LCOV - code coverage report
Current view: top level - /opt/artdaq/srcs/artdaq-database/test/CaseStudy/OtsDaqCPPInterface/test015 - CompositionNaming_t.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 82.0 % 172 141
Test Date: 2026-10-29 00:35:58 Functions: 100.0 % 15 15

            Line data    Source code
       1              : #define BOOST_TEST_DYN_LINK
       2              : #define BOOST_TEST_MODULE (CompositionNaming test)
       3              : 
       4              : #include <boost/test/unit_test.hpp>
       5              : 
       6              : #include <cstdlib>
       7              : #include <ctime>
       8              : #include <iostream>
       9              : #include <memory>
      10              : #include <string>
      11              : #include <vector>
      12              : 
      13              : #include "../DatabaseConfigurationInterface.h"
      14              : 
      15              : using namespace ots;
      16              : 
      17              : struct CompositionNamingTestData {
      18            2 :   CompositionNamingTestData() {
      19            2 :     srand(time(nullptr));
      20            2 :     baseVersion = rand() % 99999 + 100000;
      21            2 :     std::cout << "=== COMPOSITION NAMING TEST SUITE ===\n";
      22            2 :     std::cout << "Base version: " << baseVersion << "\n\n";
      23            2 :   }
      24              : 
      25            2 :   ~CompositionNamingTestData() { std::cout << "\n=== TEST SUITE COMPLETE ===\n"; }
      26              : 
      27              :   int baseVersion;
      28              : };
      29              : 
      30              : CompositionNamingTestData fixture;
      31              : 
      32              : BOOST_AUTO_TEST_SUITE(composition_naming_test)
      33              : 
      34           12 : void createTestVersion(DatabaseConfigurationInterface& ifc, int version) {
      35           12 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      36           12 :   cfg->getView().version = version;
      37           12 :   ifc.saveActiveVersion(cfg.get());
      38           12 : }
      39              : 
      40            4 : BOOST_AUTO_TEST_CASE(empty_composition_name_rejected) {
      41            2 :   std::cout << "\n=== TEST 1: Empty composition name rejected ===\n";
      42              : 
      43            2 :   auto ifc = DatabaseConfigurationInterface();
      44            2 :   int testVersion = fixture.baseVersion;
      45            2 :   createTestVersion(ifc, testVersion);
      46              : 
      47            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
      48            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      49            2 :   map[cfg->getConfigurationName()] = testVersion;
      50              : 
      51            2 :   bool threwException = false;
      52              :   try {
      53            4 :     ifc.storeGlobalConfiguration(map, "");
      54            2 :   } catch (std::exception& e) {
      55            2 :     threwException = true;
      56            2 :     std::cout << "  Exception: " << e.what() << "\n";
      57            2 :   }
      58              : 
      59            2 :   std::cout << "Step 1: Empty name threw exception: " << (threwException ? "yes" : "no") << "\n";
      60              : 
      61            2 :   if (!threwException) {
      62            0 :     BOOST_WARN_MESSAGE(false, "Empty composition name was accepted - may need validation");
      63              :     try {
      64            0 :       auto loaded = ifc.loadGlobalConfiguration("");
      65            0 :       std::cout << "  NOTE: Empty name composition loaded successfully\n";
      66            0 :     } catch (...) {
      67            0 :       std::cout << "  NOTE: Empty name composition could not be loaded\n";
      68            0 :     }
      69              :   }
      70              : 
      71            2 :   BOOST_CHECK(true);
      72            2 :   std::cout << "  Documented: Empty name behavior\n";
      73            2 : }
      74              : 
      75            4 : BOOST_AUTO_TEST_CASE(whitespace_only_name_rejected) {
      76            2 :   std::cout << "\n=== TEST 2: Whitespace only name rejected ===\n";
      77              : 
      78            2 :   auto ifc = DatabaseConfigurationInterface();
      79            2 :   int testVersion = fixture.baseVersion + 1;
      80            2 :   createTestVersion(ifc, testVersion);
      81              : 
      82            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
      83            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      84            2 :   map[cfg->getConfigurationName()] = testVersion;
      85              : 
      86            2 :   bool threwException = false;
      87              :   try {
      88            4 :     ifc.storeGlobalConfiguration(map, "   ");
      89            0 :   } catch (std::exception& e) {
      90            0 :     threwException = true;
      91            0 :     std::cout << "  Exception: " << e.what() << "\n";
      92            0 :   }
      93              : 
      94            2 :   std::cout << "Step 1: Whitespace-only name threw exception: " << (threwException ? "yes" : "no") << "\n";
      95              : 
      96            2 :   if (!threwException) {
      97            2 :     BOOST_WARN_MESSAGE(false, "Whitespace-only composition name was accepted");
      98              :   }
      99              : 
     100            2 :   BOOST_CHECK(true);
     101            2 :   std::cout << "  Documented: Whitespace-only name behavior\n";
     102            2 : }
     103              : 
     104            4 : BOOST_AUTO_TEST_CASE(very_long_name_handling) {
     105            2 :   std::cout << "\n=== TEST 3: Very long name handling ===\n";
     106              : 
     107            2 :   auto ifc = DatabaseConfigurationInterface();
     108            2 :   int testVersion = fixture.baseVersion + 2;
     109            2 :   createTestVersion(ifc, testVersion);
     110              : 
     111            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
     112            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     113            2 :   map[cfg->getConfigurationName()] = testVersion;
     114              : 
     115            2 :   std::string longName(500, 'x');
     116            2 :   longName += "_" + std::to_string(fixture.baseVersion);
     117            2 :   std::cout << "Step 1: Testing name with " << longName.size() << " characters\n";
     118              : 
     119            2 :   bool succeeded = false;
     120            2 :   bool threwException = false;
     121              :   try {
     122            2 :     ifc.storeGlobalConfiguration(map, longName);
     123            2 :     succeeded = true;
     124            0 :   } catch (std::exception& e) {
     125            0 :     threwException = true;
     126            0 :     std::cout << "  Exception: " << e.what() << "\n";
     127            0 :   }
     128              : 
     129            2 :   std::cout << "Step 2: Long name succeeded: " << (succeeded ? "yes" : "no") << ", threw: " << (threwException ? "yes" : "no") << "\n";
     130              : 
     131            2 :   if (succeeded) {
     132              :     try {
     133            2 :       auto loaded = ifc.loadGlobalConfiguration(longName);
     134            2 :       std::cout << "Step 3: Long name composition loaded with " << loaded.size() << " members\n";
     135            2 :       BOOST_CHECK_EQUAL(loaded.size(), 1);
     136            2 :     } catch (std::exception& e) {
     137            0 :       std::cout << "Step 3: Could not load: " << e.what() << "\n";
     138            0 :       BOOST_WARN_MESSAGE(false, "Long name was stored but could not be loaded");
     139            0 :     }
     140              :   }
     141              : 
     142            2 :   BOOST_CHECK(true);
     143            2 :   std::cout << "  Documented: Long name behavior\n";
     144            2 : }
     145              : 
     146            4 : BOOST_AUTO_TEST_CASE(special_characters_in_name) {
     147            2 :   std::cout << "\n=== TEST 4: Special characters in name ===\n";
     148              : 
     149            2 :   auto ifc = DatabaseConfigurationInterface();
     150            2 :   int testVersion = fixture.baseVersion + 3;
     151            2 :   createTestVersion(ifc, testVersion);
     152              : 
     153            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
     154            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     155            2 :   map[cfg->getConfigurationName()] = testVersion;
     156              : 
     157              :   std::vector<std::pair<std::string, std::string>> specialNames = {
     158            4 :       {"with_underscore_" + std::to_string(fixture.baseVersion), "underscore"},
     159            4 :       {"with-dash-" + std::to_string(fixture.baseVersion), "dash"},
     160            4 :       {"with.dot." + std::to_string(fixture.baseVersion), "dot"},
     161           10 :   };
     162              : 
     163            8 :   for (const auto& [name, desc] : specialNames) {
     164            6 :     bool succeeded = false;
     165              :     try {
     166            6 :       ifc.storeGlobalConfiguration(map, name);
     167            6 :       succeeded = true;
     168            0 :     } catch (std::exception& e) {
     169            0 :       std::cout << "  " << desc << ": rejected (" << e.what() << ")\n";
     170            0 :     }
     171              : 
     172            6 :     if (succeeded) {
     173            6 :       std::cout << "  " << desc << ": accepted\n";
     174              :     }
     175              :   }
     176              : 
     177            2 :   BOOST_CHECK(true);
     178            2 :   std::cout << "  Documented: Special character behavior\n";
     179           10 : }
     180              : 
     181            4 : BOOST_AUTO_TEST_CASE(leading_trailing_whitespace_handling) {
     182            2 :   std::cout << "\n=== TEST 5: Leading/trailing whitespace handling ===\n";
     183              : 
     184            2 :   auto ifc = DatabaseConfigurationInterface();
     185            2 :   int testVersion = fixture.baseVersion + 5;
     186            2 :   createTestVersion(ifc, testVersion);
     187              : 
     188            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
     189            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     190            2 :   map[cfg->getConfigurationName()] = testVersion;
     191              : 
     192            2 :   std::string baseName = "TrimTest_" + std::to_string(fixture.baseVersion);
     193            2 :   std::string paddedName = "  " + baseName + "  ";
     194              : 
     195            2 :   bool succeeded = false;
     196              :   try {
     197            2 :     ifc.storeGlobalConfiguration(map, paddedName);
     198            2 :     succeeded = true;
     199            2 :     std::cout << "Step 1: Stored with padded name \"" << paddedName << "\"\n";
     200            0 :   } catch (std::exception& e) {
     201            0 :     std::cout << "Step 1: Padded name rejected: " << e.what() << "\n";
     202            0 :   }
     203              : 
     204            2 :   if (succeeded) {
     205              :     try {
     206            2 :       auto loaded = ifc.loadGlobalConfiguration(paddedName);
     207            2 :       std::cout << "Step 2a: Loaded with padded name (size=" << loaded.size() << ")\n";
     208            2 :     } catch (...) {
     209            0 :       std::cout << "Step 2a: Could not load with padded name\n";
     210            0 :     }
     211              : 
     212              :     try {
     213            2 :       auto loaded = ifc.loadGlobalConfiguration(baseName);
     214            0 :       std::cout << "Step 2b: Loaded with trimmed name (size=" << loaded.size() << ")\n";
     215            2 :     } catch (...) {
     216            2 :       std::cout << "Step 2b: Could not load with trimmed name\n";
     217            2 :     }
     218              :   }
     219              : 
     220            2 :   BOOST_CHECK(true);
     221            2 :   std::cout << "  Documented: Whitespace handling behavior\n";
     222            2 : }
     223              : 
     224            4 : BOOST_AUTO_TEST_CASE(case_sensitivity_in_names) {
     225            2 :   std::cout << "\n=== TEST 6: Case sensitivity in names ===\n";
     226              : 
     227            2 :   auto ifc = DatabaseConfigurationInterface();
     228            2 :   int testVersion = fixture.baseVersion + 6;
     229            2 :   createTestVersion(ifc, testVersion);
     230              : 
     231            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
     232            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     233            2 :   map[cfg->getConfigurationName()] = testVersion;
     234              : 
     235            2 :   std::string lowerName = "casetest_" + std::to_string(fixture.baseVersion);
     236            2 :   std::string upperName = "CASETEST_" + std::to_string(fixture.baseVersion);
     237              : 
     238            2 :   ifc.storeGlobalConfiguration(map, lowerName);
     239            2 :   std::cout << "Step 1: Stored \"" << lowerName << "\"\n";
     240              : 
     241            2 :   bool upperSucceeded = false;
     242              :   try {
     243            2 :     ifc.storeGlobalConfiguration(map, upperName);
     244            2 :     upperSucceeded = true;
     245            2 :     std::cout << "Step 2: \"" << upperName << "\" stored as separate composition (case sensitive)\n";
     246            0 :   } catch (std::exception& e) {
     247            0 :     std::cout << "Step 2: \"" << upperName << "\" rejected (case insensitive)\n";
     248            0 :   }
     249              : 
     250            2 :   if (upperSucceeded) {
     251              :     try {
     252            2 :       auto loadedLower = ifc.loadGlobalConfiguration(lowerName);
     253            2 :       auto loadedUpper = ifc.loadGlobalConfiguration(upperName);
     254            2 :       std::cout << "Step 3: Both compositions exist separately\n";
     255            2 :     } catch (...) {
     256            0 :       std::cout << "Step 3: Issue loading compositions\n";
     257            0 :     }
     258              :   }
     259              : 
     260            2 :   BOOST_CHECK(true);
     261            2 :   std::cout << "  Documented: Case sensitivity behavior\n";
     262            2 : }
     263              : 
     264              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1