LCOV - code coverage report
Current view: top level - otsdaq/tools - otsdaq_export_system_aliases.cc (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 248 0
Test Date: 2026-07-30 01:56:44 Functions: 0.0 % 55 0

            Line data    Source code
       1              : #include "otsdaq/MessageFacility/MessageFacility.h"
       2              : 
       3              : #include <dirent.h>
       4              : #include <cassert>
       5              : #include <iostream>
       6              : #include <memory>
       7              : #include <string>
       8              : 
       9              : #include "otsdaq/ConfigurationInterface/ConfigurationInterface.h"
      10              : #include "otsdaq/ConfigurationInterface/ConfigurationManagerRW.h"
      11              : // #include "artdaq-database/StorageProviders/FileSystemDB/provider_filedb_index.h"
      12              : // #include "artdaq-database/JsonDocument/JSONDocument.h"
      13              : 
      14              : // Shared test utilities
      15              : #include "otsdaq/Macros/TestUtilities.h"
      16              : 
      17              : /// Exports all active groups and system alias groups (specified by the active backbone)
      18              : ///             to the path specified. Each group's member tables will be organized in a folder with metadata.
      19              : ///             Each table is exported as a json format text file.
      20              : /// usage:
      21              : /// otsdaq_export_system_aliases <path to export to>
      22              : ///
      23              : ///
      24              : using namespace ots;
      25              : 
      26            0 : void ExportActiveSystemAliasTableGroups(int argc, char* argv[])
      27              : {
      28            0 :         std::cout << "=================================================\n";
      29            0 :         std::cout << "=================================================\n";
      30            0 :         std::cout << "=================================================\n";
      31            0 :         __COUT__ << "\nExporting Active System Aliases!" << std::endl;
      32              : 
      33            0 :         std::cout << "\n\nusage: One argument:\n\t <export path> \n\n" << std::endl;
      34              : 
      35            0 :         std::cout << "argc = " << argc << std::endl;
      36            0 :         for(int i = 0; i < argc; i++)
      37            0 :                 std::cout << "argv[" << i << "] = " << argv[i] << std::endl;
      38              : 
      39            0 :         if(argc != 2)
      40              :         {
      41            0 :                 std::cout << "Error! Must provide one parameter.\n\n" << std::endl;
      42            0 :                 return;
      43              :         }
      44              : 
      45            0 :         std::string exportPath = argv[1];
      46            0 :         __COUTV__(exportPath);
      47              : 
      48              :         // make directory just in case
      49            0 :         mkdir(exportPath.c_str(), 0755);
      50              : 
      51              :         DIR* dp;
      52            0 :         if((dp = opendir(exportPath.c_str())) == 0)
      53              :         {
      54            0 :                 __COUT_ERR__ << "ERROR:(" << errno
      55            0 :                              << ").  Can't open directory for export: " << exportPath
      56            0 :                              << std::endl;
      57            0 :                 exit(0);
      58              :         }
      59            0 :         closedir(dp);
      60              : 
      61              :         // return;
      62              : 
      63              :         //==============================================================================
      64              :         // Define environment variables
      65              :         //      Note: normally these environment variables are set by ots script
      66              : 
      67            0 :         test::util::check_and_make_envs();
      68              :         ////////////////////////////////////////////////////
      69              : 
      70              :         //==============================================================================
      71              :         // get prepared with initial source db
      72              : 
      73              :         // ConfigurationManager instance immediately loads active groups
      74            0 :         __COUT__ << "Loading active Aliases..." << std::endl;
      75              : 
      76            0 :         std::string ARTDAQ_DATABASE_URI = __ENV__("ARTDAQ_DATABASE_URI");
      77            0 :         __COUTV__(ARTDAQ_DATABASE_URI);
      78              : 
      79              :         // return;
      80              : 
      81            0 :         ConfigurationManagerRW  cfgMgrInst("export_admin");
      82            0 :         ConfigurationManagerRW* cfgMgr = &cfgMgrInst;
      83              : 
      84              :         if(0)
      85              :         {
      86              :                 std::string                             accumulatedWarnings;
      87              :                 const std::map<std::string, TableInfo>& allTableInfo =
      88              :                     cfgMgr->getAllTableInfo(true /* refresh */,
      89              :                                             &accumulatedWarnings,
      90              :                                             "" /* errorFilterName */,
      91              :                                             true /* getGroupKeys*/,
      92              :                                             false /* getGroupInfo */,
      93              :                                             true /* initializeActiveGroups */);
      94              :                 __COUTV__(allTableInfo.size());
      95              :                 auto groups = cfgMgr->getAllGroupInfo();
      96              :                 __COUTV__(groups.size());
      97              :                 for(auto& group : groups)
      98              :                 {
      99              :                         __COUTV__(group.first);
     100              :                 }
     101              :         }
     102              : 
     103              :         if(1)
     104              :         {
     105            0 :                 std::string accumulatedWarnings;
     106            0 :                 cfgMgr->restoreActiveTableGroups(false /*throwErrors*/,
     107              :                                                  "" /*pathToActiveGroupsFile*/,
     108              :                                                  ConfigurationManager::LoadGroupType::ALL_TYPES,
     109              :                                                  &accumulatedWarnings);
     110              : 
     111            0 :                 __COUT__ << "Done Loading active groups." << std::endl;
     112            0 :         }
     113              :         // return;
     114              : 
     115              :         // create set of groups to persist
     116              :         //      include active context
     117              :         //      include active backbone
     118              :         //      include active iterate group
     119              :         //      include active config group
     120              :         //              (keep key translation separate activeGroupKeys)
     121              :         //      include all groups with system aliases
     122              : 
     123              :         // for each group in set
     124              :         //      load/activate group
     125              :         //              export each table as json doc to a folder <group name>_<export time>/
     126              : 
     127              :         /* map<<groupName, origKey>, newKey> */
     128            0 :         std::map<std::pair<std::string, TableGroupKey>, TableGroupKey> groupSet;
     129              :         /* <tableName, <origVersion, newVersion> >*/
     130            0 :         std::map<std::pair<std::string, TableVersion>, TableVersion>   modifiedTables;
     131            0 :         std::map<std::string, std::pair<TableGroupKey, TableGroupKey>> activeGroupKeys;
     132            0 :         std::map<std::pair<std::string, TableGroupKey>, std::string>   groupErrors;
     133              : 
     134            0 :         std::string activeBackboneGroupName = "";
     135            0 :         std::string activeContextGroupName  = "";
     136            0 :         std::string activeIterateGroupName  = "";
     137            0 :         std::string activeConfigGroupName   = "";
     138              : 
     139            0 :         std::string nowTime = std::to_string(time(0));
     140              : 
     141              :         // add active groups to set
     142              :         std::map<std::string, std::pair<std::string, TableGroupKey>> activeGroupsMap =
     143            0 :             cfgMgr->getActiveTableGroups();
     144              : 
     145            0 :         bool foundAnyActiveGroups = false;
     146              : 
     147            0 :         for(const auto& activeGroup : activeGroupsMap)
     148              :         {
     149            0 :                 if(activeGroup.second.second.TableGroupKey::isInvalid())
     150            0 :                         continue;
     151              : 
     152            0 :                 groupSet.insert(std::pair<std::pair<std::string, TableGroupKey>, TableGroupKey>(
     153            0 :                     std::pair<std::string, TableGroupKey>(activeGroup.second.first,
     154            0 :                                                           activeGroup.second.second),
     155            0 :                     TableGroupKey()));
     156            0 :                 activeGroupKeys.insert(
     157            0 :                     std::pair<std::string, std::pair<TableGroupKey, TableGroupKey>>(
     158            0 :                         activeGroup.second.first,
     159            0 :                         std::pair<TableGroupKey, TableGroupKey>(activeGroup.second.second,
     160            0 :                                                                 TableGroupKey())));
     161              : 
     162            0 :                 if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_BACKBONE)
     163              :                 {
     164            0 :                         activeBackboneGroupName = activeGroup.second.first;
     165            0 :                         __COUT__ << "found activeBackboneGroupName = " << activeBackboneGroupName
     166            0 :                                  << std::endl;
     167            0 :                         foundAnyActiveGroups = true;
     168              :                 }
     169            0 :                 else if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_CONTEXT)
     170              :                 {
     171            0 :                         activeContextGroupName = activeGroup.second.first;
     172            0 :                         __COUT__ << "found activeContextGroupName = " << activeContextGroupName
     173            0 :                                  << std::endl;
     174            0 :                         foundAnyActiveGroups = true;
     175              :                 }
     176            0 :                 else if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_ITERATE)
     177              :                 {
     178            0 :                         activeIterateGroupName = activeGroup.second.first;
     179            0 :                         __COUT__ << "found activeIterateGroupName = " << activeIterateGroupName
     180            0 :                                  << std::endl;
     181            0 :                         foundAnyActiveGroups = true;
     182              :                 }
     183            0 :                 else if(activeGroup.first == ConfigurationManager::GROUP_TYPE_NAME_CONFIGURATION)
     184              :                 {
     185            0 :                         activeConfigGroupName = activeGroup.second.first;
     186            0 :                         __COUT__ << "found activeConfigGroupName = " << activeConfigGroupName
     187            0 :                                  << std::endl;
     188            0 :                         foundAnyActiveGroups = true;
     189              :                 }
     190              :         }
     191              : 
     192            0 :         if(activeBackboneGroupName == "" || !foundAnyActiveGroups)
     193              :         {
     194            0 :                 __SS__ << "Did not find valid active groups to export! "
     195              :                           "Must have a backbone at least. Is the current database URI correct? "
     196              :                           "ARTDAQ_DATABASE_URI = "
     197            0 :                        << ARTDAQ_DATABASE_URI << std::endl;
     198            0 :                 __SS_THROW__;
     199            0 :         }
     200              : 
     201            0 :         __COUT__ << "Identified active groups:" << std::endl;
     202            0 :         for(auto& group : groupSet)
     203            0 :                 __COUT__ << " ==> Group to export: " << group.first.first << " ("
     204            0 :                          << group.first.second << ")" << std::endl;
     205              :         // return;
     206              : 
     207              :         // add system alias groups to set
     208              :         const std::string groupAliasesTableName =
     209            0 :             ConfigurationManager::GROUP_ALIASES_TABLE_NAME;
     210            0 :         std::map<std::string, TableVersion> activeVersions = cfgMgr->getActiveVersions();
     211            0 :         if(activeVersions.find(groupAliasesTableName) == activeVersions.end())
     212              :         {
     213            0 :                 __SS__ << "\nActive version of " << groupAliasesTableName << " missing! "
     214              :                        << groupAliasesTableName
     215              :                        << " is a required member of the Backbone configuration group."
     216            0 :                        << "\n\nLikely you need to activate a valid Backbone group." << std::endl;
     217            0 :                 __SS_THROW__;
     218            0 :         }
     219              : 
     220              :         std::vector<std::pair<std::string, ConfigurationTree>> aliasNodePairs =
     221            0 :             cfgMgr->getNode(groupAliasesTableName).getChildren();
     222            0 :         for(auto& groupPair : aliasNodePairs)
     223            0 :                 groupSet.insert(std::pair<std::pair<std::string, TableGroupKey>, TableGroupKey>(
     224            0 :                     std::pair<std::string, TableGroupKey>(
     225            0 :                         groupPair.second.getNode("GroupName").getValueAsString(),
     226            0 :                         TableGroupKey(groupPair.second.getNode("GroupKey").getValueAsString())),
     227            0 :                     TableGroupKey()));
     228              : 
     229              :         //at this point, all groups to export have been identified! ------------
     230            0 :         __COUT__ << "All identified groups:" << std::endl;
     231            0 :         for(auto& group : groupSet)
     232            0 :                 __COUT__ << " ==> Group to export: " << group.first.first << " ("
     233            0 :                          << group.first.second << ")" << std::endl;
     234            0 :         __COUT__ << std::endl;
     235            0 :         __COUT__ << std::endl;
     236              : 
     237            0 :         if(!groupSet.size())
     238              :         {
     239            0 :                 __SS__ << "No groups identified to export!" << __E__;
     240            0 :                 __SS_THROW__;
     241            0 :         }
     242              : 
     243            0 :         ConfigurationInterface* theInterface_ = ConfigurationInterface::getInstance(
     244              :             ConfigurationInterface::CONFIGURATION_MODE::ARTDAQ_DATABASE);
     245              : 
     246              :         //now, for each group in set
     247              :         //      load/activate group
     248              :         //              export each table as json doc to a folder <group name>_<export time>/
     249              : 
     250            0 :         bool errDetected = false;
     251            0 :         for(auto& group : groupSet)
     252              :         {
     253            0 :                 __COUT__ << " ==> Group to export: " << group.first.first << " ("
     254            0 :                          << group.first.second << ")" << std::endl;
     255              : 
     256              :                 std::string groupPath =
     257            0 :                     exportPath + "/" + group.first.first + "_" + group.first.second.str();
     258            0 :                 __COUTV__(groupPath);
     259              :                 //check if output directory already exists, and do not overwrite throw error
     260              :                 {
     261              :                         DIR* dp;
     262            0 :                         if((dp = opendir(groupPath.c_str())) != 0)
     263              :                         {
     264            0 :                                 closedir(dp);
     265            0 :                                 __COUT__ << "ERROR: Can't export to directory (already exists! Please "
     266            0 :                                             "choose a different export path.): "
     267            0 :                                          << groupPath << std::endl;
     268            0 :                                 exit(0);
     269              :                         }
     270              :                 }
     271            0 :                 mkdir(groupPath.c_str(), 0755);
     272              : 
     273            0 :                 if(group.first.first ==
     274              :                    activeBackboneGroupName)  //create special metadata file to flag the active Backbone group
     275              :                 {
     276            0 :                         std::string groupIsBackbonePath = groupPath + "/" + "groupIsBackbone.txt";
     277            0 :                         __COUTV__(groupIsBackbonePath);
     278            0 :                         FILE* fp = std::fopen(groupIsBackbonePath.c_str(), "w");
     279            0 :                         if(!fp)
     280              :                         {
     281            0 :                                 __COUT_ERR__ << "\n\nERROR! Could not open file at "
     282            0 :                                              << groupIsBackbonePath << ". Error: " << errno << " - "
     283            0 :                                              << strerror(errno) << __E__;
     284            0 :                                 return;
     285              :                         }
     286            0 :                         fputs("1", fp);
     287            0 :                         fclose(fp);
     288            0 :                 }
     289              : 
     290            0 :                 std::string                                           accumulateErrors = "";
     291            0 :                 std::map<std::string /*name*/, TableVersion>          memberMap;
     292            0 :                 std::map<std::string /*name*/, std::string /*alias*/> groupAliases;
     293            0 :                 std::string                                           groupComment;
     294            0 :                 std::string                                           groupAuthor;
     295            0 :                 std::string                                           groupCreateTime;
     296            0 :                 std::string                                           groupTypeString;
     297              : 
     298              :                 //=========================
     299              :                 // load group, group metadata, and tables from original DB
     300              :                 try
     301              :                 {
     302            0 :                         accumulateErrors = "";
     303            0 :                         cfgMgr->loadTableGroup(group.first.first,
     304            0 :                                                group.first.second,
     305              :                                                true /*doActivate*/,
     306              :                                                0,  //&memberMap /*memberMap*/,
     307              :                                                0 /*progressBar*/,
     308              :                                                &accumulateErrors,
     309              :                                                &groupComment,
     310              :                                                &groupAuthor,
     311              :                                                &groupCreateTime,
     312              :                                                false /*doNotLoadMember*/,
     313              :                                                &groupTypeString /*groupTypeString*/,
     314              :                                                &groupAliases);
     315              :                 }
     316            0 :                 catch(std::runtime_error& e)
     317              :                 {
     318            0 :                         __COUT__ << "Error was caught loading members for " << group.first.first
     319            0 :                                  << "(" << group.first.second << ")" << std::endl;
     320            0 :                         __COUT__ << e.what() << std::endl;
     321            0 :                         errDetected = true;
     322            0 :                 }
     323            0 :                 catch(...)
     324              :                 {
     325            0 :                         __COUT__ << "Error was caught loading members for " << group.first.first
     326            0 :                                  << "(" << group.first.second << ")" << std::endl;
     327            0 :                         errDetected = true;
     328            0 :                 }
     329              : 
     330              :                 //Record if group is a Backbone group, because Aliases need to be handled specially on import
     331            0 :                 if(groupTypeString == ConfigurationManager::GROUP_TYPE_NAME_BACKBONE)
     332              :                 {
     333            0 :                         __COUT__ << "\t\tFound backbone type group!" << __E__;
     334              :                 }
     335              : 
     336              :                 //get full member map with Metadata table
     337              :                 {
     338              :                         // std::map<std::string /*name*/, TableVersion /*version*/> memberMap =
     339            0 :                         memberMap = theInterface_->getTableGroupMembers(
     340            0 :                             TableGroupKey::getFullGroupString(group.first.first, group.first.second),
     341            0 :                             true /*include meta data table*/);
     342              : 
     343              :                         // save meta data table separately, since there is no table definition, and then remove from member map
     344            0 :                         auto metaTablePair = memberMap.find(TableBase::GROUP_METADATA_TABLE_NAME);
     345            0 :                         if(metaTablePair != memberMap.end())
     346              :                         {
     347            0 :                                 __COUT__ << TableBase::GROUP_METADATA_TABLE_NAME << ":v"
     348            0 :                                          << metaTablePair->second << std::endl;
     349              : 
     350            0 :                                 std::string tablePath = groupPath + "/" +
     351            0 :                                                         TableBase::GROUP_METADATA_TABLE_NAME + "_v" +
     352            0 :                                                         metaTablePair->second.str() + ".json";
     353            0 :                                 __COUTV__(tablePath);
     354              : 
     355            0 :                                 auto groupMetadataTable = cfgMgr->getMetadataTable(metaTablePair->second);
     356              : 
     357            0 :                                 __COUTV__(tablePath);
     358            0 :                                 std::stringstream json;
     359            0 :                                 groupMetadataTable->getViewP()->printJSON(json);
     360              : 
     361            0 :                                 __COUTV__(tablePath);
     362            0 :                                 FILE* fp = std::fopen(tablePath.c_str(), "w");
     363            0 :                                 if(!fp)
     364              :                                 {
     365            0 :                                         __COUT_ERR__ << "\n\nERROR! Could not open file at " << tablePath
     366            0 :                                                      << ". Error: " << errno << " - " << strerror(errno)
     367            0 :                                                      << __E__;
     368            0 :                                         return;
     369              :                                 }
     370            0 :                                 fputs(json.str().c_str(), fp);
     371            0 :                                 fclose(fp);
     372              : 
     373            0 :                                 memberMap.erase(
     374              :                                     metaTablePair);  // remove from member map that is returned
     375              : 
     376            0 :                         }  // end metadata handling
     377              :                         else
     378              :                         {
     379            0 :                                 __COUT_ERR__ << "Ignoring that groupMetadataTable_ is missing for group '"
     380            0 :                                              << group.first.first << "(" << group.first.second
     381            0 :                                              << "). Going with anonymous defaults." << __E__;
     382              :                         }
     383              :                 }
     384              : 
     385              :                 // TableView* cfgView;
     386              :                 // TableBase* config;
     387              :                 //=========================
     388              :                 // export the group tables to json documents!
     389              :                 try
     390              :                 {
     391              :                         // saving tables
     392            0 :                         for(auto& memberPair : memberMap)
     393              :                         {
     394            0 :                                 __COUT__ << memberPair.first << ":v" << memberPair.second << std::endl;
     395              : 
     396            0 :                                 std::string tablePath = groupPath + "/" + memberPair.first + "_v" +
     397            0 :                                                         memberPair.second.str() + ".json";
     398            0 :                                 __COUTV__(tablePath);
     399              : 
     400            0 :                                 std::stringstream json;
     401            0 :                                 cfgMgr->getTableByName(memberPair.first)->getViewP()->printJSON(json);
     402              : 
     403            0 :                                 FILE* fp = std::fopen(tablePath.c_str(), "w");
     404            0 :                                 if(!fp)
     405              :                                 {
     406            0 :                                         __COUT_ERR__ << "\n\nERROR! Could not open file at " << tablePath
     407            0 :                                                      << ". Error: " << errno << " - " << strerror(errno)
     408            0 :                                                      << __E__;
     409            0 :                                         return;
     410              :                                 }
     411            0 :                                 fputs(json.str().c_str(), fp);
     412            0 :                                 fclose(fp);
     413              : 
     414              :                                 // change the version of the active view to flatVersion and save it
     415              :                                 // config  = cfgMgr->getTableByName(memberPair.first);
     416              :                                 // cfgView = config->getViewP();
     417              :                                 // cfgView->setVersion(TableVersion(flatVersion));
     418              :                                 // theInterface_->saveActiveVersion(config);
     419              : 
     420            0 :                         }  //end member table loop
     421              : 
     422              :                         // Note: this code copies actions in ConfigurationManagerRW::saveNewTableGroup
     423              : 
     424              :                         // add meta data
     425            0 :                         __COUTV__(StringMacros::mapToString(groupAliases));
     426            0 :                         __COUTV__(groupComment);
     427            0 :                         __COUTV__(groupAuthor);
     428            0 :                         __COUTV__(groupCreateTime);
     429              :                         // time_t        groupCreateTime_t;
     430              :                         // sscanf(groupCreateTime.c_str(), "%ld", &groupCreateTime_t);
     431              :                         // __COUTV__(groupCreateTime_t);
     432              : 
     433              :                         // theInterface_->saveActiveVersion(groupMetadataTable);
     434              : 
     435              :                         // memberMap should now consist of members with new flat version, so save
     436              :                         // group
     437              :                         // theInterface_->saveTableGroup(
     438              :                         //     memberMap,
     439              :                         //     TableGroupKey::getFullGroupString(groupPair.first.first,
     440              :                         //                                       TableGroupKey(flatVersion)));
     441              :                 }
     442            0 :                 catch(std::runtime_error& e)
     443              :                 {
     444            0 :                         __COUT__ << "Error was caught exporting group " << group.first.first << " ("
     445            0 :                                  << group.first.second << ") " << std::endl;
     446            0 :                         __COUT__ << e.what() << std::endl;
     447              : 
     448            0 :                         groupErrors.insert(
     449            0 :                             std::pair<std::pair<std::string, TableGroupKey>, std::string>(
     450            0 :                                 std::pair<std::string, TableGroupKey>(group.first.first,
     451            0 :                                                                       group.first.second),
     452              :                                 "Error caught exporting the group."));
     453            0 :                 }
     454            0 :                 catch(...)
     455              :                 {
     456            0 :                         __COUT__ << "Error was caught saving group " << group.first.first << " ("
     457            0 :                                  << group.first.second << ") " << std::endl;
     458              : 
     459            0 :                         groupErrors.insert(
     460            0 :                             std::pair<std::pair<std::string, TableGroupKey>, std::string>(
     461            0 :                                 std::pair<std::string, TableGroupKey>(group.first.first,
     462            0 :                                                                       group.first.second),
     463              :                                 "Error caught exporting the group."));
     464            0 :                 }
     465            0 :         }  //end group export loop
     466              : 
     467            0 :         if(errDetected)
     468              :         {
     469            0 :                 __COUT_ERR__ << "There was an error detected while exporting groups." << __E__;
     470              :         }
     471              : 
     472            0 :         __COUT_INFO__ << "Exported group summary: " << groupSet.size() << std::endl;
     473            0 :         for(auto& group : groupSet)
     474            0 :                 __COUT_INFO__ << " ==> Group: " << group.first.first << " (" << group.first.second
     475            0 :                               << ")" << std::endl;
     476              : 
     477            0 :         __COUT_INFO__ << "****************************" << std::endl;
     478            0 :         __COUT_INFO__ << "There were " << groupSet.size()
     479            0 :                       << " groups considered, and there were " << groupErrors.size()
     480              :                       << " errors found handling those groups. The groups were exported in "
     481            0 :                          "text/json format to the export path: "
     482            0 :                       << exportPath << std::endl;
     483            0 :         if(groupErrors.size())
     484              :         {
     485            0 :                 __COUT_ERR__ << "There were " << groupErrors.size()
     486              :                              << " errors found while loading and exporting groups. The "
     487            0 :                                 "following errors were found handling the groups:"
     488            0 :                              << std::endl;
     489            0 :                 for(auto& groupErr : groupErrors)
     490            0 :                         __COUT_ERR__ << "\t" << groupErr.first.first << " " << groupErr.first.second
     491            0 :                                      << ": \t" << groupErr.second << std::endl;
     492            0 :                 __COUT_ERR__ << "End of errors.\n\n" << std::endl;
     493              :         }
     494              :         else
     495            0 :                 __COUT_INFO__ << "There were NO ERRORS found while loading and exporting groups."
     496            0 :                               << __E__;
     497              : 
     498            0 : }  //end ExportActiveSystemAliasTableGroups()
     499              : 
     500            0 : int main(int argc, char* argv[])
     501              : {
     502            0 :         ExportActiveSystemAliasTableGroups(argc, argv);
     503            0 :         return 0;
     504              : }
     505              : // BOOST_AUTO_TEST_SUITE_END()
        

Generated by: LCOV version 2.0-1