diff options
author | Toni Uhlig <matzeton@googlemail.com> | 2023-07-16 02:03:33 +0200 |
---|---|---|
committer | Toni Uhlig <matzeton@googlemail.com> | 2023-07-16 02:03:33 +0200 |
commit | b31e4bc16d1df62b50c6f77a77041f9e7b6c906d (patch) | |
tree | 024c74c13d918aa6bde302aab6836fa33607613c /flatcc/test/reflection_test | |
parent | ba6815ef8fb8ae472412b5af2837a7caba2799c2 (diff) | |
parent | 5a40295c4cf0af5ea8da9ced04a4ce7d3621a080 (diff) |
Merge commit '5a40295c4cf0af5ea8da9ced04a4ce7d3621a080' as 'flatcc'
Diffstat (limited to 'flatcc/test/reflection_test')
-rw-r--r-- | flatcc/test/reflection_test/CMakeLists.txt | 20 | ||||
-rw-r--r-- | flatcc/test/reflection_test/reflection_test.c | 196 | ||||
-rwxr-xr-x | flatcc/test/reflection_test/reflection_test.sh | 24 |
3 files changed, 240 insertions, 0 deletions
diff --git a/flatcc/test/reflection_test/CMakeLists.txt b/flatcc/test/reflection_test/CMakeLists.txt new file mode 100644 index 0000000..f82d1f5 --- /dev/null +++ b/flatcc/test/reflection_test/CMakeLists.txt @@ -0,0 +1,20 @@ +include(CTest) + +set(INC_DIR "${PROJECT_SOURCE_DIR}/include") +set(GEN_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated") +set(FBS_DIR "${PROJECT_SOURCE_DIR}/test/monster_test") + +include_directories("${GEN_DIR}" "${INC_DIR}") + +add_custom_target(gen_reflection_test ALL) +add_custom_command ( + TARGET gen_reflection_test + COMMAND ${CMAKE_COMMAND} -E make_directory "${GEN_DIR}" + COMMAND flatcc_cli --schema -o "${GEN_DIR}" "${FBS_DIR}/monster_test.fbs" + DEPENDS flatcc_cli "${FBS_DIR}/monster_test.fbs" "${FBS_DIR}/include_test1.fbs" "${FBS_DIR}/include_test2.fbs" +) +add_executable(reflection_test reflection_test.c) +add_dependencies(reflection_test gen_reflection_test) +target_link_libraries(reflection_test flatccrt) + +add_test(reflection_test reflection_test${CMAKE_EXECUTABLE_SUFFIX}) diff --git a/flatcc/test/reflection_test/reflection_test.c b/flatcc/test/reflection_test/reflection_test.c new file mode 100644 index 0000000..eef0bd1 --- /dev/null +++ b/flatcc/test/reflection_test/reflection_test.c @@ -0,0 +1,196 @@ +#include "flatcc/support/readfile.h" +#include "flatcc/reflection/reflection_reader.h" +#include "flatcc/portable/pcrt.h" + +/* -DFLATCC_PORTABLE may help if inttypes.h is missing. */ +#ifndef PRId64 +#include <inttypes.h> +#endif + + +/* This is not an exhaustive test. */ +int test_schema(const char *monster_bfbs) +{ + void *buffer; + size_t size; + int ret = -1; + reflection_Schema_table_t S; + reflection_Object_vec_t Objs; + reflection_Object_table_t Obj; + reflection_Field_vec_t Flds; + reflection_Field_table_t F; + reflection_Type_table_t T; + size_t k, monster_index; + reflection_Service_vec_t Svcs; + reflection_Service_table_t Svc; + reflection_RPCCall_vec_t Calls; + reflection_RPCCall_table_t Call; + size_t call_index; + const char *strval; + + buffer = readfile(monster_bfbs, 100000, &size); + if (!buffer) { + printf("failed to load binary schema\n"); + goto done; + } + S = reflection_Schema_as_root(buffer); + Objs = reflection_Schema_objects(S); + for (k = 0; k < reflection_Object_vec_len(Objs); ++k) { + printf("dbg: obj #%d : %s\n", (int)k, + reflection_Object_name(reflection_Object_vec_at(Objs, k))); + } + k = reflection_Object_vec_find(Objs, "MyGame.Example.Monster"); + if (k == flatbuffers_not_found) { + printf("Could not find monster in schema\n"); + goto done; + } + monster_index = k; + Obj = reflection_Object_vec_at(Objs, k); + if (strcmp(reflection_Object_name(Obj), "MyGame.Example.Monster")) { + printf("Found wrong object in schema\n"); + goto done; + } + Flds = reflection_Object_fields(Obj); + k = reflection_Field_vec_find(Flds, "mana"); + if (k == flatbuffers_not_found) { + printf("Did not find mana field in Monster schema\n"); + goto done; + } + F = reflection_Field_vec_at(Flds, k); + if (reflection_Field_default_integer(F) != 150) { + printf("mana field has wrong default value\n"); + printf("field name: %s\n", reflection_Field_name(F)); + printf("%"PRId64"\n", (int64_t)reflection_Field_default_integer(F)); + goto done; + } + T = reflection_Field_type(F); + if (reflection_Type_base_type(T) != reflection_BaseType_Short) { + printf("mana field has wrong type\n"); + goto done; + } + if (reflection_Field_optional(F)) { + printf("mana field is not optional\n"); + goto done; + } + k = reflection_Field_vec_find(Flds, "enemy"); + if (k == flatbuffers_not_found) { + printf("enemy field not found\n"); + goto done; + } + T = reflection_Field_type(reflection_Field_vec_at(Flds, k)); + if (reflection_Type_base_type(T) != reflection_BaseType_Obj) { + printf("enemy is not an object\n"); + goto done; + } + if (reflection_Type_index(T) != (int32_t)monster_index) { + printf("enemy is not a monster\n"); + goto done; + } + k = reflection_Field_vec_find(Flds, "testarrayoftables"); + if (k == flatbuffers_not_found) { + printf("array of tables not found\n"); + goto done; + } + T = reflection_Field_type(reflection_Field_vec_at(Flds, k)); + if (reflection_Type_base_type(T) != reflection_BaseType_Vector) { + printf("array of tables is not of vector type\n"); + goto done; + } + if (reflection_Type_element(T) != reflection_BaseType_Obj) { + printf("array of tables is not a vector of table type\n"); + goto done; + } + if (reflection_Type_index(T) != (int32_t)monster_index) { + printf("array of tables is not a monster vector\n"); + goto done; + } + /* list services and calls */ + Svcs = reflection_Schema_services(S); + for (k = 0; k < reflection_Service_vec_len(Svcs); ++k) { + Svc = reflection_Service_vec_at(Svcs, k); + printf("dbg: svc #%d : %s\n", (int)k, + reflection_Service_name(Svc)); + Calls = reflection_Service_calls(Svc); + for (call_index = 0 ; + call_index < reflection_RPCCall_vec_len(Calls) ; + call_index++) { + Call = reflection_RPCCall_vec_at(Calls, call_index); + printf("dbg: call %d : %s\n", (int)call_index, + reflection_RPCCall_name(Call)); + } + } + /* Within service MyGame.Example.MonsterStorage ... */ + k = reflection_Service_vec_find(Svcs, "MyGame.Example.MonsterStorage"); + if (k == flatbuffers_not_found) { + printf("Could not find MonsterStorage service in schema\n"); + goto done; + } + Svc = reflection_Service_vec_at(Svcs, k); + /* ... search the RPC call Store */ + Calls = reflection_Service_calls(Svc); + k = reflection_RPCCall_vec_find(Calls, "Store"); + if (k == flatbuffers_not_found) { + printf("Could not find call Store in service\n"); + goto done; + } + Call = reflection_RPCCall_vec_at(Calls, k); + /* Ensure request type is MyGame.Example.Monster */ + Obj = reflection_Object_vec_at(Objs, monster_index); + if (Obj != reflection_RPCCall_request(Call)) { + printf("Wrong request type of rpc call\n"); + goto done; + } + /* Ensure response type is MyGame.Example.Stat */ + k = reflection_Object_vec_find(Objs, "MyGame.Example.Stat"); + if (k == flatbuffers_not_found) { + printf("Could not find Stat in schema\n"); + goto done; + } + Obj = reflection_Object_vec_at(Objs, k); + if (Obj != reflection_RPCCall_response(Call)) { + printf("Wrong response type of rpc call\n"); + goto done; + } + /* check the call has an attribute "streaming" */ + k = reflection_KeyValue_vec_scan(reflection_RPCCall_attributes(Call), "streaming"); + if (k == flatbuffers_not_found) { + printf("Could not find attribute in call\n"); + goto done; + } + /* check the attribute value is "none" */ + strval = reflection_KeyValue_value( + reflection_KeyValue_vec_at(reflection_RPCCall_attributes(Call), k)); + if (!strval || 0 != strcmp("none", strval)) { + printf("Wrong attribute value in call\n"); + goto done; + } + ret = 0; +done: + if (buffer) { + free(buffer); + } + return ret; +} + +/* We take arguments so test can run without copying sources. */ +#define usage \ +"wrong number of arguments:\n" \ +"usage: <program> [<output-filename>]\n" + +const char *filename = "generated/monster_test.bfbs"; + +int main(int argc, char *argv[]) +{ + /* Avoid assert dialogs on Windows. */ + init_headless_crt(); + + if (argc != 1 && argc != 2) { + fprintf(stderr, usage); + exit(1); + } + if (argc == 2) { + filename = argv[1]; + } + + return test_schema(filename); +} diff --git a/flatcc/test/reflection_test/reflection_test.sh b/flatcc/test/reflection_test/reflection_test.sh new file mode 100755 index 0000000..f1ad69c --- /dev/null +++ b/flatcc/test/reflection_test/reflection_test.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +set -e +cd `dirname $0`/../.. +ROOT=`pwd` +TMP=${ROOT}/build/tmp/test/reflection_test + +CC=${CC:-cc} +${ROOT}/scripts/build.sh +mkdir -p ${TMP}/generated +rm -rf ${TMP}/generated/* +bin/flatcc --schema -o ${TMP}/generated test/monster_test/monster_test.fbs + +cp test/reflection_test/*.c ${TMP} +cd ${TMP} + +$CC -g -I ${ROOT}/include reflection_test.c \ + ${ROOT}/lib/libflatccrt.a -o reflection_test_d +$CC -O3 -DNDEBUG -I ${ROOT}/include reflection_test.c \ + ${ROOT}/lib/libflatccrt.a -o reflection_test +echo "running reflection test debug" +./reflection_test_d +echo "running reflection test optimized" +./reflection_test |