mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-06 21:37:36 +00:00
[C++] Adds basic schema evolution tests (#5611)
* Added basic schema evolution tests * Add BUILD targets for evolution tests. Added to test/generate_code scripts * Use vector.front() instead of vector.data() * Added --scoped-enums option for evolution test
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
adbcbba5d1
commit
dda095023d
@@ -37,6 +37,8 @@
|
||||
#include "monster_extra_generated.h"
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
||||
# include "arrays_test_generated.h"
|
||||
# include "evolution_test/evolution_v1_generated.h"
|
||||
# include "evolution_test/evolution_v2_generated.h"
|
||||
#endif
|
||||
|
||||
#include "native_type_test_generated.h"
|
||||
@@ -2310,6 +2312,76 @@ void InvalidNestedFlatbufferTest() {
|
||||
false);
|
||||
}
|
||||
|
||||
void EvolutionTest() {
|
||||
// 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::Verifier *verifiers[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 = test_data_path + "evolution_test/evolution_v" +
|
||||
flatbuffers::NumToString(i + 1) + ".fbs";
|
||||
TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
|
||||
std::string json = test_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]));
|
||||
|
||||
verifiers[i] = new flatbuffers::Verifier(&binaries[i].front(), bufLen);
|
||||
}
|
||||
|
||||
// Assert that all the verifiers for the different schema versions properly verify any version data.
|
||||
for (int i = 0; i < NUM_VERSIONS; ++i) {
|
||||
TEST_ASSERT(Evolution::V1::VerifyRootBuffer(*verifiers[i]));
|
||||
TEST_ASSERT(Evolution::V2::VerifyRootBuffer(*verifiers[i]));
|
||||
}
|
||||
|
||||
// Test backwards compatibility by reading old data with an evolved schema.
|
||||
auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front());
|
||||
// field 'j' is new in version 2, so it should be null.
|
||||
TEST_EQ(root_v1_viewed_from_v2->j(), NULL);
|
||||
// field 'k' is new in version 2 with a default of 56.
|
||||
TEST_EQ(root_v1_viewed_from_v2->k(), 56);
|
||||
// field 'c' of 'TableA' is new in version 2, so it should be null.
|
||||
TEST_EQ(root_v1_viewed_from_v2->e()->c(), NULL);
|
||||
// 'TableC' was added to field 'c' union in version 2, so it should be null.
|
||||
TEST_EQ(root_v1_viewed_from_v2->c_as_TableC(), NULL);
|
||||
// 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 UnionVectorTest() {
|
||||
// load FlatBuffer fbs schema and json.
|
||||
std::string schemafile, jsonfile;
|
||||
@@ -3070,6 +3142,7 @@ int FlatBufferTests() {
|
||||
FixedLengthArrayJsonTest(true);
|
||||
ReflectionTest(flatbuf.data(), flatbuf.size());
|
||||
ParseProtoTest();
|
||||
EvolutionTest();
|
||||
UnionVectorTest();
|
||||
LoadVerifyBinaryTest();
|
||||
GenerateTableTextTest();
|
||||
|
||||
Reference in New Issue
Block a user