Skip to content

Commit

Permalink
Refactor test.cpp (#7487)
Browse files Browse the repository at this point in the history
* Add timing command to cmakelist

* Start to split test.cpp. Move flexbuffers tests

* Move monster related tests to own file

* Move parser related tests to own file

* Move json related tests to own file

* Move proto related tests to own file

* moved more functions to parser test

* moved more functions to parser test2

* move monster extra tests to monster test

* move evolution tests to own file

* move reflection tests to own file

* move util tests to own file

* rehomed various tests

* move optional scalars test to own file:

* rehome more tests

* move fuzz tests. Got rid of global test_data_path

* fixes for CI failures

* add bazel files
  • Loading branch information
dbaileychess committed Aug 28, 2022
1 parent 7edf8c9 commit 694add6
Show file tree
Hide file tree
Showing 24 changed files with 3,794 additions and 3,405 deletions.
18 changes: 18 additions & 0 deletions CMakeLists.txt
Expand Up @@ -87,6 +87,14 @@ if(MSVC OR CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC")
set(MSVC_LIKE ON)
endif()

if(DEFINED FLATBUFFERS_COMPILATION_TIMINGS)
message("Recording Compilation Timings to ${FLATBUFFERS_COMPILATION_TIMINGS}")
file(REMOVE ${FLATBUFFERS_COMPILATION_TIMINGS})
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "time -f 'Wall: %E User: %U Sys: %S | %C' -q -a -o ${FLATBUFFERS_COMPILATION_TIMINGS}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_CUSTOM "time -f 'Wall: %E User: %U Sys: %S | %C' -q -a -o ${FLATBUFFERS_COMPILATION_TIMINGS}")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "time -f 'Wall: %E User: %U Sys: %S | %C' -q -a -o ${FLATBUFFERS_COMPILATION_TIMINGS}")
endif()

if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
message(WARNING
"Cannot build tests without building the compiler. Tests will be disabled.")
Expand Down Expand Up @@ -205,11 +213,21 @@ set(FlatHash_SRCS
set(FlatBuffers_Tests_SRCS
${FlatBuffers_Library_SRCS}
src/idl_gen_fbs.cpp
tests/evolution_test.cpp
tests/flexbuffers_test.cpp
tests/fuzz_test.cpp
tests/json_test.cpp
tests/monster_test.cpp
tests/optional_scalars_test.cpp
tests/parser_test.cpp
tests/proto_test.cpp
tests/reflection_test.cpp
tests/test.cpp
tests/test_assert.h
tests/test_assert.cpp
tests/test_builder.h
tests/test_builder.cpp
tests/util_test.cpp
tests/native_type_test_impl.h
tests/native_type_test_impl.cpp
include/flatbuffers/code_generators.h
Expand Down
21 changes: 21 additions & 0 deletions tests/BUILD.bazel
Expand Up @@ -9,20 +9,41 @@ cc_test(
name = "flatbuffers_test",
testonly = 1,
srcs = [
"evolution_test.cpp",
"evolution_test.h",
"evolution_test/evolution_v1_generated.h",
"evolution_test/evolution_v2_generated.h",
"flexbuffers_test.cpp",
"flexbuffers_test.h",
"fuzz_test.cpp",
"fuzz_test.h",
"is_quiet_nan.h",
"json_test.cpp",
"json_test.h",
"monster_test.cpp",
"monster_test.h",
"monster_test_bfbs_generated.h",
"namespace_test/namespace_test1_generated.h",
"namespace_test/namespace_test2_generated.h",
"native_type_test_impl.cpp",
"native_type_test_impl.h",
"optional_scalars_generated.h",
"optional_scalars_test.cpp",
"optional_scalars_test.h",
"parser_test.cpp",
"parser_test.h",
"proto_test.cpp",
"proto_test.h",
"reflection_test.cpp",
"reflection_test.h",
"test.cpp",
"test_assert.cpp",
"test_assert.h",
"test_builder.cpp",
"test_builder.h",
"union_vector/union_vector_generated.h",
"util_test.cpp",
"util_test.h",
],
copts = [
"-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
Expand Down
139 changes: 139 additions & 0 deletions tests/evolution_test.cpp
@@ -0,0 +1,139 @@
#include "evolution_test.h"

#include "evolution_test/evolution_v1_generated.h"
#include "evolution_test/evolution_v2_generated.h"
#include "flatbuffers/idl.h"
#include "test_assert.h"

namespace flatbuffers {
namespace tests {

void EvolutionTest(const std::string &tests_data_path) {
// VS10 does not support typed enums, exclude from tests
#if !defined(_MSC_VER) || _MSC_VER >= 1700
const int NUM_VERSIONS = 2;
std::string schemas[NUM_VERSIONS];
std::string jsonfiles[NUM_VERSIONS];
std::vector<uint8_t> binaries[NUM_VERSIONS];

flatbuffers::IDLOptions idl_opts;
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
flatbuffers::Parser parser(idl_opts);

// Load all the schema versions and their associated data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
std::string schema = tests_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".fbs";
TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
std::string json = tests_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".json";
TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i]));

TEST_ASSERT(parser.Parse(schemas[i].c_str()));
TEST_ASSERT(parser.Parse(jsonfiles[i].c_str()));

auto bufLen = parser.builder_.GetSize();
auto buf = parser.builder_.GetBufferPointer();
binaries[i].reserve(bufLen);
std::copy(buf, buf + bufLen, std::back_inserter(binaries[i]));
}

// Assert that all the verifiers for the different schema versions properly
// verify any version data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
flatbuffers::Verifier verifier(&binaries[i].front(), binaries[i].size());
TEST_ASSERT(Evolution::V1::VerifyRootBuffer(verifier));
TEST_ASSERT(Evolution::V2::VerifyRootBuffer(verifier));
}

// Test backwards compatibility by reading old data with an evolved schema.
auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front());
// field 'k' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->k());
// field 'l' is new in version 2 with a default of 56.
TEST_EQ(root_v1_viewed_from_v2->l(), 56);
// field 'c' of 'TableA' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c());
// 'TableC' was added to field 'c' union in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->c_as_TableC());
// The field 'c' union should be of type 'TableB' regardless of schema version
TEST_ASSERT(root_v1_viewed_from_v2->c_type() == Evolution::V2::Union::TableB);
// The field 'f' was renamed to 'ff' in version 2, it should still be
// readable.
TEST_EQ(root_v1_viewed_from_v2->ff()->a(), 16);

// Test forwards compatibility by reading new data with an old schema.
auto root_v2_viewed_from_v1 = Evolution::V1::GetRoot(&binaries[1].front());
// The field 'c' union in version 2 is a new table (index = 3) and should
// still be accessible, but not interpretable.
TEST_EQ(static_cast<uint8_t>(root_v2_viewed_from_v1->c_type()), 3);
TEST_NOTNULL(root_v2_viewed_from_v1->c());
// The field 'd' enum in verison 2 has new members and should still be
// accessible, but not interpretable.
TEST_EQ(static_cast<int8_t>(root_v2_viewed_from_v1->d()), 3);
// The field 'a' in version 2 is deprecated and should return the default
// value (0) instead of the value stored in the in the buffer (42).
TEST_EQ(root_v2_viewed_from_v1->a(), 0);
// The field 'ff' was originally named 'f' in version 1, it should still be
// readable.
TEST_EQ(root_v2_viewed_from_v1->f()->a(), 35);
#endif
}

void ConformTest() {
flatbuffers::Parser parser;
TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);

auto test_conform = [](flatbuffers::Parser &parser1, const char *test,
const char *expected_err) {
flatbuffers::Parser parser2;
TEST_EQ(parser2.Parse(test), true);
auto err = parser2.ConformTo(parser1);
TEST_NOTNULL(strstr(err.c_str(), expected_err));
};

test_conform(parser, "table T { A:byte; }", "types differ for field");
test_conform(parser, "table T { B:int; A:int; }", "offsets differ for field");
test_conform(parser, "table T { A:int = 1; }", "defaults differ for field");
test_conform(parser, "table T { B:float; }",
"field renamed to different type");
test_conform(parser, "enum E:byte { B, A }", "values differ for enum");
}

void UnionDeprecationTest(const std::string& tests_data_path) {
const int NUM_VERSIONS = 2;
std::string schemas[NUM_VERSIONS];
std::string jsonfiles[NUM_VERSIONS];
std::vector<uint8_t> binaries[NUM_VERSIONS];

flatbuffers::IDLOptions idl_opts;
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
flatbuffers::Parser parser(idl_opts);

// Load all the schema versions and their associated data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
std::string schema = tests_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".fbs";
TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
std::string json = tests_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".json";
TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i]));

TEST_ASSERT(parser.Parse(schemas[i].c_str()));
TEST_ASSERT(parser.Parse(jsonfiles[i].c_str()));

auto bufLen = parser.builder_.GetSize();
auto buf = parser.builder_.GetBufferPointer();
binaries[i].reserve(bufLen);
std::copy(buf, buf + bufLen, std::back_inserter(binaries[i]));
}

auto v2 = parser.LookupStruct("Evolution.V2.Root");
TEST_NOTNULL(v2);
auto j_type_field = v2->fields.Lookup("j_type");
TEST_NOTNULL(j_type_field);
TEST_ASSERT(j_type_field->deprecated);
}

} // namespace tests
} // namespace flatbuffers
16 changes: 16 additions & 0 deletions tests/evolution_test.h
@@ -0,0 +1,16 @@
#ifndef TESTS_EVOLUTION_TEST_H
#define TESTS_EVOLUTION_TEST_H

#include <string>

namespace flatbuffers {
namespace tests {

void EvolutionTest(const std::string &tests_data_path);
void ConformTest();
void UnionDeprecationTest(const std::string &tests_data_path);

} // namespace tests
} // namespace flatbuffers

#endif

0 comments on commit 694add6

Please sign in to comment.