From 14c201031fa9a8c1cb8f1ce53ce32ea618dee219 Mon Sep 17 00:00:00 2001 From: tmadlener Date: Thu, 15 Jun 2023 11:15:55 +0200 Subject: [PATCH] Add first simple tests for "trivial" schema evolution --- tests/CTestCustom.cmake | 3 + tests/schema_evolution/CMakeLists.txt | 20 +++++++ tests/schema_evolution/README.md | 18 ++++++ tests/schema_evolution/datalayout_old.yaml | 1 - tests/schema_evolution/read_new_data.h | 51 +++++++++++++++++ tests/schema_evolution/root_io/CMakeLists.txt | 4 ++ .../root_io/read_new_data_root.cpp | 7 +++ .../root_io/write_old_data_root.cpp | 7 +++ tests/schema_evolution/write_old_data.h | 55 +++++++++++++++++++ 9 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 tests/schema_evolution/README.md create mode 100644 tests/schema_evolution/read_new_data.h create mode 100644 tests/schema_evolution/root_io/CMakeLists.txt create mode 100644 tests/schema_evolution/root_io/read_new_data_root.cpp create mode 100644 tests/schema_evolution/root_io/write_old_data_root.cpp create mode 100644 tests/schema_evolution/write_old_data.h diff --git a/tests/CTestCustom.cmake b/tests/CTestCustom.cmake index f435ebc7c..5dd3d86d9 100644 --- a/tests/CTestCustom.cmake +++ b/tests/CTestCustom.cmake @@ -58,6 +58,9 @@ if ((NOT "@FORCE_RUN_ALL_TESTS@" STREQUAL "ON") AND (NOT "@USE_SANITIZER@" STREQ datamodel_def_store_roundtrip_root_extension datamodel_def_store_roundtrip_sio datamodel_def_store_roundtrip_sio_extension + + write_old_data_root + read_new_data_root ) foreach(version in @legacy_versions@) diff --git a/tests/schema_evolution/CMakeLists.txt b/tests/schema_evolution/CMakeLists.txt index ef738f3cd..e76867a13 100644 --- a/tests/schema_evolution/CMakeLists.txt +++ b/tests/schema_evolution/CMakeLists.txt @@ -12,3 +12,23 @@ PODIO_ADD_ROOT_IO_DICT(TestDataModel_v1Dict TestDataModel_v1 "${headers}" ${CMAK ) PODIO_ADD_SIO_IO_BLOCKS(TestDataModel_v1 "${headers}" "${sources}") + +#--- Helper function to create a test in an environment that is suitable to +#--- write data in an old schema version +function(PODIO_CREATE_WRITE_OLD_DATA_TEST sourcefile additional_libs) + string( REPLACE ".cpp" "" name ${sourcefile} ) + add_executable( ${name} ${sourcefile} ) + add_test(NAME ${name} COMMAND ${name}) + + target_link_libraries(${name} PRIVATE TestDataModel_v1 ${additional_libs}) + target_include_directories(${name} PRIVATE ${CMAKE_SOURCE_DIR}/tests/schema_evolution) + + set_property(TEST ${name} + PROPERTY ENVIRONMENT + LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/src:${CMAKE_CURRENT_BINARY_DIR}:$:$<$:$>:$ENV{LD_LIBRARY_PATH} + PODIO_SIO_BLOCK=${CMAKE_CURRENT_BINARY_DIR} + ROOT_INCLUDE_PATH=${CMAKE_CURRENT_BINARY_DIR}/datamodel_old:${CMAKE_SOURCE_DIR}/include + ) +endfunction() + +add_subdirectory(root_io) diff --git a/tests/schema_evolution/README.md b/tests/schema_evolution/README.md new file mode 100644 index 000000000..0b55945ab --- /dev/null +++ b/tests/schema_evolution/README.md @@ -0,0 +1,18 @@ +# Schema Evolution tests +This folder contains tests for the schema evolution functionality in podio. The +functionality is tested by first writing data with an old schema version and +then reading in with the current schema version. +[`datalayout_old.yaml`](./datalayout_old.yaml) holds the definition of the old +version, using schema version 1, while the +[`datalayout.yaml`](../datalayout.yaml) that is also used for the other I/O +tests is used as the current version (schema version 2). + +## Differences between the two schema versions +Since it is not immediately visible from the test code this list contains the +differences between the two schema versions, and also how this evolution is +tested (if it is supported) + +| component / datatype | difference from v1 to v2 | purpose of test | tested with | +|--|--|--|--| +| `SimpleStruct` | no `int y` member in v1 | Addition of new members in components | As member of `ExampleWithArrayComponent` | +| `ExampleHit` | no `double energy` member in v1 | Addition of new members in datatypes | Directly via `ExampleHit` | diff --git a/tests/schema_evolution/datalayout_old.yaml b/tests/schema_evolution/datalayout_old.yaml index b6aa605b8..514a75b72 100755 --- a/tests/schema_evolution/datalayout_old.yaml +++ b/tests/schema_evolution/datalayout_old.yaml @@ -71,7 +71,6 @@ datatypes : - double x // x-coordinate - double y // y-coordinate - double z // z-coordinate - - double energy // measured energy deposit ExampleMC : Description : "Example MC-particle" diff --git a/tests/schema_evolution/read_new_data.h b/tests/schema_evolution/read_new_data.h new file mode 100644 index 000000000..e31e3c3e8 --- /dev/null +++ b/tests/schema_evolution/read_new_data.h @@ -0,0 +1,51 @@ +#ifndef PODIO_TESTS_SCHEMAEVOLUTION_READNEWDATA_H // NOLINT(llvm-header-guard): folder structure not suitable +#define PODIO_TESTS_SCHEMAEVOLUTION_READNEWDATA_H // NOLINT(llvm-header-guard): folder structure not suitable + +#include "datamodel/ExampleHitCollection.h" +#include "datamodel/ExampleWithArrayComponentCollection.h" + +#include "podio/Frame.h" + +#include +#include + +int readSimpleStruct(const podio::Frame& event) { + const auto& coll = event.get("simpleStructTest"); + auto elem = coll[0]; + const auto sstruct = elem.s(); + + if (sstruct.y != 0 || sstruct.x != 42 || sstruct.z != 123) { + return 1; + } + return 0; +} + +int readExampleHit(const podio::Frame& event) { + const auto& coll = event.get("datatypeMemberAdditionTest"); + auto elem = coll[0]; + + if (elem.energy() != 0) { + return 1; + } + if (elem.x() != 1.23 || elem.y() != 1.23 || elem.z() != 1.23 || elem.cellID() != 0xcaffee) { + return 1; + } + + return 0; +} + +template +int read_new_data(const std::string& filename) { + ReaderT reader{}; + reader.openFile(filename); + + const auto event = podio::Frame(reader.readEntry("events", 0)); + + int result = 0; + result += readSimpleStruct(event); + result += readExampleHit(event); + + return result; +} + +#endif // PODIO_TESTS_SCHEMAEVOLUTION_WRITEOLDDATA_H diff --git a/tests/schema_evolution/root_io/CMakeLists.txt b/tests/schema_evolution/root_io/CMakeLists.txt new file mode 100644 index 000000000..e756cc01a --- /dev/null +++ b/tests/schema_evolution/root_io/CMakeLists.txt @@ -0,0 +1,4 @@ +PODIO_CREATE_WRITE_OLD_DATA_TEST(write_old_data_root.cpp "TestDataModel_v1Dict;podio::podioRootIO") + +CREATE_PODIO_TEST(read_new_data_root.cpp "TestDataModelDict;podioRootIO") +set_property(TEST read_new_data_root PROPERTY DEPENDS write_old_data_root) diff --git a/tests/schema_evolution/root_io/read_new_data_root.cpp b/tests/schema_evolution/root_io/read_new_data_root.cpp new file mode 100644 index 000000000..8bf874e78 --- /dev/null +++ b/tests/schema_evolution/root_io/read_new_data_root.cpp @@ -0,0 +1,7 @@ +#include "schema_evolution/read_new_data.h" + +#include "podio/ROOTFrameReader.h" + +int main() { + return read_new_data("example_data_old_schema.root"); +} diff --git a/tests/schema_evolution/root_io/write_old_data_root.cpp b/tests/schema_evolution/root_io/write_old_data_root.cpp new file mode 100644 index 000000000..c5fc23880 --- /dev/null +++ b/tests/schema_evolution/root_io/write_old_data_root.cpp @@ -0,0 +1,7 @@ +#include "write_old_data.h" + +#include "podio/ROOTFrameWriter.h" + +int main() { + return writeData("example_data_old_schema.root"); +} diff --git a/tests/schema_evolution/write_old_data.h b/tests/schema_evolution/write_old_data.h new file mode 100644 index 000000000..651359c90 --- /dev/null +++ b/tests/schema_evolution/write_old_data.h @@ -0,0 +1,55 @@ +#ifndef PODIO_TESTS_SCHEMAEVOLUTION_WRITEOLDDATA_H // NOLINT(llvm-header-guard): folder structure not suitable +#define PODIO_TESTS_SCHEMAEVOLUTION_WRITEOLDDATA_H // NOLINT(llvm-header-guard): folder structure not suitable + +#include "datamodel/ExampleHitCollection.h" +#include "datamodel/ExampleWithArrayComponentCollection.h" + +#include "podio/Frame.h" + +#include + +/// This is a datatype that holds a SimpleStruct component +auto writeSimpleStruct() { + ExampleWithArrayComponentCollection coll; + auto elem = coll.create(); + auto sstruct = SimpleStruct(); + sstruct.x = 42; + sstruct.z = 123; + elem.s(sstruct); + + return coll; +} + +auto writeExampleHit() { + ExampleHitCollection coll; + auto elem = coll.create(); + elem.x(1.23); + elem.y(1.23); + elem.z(1.23); + elem.cellID(0xcaffee); + + return coll; +} + +podio::Frame createFrame() { + podio::Frame event; + + event.put(writeSimpleStruct(), "simpleStructTest"); + event.put(writeExampleHit(), "dataTypeMemberAdditionTest"); + + return event; +} + +template +int writeData(const std::string& filename) { + WriterT writer(filename); + + auto event = createFrame(); + writer.writeFrame(event, "events"); + + writer.finish(); + + return 0; +} + +#endif // PODIO_TESTS_SCHEMAEVOLUTION_WRITEOLDDATA_H