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