LCOV - code coverage report
Current view: top level - /opt/artdaq/srcs/artdaq-database/test/CaseStudy/OtsDaqCPPInterface/test012 - VersionEdgeCases_t.cc (source / functions) Coverage Total Hit
Test: artdaq.info.cleaned Lines: 92.6 % 175 162
Test Date: 2026-10-29 00:35:58 Functions: 100.0 % 18 18

            Line data    Source code
       1              : #define BOOST_TEST_DYN_LINK
       2              : #define BOOST_TEST_MODULE (VersionEdgeCases test)
       3              : 
       4              : #include <boost/test/unit_test.hpp>
       5              : 
       6              : #include <climits>
       7              : #include <cstdlib>
       8              : #include <ctime>
       9              : #include <iostream>
      10              : #include <memory>
      11              : #include <string>
      12              : #include <vector>
      13              : 
      14              : #include "../DatabaseConfigurationInterface.h"
      15              : 
      16              : using namespace ots;
      17              : 
      18              : struct VersionEdgeCasesTestData {
      19            2 :   VersionEdgeCasesTestData() {
      20            2 :     srand(time(nullptr));
      21            2 :     baseVersion = rand() % 99999 + 100000;
      22            2 :     std::cout << "=== VERSION EDGE CASES TEST SUITE ===\n";
      23            2 :     std::cout << "Base version: " << baseVersion << "\n\n";
      24            2 :   }
      25              : 
      26            2 :   ~VersionEdgeCasesTestData() { std::cout << "\n=== TEST SUITE COMPLETE ===\n"; }
      27              : 
      28              :   int baseVersion;
      29              : };
      30              : 
      31              : VersionEdgeCasesTestData fixture;
      32              : 
      33              : BOOST_AUTO_TEST_SUITE(version_edge_cases_test)
      34              : 
      35            4 : BOOST_AUTO_TEST_CASE(version_zero_is_valid) {
      36            2 :   std::cout << "\n=== TEST 1: Version zero is valid ===\n";
      37              : 
      38            2 :   auto ifc = DatabaseConfigurationInterface();
      39              : 
      40            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      41            2 :   cfg->getView().version = 0;
      42              : 
      43            2 :   auto result = ifc.saveActiveVersion(cfg.get());
      44            2 :   std::cout << "Step 1: Save version 0 returned: " << result << "\n";
      45              : 
      46            2 :   if (result != 0) {
      47            0 :     std::cout << "  NOTE: Version 0 may already exist from previous test runs\n";
      48            0 :     std::shared_ptr<ConfigurationBase> readCfg = std::make_shared<TestConfiguration001>();
      49            0 :     auto fillResult = ifc.fill(readCfg.get(), 0);
      50            0 :     if (fillResult == 0) {
      51            0 :       std::cout << "  Version 0 already exists and is loadable\n";
      52            0 :       BOOST_CHECK(true);
      53              :     } else {
      54            0 :       std::cout << "  Version 0 is rejected by the system\n";
      55            0 :       BOOST_WARN_MESSAGE(false, "Version 0 may not be supported");
      56              :     }
      57            0 :   } else {
      58            2 :     auto versions = ifc.getVersions(cfg.get());
      59            2 :     bool found = (versions.find(0) != versions.end());
      60            2 :     std::cout << "Step 2: Version 0 found in getVersions: " << (found ? "yes" : "no") << "\n";
      61            2 :     BOOST_CHECK(found);
      62            2 :   }
      63              : 
      64            2 :   std::cout << "  Documented: Version 0 behavior\n";
      65            2 : }
      66              : 
      67            4 : BOOST_AUTO_TEST_CASE(negative_version_handling) {
      68            2 :   std::cout << "\n=== TEST 2: Negative version handling ===\n";
      69              : 
      70            2 :   auto ifc = DatabaseConfigurationInterface();
      71              : 
      72            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      73            2 :   cfg->getView().version = -1;
      74              : 
      75            2 :   auto result = ifc.saveActiveVersion(cfg.get());
      76            2 :   std::cout << "Step 1: Save version -1 returned: " << result << "\n";
      77              : 
      78            2 :   if (result == 0) {
      79            2 :     std::cout << "  NOTE: Negative versions are accepted by the system\n";
      80            2 :     BOOST_WARN_MESSAGE(false, "Negative versions are accepted - may need validation");
      81              : 
      82            2 :     auto versions = ifc.getVersions(cfg.get());
      83            2 :     bool found = (versions.find(-1) != versions.end());
      84            2 :     std::cout << "Step 2: Version -1 found in getVersions: " << (found ? "yes" : "no") << "\n";
      85            2 :   } else {
      86            0 :     std::cout << "  OK: Negative versions are rejected\n";
      87              :   }
      88              : 
      89            2 :   BOOST_CHECK(true);
      90            2 :   std::cout << "  Documented: Negative version behavior\n";
      91            2 : }
      92              : 
      93            4 : BOOST_AUTO_TEST_CASE(max_int_version) {
      94            2 :   std::cout << "\n=== TEST 3: Maximum integer version ===\n";
      95              : 
      96            2 :   auto ifc = DatabaseConfigurationInterface();
      97              : 
      98            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      99            2 :   cfg->getView().version = INT_MAX;
     100            2 :   std::cout << "Using INT_MAX = " << INT_MAX << "\n";
     101              : 
     102            2 :   auto result = ifc.saveActiveVersion(cfg.get());
     103            2 :   std::cout << "Step 1: Save version INT_MAX returned: " << result << "\n";
     104              : 
     105            2 :   if (result == 0) {
     106            2 :     std::cout << "  INT_MAX version accepted\n";
     107            2 :     auto versions = ifc.getVersions(cfg.get());
     108            2 :     bool found = (versions.find(INT_MAX) != versions.end());
     109            2 :     std::cout << "Step 2: INT_MAX found in getVersions: " << (found ? "yes" : "no") << "\n";
     110            2 :   } else {
     111            0 :     std::cout << "  INT_MAX version rejected (acceptable)\n";
     112              :   }
     113              : 
     114            2 :   BOOST_CHECK(true);
     115            2 :   std::cout << "  Verified: INT_MAX handled without crash\n";
     116            2 : }
     117              : 
     118            4 : BOOST_AUTO_TEST_CASE(version_gap_findlatest_correct) {
     119            2 :   std::cout << "\n=== TEST 4: Version gap findLatest correct ===\n";
     120              : 
     121            2 :   auto ifc = DatabaseConfigurationInterface();
     122            2 :   int baseV = fixture.baseVersion + 1000;
     123              : 
     124            4 :   std::vector<int> versions = {baseV + 1, baseV + 5, baseV + 10, baseV + 100};
     125              : 
     126           10 :   for (int v : versions) {
     127            8 :     std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     128            8 :     cfg->getView().version = v;
     129            8 :     auto result = ifc.saveActiveVersion(cfg.get());
     130            8 :     BOOST_REQUIRE_EQUAL(result, 0);
     131            8 :   }
     132            2 :   std::cout << "Step 1: Created versions with gaps: " << versions[0] << ", " << versions[1] << ", " << versions[2] << ", " << versions[3] << "\n";
     133              : 
     134            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     135            2 :   auto latest = ifc.findLatestVersion(cfg.get());
     136            2 :   std::cout << "Step 2: findLatestVersion returned: " << latest << "\n";
     137              : 
     138            2 :   BOOST_CHECK_GE(latest, baseV + 100);
     139            2 :   std::cout << "  Verified: findLatestVersion works correctly with gaps\n";
     140            2 : }
     141              : 
     142            4 : BOOST_AUTO_TEST_CASE(version_ordering_not_insertion_order) {
     143            2 :   std::cout << "\n=== TEST 5: Version ordering not insertion order ===\n";
     144              : 
     145            2 :   auto ifc = DatabaseConfigurationInterface();
     146            2 :   int baseV = fixture.baseVersion + 2000;
     147              : 
     148            4 :   std::vector<int> insertOrder = {baseV + 50, baseV + 10, baseV + 30, baseV + 20};
     149              : 
     150           10 :   for (int v : insertOrder) {
     151            8 :     std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     152            8 :     cfg->getView().version = v;
     153            8 :     auto result = ifc.saveActiveVersion(cfg.get());
     154            8 :     BOOST_REQUIRE_EQUAL(result, 0);
     155            8 :   }
     156            2 :   std::cout << "Step 1: Inserted versions in order: " << insertOrder[0] << ", " << insertOrder[1] << ", " << insertOrder[2] << ", " << insertOrder[3]
     157            2 :             << "\n";
     158              : 
     159            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     160            2 :   auto latest = ifc.findLatestVersion(cfg.get());
     161            2 :   std::cout << "Step 2: findLatestVersion returned: " << latest << " (expected >= " << baseV + 50 << ")\n";
     162              : 
     163            2 :   BOOST_CHECK_GE(latest, baseV + 50);
     164            2 :   std::cout << "  Verified: findLatestVersion uses numeric ordering, not insertion order\n";
     165            2 : }
     166              : 
     167            4 : BOOST_AUTO_TEST_CASE(getversions_returns_sorted) {
     168            2 :   std::cout << "\n=== TEST 6: getVersions returns sorted ===\n";
     169              : 
     170            2 :   auto ifc = DatabaseConfigurationInterface();
     171            2 :   int baseV = fixture.baseVersion + 3000;
     172              : 
     173            4 :   std::vector<int> insertOrder = {baseV + 100, baseV + 1, baseV + 50, baseV + 25, baseV + 75};
     174              : 
     175           12 :   for (int v : insertOrder) {
     176           10 :     std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     177           10 :     cfg->getView().version = v;
     178           10 :     auto result = ifc.saveActiveVersion(cfg.get());
     179           10 :     BOOST_REQUIRE_EQUAL(result, 0);
     180           10 :   }
     181            2 :   std::cout << "Step 1: Inserted " << insertOrder.size() << " versions in random order\n";
     182              : 
     183            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     184            2 :   auto versions = ifc.getVersions(cfg.get());
     185              : 
     186            2 :   std::vector<int> foundVersions;
     187           12 :   for (int v : insertOrder) {
     188           10 :     if (versions.find(v) != versions.end()) {
     189           10 :       foundVersions.push_back(v);
     190              :     }
     191              :   }
     192              : 
     193            2 :   std::cout << "Step 2: Found " << foundVersions.size() << "/" << insertOrder.size() << " inserted versions\n";
     194            2 :   BOOST_CHECK_EQUAL(foundVersions.size(), insertOrder.size());
     195              : 
     196            2 :   int prev = INT_MIN;
     197            2 :   bool isSorted = true;
     198           34 :   for (int v : versions) {
     199           32 :     if (v < prev) {
     200            0 :       isSorted = false;
     201            0 :       break;
     202              :     }
     203           32 :     prev = v;
     204              :   }
     205              : 
     206            2 :   std::cout << "Step 3: All versions sorted: " << (isSorted ? "yes" : "no") << "\n";
     207            2 :   BOOST_CHECK(isSorted);
     208              : 
     209            2 :   std::cout << "  Verified: getVersions returns sorted set\n";
     210            2 : }
     211              : 
     212            4 : BOOST_AUTO_TEST_CASE(same_version_different_data_overwrite) {
     213            2 :   std::cout << "\n=== TEST 7: Same version different data overwrite ===\n";
     214              : 
     215            2 :   auto ifc = DatabaseConfigurationInterface();
     216            2 :   int testVersion = fixture.baseVersion + 4000;
     217              : 
     218            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     219            2 :   cfg->getView().version = testVersion;
     220            4 :   cfg->getView().fillFromJSON("{\"data\": \"original_value_12345\"}");
     221            2 :   auto result1 = ifc.saveActiveVersion(cfg.get());
     222            2 :   BOOST_REQUIRE_EQUAL(result1, 0);
     223            2 :   std::cout << "Step 1: Saved version " << testVersion << " with original data\n";
     224              : 
     225            4 :   cfg->getView().fillFromJSON("{\"data\": \"updated_value_67890\"}");
     226            2 :   auto result2 = ifc.saveActiveVersion(cfg.get(), true);
     227            2 :   BOOST_CHECK_EQUAL(result2, 0);
     228            2 :   std::cout << "Step 2: Overwrote with updated data, result: " << result2 << "\n";
     229              : 
     230            2 :   std::shared_ptr<ConfigurationBase> readCfg = std::make_shared<TestConfiguration001>();
     231            2 :   auto fillResult = ifc.fill(readCfg.get(), testVersion);
     232            2 :   BOOST_REQUIRE_EQUAL(fillResult, 0);
     233              : 
     234            2 :   bool hasUpdated = (readCfg->getView()._json.find("updated_value_67890") != std::string::npos);
     235            2 :   bool hasOriginal = (readCfg->getView()._json.find("original_value_12345") != std::string::npos);
     236            2 :   std::cout << "Step 3: Loaded data contains updated: " << (hasUpdated ? "yes" : "no") << ", original: " << (hasOriginal ? "yes" : "no") << "\n";
     237              : 
     238            2 :   BOOST_CHECK(hasUpdated);
     239            2 :   BOOST_CHECK(!hasOriginal);
     240            2 :   std::cout << "  Verified: Overwrite replaces data correctly\n";
     241            2 : }
     242              : 
     243            4 : BOOST_AUTO_TEST_CASE(version_one_million) {
     244            2 :   std::cout << "\n=== TEST 8: Version one million ===\n";
     245              : 
     246            2 :   auto ifc = DatabaseConfigurationInterface();
     247              : 
     248            2 :   int largeVersion = fixture.baseVersion + 1000000;
     249            2 :   std::cout << "Using version: " << largeVersion << "\n";
     250              : 
     251            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     252            2 :   cfg->getView().version = largeVersion;
     253              : 
     254            2 :   auto result = ifc.saveActiveVersion(cfg.get());
     255            2 :   std::cout << "Step 1: Save version " << largeVersion << " returned: " << result << "\n";
     256            2 :   BOOST_CHECK_EQUAL(result, 0);
     257              : 
     258            2 :   std::shared_ptr<ConfigurationBase> readCfg = std::make_shared<TestConfiguration001>();
     259            2 :   auto fillResult = ifc.fill(readCfg.get(), largeVersion);
     260            2 :   std::cout << "Step 2: fill() for version " << largeVersion << " returned: " << fillResult << "\n";
     261            2 :   BOOST_CHECK_EQUAL(fillResult, 0);
     262              : 
     263            2 :   std::cout << "  Verified: Large version numbers work correctly\n";
     264            2 : }
     265              : 
     266              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1