LCOV - code coverage report
Current view: top level - /opt/artdaq/srcs/artdaq-database/test/CaseStudy/OtsDaqCPPInterface/test004 - ThreeVersionsBug_t.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 97.1 % 104 101
Test Date: 2026-10-29 00:35:58 Functions: 100.0 % 10 10

            Line data    Source code
       1              : #define BOOST_TEST_DYN_LINK
       2              : #define BOOST_TEST_MODULE (ThreeVersionsBug test)
       3              : 
       4              : #include <boost/test/unit_test.hpp>
       5              : 
       6              : #include <iostream>
       7              : #include <memory>
       8              : #include <string>
       9              : 
      10              : #include "../DatabaseConfigurationInterface.h"
      11              : 
      12              : using namespace ots;
      13              : 
      14              : struct BugTestData {
      15            2 :   BugTestData() {
      16            2 :     srand(time(nullptr));
      17            2 :     baseVersion = rand() % 99999 + 100000;
      18            2 :     std::cout << "=== INVESTIGATING THREE VERSIONS BUG ===\n";
      19            2 :     std::cout << "Base version: " << baseVersion << "\n\n";
      20            2 :   }
      21              : 
      22            2 :   ~BugTestData() { std::cout << "\n=== INVESTIGATION COMPLETE ===\n"; }
      23              : 
      24              :   int baseVersion;
      25              : };
      26              : 
      27              : BugTestData fixture;
      28              : 
      29              : BOOST_AUTO_TEST_SUITE(three_versions_bug_test)
      30              : 
      31            4 : BOOST_AUTO_TEST_CASE(attempt_three_versions_same_type) {
      32            2 :   std::cout << "\n=== TEST 1: Attempting to add three versions ===\n";
      33              : 
      34            2 :   auto ifc = DatabaseConfigurationInterface();
      35              : 
      36            2 :   int version1 = fixture.baseVersion;
      37            2 :   int version2 = fixture.baseVersion + 1;
      38            2 :   int version3 = fixture.baseVersion + 2;
      39              : 
      40            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
      41            2 :   cfg1->getView().version = version1;
      42            2 :   ifc.saveActiveVersion(cfg1.get());
      43            2 :   std::cout << "Created version 1: " << version1 << "\n";
      44              : 
      45            2 :   std::shared_ptr<ConfigurationBase> cfg2 = std::make_shared<TestConfiguration001>();
      46            2 :   cfg2->getView().version = version2;
      47            2 :   ifc.saveActiveVersion(cfg2.get());
      48            2 :   std::cout << "Created version 2: " << version2 << "\n";
      49              : 
      50            2 :   std::shared_ptr<ConfigurationBase> cfg3 = std::make_shared<TestConfiguration001>();
      51            2 :   cfg3->getView().version = version3;
      52            2 :   ifc.saveActiveVersion(cfg3.get());
      53            2 :   std::cout << "Created version 3: " << version3 << "\n";
      54              : 
      55            2 :   std::cout << "\nAttempt 1: Using std::map...\n";
      56            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
      57              : 
      58            2 :   compositionMap[cfg1->getConfigurationName()] = version1;
      59            2 :   std::cout << "  Added version1, map size: " << compositionMap.size() << "\n";
      60              : 
      61            2 :   compositionMap[cfg2->getConfigurationName()] = version2;
      62            2 :   std::cout << "  Added version2, map size: " << compositionMap.size() << " (should still be 1)\n";
      63              : 
      64            2 :   compositionMap[cfg3->getConfigurationName()] = version3;
      65            2 :   std::cout << "  Added version3, map size: " << compositionMap.size() << " (should still be 1)\n";
      66              : 
      67            2 :   BOOST_CHECK_EQUAL(compositionMap.size(), 1);
      68            2 :   BOOST_CHECK_EQUAL(compositionMap[cfg1->getConfigurationName()], version3);
      69              : 
      70            2 :   std::cout << "  Result: Map correctly contains only last version: " << version3 << "\n";
      71              : 
      72            6 :   std::string compName = std::string{"BugTest1_"} + std::to_string(fixture.baseVersion);
      73              : 
      74            2 :   ifc.storeGlobalConfiguration(compositionMap, compName);
      75            2 :   std::cout << "  Created composition: " << compName << "\n";
      76              : 
      77            2 :   auto loadedMap = ifc.loadGlobalConfiguration(compName);
      78            2 :   BOOST_CHECK_EQUAL(loadedMap.size(), 1);
      79              : 
      80            2 :   std::cout << "  Verified: Composition has " << loadedMap.size() << " member (correct)\n";
      81            2 : }
      82              : 
      83            4 : BOOST_AUTO_TEST_CASE(inspect_database_storage_format) {
      84            2 :   std::cout << "\n=== TEST 2: Inspecting database storage format ===\n";
      85              : 
      86            2 :   auto ifc = DatabaseConfigurationInterface();
      87              : 
      88            2 :   int version1 = fixture.baseVersion + 10;
      89            2 :   int version2 = fixture.baseVersion + 11;
      90              : 
      91            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
      92            2 :   cfg1->getView().version = version1;
      93            2 :   ifc.saveActiveVersion(cfg1.get());
      94              : 
      95            2 :   std::shared_ptr<ConfigurationBase> cfg2 = std::make_shared<TestConfiguration002>();
      96            2 :   cfg2->getView().version = version2;
      97            2 :   ifc.saveActiveVersion(cfg2.get());
      98              : 
      99            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
     100            2 :   compositionMap[cfg1->getConfigurationName()] = version1;
     101            2 :   compositionMap[cfg2->getConfigurationName()] = version2;
     102              : 
     103            6 :   std::string compName = std::string{"BugTest2_"} + std::to_string(fixture.baseVersion);
     104              : 
     105            2 :   ifc.storeGlobalConfiguration(compositionMap, compName);
     106              : 
     107            2 :   auto loadedMap = ifc.loadGlobalConfiguration(compName);
     108              : 
     109            2 :   std::cout << "Composition '" << compName << "' contains:\n";
     110            6 :   for (auto const& entry : loadedMap) {
     111            4 :     std::cout << "  " << entry.first << " -> version " << entry.second << "\n";
     112              :   }
     113              : 
     114            2 :   BOOST_CHECK_EQUAL(loadedMap.size(), 2);
     115              : 
     116            2 :   int count001 = loadedMap.count(cfg1->getConfigurationName());
     117            2 :   int count002 = loadedMap.count(cfg2->getConfigurationName());
     118              : 
     119            2 :   BOOST_CHECK_EQUAL(count001, 1);
     120            2 :   BOOST_CHECK_EQUAL(count002, 1);
     121              : 
     122            2 :   std::cout << "  Verified: Each configuration type appears exactly once\n";
     123            2 : }
     124              : 
     125            4 : BOOST_AUTO_TEST_CASE(scan_database_for_duplicates) {
     126            2 :   std::cout << "\n=== TEST 3: Scanning database for duplicate entries ===\n";
     127              : 
     128            2 :   auto ifc = DatabaseConfigurationInterface();
     129              : 
     130            2 :   auto allCompositions = ifc.findAllGlobalConfigurations();
     131              : 
     132            2 :   std::cout << "Scanning " << allCompositions.size() << " compositions for duplicates...\n";
     133              : 
     134            2 :   int duplicatesFound = 0;
     135              : 
     136            6 :   for (auto const& compName : allCompositions) {
     137              :     try {
     138            4 :       auto members = ifc.loadGlobalConfiguration(compName);
     139              : 
     140            4 :       if (members.size() > 10) {
     141            0 :         std::cout << "  " << compName << ": " << members.size() << " members\n";
     142              :       }
     143              : 
     144            4 :     } catch (std::exception const& e) {
     145            0 :       std::cout << "  Error loading " << compName << ": " << e.what() << "\n";
     146            0 :     }
     147              :   }
     148              : 
     149            2 :   std::cout << "\nSummary: Found " << duplicatesFound << " compositions with duplicate detection issues\n";
     150            2 : }
     151              : 
     152            4 : BOOST_AUTO_TEST_CASE(map_interface_prevents_duplicates) {
     153            2 :   std::cout << "\n=== TEST 4: Map interface prevents duplicates ===\n";
     154              : 
     155            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
     156              : 
     157            2 :   std::string typeName = "TestConfiguration001";
     158              : 
     159            2 :   compositionMap[typeName] = 100;
     160            2 :   std::cout << "Added version 100, map size: " << compositionMap.size() << "\n";
     161            2 :   BOOST_CHECK_EQUAL(compositionMap.size(), 1);
     162            2 :   BOOST_CHECK_EQUAL(compositionMap[typeName], 100);
     163              : 
     164            2 :   compositionMap[typeName] = 200;
     165            2 :   std::cout << "Added version 200, map size: " << compositionMap.size() << "\n";
     166            2 :   BOOST_CHECK_EQUAL(compositionMap.size(), 1);
     167            2 :   BOOST_CHECK_EQUAL(compositionMap[typeName], 200);
     168              : 
     169            2 :   compositionMap[typeName] = 300;
     170            2 :   std::cout << "Added version 300, map size: " << compositionMap.size() << "\n";
     171            2 :   BOOST_CHECK_EQUAL(compositionMap.size(), 1);
     172            2 :   BOOST_CHECK_EQUAL(compositionMap[typeName], 300);
     173              : 
     174            2 :   std::cout << "  Verified: std::map automatically prevents duplicates\n";
     175            2 :   std::cout << "  Final value: " << compositionMap[typeName] << " (should be 300)\n";
     176            2 : }
     177              : 
     178              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1