LCOV - code coverage report
Current view: top level - /opt/artdaq/srcs/artdaq-database/test/CaseStudy/OtsDaqCPPInterface/test005 - CaseSensitivity_t.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 96.1 % 180 173
Test Date: 2026-10-29 00:35:58 Functions: 100.0 % 14 14

            Line data    Source code
       1              : #define BOOST_TEST_DYN_LINK
       2              : #define BOOST_TEST_MODULE (CaseSensitivity test)
       3              : 
       4              : #include <boost/test/unit_test.hpp>
       5              : 
       6              : #include <algorithm>
       7              : #include <iostream>
       8              : #include <memory>
       9              : #include <set>
      10              : #include <string>
      11              : 
      12              : #include "../DatabaseConfigurationInterface.h"
      13              : 
      14              : using namespace ots;
      15              : 
      16              : struct CaseSensitivityTestData {
      17            2 :   CaseSensitivityTestData() {
      18            2 :     srand(time(nullptr));
      19            2 :     baseVersion = rand() % 99999 + 100000;
      20            2 :     std::cout << "=== CASE SENSITIVITY VERIFICATION TEST SUITE ===\n";
      21            2 :     std::cout << "Base version: " << baseVersion << "\n\n";
      22            2 :   }
      23              : 
      24            2 :   ~CaseSensitivityTestData() { std::cout << "\n=== TEST SUITE COMPLETE ===\n"; }
      25              : 
      26              :   int baseVersion;
      27              : };
      28              : 
      29              : CaseSensitivityTestData fixture;
      30              : 
      31              : BOOST_AUTO_TEST_SUITE(case_sensitivity_test)
      32              : 
      33            4 : BOOST_AUTO_TEST_CASE(different_cases_create_different_compositions) {
      34            2 :   std::cout << "\n=== TEST 1: Different cases create different compositions ===\n";
      35              : 
      36            2 :   auto ifc = DatabaseConfigurationInterface();
      37              : 
      38            2 :   int version1 = fixture.baseVersion;
      39              : 
      40            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
      41            2 :   cfg1->getView().version = version1;
      42            2 :   auto result1 = ifc.saveActiveVersion(cfg1.get());
      43            2 :   BOOST_CHECK_EQUAL(result1, 0);
      44              : 
      45            2 :   std::cout << "Created configuration version: " << version1 << "\n";
      46              : 
      47            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
      48            2 :   compositionMap[cfg1->getConfigurationName()] = version1;
      49              : 
      50            4 :   std::string name1 = "RunConfig";
      51            4 :   std::string name2 = "runconfig";
      52            2 :   std::string name3 = "RUNCONFIG";
      53              : 
      54            2 :   std::cout << "Creating compositions with different cases:\n";
      55            2 :   std::cout << "  1. '" << name1 << "'\n";
      56            2 :   std::cout << "  2. '" << name2 << "'\n";
      57            2 :   std::cout << "  3. '" << name3 << "'\n";
      58              : 
      59            2 :   ifc.storeGlobalConfiguration(compositionMap, name1);
      60            2 :   ifc.storeGlobalConfiguration(compositionMap, name2);
      61            2 :   ifc.storeGlobalConfiguration(compositionMap, name3);
      62              : 
      63            2 :   auto allCompositions = ifc.findAllGlobalConfigurations();
      64              : 
      65            2 :   bool found1 = (allCompositions.find(name1) != allCompositions.end());
      66            2 :   bool found2 = (allCompositions.find(name2) != allCompositions.end());
      67            2 :   bool found3 = (allCompositions.find(name3) != allCompositions.end());
      68              : 
      69            2 :   std::cout << "Results:\n";
      70            2 :   std::cout << "  '" << name1 << "' found: " << (found1 ? "YES" : "NO") << "\n";
      71            2 :   std::cout << "  '" << name2 << "' found: " << (found2 ? "YES" : "NO") << "\n";
      72            2 :   std::cout << "  '" << name3 << "' found: " << (found3 ? "YES" : "NO") << "\n";
      73              : 
      74            2 :   BOOST_CHECK_EQUAL(found1, true);
      75            2 :   BOOST_CHECK_EQUAL(found2, true);
      76            2 :   BOOST_CHECK_EQUAL(found3, true);
      77              : 
      78            2 :   std::cout << "  Verified: All three compositions exist independently\n";
      79            2 : }
      80              : 
      81            4 : BOOST_AUTO_TEST_CASE(case_sensitive_lookup) {
      82            2 :   std::cout << "\n=== TEST 2: Case-sensitive lookup ===\n";
      83              : 
      84            2 :   auto ifc = DatabaseConfigurationInterface();
      85              : 
      86            2 :   int version1 = fixture.baseVersion + 10;
      87              : 
      88            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
      89            2 :   cfg1->getView().version = version1;
      90            2 :   ifc.saveActiveVersion(cfg1.get());
      91              : 
      92            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
      93            2 :   compositionMap[cfg1->getConfigurationName()] = version1;
      94              : 
      95            2 :   std::string exactName = "TestComp_Case";
      96            2 :   ifc.storeGlobalConfiguration(compositionMap, exactName);
      97              : 
      98            2 :   std::cout << "Created composition: '" << exactName << "'\n";
      99              : 
     100            2 :   std::cout << "Loading with exact case: '" << exactName << "'...\n";
     101              :   try {
     102            2 :     auto loadedMap = ifc.loadGlobalConfiguration(exactName);
     103            2 :     BOOST_CHECK_EQUAL(loadedMap.size(), 1);
     104            2 :     std::cout << "  SUCCESS: Loaded composition with exact case\n";
     105            2 :   } catch (std::exception const& e) {
     106            0 :     BOOST_FAIL("Failed to load with exact case: " << e.what());
     107            0 :   }
     108              : 
     109            2 :   std::string wrongCase = "testcomp_case";
     110            2 :   std::cout << "Loading with different case: '" << wrongCase << "'...\n";
     111              : 
     112            2 :   bool loadedWithWrongCase = true;
     113              :   try {
     114            2 :     auto loadedMap = ifc.loadGlobalConfiguration(wrongCase);
     115            0 :     loadedWithWrongCase = true;
     116            0 :     std::cout << "  UNEXPECTED: Loaded with different case (case-insensitive!)\n";
     117            2 :   } catch (std::exception const& e) {
     118            2 :     loadedWithWrongCase = false;
     119            2 :     std::cout << "  EXPECTED: Failed to load with different case (case-sensitive)\n";
     120            2 :   }
     121              : 
     122            2 :   BOOST_CHECK_EQUAL(loadedWithWrongCase, false);
     123            2 : }
     124              : 
     125            4 : BOOST_AUTO_TEST_CASE(case_sensitive_search) {
     126            2 :   std::cout << "\n=== TEST 3: Case-sensitive search ===\n";
     127              : 
     128            2 :   auto ifc = DatabaseConfigurationInterface();
     129              : 
     130            2 :   int version1 = fixture.baseVersion + 20;
     131              : 
     132            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
     133            2 :   cfg1->getView().version = version1;
     134            2 :   ifc.saveActiveVersion(cfg1.get());
     135              : 
     136            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
     137            2 :   compositionMap[cfg1->getConfigurationName()] = version1;
     138              : 
     139            4 :   std::string name1 = "SearchTest_ABC";
     140            2 :   std::string name2 = "SearchTest_abc";
     141              : 
     142            2 :   ifc.storeGlobalConfiguration(compositionMap, name1);
     143            2 :   ifc.storeGlobalConfiguration(compositionMap, name2);
     144              : 
     145            2 :   std::cout << "Created compositions:\n";
     146            2 :   std::cout << "  1. '" << name1 << "'\n";
     147            2 :   std::cout << "  2. '" << name2 << "'\n";
     148              : 
     149            2 :   std::cout << "Searching for exact match: '" << name1 << "'\n";
     150            2 :   auto results1 = ifc.findAllGlobalConfigurations(name1);
     151              : 
     152            2 :   std::cout << "Found " << results1.size() << " result(s)\n";
     153              : 
     154            2 :   if (results1.size() == 1) {
     155            2 :     std::cout << "  CASE-SENSITIVE: Found only exact match\n";
     156            2 :     BOOST_CHECK_EQUAL(results1.size(), 1);
     157            0 :   } else if (results1.size() == 2) {
     158            0 :     std::cout << "  CASE-INSENSITIVE: Found both variations (potential bug)\n";
     159            0 :     BOOST_WARN_MESSAGE(false, "Search appears to be case-insensitive");
     160              :   }
     161              : 
     162            2 :   bool foundExact = (results1.find(name1) != results1.end());
     163            2 :   BOOST_CHECK_EQUAL(foundExact, true);
     164            2 : }
     165              : 
     166            4 : BOOST_AUTO_TEST_CASE(case_preservation_in_storage) {
     167            2 :   std::cout << "\n=== TEST 4: Case preservation in storage ===\n";
     168              : 
     169            2 :   auto ifc = DatabaseConfigurationInterface();
     170              : 
     171            2 :   int version1 = fixture.baseVersion + 30;
     172              : 
     173            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
     174            2 :   cfg1->getView().version = version1;
     175            2 :   ifc.saveActiveVersion(cfg1.get());
     176              : 
     177            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
     178            2 :   compositionMap[cfg1->getConfigurationName()] = version1;
     179              : 
     180            2 :   std::string originalName = "MixedCase_TeStNaMe_123";
     181            2 :   ifc.storeGlobalConfiguration(compositionMap, originalName);
     182              : 
     183            2 :   std::cout << "Stored composition with name: '" << originalName << "'\n";
     184              : 
     185            2 :   auto allCompositions = ifc.findAllGlobalConfigurations();
     186              : 
     187            2 :   bool foundWithOriginalCase = (allCompositions.find(originalName) != allCompositions.end());
     188              : 
     189            2 :   std::cout << "Searching for composition in returned list...\n";
     190            2 :   std::cout << "  Original case '" << originalName << "' found: " << (foundWithOriginalCase ? "YES" : "NO") << "\n";
     191              : 
     192            2 :   BOOST_CHECK_EQUAL(foundWithOriginalCase, true);
     193              : 
     194            2 :   auto loadedMap = ifc.loadGlobalConfiguration(originalName);
     195            2 :   BOOST_CHECK_EQUAL(loadedMap.size(), 1);
     196              : 
     197            2 :   std::cout << "  Verified: Case is preserved in storage and retrieval\n";
     198            2 : }
     199              : 
     200            4 : BOOST_AUTO_TEST_CASE(configuration_type_names_case_sensitive) {
     201            2 :   std::cout << "\n=== TEST 5: Configuration type names case-sensitive ===\n";
     202              : 
     203            2 :   auto ifc = DatabaseConfigurationInterface();
     204              : 
     205            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
     206            2 :   std::string actualTypeName = cfg1->getConfigurationName();
     207              : 
     208            2 :   std::cout << "Actual configuration type name: '" << actualTypeName << "'\n";
     209              : 
     210            2 :   int version1 = fixture.baseVersion + 40;
     211            2 :   cfg1->getView().version = version1;
     212            2 :   ifc.saveActiveVersion(cfg1.get());
     213              : 
     214            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
     215            2 :   compositionMap[actualTypeName] = version1;
     216              : 
     217            2 :   std::string compName = "TypeNameTest_" + std::to_string(fixture.baseVersion);
     218            2 :   ifc.storeGlobalConfiguration(compositionMap, compName);
     219              : 
     220            2 :   std::cout << "Created composition with type: '" << actualTypeName << "'\n";
     221              : 
     222            2 :   auto loadedMap = ifc.loadGlobalConfiguration(compName);
     223              : 
     224            2 :   bool foundExactType = (loadedMap.find(actualTypeName) != loadedMap.end());
     225              : 
     226            2 :   std::cout << "Loaded composition, checking for exact type name...\n";
     227            2 :   std::cout << "  Found '" << actualTypeName << "': " << (foundExactType ? "YES" : "NO") << "\n";
     228              : 
     229            2 :   BOOST_CHECK_EQUAL(foundExactType, true);
     230            2 :   BOOST_CHECK_EQUAL(loadedMap.size(), 1);
     231              : 
     232            2 :   std::cout << "  All configuration types in composition:\n";
     233            4 :   for (auto const& entry : loadedMap) {
     234            2 :     std::cout << "    - '" << entry.first << "' -> version " << entry.second << "\n";
     235              :   }
     236              : 
     237            2 :   std::cout << "  Verified: Configuration type names are case-sensitive\n";
     238            2 : }
     239              : 
     240            4 : BOOST_AUTO_TEST_CASE(case_sensitive_reverse_lookup) {
     241            2 :   std::cout << "\n=== TEST 6: Case-sensitive reverse lookup ===\n";
     242              : 
     243            2 :   auto ifc = DatabaseConfigurationInterface();
     244              : 
     245            2 :   int version1 = fixture.baseVersion + 50;
     246              : 
     247            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
     248            2 :   cfg1->getView().version = version1;
     249            2 :   ifc.saveActiveVersion(cfg1.get());
     250              : 
     251            2 :   std::string configTypeName = cfg1->getConfigurationName();
     252              : 
     253            2 :   auto compositionMap = DatabaseConfigurationInterface::config_version_map_t{};
     254            2 :   compositionMap[configTypeName] = version1;
     255              : 
     256            4 :   std::string comp1Name = "ReverseTest_ABC";
     257            2 :   std::string comp2Name = "ReverseTest_abc";
     258              : 
     259            2 :   ifc.storeGlobalConfiguration(compositionMap, comp1Name);
     260            2 :   ifc.storeGlobalConfiguration(compositionMap, comp2Name);
     261              : 
     262            2 :   std::cout << "Created compositions:\n";
     263            2 :   std::cout << "  1. '" << comp1Name << "'\n";
     264            2 :   std::cout << "  2. '" << comp2Name << "'\n";
     265              : 
     266            2 :   auto foundCompositions = ifc.findCompositionsContaining(configTypeName, std::to_string(version1));
     267              : 
     268            2 :   std::cout << "Reverse lookup for version " << version1 << " found " << foundCompositions.size() << " compositions\n";
     269              : 
     270            2 :   BOOST_CHECK_EQUAL(foundCompositions.size(), 2);
     271              : 
     272            2 :   bool found1 = (foundCompositions.find(comp1Name) != foundCompositions.end());
     273            2 :   bool found2 = (foundCompositions.find(comp2Name) != foundCompositions.end());
     274              : 
     275            2 :   std::cout << "  Found '" << comp1Name << "': " << (found1 ? "YES" : "NO") << "\n";
     276            2 :   std::cout << "  Found '" << comp2Name << "': " << (found2 ? "YES" : "NO") << "\n";
     277              : 
     278            2 :   BOOST_CHECK_EQUAL(found1, true);
     279            2 :   BOOST_CHECK_EQUAL(found2, true);
     280              : 
     281            6 :   for (auto const& compName : foundCompositions) {
     282            4 :     std::cout << "  - '" << compName << "'\n";
     283              : 
     284            4 :     if (compName == comp1Name) {
     285            2 :       std::cout << "    Matches '" << comp1Name << "' exactly (case preserved)\n";
     286            2 :     } else if (compName == comp2Name) {
     287            2 :       std::cout << "    Matches '" << comp2Name << "' exactly (case preserved)\n";
     288              :     }
     289              :   }
     290              : 
     291            2 :   std::cout << "  Verified: Reverse lookup preserves case in composition names\n";
     292            2 : }
     293              : 
     294              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1