LCOV - code coverage report
Current view: top level - tpglibs/unittest - ProcessorInternalStateNameRegistry_test.cxx (source / functions) Coverage Total Hit
Test: code.result Lines: 100.0 % 535 535
Test Date: 2025-12-21 13:07:08 Functions: 100.0 % 106 106

            Line data    Source code
       1              : /**
       2              :  * @file ProcessorInternalStateNameRegistry_test.cxx
       3              :  *
       4              :  * @brief Comprehensive unit tests for ProcessorInternalStateNameRegistry
       5              :  *
       6              :  * @copyright This is part of the DUNE DAQ Software Suite, copyright 2020.
       7              :  * Licensing/copyright details are in the COPYING file that you should have
       8              :  * received with this code.
       9              :  */
      10              : 
      11              : #define BOOST_TEST_MODULE ProcessorInternalStateNameRegistry_test
      12              : #define FMT_HEADER_ONLY
      13              : #define TPGLIBS_ENABLE_TEST_INTERFACES
      14              : 
      15              : #include "tpglibs/ProcessorInternalStateNameRegistry.hpp"
      16              : 
      17              : #include <boost/test/unit_test.hpp>
      18              : #include <immintrin.h>
      19              : #include <array>
      20              : #include <memory>
      21              : #include <string>
      22              : #include <algorithm>
      23              : 
      24              : namespace tpglibs {
      25              : 
      26              : // =============================================================================
      27              : // SECTION 1: Object Lifetime Tests
      28              : // =============================================================================
      29              : 
      30              : BOOST_AUTO_TEST_SUITE(ObjectLifetime)
      31              : 
      32            2 : BOOST_AUTO_TEST_CASE(test_default_construction)
      33              : {
      34            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
      35            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 0);
      36            1 :   BOOST_TEST(registry.get_names_of_requested_internal_states().empty());
      37            1 :   BOOST_TEST(registry.test_get_map_size() == 0);
      38            1 : }
      39              : 
      40            2 : BOOST_AUTO_TEST_CASE(test_destruction_with_empty_registry)
      41              : {
      42            1 :   {
      43            1 :     ProcessorInternalStateNameRegistry<__m256i> registry;
      44            1 :   } // Should not crash on destruction
      45            1 :   BOOST_TEST(true); // If we reach here, destruction succeeded
      46            1 : }
      47              : 
      48            2 : BOOST_AUTO_TEST_CASE(test_destruction_with_registered_states)
      49              : {
      50            1 :   {
      51            1 :     ProcessorInternalStateNameRegistry<__m256i> registry;
      52            1 :     auto state1 = std::make_shared<__m256i>();
      53            1 :     auto state2 = std::make_shared<__m256i>();
      54            1 :     registry.register_internal_state("state1", state1);
      55            1 :     registry.register_internal_state("state2", state2);
      56            1 :   } // Should properly clean up all registered states
      57            1 :   BOOST_TEST(true);
      58            1 : }
      59              : 
      60            2 : BOOST_AUTO_TEST_CASE(test_destruction_clears_shared_ptrs)
      61              : {
      62            1 :   std::weak_ptr<__m256i> weak_state;
      63            1 :   {
      64            1 :     ProcessorInternalStateNameRegistry<__m256i> registry;
      65            1 :     auto state = std::make_shared<__m256i>();
      66            1 :     weak_state = state;
      67            1 :     registry.register_internal_state("state", state);
      68            1 :     BOOST_TEST(!weak_state.expired());
      69            1 :   }
      70              :   // After registry is destroyed, if no other references exist, weak_ptr should expire
      71              :   // Note: state variable above still holds reference, so this is more about testing cleanup
      72            1 : }
      73              : 
      74            2 : BOOST_AUTO_TEST_CASE(test_move_construction)
      75              : {
      76            1 :   ProcessorInternalStateNameRegistry<__m256i> registry1;
      77            1 :   registry1.parse_requested_internal_state_items("a,b,c");
      78            1 :   auto state = std::make_shared<__m256i>();
      79            1 :   registry1.register_internal_state("a", state);
      80              :   
      81            1 :   ProcessorInternalStateNameRegistry<__m256i> registry2(std::move(registry1));
      82              :   
      83            1 :   BOOST_TEST(registry2.get_number_of_requested_internal_states() == 3);
      84            1 :   BOOST_TEST(registry2.is_registered("a"));
      85            1 :   BOOST_TEST(registry2.get_internal_state_item_ptr("a") == state);
      86            1 : }
      87              : 
      88            2 : BOOST_AUTO_TEST_CASE(test_move_assignment)
      89              : {
      90            1 :   ProcessorInternalStateNameRegistry<__m256i> registry1;
      91            1 :   registry1.parse_requested_internal_state_items("x,y");
      92            1 :   auto state = std::make_shared<__m256i>();
      93            1 :   registry1.register_internal_state("x", state);
      94              :   
      95            1 :   ProcessorInternalStateNameRegistry<__m256i> registry2;
      96            1 :   registry2 = std::move(registry1);
      97              :   
      98            1 :   BOOST_TEST(registry2.get_number_of_requested_internal_states() == 2);
      99            1 :   BOOST_TEST(registry2.is_registered("x"));
     100            1 :   BOOST_TEST(registry2.get_internal_state_item_ptr("x") == state);
     101            1 : }
     102              : 
     103            2 : BOOST_AUTO_TEST_CASE(test_multiple_instances_independence)
     104              : {
     105            1 :   ProcessorInternalStateNameRegistry<__m256i> registry1;
     106            1 :   ProcessorInternalStateNameRegistry<__m256i> registry2;
     107              :   
     108            1 :   registry1.parse_requested_internal_state_items("a,b");
     109            1 :   registry2.parse_requested_internal_state_items("c,d");
     110              :   
     111            1 :   auto state1 = std::make_shared<__m256i>();
     112            1 :   auto state2 = std::make_shared<__m256i>();
     113              :   
     114            1 :   registry1.register_internal_state("a", state1);
     115            1 :   registry2.register_internal_state("c", state2);
     116              :   
     117              :   // Verify independence
     118            1 :   BOOST_TEST(registry1.get_number_of_requested_internal_states() == 2);
     119            1 :   BOOST_TEST(registry2.get_number_of_requested_internal_states() == 2);
     120            1 :   BOOST_TEST(registry1.is_registered("a"));
     121            1 :   BOOST_TEST(!registry1.is_registered("c"));
     122            1 :   BOOST_TEST(registry2.is_registered("c"));
     123            1 :   BOOST_TEST(!registry2.is_registered("a"));
     124            1 : }
     125              : 
     126            2 : BOOST_AUTO_TEST_CASE(test_different_template_types)
     127              : {
     128              :   // Test with __m256i
     129            1 :   ProcessorInternalStateNameRegistry<__m256i> registry_avx;
     130            1 :   auto state_avx = std::make_shared<__m256i>();
     131            1 :   registry_avx.register_internal_state("avx_state", state_avx);
     132            1 :   BOOST_TEST(registry_avx.is_registered("avx_state"));
     133              :   
     134              :   // Test with array type
     135            1 :   ProcessorInternalStateNameRegistry<std::array<int16_t, 16>> registry_array;
     136            1 :   auto state_array = std::make_shared<std::array<int16_t, 16>>();
     137            1 :   registry_array.register_internal_state("array_state", state_array);
     138            1 :   BOOST_TEST(registry_array.is_registered("array_state"));
     139              :   
     140              :   // Test with simple int
     141            1 :   ProcessorInternalStateNameRegistry<int> registry_int;
     142            1 :   auto state_int = std::make_shared<int>(42);
     143            1 :   registry_int.register_internal_state("int_state", state_int);
     144            1 :   BOOST_TEST(registry_int.is_registered("int_state"));
     145            1 :   BOOST_TEST(*registry_int.get_internal_state_item_ptr("int_state") == 42);
     146            1 : }
     147              : 
     148              : BOOST_AUTO_TEST_SUITE_END()
     149              : 
     150              : // =============================================================================
     151              : // SECTION 2: Parse Operation Tests
     152              : // =============================================================================
     153              : 
     154              : BOOST_AUTO_TEST_SUITE(ParseOperations)
     155              : 
     156            2 : BOOST_AUTO_TEST_CASE(test_parse_empty_string)
     157              : {
     158            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     159            1 :   registry.parse_requested_internal_state_items("");
     160            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 0);
     161            1 :   BOOST_TEST(registry.get_names_of_requested_internal_states().empty());
     162            1 : }
     163              : 
     164            2 : BOOST_AUTO_TEST_CASE(test_parse_single_item)
     165              : {
     166            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     167            1 :   registry.parse_requested_internal_state_items("state1");
     168            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 1);
     169            1 :   BOOST_TEST(registry.get_names_of_requested_internal_states()[0] == "state1");
     170            1 :   BOOST_TEST(registry.is_requested("state1"));
     171            1 : }
     172              : 
     173            2 : BOOST_AUTO_TEST_CASE(test_parse_multiple_items)
     174              : {
     175            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     176            1 :   registry.parse_requested_internal_state_items("a,b,c,d,e");
     177              :   
     178            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 5);
     179            1 :   auto names = registry.get_names_of_requested_internal_states();
     180            1 :   BOOST_TEST(names[0] == "a");
     181            1 :   BOOST_TEST(names[1] == "b");
     182            1 :   BOOST_TEST(names[2] == "c");
     183            1 :   BOOST_TEST(names[3] == "d");
     184            1 :   BOOST_TEST(names[4] == "e");
     185            1 : }
     186              : 
     187            2 : BOOST_AUTO_TEST_CASE(test_parse_with_spaces)
     188              : {
     189            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     190            1 :   registry.parse_requested_internal_state_items(" a , b , c ");
     191              :   
     192            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     193            1 :   auto names = registry.get_names_of_requested_internal_states();
     194            1 :   BOOST_TEST(names[0] == "a");
     195            1 :   BOOST_TEST(names[1] == "b");
     196            1 :   BOOST_TEST(names[2] == "c");
     197            1 : }
     198              : 
     199            2 : BOOST_AUTO_TEST_CASE(test_parse_with_tabs_and_newlines)
     200              : {
     201            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     202            1 :   registry.parse_requested_internal_state_items("\ta\t,\nb\n,\r\nc\r\n");
     203              :   
     204            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     205            1 :   auto names = registry.get_names_of_requested_internal_states();
     206            1 :   BOOST_TEST(names[0] == "a");
     207            1 :   BOOST_TEST(names[1] == "b");
     208            1 :   BOOST_TEST(names[2] == "c");
     209            1 : }
     210              : 
     211            2 : BOOST_AUTO_TEST_CASE(test_parse_with_empty_items)
     212              : {
     213            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     214            1 :   registry.parse_requested_internal_state_items("a,,b,,,c");
     215              :   
     216              :   // Empty items should be filtered out
     217            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     218            1 :   auto names = registry.get_names_of_requested_internal_states();
     219            1 :   BOOST_TEST(names[0] == "a");
     220            1 :   BOOST_TEST(names[1] == "b");
     221            1 :   BOOST_TEST(names[2] == "c");
     222            1 : }
     223              : 
     224            2 : BOOST_AUTO_TEST_CASE(test_parse_with_only_commas)
     225              : {
     226            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     227            1 :   registry.parse_requested_internal_state_items(",,,");
     228            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 0);
     229            1 : }
     230              : 
     231            2 : BOOST_AUTO_TEST_CASE(test_parse_with_only_whitespace)
     232              : {
     233            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     234            1 :   registry.parse_requested_internal_state_items("   \t\n  ");
     235            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 0);
     236            1 : }
     237              : 
     238            2 : BOOST_AUTO_TEST_CASE(test_parse_trailing_comma)
     239              : {
     240            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     241            1 :   registry.parse_requested_internal_state_items("a,b,c,");
     242              :   
     243            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     244            1 :   auto names = registry.get_names_of_requested_internal_states();
     245            1 :   BOOST_TEST(names[0] == "a");
     246            1 :   BOOST_TEST(names[1] == "b");
     247            1 :   BOOST_TEST(names[2] == "c");
     248            1 : }
     249              : 
     250            2 : BOOST_AUTO_TEST_CASE(test_parse_leading_comma)
     251              : {
     252            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     253            1 :   registry.parse_requested_internal_state_items(",a,b,c");
     254              :   
     255            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     256            1 :   auto names = registry.get_names_of_requested_internal_states();
     257            1 :   BOOST_TEST(names[0] == "a");
     258            1 :   BOOST_TEST(names[1] == "b");
     259            1 :   BOOST_TEST(names[2] == "c");
     260            1 : }
     261              : 
     262            2 : BOOST_AUTO_TEST_CASE(test_parse_duplicate_names)
     263              : {
     264            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     265            1 :   registry.parse_requested_internal_state_items("a,b,a,c,b");
     266              :   
     267              :   // Current implementation doesn't deduplicate
     268            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 5);
     269            1 :   auto names = registry.get_names_of_requested_internal_states();
     270            1 :   BOOST_TEST(names[0] == "a");
     271            1 :   BOOST_TEST(names[1] == "b");
     272            1 :   BOOST_TEST(names[2] == "a");
     273            1 :   BOOST_TEST(names[3] == "c");
     274            1 :   BOOST_TEST(names[4] == "b");
     275            1 : }
     276              : 
     277            2 : BOOST_AUTO_TEST_CASE(test_parse_overwrite_previous)
     278              : {
     279            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     280            1 :   registry.parse_requested_internal_state_items("a,b,c");
     281            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     282              :   
     283              :   // Parse again - should clear previous
     284            1 :   registry.parse_requested_internal_state_items("x,y");
     285            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 2);
     286            1 :   auto names = registry.get_names_of_requested_internal_states();
     287            1 :   BOOST_TEST(names[0] == "x");
     288            1 :   BOOST_TEST(names[1] == "y");
     289            1 : }
     290              : 
     291            2 : BOOST_AUTO_TEST_CASE(test_parse_long_names)
     292              : {
     293            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     294            1 :   std::string long_name(1000, 'x');
     295            1 :   registry.parse_requested_internal_state_items(long_name);
     296              :   
     297            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 1);
     298            1 :   BOOST_TEST(registry.get_names_of_requested_internal_states()[0] == long_name);
     299            1 : }
     300              : 
     301            2 : BOOST_AUTO_TEST_CASE(test_parse_special_characters)
     302              : {
     303            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     304            1 :   registry.parse_requested_internal_state_items("state_1,state-2,state.3,state:4");
     305              :   
     306            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 4);
     307            1 :   auto names = registry.get_names_of_requested_internal_states();
     308            1 :   BOOST_TEST(names[0] == "state_1");
     309            1 :   BOOST_TEST(names[1] == "state-2");
     310            1 :   BOOST_TEST(names[2] == "state.3");
     311            1 :   BOOST_TEST(names[3] == "state:4");
     312            1 : }
     313              : 
     314            2 : BOOST_AUTO_TEST_CASE(test_parse_very_many_items)
     315              : {
     316            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     317            1 :   std::string config;
     318         1001 :   for (int i = 0; i < 1000; ++i) {
     319         1000 :     if (i > 0) config += ",";
     320         1000 :     config += "state" + std::to_string(i);
     321              :   }
     322              :   
     323            1 :   registry.parse_requested_internal_state_items(config);
     324            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 1000);
     325            1 : }
     326              : 
     327              : BOOST_AUTO_TEST_SUITE_END()
     328              : 
     329              : // =============================================================================
     330              : // SECTION 3: Register Operation Tests
     331              : // =============================================================================
     332              : 
     333              : BOOST_AUTO_TEST_SUITE(RegisterOperations)
     334              : 
     335            2 : BOOST_AUTO_TEST_CASE(test_register_single_state)
     336              : {
     337            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     338            1 :   auto state = std::make_shared<__m256i>();
     339              :   
     340            1 :   registry.register_internal_state("test_state", state);
     341              :   
     342            1 :   BOOST_TEST(registry.is_registered("test_state"));
     343            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("test_state") == state);
     344            1 : }
     345              : 
     346            2 : BOOST_AUTO_TEST_CASE(test_register_multiple_states)
     347              : {
     348            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     349            1 :   auto state1 = std::make_shared<__m256i>();
     350            1 :   auto state2 = std::make_shared<__m256i>();
     351            1 :   auto state3 = std::make_shared<__m256i>();
     352              :   
     353            1 :   registry.register_internal_state("s1", state1);
     354            1 :   registry.register_internal_state("s2", state2);
     355            1 :   registry.register_internal_state("s3", state3);
     356              :   
     357            1 :   BOOST_TEST(registry.test_get_map_size() == 3);
     358            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("s1") == state1);
     359            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("s2") == state2);
     360            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("s3") == state3);
     361            1 : }
     362              : 
     363            2 : BOOST_AUTO_TEST_CASE(test_register_overwrites_existing)
     364              : {
     365            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     366            1 :   auto state1 = std::make_shared<__m256i>();
     367            1 :   auto state2 = std::make_shared<__m256i>();
     368              :   
     369            1 :   registry.register_internal_state("test", state1);
     370            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("test") == state1);
     371              :   
     372              :   // Register again with different pointer
     373            1 :   registry.register_internal_state("test", state2);
     374            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("test") == state2);
     375            1 :   BOOST_TEST(registry.test_get_map_size() == 1); // Should not create duplicate
     376            1 : }
     377              : 
     378            2 : BOOST_AUTO_TEST_CASE(test_register_nullptr)
     379              : {
     380            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     381              :   
     382              :   // Registering nullptr should be allowed (user might do this)
     383            1 :   registry.register_internal_state("null_state", nullptr);
     384            1 :   BOOST_TEST(registry.is_registered("null_state"));
     385            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("null_state") == nullptr);
     386            1 : }
     387              : 
     388            2 : BOOST_AUTO_TEST_CASE(test_register_empty_name)
     389              : {
     390            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     391            1 :   auto state = std::make_shared<__m256i>();
     392              :   
     393              :   // Empty string as name should work (though not recommended)
     394            1 :   registry.register_internal_state("", state);
     395            1 :   BOOST_TEST(registry.is_registered(""));
     396            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("") == state);
     397            1 : }
     398              : 
     399            2 : BOOST_AUTO_TEST_CASE(test_register_names_with_whitespace)
     400              : {
     401            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     402            1 :   auto state1 = std::make_shared<__m256i>();
     403            1 :   auto state2 = std::make_shared<__m256i>();
     404              :   
     405            1 :   registry.register_internal_state(" a ", state1);
     406            1 :   registry.register_internal_state("a", state2);
     407              :   
     408              :   // These are different names (with and without spaces)
     409            1 :   BOOST_TEST(registry.test_get_map_size() == 2);
     410            1 :   BOOST_TEST(registry.get_internal_state_item_ptr(" a ") == state1);
     411            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("a") == state2);
     412            1 : }
     413              : 
     414            2 : BOOST_AUTO_TEST_CASE(test_register_shared_ownership)
     415              : {
     416            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     417            1 :   auto state = std::make_shared<__m256i>();
     418            1 :   std::weak_ptr<__m256i> weak_state = state;
     419              :   
     420            1 :   registry.register_internal_state("shared", state);
     421              :   
     422              :   // Registry should hold a reference
     423            1 :   BOOST_TEST(state.use_count() == 2); // Original + registry
     424              :   
     425              :   // Release original reference
     426            1 :   state.reset();
     427            1 :   BOOST_TEST(!weak_state.expired()); // Registry still holds it
     428              :   
     429              :   // Get pointer from registry
     430            1 :   auto retrieved = registry.get_internal_state_item_ptr("shared");
     431            1 :   BOOST_TEST(retrieved != nullptr);
     432            1 :   BOOST_TEST(retrieved.use_count() == 2); // Registry + retrieved
     433            1 : }
     434              : 
     435              : BOOST_AUTO_TEST_SUITE_END()
     436              : 
     437              : // =============================================================================
     438              : // SECTION 4: Retrieval Operation Tests
     439              : // =============================================================================
     440              : 
     441              : BOOST_AUTO_TEST_SUITE(RetrievalOperations)
     442              : 
     443            2 : BOOST_AUTO_TEST_CASE(test_get_unregistered_name)
     444              : {
     445            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     446              :   
     447              :   // Getting non-existent key returns nullptr (default-constructed shared_ptr)
     448            1 :   auto ptr = registry.get_internal_state_item_ptr("nonexistent");
     449            1 :   BOOST_TEST(ptr == nullptr);
     450            1 : }
     451              : 
     452            2 : BOOST_AUTO_TEST_CASE(test_is_registered)
     453              : {
     454            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     455            1 :   auto state = std::make_shared<__m256i>();
     456              :   
     457            1 :   BOOST_TEST(!registry.is_registered("test"));
     458            1 :   registry.register_internal_state("test", state);
     459            1 :   BOOST_TEST(registry.is_registered("test"));
     460            1 : }
     461              : 
     462            2 : BOOST_AUTO_TEST_CASE(test_is_requested)
     463              : {
     464            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     465              :   
     466            1 :   registry.parse_requested_internal_state_items("a,b,c");
     467              :   
     468            1 :   BOOST_TEST(registry.is_requested("a"));
     469            1 :   BOOST_TEST(registry.is_requested("b"));
     470            1 :   BOOST_TEST(registry.is_requested("c"));
     471            1 :   BOOST_TEST(!registry.is_requested("d"));
     472            1 : }
     473              : 
     474            2 : BOOST_AUTO_TEST_CASE(test_get_all_registered_names)
     475              : {
     476            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     477            1 :   auto state1 = std::make_shared<__m256i>();
     478            1 :   auto state2 = std::make_shared<__m256i>();
     479            1 :   auto state3 = std::make_shared<__m256i>();
     480              :   
     481            1 :   registry.register_internal_state("x", state1);
     482            1 :   registry.register_internal_state("y", state2);
     483            1 :   registry.register_internal_state("z", state3);
     484              :   
     485            1 :   auto names = registry.test_get_all_registered_internal_state_names();
     486            1 :   BOOST_TEST(names.size() == 3);
     487              :   
     488              :   // Order not guaranteed in unordered_map, so check presence
     489            1 :   bool has_x = (std::find(names.begin(), names.end(), "x") != names.end());
     490            1 :   bool has_y = (std::find(names.begin(), names.end(), "y") != names.end());
     491            1 :   bool has_z = (std::find(names.begin(), names.end(), "z") != names.end());
     492            1 :   BOOST_TEST(has_x);
     493            1 :   BOOST_TEST(has_y);
     494            1 :   BOOST_TEST(has_z);
     495            1 : }
     496              : 
     497            2 : BOOST_AUTO_TEST_CASE(test_get_all_requested_item_ptrs_empty)
     498              : {
     499            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     500              :   
     501            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     502            1 :   BOOST_TEST(ptrs.empty());
     503            1 : }
     504              : 
     505            2 : BOOST_AUTO_TEST_CASE(test_get_all_requested_item_ptrs_all_registered)
     506              : {
     507            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     508              :   
     509            1 :   registry.parse_requested_internal_state_items("a,b,c");
     510              :   
     511            1 :   auto state_a = std::make_shared<__m256i>();
     512            1 :   auto state_b = std::make_shared<__m256i>();
     513            1 :   auto state_c = std::make_shared<__m256i>();
     514              :   
     515            1 :   registry.register_internal_state("a", state_a);
     516            1 :   registry.register_internal_state("b", state_b);
     517            1 :   registry.register_internal_state("c", state_c);
     518              :   
     519            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     520            1 :   BOOST_TEST(ptrs.size() == 3);
     521            1 :   BOOST_TEST(ptrs[0] == state_a);
     522            1 :   BOOST_TEST(ptrs[1] == state_b);
     523            1 :   BOOST_TEST(ptrs[2] == state_c);
     524            1 : }
     525              : 
     526            2 : BOOST_AUTO_TEST_CASE(test_get_all_requested_item_ptrs_partial_registered)
     527              : {
     528            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     529              :   
     530            1 :   registry.parse_requested_internal_state_items("a,b,c");
     531              :   
     532            1 :   auto state_a = std::make_shared<__m256i>();
     533            1 :   registry.register_internal_state("a", state_a);
     534              :   // b and c not registered
     535              :   
     536            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     537            1 :   BOOST_TEST(ptrs.size() == 3);
     538            1 :   BOOST_TEST(ptrs[0] == state_a);
     539            1 :   BOOST_TEST(ptrs[1] == nullptr); // Not registered
     540            1 :   BOOST_TEST(ptrs[2] == nullptr); // Not registered
     541            1 : }
     542              : 
     543            2 : BOOST_AUTO_TEST_CASE(test_get_all_requested_item_ptrs_order_preserved)
     544              : {
     545            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     546              :   
     547              :   // Parse in specific order
     548            1 :   registry.parse_requested_internal_state_items("z,a,m,b");
     549              :   
     550            1 :   auto state_z = std::make_shared<__m256i>();
     551            1 :   auto state_a = std::make_shared<__m256i>();
     552            1 :   auto state_m = std::make_shared<__m256i>();
     553            1 :   auto state_b = std::make_shared<__m256i>();
     554              :   
     555              :   // Register in different order
     556            1 :   registry.register_internal_state("a", state_a);
     557            1 :   registry.register_internal_state("z", state_z);
     558            1 :   registry.register_internal_state("b", state_b);
     559            1 :   registry.register_internal_state("m", state_m);
     560              :   
     561            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     562              :   
     563              :   // Should follow requested order, not registration order
     564            1 :   BOOST_TEST(ptrs[0] == state_z);
     565            1 :   BOOST_TEST(ptrs[1] == state_a);
     566            1 :   BOOST_TEST(ptrs[2] == state_m);
     567            1 :   BOOST_TEST(ptrs[3] == state_b);
     568            1 : }
     569              : 
     570              : BOOST_AUTO_TEST_SUITE_END()
     571              : 
     572              : // =============================================================================
     573              : // SECTION 5: Clear Operation Tests
     574              : // =============================================================================
     575              : 
     576              : BOOST_AUTO_TEST_SUITE(ClearOperations)
     577              : 
     578            2 : BOOST_AUTO_TEST_CASE(test_clear_empty_registry)
     579              : {
     580            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     581            1 :   registry.test_clear();
     582              :   
     583            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 0);
     584            1 :   BOOST_TEST(registry.test_get_map_size() == 0);
     585            1 : }
     586              : 
     587            2 : BOOST_AUTO_TEST_CASE(test_clear_removes_all_data)
     588              : {
     589            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     590              :   
     591            1 :   registry.parse_requested_internal_state_items("a,b,c");
     592            1 :   auto state1 = std::make_shared<__m256i>();
     593            1 :   auto state2 = std::make_shared<__m256i>();
     594            1 :   registry.register_internal_state("a", state1);
     595            1 :   registry.register_internal_state("b", state2);
     596              :   
     597            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     598            1 :   BOOST_TEST(registry.test_get_map_size() == 2);
     599              :   
     600            1 :   registry.test_clear();
     601              :   
     602            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 0);
     603            1 :   BOOST_TEST(registry.test_get_map_size() == 0);
     604            1 :   BOOST_TEST(!registry.is_registered("a"));
     605            1 :   BOOST_TEST(!registry.is_registered("b"));
     606            1 : }
     607              : 
     608            2 : BOOST_AUTO_TEST_CASE(test_clear_releases_shared_ptrs)
     609              : {
     610            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     611              :   
     612            1 :   auto state = std::make_shared<__m256i>();
     613            1 :   std::weak_ptr<__m256i> weak_state = state;
     614              :   
     615            1 :   registry.register_internal_state("test", state);
     616            1 :   BOOST_TEST(state.use_count() == 2);
     617              :   
     618            1 :   state.reset(); // Release original
     619            1 :   BOOST_TEST(!weak_state.expired()); // Registry still holds it
     620              :   
     621            1 :   registry.test_clear();
     622            1 :   BOOST_TEST(weak_state.expired()); // Now it should be gone
     623            1 : }
     624              : 
     625            2 : BOOST_AUTO_TEST_CASE(test_use_after_clear)
     626              : {
     627            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     628              :   
     629            1 :   registry.parse_requested_internal_state_items("a,b");
     630            1 :   registry.test_clear();
     631              :   
     632              :   // Should be usable after clear
     633            1 :   registry.parse_requested_internal_state_items("x,y,z");
     634            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     635              :   
     636            1 :   auto state = std::make_shared<__m256i>();
     637            1 :   registry.register_internal_state("x", state);
     638            1 :   BOOST_TEST(registry.is_registered("x"));
     639            1 : }
     640              : 
     641              : BOOST_AUTO_TEST_SUITE_END()
     642              : 
     643              : // =============================================================================
     644              : // SECTION 6: Edge Cases and Integration Tests
     645              : // =============================================================================
     646              : 
     647              : BOOST_AUTO_TEST_SUITE(EdgeCasesAndIntegration)
     648              : 
     649            2 : BOOST_AUTO_TEST_CASE(test_parse_then_register_workflow)
     650              : {
     651            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     652              :   
     653              :   // Typical workflow: parse config, then register states
     654            1 :   registry.parse_requested_internal_state_items("input,output,temp");
     655              :   
     656            1 :   auto input_state = std::make_shared<__m256i>();
     657            1 :   auto output_state = std::make_shared<__m256i>();
     658            1 :   auto temp_state = std::make_shared<__m256i>();
     659              :   
     660            1 :   registry.register_internal_state("input", input_state);
     661            1 :   registry.register_internal_state("output", output_state);
     662            1 :   registry.register_internal_state("temp", temp_state);
     663              :   
     664            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     665            1 :   BOOST_TEST(ptrs.size() == 3);
     666            1 :   BOOST_TEST(ptrs[0] == input_state);
     667            1 :   BOOST_TEST(ptrs[1] == output_state);
     668            1 :   BOOST_TEST(ptrs[2] == temp_state);
     669            1 : }
     670              : 
     671            2 : BOOST_AUTO_TEST_CASE(test_register_then_parse_workflow)
     672              : {
     673            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     674              :   
     675              :   // Register states first
     676            1 :   auto state1 = std::make_shared<__m256i>();
     677            1 :   auto state2 = std::make_shared<__m256i>();
     678            1 :   registry.register_internal_state("s1", state1);
     679            1 :   registry.register_internal_state("s2", state2);
     680              :   
     681              :   // Then parse which ones to request
     682            1 :   registry.parse_requested_internal_state_items("s1");
     683              :   
     684            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     685            1 :   BOOST_TEST(ptrs.size() == 1);
     686            1 :   BOOST_TEST(ptrs[0] == state1);
     687            1 : }
     688              : 
     689            2 : BOOST_AUTO_TEST_CASE(test_requesting_unregistered_states)
     690              : {
     691            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     692              :   
     693            1 :   registry.parse_requested_internal_state_items("a,b,c");
     694              :   // Don't register anything
     695              :   
     696            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     697            1 :   BOOST_TEST(ptrs.size() == 3);
     698            1 :   BOOST_TEST(ptrs[0] == nullptr);
     699            1 :   BOOST_TEST(ptrs[1] == nullptr);
     700            1 :   BOOST_TEST(ptrs[2] == nullptr);
     701            1 : }
     702              : 
     703            2 : BOOST_AUTO_TEST_CASE(test_registering_unrequested_states)
     704              : {
     705            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     706              :   
     707            1 :   registry.parse_requested_internal_state_items("a");
     708              :   
     709            1 :   auto state_a = std::make_shared<__m256i>();
     710            1 :   auto state_b = std::make_shared<__m256i>();
     711            1 :   auto state_c = std::make_shared<__m256i>();
     712              :   
     713            1 :   registry.register_internal_state("a", state_a);
     714            1 :   registry.register_internal_state("b", state_b);
     715            1 :   registry.register_internal_state("c", state_c);
     716              :   
     717              :   // All are registered
     718            1 :   BOOST_TEST(registry.test_get_map_size() == 3);
     719              :   
     720              :   // But only 'a' is requested
     721            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     722            1 :   BOOST_TEST(ptrs.size() == 1);
     723            1 :   BOOST_TEST(ptrs[0] == state_a);
     724            1 : }
     725              : 
     726            2 : BOOST_AUTO_TEST_CASE(test_case_sensitive_names)
     727              : {
     728            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     729              :   
     730            1 :   auto state_lower = std::make_shared<__m256i>();
     731            1 :   auto state_upper = std::make_shared<__m256i>();
     732              :   
     733            1 :   registry.register_internal_state("test", state_lower);
     734            1 :   registry.register_internal_state("TEST", state_upper);
     735              :   
     736              :   // Case-sensitive, should be different
     737            1 :   BOOST_TEST(registry.test_get_map_size() == 2);
     738            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("test") == state_lower);
     739            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("TEST") == state_upper);
     740            1 : }
     741              : 
     742            2 : BOOST_AUTO_TEST_CASE(test_unicode_names)
     743              : {
     744            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     745              :   
     746            1 :   auto state = std::make_shared<__m256i>();
     747            1 :   registry.register_internal_state("状態", state);
     748              :   
     749            1 :   BOOST_TEST(registry.is_registered("状態"));
     750            1 :   BOOST_TEST(registry.get_internal_state_item_ptr("状態") == state);
     751            1 : }
     752              : 
     753            2 : BOOST_AUTO_TEST_CASE(test_very_long_name)
     754              : {
     755            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     756              :   
     757            1 :   std::string very_long_name(10000, 'x');
     758            1 :   auto state = std::make_shared<__m256i>();
     759              :   
     760            1 :   registry.register_internal_state(very_long_name, state);
     761            1 :   BOOST_TEST(registry.is_registered(very_long_name));
     762            1 :   BOOST_TEST(registry.get_internal_state_item_ptr(very_long_name) == state);
     763            1 : }
     764              : 
     765            2 : BOOST_AUTO_TEST_CASE(test_repeated_parse_calls)
     766              : {
     767            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     768              :   
     769            1 :   registry.parse_requested_internal_state_items("a,b");
     770            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 2);
     771              :   
     772            1 :   registry.parse_requested_internal_state_items("c,d,e");
     773            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 3);
     774            1 :   BOOST_TEST(!registry.is_requested("a")); // Previous should be cleared
     775            1 :   BOOST_TEST(registry.is_requested("c"));
     776              :   
     777            1 :   registry.parse_requested_internal_state_items("");
     778            1 :   BOOST_TEST(registry.get_number_of_requested_internal_states() == 0);
     779            1 : }
     780              : 
     781            2 : BOOST_AUTO_TEST_CASE(test_stress_many_operations)
     782              : {
     783            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     784              :   
     785              :   // Register many states
     786            1 :   std::vector<std::shared_ptr<__m256i>> states;
     787          101 :   for (int i = 0; i < 100; ++i) {
     788          100 :     auto state = std::make_shared<__m256i>();
     789          100 :     states.push_back(state);
     790          100 :     registry.register_internal_state("state" + std::to_string(i), state);
     791          100 :   }
     792              :   
     793            1 :   BOOST_TEST(registry.test_get_map_size() == 100);
     794              :   
     795              :   // Request subset
     796            1 :   std::string config;
     797           51 :   for (int i = 0; i < 50; ++i) {
     798           50 :     if (i > 0) config += ",";
     799           50 :     config += "state" + std::to_string(i * 2); // Even indices
     800              :   }
     801            1 :   registry.parse_requested_internal_state_items(config);
     802              :   
     803            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     804            1 :   BOOST_TEST(ptrs.size() == 50);
     805              :   
     806              :   // Verify correctness
     807           51 :   for (int i = 0; i < 50; ++i) {
     808           50 :     BOOST_TEST(ptrs[i] == states[i * 2]);
     809              :   }
     810            1 : }
     811              : 
     812            2 : BOOST_AUTO_TEST_CASE(test_interleaved_parse_register)
     813              : {
     814            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     815              :   
     816            1 :   registry.parse_requested_internal_state_items("a,b");
     817              :   
     818            1 :   auto state_a = std::make_shared<__m256i>();
     819            1 :   registry.register_internal_state("a", state_a);
     820              :   
     821            1 :   registry.parse_requested_internal_state_items("a,b,c");
     822              :   
     823            1 :   auto state_b = std::make_shared<__m256i>();
     824            1 :   auto state_c = std::make_shared<__m256i>();
     825            1 :   registry.register_internal_state("b", state_b);
     826            1 :   registry.register_internal_state("c", state_c);
     827              :   
     828            1 :   auto ptrs = registry.get_all_requested_internal_state_item_ptrs();
     829            1 :   BOOST_TEST(ptrs.size() == 3);
     830            1 :   BOOST_TEST(ptrs[0] == state_a);
     831            1 :   BOOST_TEST(ptrs[1] == state_b);
     832            1 :   BOOST_TEST(ptrs[2] == state_c);
     833            1 : }
     834              : 
     835            2 : BOOST_AUTO_TEST_CASE(test_memory_leak_scenario)
     836              : {
     837              :   // Test that circular references don't prevent cleanup
     838            1 :   ProcessorInternalStateNameRegistry<__m256i> registry;
     839              :   
     840            1 :   std::weak_ptr<__m256i> weak_state;
     841              :   
     842            1 :   {
     843            1 :     auto state = std::make_shared<__m256i>();
     844            1 :     weak_state = state;
     845            1 :     registry.register_internal_state("test", state);
     846            1 :     BOOST_TEST(state.use_count() == 2);
     847              :     // state goes out of scope
     848            1 :   }
     849              :   
     850            1 :   BOOST_TEST(!weak_state.expired()); // Registry still holds it
     851              :   
     852            1 :   registry.test_clear();
     853            1 :   BOOST_TEST(weak_state.expired()); // Should be cleaned up
     854            1 : }
     855              : 
     856              : BOOST_AUTO_TEST_SUITE_END()
     857              : 
     858              : } // namespace tpglibs
        

Generated by: LCOV version 2.0-1