File indexing completed on 2025-04-10 08:00:12
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/unit_test.hpp>
0010 #include <boost/test/unit_test_log.hpp>
0011
0012 #include "Acts/Tests/CommonHelpers/WhiteBoardUtilities.hpp"
0013 #include "Acts/Utilities/Logger.hpp"
0014 #include "ActsExamples/Framework/DataHandle.hpp"
0015 #include "ActsExamples/Framework/Sequencer.hpp"
0016 #include "ActsExamples/Framework/WhiteBoard.hpp"
0017
0018 using namespace Acts::Test;
0019 using namespace ActsExamples;
0020 using Acts::Logging::ScopedFailureThreshold;
0021
0022
0023 const Acts::Logger& logger() {
0024 static const auto logger =
0025 Acts::getDefaultLogger("DataHandleTest", Acts::Logging::VERBOSE);
0026 return *logger;
0027 }
0028
0029 BOOST_AUTO_TEST_SUITE(DataHandleTest)
0030
0031 BOOST_AUTO_TEST_CASE(BasicOperations) {
0032 WhiteBoard wb;
0033 DummySequenceElement dummyElement;
0034
0035 BOOST_TEST_CHECKPOINT("Test adding and retrieving objects");
0036 {
0037 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0038 writeHandle.initialize("test_key");
0039 writeHandle(wb, 42);
0040
0041 ReadDataHandle<int> readHandle(&dummyElement, "test");
0042 readHandle.initialize("test_key");
0043 BOOST_CHECK_EQUAL(readHandle(wb), 42);
0044 }
0045
0046 BOOST_TEST_CHECKPOINT("Test initialize with empty key");
0047 {
0048 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0049 BOOST_CHECK_THROW(writeHandle.initialize(""), std::invalid_argument);
0050 }
0051
0052 BOOST_TEST_CHECKPOINT("Test maybeInitialize");
0053 {
0054 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0055 writeHandle.maybeInitialize("");
0056 BOOST_CHECK(!writeHandle.isInitialized());
0057
0058 writeHandle.maybeInitialize("maybe_key");
0059 BOOST_CHECK(writeHandle.isInitialized());
0060 writeHandle(wb, 42);
0061
0062 ReadDataHandle<int> readHandle(&dummyElement, "test");
0063 readHandle.maybeInitialize("maybe_key");
0064 BOOST_CHECK(readHandle.isInitialized());
0065 BOOST_CHECK_EQUAL(readHandle(wb), 42);
0066 }
0067
0068 BOOST_TEST_CHECKPOINT("Test uninitialized handles");
0069 {
0070 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0071 BOOST_CHECK_THROW(writeHandle(wb, 42), std::runtime_error);
0072
0073 ReadDataHandle<int> readHandle(&dummyElement, "test");
0074 BOOST_CHECK_THROW(readHandle(wb), std::runtime_error);
0075 }
0076
0077 BOOST_TEST_CHECKPOINT("Test adding duplicate objects");
0078 {
0079 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0080 writeHandle.initialize("duplicate_key");
0081 writeHandle(wb, 42);
0082 BOOST_CHECK_THROW(writeHandle(wb, 43), std::invalid_argument);
0083 }
0084
0085 BOOST_TEST_CHECKPOINT("Test getting non-existent objects");
0086 {
0087 ReadDataHandle<int> readHandle(&dummyElement, "test");
0088 readHandle.initialize("missing_key");
0089 BOOST_CHECK_THROW(readHandle(wb), std::out_of_range);
0090 }
0091
0092 BOOST_TEST_CHECKPOINT("Test getting objects with wrong type");
0093 {
0094 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0095 writeHandle.initialize("type_key");
0096 writeHandle(wb, 42);
0097
0098 ReadDataHandle<std::string> readHandle(&dummyElement, "test");
0099 readHandle.initialize("type_key");
0100 BOOST_CHECK_THROW(readHandle(wb), std::out_of_range);
0101 }
0102
0103 BOOST_TEST_CHECKPOINT("Test similar name suggestions");
0104 {
0105 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0106 writeHandle.initialize("similar_key");
0107 writeHandle(wb, 42);
0108
0109 ReadDataHandle<int> readHandle(&dummyElement, "test");
0110 readHandle.initialize("similr_key");
0111 BOOST_CHECK_THROW(readHandle(wb), std::out_of_range);
0112 }
0113 }
0114
0115 BOOST_AUTO_TEST_CASE(ComplexTypes) {
0116 WhiteBoard wb;
0117 DummySequenceElement dummyElement;
0118
0119 BOOST_TEST_CHECKPOINT("Test with vector type");
0120 {
0121 std::vector<int> data = {1, 2, 3};
0122 WriteDataHandle<std::vector<int>> writeHandle(&dummyElement, "test");
0123 writeHandle.initialize("vector_key");
0124 writeHandle(wb, std::move(data));
0125
0126 ReadDataHandle<std::vector<int>> readHandle(&dummyElement, "test");
0127 readHandle.initialize("vector_key");
0128 const auto& result = readHandle(wb);
0129 BOOST_CHECK_EQUAL(result.size(), 3);
0130 BOOST_CHECK_EQUAL(result[0], 1);
0131 BOOST_CHECK_EQUAL(result[1], 2);
0132 BOOST_CHECK_EQUAL(result[2], 3);
0133 }
0134
0135 BOOST_TEST_CHECKPOINT("Test with string type");
0136 {
0137 std::string data = "test string";
0138 WriteDataHandle<std::string> writeHandle(&dummyElement, "test");
0139 writeHandle.initialize("string_key");
0140 writeHandle(wb, std::move(data));
0141
0142 ReadDataHandle<std::string> readHandle(&dummyElement, "test");
0143 readHandle.initialize("string_key");
0144 BOOST_CHECK_EQUAL(readHandle(wb), "test string");
0145 }
0146 }
0147
0148 BOOST_AUTO_TEST_CASE(DataHandleCompatibility) {
0149 WhiteBoard wb;
0150 DummySequenceElement dummyElement;
0151
0152 BOOST_TEST_CHECKPOINT("Test write handle with same type");
0153 {
0154 WriteDataHandle<int> writeHandle1(&dummyElement, "test1");
0155 writeHandle1.initialize("same_key");
0156 writeHandle1(wb, 42);
0157
0158 WriteDataHandle<int> writeHandle2(&dummyElement, "test2");
0159 writeHandle2.initialize("same_key");
0160 BOOST_CHECK_THROW(writeHandle2(wb, 43), std::invalid_argument);
0161 }
0162
0163 BOOST_TEST_CHECKPOINT("Test write handle with different type");
0164 {
0165 WriteDataHandle<int> writeHandle1(&dummyElement, "test1");
0166 writeHandle1.initialize("diff_key");
0167 writeHandle1(wb, 42);
0168
0169 WriteDataHandle<std::string> writeHandle2(&dummyElement, "test2");
0170 writeHandle2.initialize("diff_key");
0171 BOOST_CHECK_THROW(writeHandle2(wb, "test"), std::invalid_argument);
0172 }
0173
0174 BOOST_TEST_CHECKPOINT("Test read handle with same type");
0175 {
0176 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0177 writeHandle.initialize("read_key");
0178 writeHandle(wb, 42);
0179
0180 ReadDataHandle<int> readHandle1(&dummyElement, "test1");
0181 readHandle1.initialize("read_key");
0182 BOOST_CHECK_EQUAL(readHandle1(wb), 42);
0183
0184 ReadDataHandle<int> readHandle2(&dummyElement, "test2");
0185 readHandle2.initialize("read_key");
0186 BOOST_CHECK_EQUAL(readHandle2(wb), 42);
0187 }
0188
0189 BOOST_TEST_CHECKPOINT("Test read handle with different type");
0190 {
0191 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0192 writeHandle.initialize("type_key");
0193 writeHandle(wb, 42);
0194
0195 ReadDataHandle<std::string> readHandle(&dummyElement, "test");
0196 readHandle.initialize("type_key");
0197 BOOST_CHECK_THROW(readHandle(wb), std::out_of_range);
0198 }
0199 }
0200
0201 BOOST_AUTO_TEST_CASE(WhiteBoardCopy) {
0202 WhiteBoard wb1;
0203 WhiteBoard wb2;
0204 DummySequenceElement dummyElement;
0205
0206 BOOST_TEST_CHECKPOINT("Test copying from another whiteboard");
0207 {
0208 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0209 writeHandle.initialize("copy_key");
0210 writeHandle(wb1, 42);
0211
0212 wb2.copyFrom(wb1);
0213
0214 ReadDataHandle<int> readHandle(&dummyElement, "test");
0215 readHandle.initialize("copy_key");
0216 BOOST_CHECK_EQUAL(readHandle(wb2), 42);
0217 }
0218
0219 BOOST_TEST_CHECKPOINT("Test copying with duplicate keys");
0220 {
0221 WriteDataHandle<int> writeHandle1(&dummyElement, "test1");
0222 writeHandle1.initialize("duplicate_key");
0223 writeHandle1(wb1, 42);
0224
0225 WriteDataHandle<int> writeHandle2(&dummyElement, "test2");
0226 writeHandle2.initialize("duplicate_key");
0227 writeHandle2(wb2, 43);
0228
0229 BOOST_CHECK_THROW(wb2.copyFrom(wb1), std::invalid_argument);
0230 }
0231 }
0232
0233 BOOST_AUTO_TEST_CASE(EmulateStateConsistency) {
0234 DummySequenceElement dummyElement;
0235 DataHandleBase::StateMapType state;
0236 WhiteBoard::AliasMapType aliases;
0237 std::vector<std::unique_ptr<WriteDataHandleBase>> writeHandles;
0238 std::vector<std::unique_ptr<ReadDataHandleBase>> readHandles;
0239
0240 BOOST_TEST_CHECKPOINT("Test write handle emulation");
0241 {
0242 auto& writeHandle = *writeHandles.emplace_back(
0243 std::make_unique<WriteDataHandle<int>>(&dummyElement, "test"));
0244 writeHandle.initialize("test_key");
0245 writeHandle.emulate(state, aliases, logger());
0246
0247
0248 BOOST_CHECK(state.contains("test_key"));
0249 BOOST_CHECK_EQUAL(state["test_key"], &writeHandle);
0250 }
0251
0252 BOOST_TEST_CHECKPOINT(
0253 "Test read handle emulation with compatible write handle");
0254 {
0255 auto& readHandle = *readHandles.emplace_back(
0256 std::make_unique<ReadDataHandle<int>>(&dummyElement, "test"));
0257 readHandle.initialize("test_key");
0258 readHandle.emulate(state, aliases, logger());
0259
0260 }
0261
0262 BOOST_TEST_CHECKPOINT(
0263 "Test read handle emulation with incompatible write handle");
0264 {
0265 state.clear();
0266 aliases.clear();
0267
0268 auto& writeHandle = *writeHandles.emplace_back(
0269 std::make_unique<WriteDataHandle<std::string>>(&dummyElement, "test"));
0270 writeHandle.initialize("test_key");
0271 writeHandle.emulate(state, aliases, logger());
0272
0273 auto& readHandle = *readHandles.emplace_back(
0274 std::make_unique<ReadDataHandle<int>>(&dummyElement, "test"));
0275 readHandle.initialize("test_key");
0276 ScopedFailureThreshold st(Acts::Logging::Level::FATAL);
0277 BOOST_CHECK_THROW(readHandle.emulate(state, aliases, logger()),
0278 SequenceConfigurationException);
0279 }
0280
0281 BOOST_TEST_CHECKPOINT("Test read handle emulation with missing write handle");
0282 {
0283 state.clear();
0284 aliases.clear();
0285 auto& readHandle = *readHandles.emplace_back(
0286 std::make_unique<ReadDataHandle<int>>(&dummyElement, "test"));
0287 readHandle.initialize("missing_key");
0288 ScopedFailureThreshold st(Acts::Logging::Level::FATAL);
0289 BOOST_CHECK_THROW(readHandle.emulate(state, aliases, logger()),
0290 SequenceConfigurationException);
0291 }
0292
0293 BOOST_TEST_CHECKPOINT("Test write handle emulation with duplicate key");
0294 {
0295 state.clear();
0296 aliases.clear();
0297 auto& writeHandle1 = *writeHandles.emplace_back(
0298 std::make_unique<WriteDataHandle<int>>(&dummyElement, "test1"));
0299 writeHandle1.initialize("duplicate_key");
0300 writeHandle1.emulate(state, aliases, logger());
0301
0302 auto& writeHandle2 = *writeHandles.emplace_back(
0303 std::make_unique<WriteDataHandle<int>>(&dummyElement, "test2"));
0304 writeHandle2.initialize("duplicate_key");
0305 ScopedFailureThreshold st(Acts::Logging::Level::FATAL);
0306 BOOST_CHECK_THROW(writeHandle2.emulate(state, aliases, logger()),
0307 SequenceConfigurationException);
0308 }
0309
0310 BOOST_TEST_CHECKPOINT("Test alias handling");
0311 {
0312 state.clear();
0313 aliases.clear();
0314
0315 auto& writeHandle = *writeHandles.emplace_back(
0316 std::make_unique<WriteDataHandle<int>>(&dummyElement, "test"));
0317 writeHandle.initialize("original_key");
0318 writeHandle.emulate(state, aliases, logger());
0319
0320
0321 aliases.insert({"original_key", "alias_key"});
0322 state.insert({"alias_key", &writeHandle});
0323
0324
0325 auto& readHandle = *readHandles.emplace_back(
0326 std::make_unique<ReadDataHandle<int>>(&dummyElement, "test"));
0327 readHandle.initialize("alias_key");
0328 readHandle.emulate(state, aliases, logger());
0329
0330 }
0331 }
0332
0333 BOOST_AUTO_TEST_CASE(ConsumeDataHandleTest) {
0334 WhiteBoard wb;
0335 DummySequenceElement dummyElement;
0336
0337 BOOST_TEST_CHECKPOINT("Test basic consume functionality");
0338 {
0339 WriteDataHandle<int> writeHandle(&dummyElement, "test");
0340 writeHandle.initialize("consume_key");
0341 writeHandle(wb, 42);
0342
0343 ConsumeDataHandle<int> consumeHandle(&dummyElement, "test");
0344 consumeHandle.initialize("consume_key");
0345 BOOST_CHECK_EQUAL(consumeHandle(wb), 42);
0346
0347
0348 BOOST_CHECK(!wb.exists("consume_key"));
0349 ReadDataHandle<int> readHandle(&dummyElement, "test");
0350 readHandle.initialize("consume_key");
0351 BOOST_CHECK_THROW(readHandle(wb), std::out_of_range);
0352 }
0353
0354 BOOST_TEST_CHECKPOINT("Test consume handle emulation");
0355 {
0356 DataHandleBase::StateMapType state;
0357 WhiteBoard::AliasMapType aliases;
0358 std::vector<std::unique_ptr<WriteDataHandleBase>> writeHandles;
0359 std::vector<std::unique_ptr<ReadDataHandleBase>> readHandles;
0360
0361
0362 auto& writeHandle = *writeHandles.emplace_back(
0363 std::make_unique<WriteDataHandle<int>>(&dummyElement, "test"));
0364 writeHandle.initialize("consume_key");
0365 writeHandle.emulate(state, aliases, logger());
0366
0367
0368 auto& consumeHandle = *readHandles.emplace_back(
0369 std::make_unique<ConsumeDataHandle<int>>(&dummyElement, "test"));
0370 consumeHandle.initialize("consume_key");
0371 consumeHandle.emulate(state, aliases, logger());
0372 BOOST_CHECK(!state.contains("consume_key"));
0373
0374
0375 auto& consumeHandle2 = *readHandles.emplace_back(
0376 std::make_unique<ConsumeDataHandle<int>>(&dummyElement, "test2"));
0377 consumeHandle2.initialize("consume_key");
0378 ScopedFailureThreshold st(Acts::Logging::Level::FATAL);
0379 BOOST_CHECK_THROW(consumeHandle2.emulate(state, aliases, logger()),
0380 SequenceConfigurationException);
0381 }
0382
0383 BOOST_TEST_CHECKPOINT("Test consume handle with incompatible type");
0384 {
0385 WriteDataHandle<std::string> writeHandle(&dummyElement, "test");
0386 writeHandle.initialize("type_key");
0387 writeHandle(wb, "test string");
0388
0389 ConsumeDataHandle<int> consumeHandle(&dummyElement, "test");
0390 consumeHandle.initialize("type_key");
0391 BOOST_CHECK_THROW(consumeHandle(wb), std::out_of_range);
0392 }
0393
0394 BOOST_TEST_CHECKPOINT("Test consume handle with missing data");
0395 {
0396 ConsumeDataHandle<int> consumeHandle(&dummyElement, "test");
0397 consumeHandle.initialize("missing_key");
0398 BOOST_CHECK_THROW(consumeHandle(wb), std::out_of_range);
0399 }
0400
0401 BOOST_TEST_CHECKPOINT("Test consume handle with uninitialized key");
0402 {
0403 ConsumeDataHandle<int> consumeHandle(&dummyElement, "test");
0404 BOOST_CHECK_THROW(consumeHandle(wb), std::runtime_error);
0405 }
0406 }
0407
0408 BOOST_AUTO_TEST_CASE(ConsumeDataHandleWithAliases) {
0409 DummySequenceElement dummyElement;
0410 DataHandleBase::StateMapType state;
0411 WhiteBoard::AliasMapType aliases;
0412 std::vector<std::unique_ptr<WriteDataHandleBase>> writeHandles;
0413 std::vector<std::unique_ptr<ReadDataHandleBase>> readHandles;
0414
0415 BOOST_TEST_CHECKPOINT("Test consume handle emulation with aliases");
0416 {
0417 aliases.insert({"original_key", "alias_key"});
0418
0419 auto& writeHandle = *writeHandles.emplace_back(
0420 std::make_unique<WriteDataHandle<int>>(&dummyElement, "test"));
0421 writeHandle.initialize("original_key");
0422 writeHandle.emulate(state, aliases, logger());
0423
0424
0425 BOOST_CHECK(state.contains("original_key"));
0426 BOOST_CHECK(state.contains("alias_key"));
0427 BOOST_CHECK_EQUAL(state["original_key"], &writeHandle);
0428 BOOST_CHECK_EQUAL(state["alias_key"], &writeHandle);
0429
0430
0431 auto& consumeHandle = *readHandles.emplace_back(
0432 std::make_unique<ConsumeDataHandle<int>>(&dummyElement, "test"));
0433 consumeHandle.initialize("alias_key");
0434 consumeHandle.emulate(state, aliases, logger());
0435
0436
0437 BOOST_CHECK(!state.contains("original_key"));
0438 BOOST_CHECK(!state.contains("alias_key"));
0439 }
0440
0441 BOOST_TEST_CHECKPOINT("Test consume handle emulation with original key");
0442 {
0443 state.clear();
0444 aliases.clear();
0445 aliases.insert({"original_key", "alias_key"});
0446
0447
0448 auto& writeHandle = *writeHandles.emplace_back(
0449 std::make_unique<WriteDataHandle<int>>(&dummyElement, "test"));
0450 writeHandle.initialize("original_key");
0451 writeHandle.emulate(state, aliases, logger());
0452
0453
0454 BOOST_CHECK(state.contains("original_key"));
0455 BOOST_CHECK(state.contains("alias_key"));
0456 BOOST_CHECK_EQUAL(state["original_key"], &writeHandle);
0457 BOOST_CHECK_EQUAL(state["alias_key"], &writeHandle);
0458
0459
0460 auto& consumeHandle = *readHandles.emplace_back(
0461 std::make_unique<ConsumeDataHandle<int>>(&dummyElement, "test"));
0462 consumeHandle.initialize("original_key");
0463 consumeHandle.emulate(state, aliases, logger());
0464
0465
0466 BOOST_CHECK(!state.contains("original_key"));
0467 BOOST_CHECK(!state.contains("alias_key"));
0468 }
0469 }
0470
0471
0472 struct DestructorCounter {
0473 static int count;
0474 int value;
0475 explicit DestructorCounter(int v) : value(v) {}
0476 ~DestructorCounter() { count++; }
0477 };
0478 int DestructorCounter::count = 0;
0479
0480 BOOST_AUTO_TEST_CASE(ConsumeDataHandleDestructor) {
0481 WhiteBoard wb;
0482 DummySequenceElement dummyElement;
0483
0484 BOOST_TEST_CHECKPOINT("Test value destructor is not called when popping");
0485 {
0486
0487 DestructorCounter::count = 0;
0488
0489
0490 WriteDataHandle<std::unique_ptr<DestructorCounter>> writeHandle(
0491 &dummyElement, "test");
0492 writeHandle.initialize("destructor_key");
0493 writeHandle(wb, std::make_unique<DestructorCounter>(42));
0494
0495
0496 BOOST_CHECK_EQUAL(DestructorCounter::count, 0);
0497
0498
0499 ConsumeDataHandle<std::unique_ptr<DestructorCounter>> consumeHandle(
0500 &dummyElement, "test");
0501 consumeHandle.initialize("destructor_key");
0502 auto value = consumeHandle(wb);
0503
0504
0505 BOOST_CHECK_EQUAL(value->value, 42);
0506
0507 BOOST_CHECK_EQUAL(DestructorCounter::count, 0);
0508
0509
0510 BOOST_CHECK(!wb.exists("destructor_key"));
0511
0512
0513 value.reset();
0514 BOOST_CHECK_EQUAL(DestructorCounter::count, 1);
0515 }
0516 }
0517
0518 BOOST_AUTO_TEST_SUITE_END()