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

            Line data    Source code
       1              : #define BOOST_TEST_DYN_LINK
       2              : #define BOOST_TEST_MODULE (WorkflowIntegration 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 WorkflowIntegrationTestData {
      18            2 :   WorkflowIntegrationTestData() {
      19            2 :     srand(time(nullptr));
      20            2 :     baseVersion = rand() % 99999 + 100000;
      21            2 :     std::cout << "=== WORKFLOW INTEGRATION TEST SUITE ===\n";
      22            2 :     std::cout << "Base version: " << baseVersion << "\n\n";
      23            2 :   }
      24              : 
      25            2 :   ~WorkflowIntegrationTestData() { std::cout << "\n=== TEST SUITE COMPLETE ===\n"; }
      26              : 
      27              :   int baseVersion;
      28              : };
      29              : 
      30              : WorkflowIntegrationTestData fixture;
      31              : 
      32              : BOOST_AUTO_TEST_SUITE(workflow_integration_test)
      33              : 
      34            4 : BOOST_AUTO_TEST_CASE(complete_crud_lifecycle) {
      35            2 :   std::cout << "\n=== TEST 1: Complete CRUD lifecycle ===\n";
      36              : 
      37            2 :   auto ifc = DatabaseConfigurationInterface();
      38            2 :   int version1 = fixture.baseVersion;
      39            2 :   int version2 = fixture.baseVersion + 1;
      40              : 
      41            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      42            2 :   cfg->getView().version = version1;
      43            4 :   cfg->getView().fillFromJSON("{\"stage\": \"created\"}");
      44            2 :   auto createResult = ifc.saveActiveVersion(cfg.get());
      45            2 :   BOOST_REQUIRE_EQUAL(createResult, 0);
      46            2 :   std::cout << "Step 1 (CREATE): Saved version " << version1 << "\n";
      47              : 
      48            2 :   std::shared_ptr<ConfigurationBase> readCfg = std::make_shared<TestConfiguration001>();
      49            2 :   auto readResult = ifc.fill(readCfg.get(), version1);
      50            2 :   BOOST_REQUIRE_EQUAL(readResult, 0);
      51            2 :   bool hasCreated = (readCfg->getView()._json.find("created") != std::string::npos);
      52            2 :   BOOST_CHECK(hasCreated);
      53            2 :   std::cout << "Step 2 (READ): Loaded version " << version1 << ", has 'created': " << (hasCreated ? "yes" : "no") << "\n";
      54              : 
      55            2 :   cfg->getView().version = version2;
      56            4 :   cfg->getView().fillFromJSON("{\"stage\": \"updated\"}");
      57            2 :   auto updateResult = ifc.saveActiveVersion(cfg.get());
      58            2 :   BOOST_REQUIRE_EQUAL(updateResult, 0);
      59            2 :   std::cout << "Step 3 (UPDATE): Saved version " << version2 << "\n";
      60              : 
      61            2 :   auto versions = ifc.getVersions(cfg.get());
      62            2 :   bool hasV1 = (versions.find(version1) != versions.end());
      63            2 :   bool hasV2 = (versions.find(version2) != versions.end());
      64            2 :   BOOST_CHECK(hasV1);
      65            2 :   BOOST_CHECK(hasV2);
      66            2 :   std::cout << "Step 4 (VERIFY): Has v1: " << (hasV1 ? "yes" : "no") << ", Has v2: " << (hasV2 ? "yes" : "no") << "\n";
      67              : 
      68            2 :   std::cout << "  Verified: Complete CRUD lifecycle works\n";
      69            2 : }
      70              : 
      71            4 : BOOST_AUTO_TEST_CASE(version_promotion_workflow) {
      72            2 :   std::cout << "\n=== TEST 2: Version promotion workflow ===\n";
      73              : 
      74            2 :   auto ifc = DatabaseConfigurationInterface();
      75            2 :   int testVersion = fixture.baseVersion + 10;
      76            2 :   std::string suffix = "_" + std::to_string(fixture.baseVersion);
      77              : 
      78            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
      79            2 :   cfg->getView().version = testVersion;
      80            4 :   cfg->getView().fillFromJSON("{\"environment\": \"development\"}");
      81            2 :   ifc.saveActiveVersion(cfg.get());
      82            2 :   std::cout << "Step 1: Created development version " << testVersion << "\n";
      83              : 
      84            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
      85            2 :   map[cfg->getConfigurationName()] = testVersion;
      86            2 :   ifc.storeGlobalConfiguration(map, "Development" + suffix);
      87            2 :   std::cout << "Step 2: Created Development composition\n";
      88              : 
      89            2 :   ifc.storeGlobalConfiguration(map, "Staging" + suffix);
      90            2 :   std::cout << "Step 3: Promoted to Staging composition\n";
      91              : 
      92            2 :   ifc.storeGlobalConfiguration(map, "Production" + suffix);
      93            2 :   std::cout << "Step 4: Promoted to Production composition\n";
      94              : 
      95            2 :   auto devLoaded = ifc.loadGlobalConfiguration("Development" + suffix);
      96            2 :   auto stagingLoaded = ifc.loadGlobalConfiguration("Staging" + suffix);
      97            2 :   auto prodLoaded = ifc.loadGlobalConfiguration("Production" + suffix);
      98              : 
      99            2 :   BOOST_CHECK_EQUAL(devLoaded[cfg->getConfigurationName()], testVersion);
     100            2 :   BOOST_CHECK_EQUAL(stagingLoaded[cfg->getConfigurationName()], testVersion);
     101            2 :   BOOST_CHECK_EQUAL(prodLoaded[cfg->getConfigurationName()], testVersion);
     102              : 
     103            2 :   std::cout << "Step 5: All compositions reference version " << testVersion << "\n";
     104            2 :   std::cout << "  Verified: Version promotion workflow works\n";
     105            2 : }
     106              : 
     107            4 : BOOST_AUTO_TEST_CASE(rollback_simulation) {
     108            2 :   std::cout << "\n=== TEST 3: Rollback simulation ===\n";
     109              : 
     110            2 :   auto ifc = DatabaseConfigurationInterface();
     111            2 :   int goodVersion = fixture.baseVersion + 20;
     112            2 :   int badVersion = fixture.baseVersion + 21;
     113            2 :   std::string compName = "RollbackTest_" + std::to_string(fixture.baseVersion);
     114              : 
     115            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     116            2 :   cfg->getView().version = goodVersion;
     117            4 :   cfg->getView().fillFromJSON("{\"status\": \"good_version\"}");
     118            2 :   ifc.saveActiveVersion(cfg.get());
     119            2 :   std::cout << "Step 1: Created good version " << goodVersion << "\n";
     120              : 
     121            2 :   cfg->getView().version = badVersion;
     122            4 :   cfg->getView().fillFromJSON("{\"status\": \"bad_version\"}");
     123            2 :   ifc.saveActiveVersion(cfg.get());
     124            2 :   std::cout << "Step 2: Created bad version " << badVersion << "\n";
     125              : 
     126            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
     127            2 :   map[cfg->getConfigurationName()] = badVersion;
     128            2 :   ifc.storeGlobalConfiguration(map, compName);
     129            2 :   std::cout << "Step 3: Created composition pointing to bad version\n";
     130              : 
     131            2 :   auto loaded1 = ifc.loadGlobalConfiguration(compName);
     132            2 :   BOOST_CHECK_EQUAL(loaded1[cfg->getConfigurationName()], badVersion);
     133              : 
     134            2 :   map[cfg->getConfigurationName()] = goodVersion;
     135            2 :   ifc.storeGlobalConfiguration(map, compName, true);
     136            2 :   std::cout << "Step 4: Rolled back composition to good version\n";
     137              : 
     138            2 :   auto loaded2 = ifc.loadGlobalConfiguration(compName);
     139            2 :   BOOST_CHECK_EQUAL(loaded2[cfg->getConfigurationName()], goodVersion);
     140              : 
     141            2 :   std::cout << "Step 5: Verified composition now points to version " << loaded2[cfg->getConfigurationName()] << "\n";
     142            2 :   std::cout << "  Verified: Rollback simulation works\n";
     143            2 : }
     144              : 
     145            4 : BOOST_AUTO_TEST_CASE(parallel_development_branches) {
     146            2 :   std::cout << "\n=== TEST 4: Parallel development branches ===\n";
     147              : 
     148            2 :   auto ifc = DatabaseConfigurationInterface();
     149            2 :   std::string suffix = "_" + std::to_string(fixture.baseVersion);
     150              : 
     151            2 :   std::shared_ptr<ConfigurationBase> cfg = std::make_shared<TestConfiguration001>();
     152              : 
     153            2 :   int mainVersion = fixture.baseVersion + 30;
     154            2 :   cfg->getView().version = mainVersion;
     155            4 :   cfg->getView().fillFromJSON("{\"branch\": \"main\"}");
     156            2 :   ifc.saveActiveVersion(cfg.get());
     157              : 
     158            8 :   for (int i = 0; i < 3; i++) {
     159            6 :     cfg->getView().version = fixture.baseVersion + 100 + i;
     160            6 :     cfg->getView().fillFromJSON("{\"branch\": \"featureA\", \"iteration\": " + std::to_string(i) + "}");
     161            6 :     ifc.saveActiveVersion(cfg.get());
     162              :   }
     163              : 
     164            8 :   for (int i = 0; i < 3; i++) {
     165            6 :     cfg->getView().version = fixture.baseVersion + 200 + i;
     166            6 :     cfg->getView().fillFromJSON("{\"branch\": \"featureB\", \"iteration\": " + std::to_string(i) + "}");
     167            6 :     ifc.saveActiveVersion(cfg.get());
     168              :   }
     169            2 :   std::cout << "Step 1: Created versions for main, featureA, and featureB\n";
     170              : 
     171            8 :   auto mainMap = DatabaseConfigurationInterface::config_version_map_t{{cfg->getConfigurationName(), mainVersion}};
     172            8 :   auto featureAMap = DatabaseConfigurationInterface::config_version_map_t{{cfg->getConfigurationName(), fixture.baseVersion + 102}};
     173            8 :   auto featureBMap = DatabaseConfigurationInterface::config_version_map_t{{cfg->getConfigurationName(), fixture.baseVersion + 202}};
     174              : 
     175            2 :   ifc.storeGlobalConfiguration(mainMap, "Main" + suffix);
     176            2 :   ifc.storeGlobalConfiguration(featureAMap, "FeatureA" + suffix);
     177            2 :   ifc.storeGlobalConfiguration(featureBMap, "FeatureB" + suffix);
     178            2 :   std::cout << "Step 2: Created compositions for each branch\n";
     179              : 
     180            2 :   auto mainLoaded = ifc.loadGlobalConfiguration("Main" + suffix);
     181            2 :   auto featureALoaded = ifc.loadGlobalConfiguration("FeatureA" + suffix);
     182            2 :   auto featureBLoaded = ifc.loadGlobalConfiguration("FeatureB" + suffix);
     183              : 
     184            2 :   BOOST_CHECK_EQUAL(mainLoaded[cfg->getConfigurationName()], mainVersion);
     185            2 :   BOOST_CHECK_EQUAL(featureALoaded[cfg->getConfigurationName()], fixture.baseVersion + 102);
     186            2 :   BOOST_CHECK_EQUAL(featureBLoaded[cfg->getConfigurationName()], fixture.baseVersion + 202);
     187              : 
     188            4 :   std::cout << "Step 3: Main=" << mainLoaded[cfg->getConfigurationName()] << ", FeatureA=" << featureALoaded[cfg->getConfigurationName()]
     189            2 :             << ", FeatureB=" << featureBLoaded[cfg->getConfigurationName()] << "\n";
     190            2 :   std::cout << "  Verified: Parallel development branches work independently\n";
     191           14 : }
     192              : 
     193            4 : BOOST_AUTO_TEST_CASE(composition_evolution_history) {
     194            2 :   std::cout << "\n=== TEST 5: Composition evolution history ===\n";
     195              : 
     196            2 :   auto ifc = DatabaseConfigurationInterface();
     197            2 :   std::string compName = "Evolving_" + std::to_string(fixture.baseVersion);
     198              : 
     199            2 :   std::shared_ptr<ConfigurationBase> cfg1 = std::make_shared<TestConfiguration001>();
     200            2 :   std::shared_ptr<ConfigurationBase> cfg2 = std::make_shared<TestConfiguration002>();
     201              : 
     202            2 :   cfg1->getView().version = fixture.baseVersion + 40;
     203            2 :   cfg2->getView().version = fixture.baseVersion + 40;
     204            2 :   ifc.saveActiveVersion(cfg1.get());
     205            2 :   ifc.saveActiveVersion(cfg2.get());
     206              : 
     207            2 :   cfg1->getView().version = fixture.baseVersion + 41;
     208            2 :   ifc.saveActiveVersion(cfg1.get());
     209            2 :   std::cout << "Step 1: Created configuration versions\n";
     210              : 
     211            2 :   auto map = DatabaseConfigurationInterface::config_version_map_t{};
     212            2 :   map[cfg1->getConfigurationName()] = fixture.baseVersion + 40;
     213            2 :   ifc.storeGlobalConfiguration(map, compName);
     214              : 
     215            2 :   auto loaded1 = ifc.loadGlobalConfiguration(compName);
     216            2 :   std::cout << "Step 2: Initial composition has " << loaded1.size() << " member(s)\n";
     217            2 :   BOOST_CHECK_EQUAL(loaded1.size(), 1);
     218              : 
     219            2 :   map[cfg2->getConfigurationName()] = fixture.baseVersion + 40;
     220            2 :   ifc.storeGlobalConfiguration(map, compName, true);
     221              : 
     222            2 :   auto loaded2 = ifc.loadGlobalConfiguration(compName);
     223            2 :   std::cout << "Step 3: After adding member, has " << loaded2.size() << " member(s)\n";
     224            2 :   BOOST_CHECK_EQUAL(loaded2.size(), 2);
     225              : 
     226            2 :   map[cfg1->getConfigurationName()] = fixture.baseVersion + 41;
     227            2 :   ifc.storeGlobalConfiguration(map, compName, true);
     228              : 
     229            2 :   auto loaded3 = ifc.loadGlobalConfiguration(compName);
     230            2 :   std::cout << "Step 4: After version update, type1 version is " << loaded3[cfg1->getConfigurationName()] << "\n";
     231            2 :   BOOST_CHECK_EQUAL(loaded3[cfg1->getConfigurationName()], fixture.baseVersion + 41);
     232            2 :   BOOST_CHECK_EQUAL(loaded3.size(), 2);
     233              : 
     234            2 :   map.erase(cfg2->getConfigurationName());
     235            2 :   ifc.storeGlobalConfiguration(map, compName, true);
     236              : 
     237            2 :   auto loaded4 = ifc.loadGlobalConfiguration(compName);
     238            2 :   std::cout << "Step 5: After removing member, has " << loaded4.size() << " member(s)\n";
     239            2 :   BOOST_CHECK_EQUAL(loaded4.size(), 1);
     240            2 :   BOOST_CHECK_EQUAL(loaded4[cfg1->getConfigurationName()], fixture.baseVersion + 41);
     241              : 
     242            2 :   std::cout << "  Verified: Composition evolution works correctly\n";
     243            2 : }
     244              : 
     245              : BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1