LCOV - code coverage report
Current view: top level - otsdaq-utilities/test - ots_mm_udp_test.cpp (source / functions) Coverage Total Hit
Test: mu2edaq.info.cleaned Lines: 0.0 % 297 0
Test Date: 2026-10-29 01:38:59 Functions: 0.0 % 1 0

            Line data    Source code
       1              : 
       2              : #include "test/ots_mm_udp_interface.h"
       3              : 
       4              : #include <limits>
       5              : 
       6              : ///==============================================================================
       7              : /// To access Macro Maker with this tool
       8              : ///     first export...
       9              : /// export OTS_MACROMAKER_UDP_PORT=<YOUR_PORT>
      10              : /// export OTS_MACROMAKER_UDP_IP=127.0.0.1 #or the IP of the machine running Macro Maker
      11              : ///             then run... Macro Maker app
      12            0 : int main(int argc, char* argv[])
      13              : try
      14              : {
      15            0 :         if(argc < 3)
      16              :         {
      17            0 :                 fprintf(stderr,
      18              :                         "usage: ots_mm_udp_test <mm IP> <mm Port> <Front-end UID> <FEMacro "
      19              :                         "Name> <Macro Input args...> \n");
      20            0 :                 fprintf(stderr,
      21              :                         "       ots_mm_udp_test <mm IP> <mm Port> <Sequence Name> <iterations> "
      22              :                         "[[varName,value,step,max] ...]\n\n");
      23            0 :                 fprintf(stderr,
      24              :                         "\t If <Front-end UID> not specified, then the list of existing FE UIDs "
      25              :                         "and MoM Sequences will be output \n");
      26            0 :                 fprintf(stderr,
      27              :                         "\t If <FEMacro Name> not specified, then the list of existing FE Macro "
      28              :                         "Names will be output associated with the specified FE UID\n");
      29            0 :                 fprintf(stderr,
      30              :                         "\t If only a <Sequence Name> is given (no iterations), lists the "
      31              :                         "sequence's commands and Input Variables with their saved defaults.\n");
      32            0 :                 fprintf(stderr,
      33              :                         "\t Variable overrides use bracket syntax, e.g. [num_of_packets,200], "
      34              :                         "and are named. Step and max are optional (default 0).\n");
      35            0 :                 fprintf(stderr, "\t The $ prefix on variable names is optional.\n");
      36            0 :                 exit(1);
      37              :         }
      38              : 
      39            0 :         std::string target_mm_ip   = argv[1];
      40            0 :         int         target_mm_port = atoi(argv[2]);
      41              : 
      42              :         __COUTV__(target_mm_ip);
      43              :         __COUTV__(target_mm_port);
      44              : 
      45              :         __COUT__ << "instantiating..." << __E__;
      46            0 :         ots_mm_udp_interface mm(target_mm_ip.c_str(), target_mm_port);
      47              : 
      48            0 :         std::string feStr = mm.getFrontendList();
      49              :         __COUTV__(feStr);
      50            0 :         std::vector<std::string> fes = getVectorFromString(feStr, {';'});
      51            0 :         if(fes.size() == 0 || (fes.size() == 1 && fes[0] == ""))
      52              :         {
      53            0 :                 __COUT_ERR__
      54              :                     << "No Front-ends found in FE list! Check that a MacroMaker Supervisor is "
      55              :                     << "configured with UDP Remote Control enabled and accessible at "
      56            0 :                     << target_mm_ip << ":" << target_mm_port << "." << __E__;
      57            0 :                 return 1;
      58              :         }
      59              : 
      60            0 :         uint32_t fe  = -1;
      61            0 :         uint32_t cmd = -1;
      62              : 
      63            0 :         if(argc >= 4)
      64              :         {
      65              :                 //look for FE
      66            0 :                 std::string target_fe = argv[3];
      67            0 :                 for(fe = 0; fe < fes.size(); ++fe)
      68            0 :                         if(fes[fe] == target_fe)
      69            0 :                                 break;
      70              : 
      71            0 :                 if(fe >= fes.size())
      72              :                 {
      73              :                         // not a FE UID — check if it is a MoM sequence name
      74            0 :                         std::string              sequenceListStr = mm.getSequenceList();
      75              :                         std::vector<std::string> sequenceNames =
      76            0 :                             getVectorFromString(sequenceListStr, {';'});
      77              : 
      78            0 :                         std::string strippedTargetName = target_fe;
      79            0 :                         if(strippedTargetName.find("public/") == 0)
      80              :                                 strippedTargetName =
      81            0 :                                     strippedTargetName.substr(std::string("public/").size());
      82              : 
      83            0 :                         bool isSequenceMatch = false;
      84            0 :                         for(size_t sequenceIndex = 0; sequenceIndex < sequenceNames.size();
      85              :                             ++sequenceIndex)
      86              :                         {
      87            0 :                                 std::string candidateName = sequenceNames[sequenceIndex];
      88            0 :                                 if(candidateName.find("public/") == 0)
      89            0 :                                         candidateName = candidateName.substr(std::string("public/").size());
      90            0 :                                 if(candidateName == strippedTargetName)
      91              :                                 {
      92            0 :                                         isSequenceMatch = true;
      93            0 :                                         break;
      94              :                                 }
      95            0 :                         }
      96              : 
      97            0 :                         if(isSequenceMatch)
      98              :                         {
      99              :                                 // ======== Sequence mode ========
     100              :                                 // keep the user's exact name (including any public/ qualifier) so the
     101              :                                 // server resolves the intended directory
     102            0 :                                 std::string sequenceName = target_fe;
     103              : 
     104            0 :                                 if(argc == 4)
     105              :                                 {
     106              :                                         // Discovery mode — print commands and variables, then exit
     107            0 :                                         __COUT_INFO__ << "Loading sequence '" << sequenceName << "'..."
     108            0 :                                                       << __E__;
     109              : 
     110            0 :                                         std::string sequenceJSON        = mm.getSequenceInfo(sequenceName);
     111            0 :                                         std::string sequenceDescription = mm.describeSequence(sequenceJSON);
     112              : 
     113            0 :                                         __COUT_INFO__ << "\nSequence '" << sequenceName << "':\n"
     114            0 :                                                       << sequenceDescription << __E__;
     115              : 
     116            0 :                                         __COUT_INFO__ << "To run: ots_mm_udp_test " << target_mm_ip << " "
     117              :                                                       << target_mm_port << " \"" << sequenceName
     118            0 :                                                       << "\" <iterations> [varName,value] ..." << __E__;
     119            0 :                                         __COUT_INFO__ << "  e.g.: ots_mm_udp_test " << target_mm_ip << " "
     120              :                                                       << target_mm_port << " \"" << sequenceName
     121            0 :                                                       << "\" 1 [var1,0]" << __E__;
     122            0 :                                         return 0;
     123            0 :                                 }
     124              : 
     125              :                                 // Run mode — argv[4] is iteration count, argv[5..] are variable overrides
     126            0 :                                 unsigned int iterationCount = 0;
     127            0 :                                 if(!ots_mm_udp_interface::parseIterationCount(argv[4], iterationCount))
     128              :                                 {
     129            0 :                                         __COUT_ERR__
     130            0 :                                             << "Invalid iteration count: '" << argv[4]
     131            0 :                                             << "'. Must be a positive integer (digits only) no larger than "
     132            0 :                                             << std::numeric_limits<unsigned int>::max() << "." << __E__;
     133            0 :                                         return 1;
     134              :                                 }
     135              : 
     136              :                                 // Parse variable overrides from [value,step,max] arguments
     137              :                                 // First, load the sequence to get variable names in order
     138            0 :                                 std::string sequenceJSON = mm.getSequenceInfo(sequenceName);
     139              : 
     140              :                                 // Extract variable names in order from __variables__ block
     141              :                                 // (Same approach as discovery mode but just collecting names)
     142            0 :                                 std::vector<std::string> variableNamesInOrder;
     143              :                                 {
     144            0 :                                         size_t variablesKeyPosition = sequenceJSON.find("\"__variables__\"");
     145            0 :                                         if(variablesKeyPosition != std::string::npos)
     146              :                                         {
     147              :                                                 size_t variablesObjectStart =
     148            0 :                                                     sequenceJSON.find('{', variablesKeyPosition);
     149            0 :                                                 if(variablesObjectStart != std::string::npos)
     150              :                                                 {
     151            0 :                                                         size_t scanPosition = variablesObjectStart + 1;
     152            0 :                                                         int    depth        = 1;
     153            0 :                                                         while(scanPosition < sequenceJSON.size() && depth > 0)
     154              :                                                         {
     155            0 :                                                                 size_t nameStart = sequenceJSON.find('"', scanPosition);
     156            0 :                                                                 if(nameStart == std::string::npos)
     157            0 :                                                                         break;
     158              : 
     159              :                                                                 // check if we've left the __variables__ block
     160            0 :                                                                 bool insideQuote = false;
     161            0 :                                                                 bool leftBlock   = false;
     162            0 :                                                                 for(size_t checkPos = variablesObjectStart + 1;
     163            0 :                                                                     checkPos < nameStart;
     164              :                                                                     ++checkPos)
     165              :                                                                 {
     166            0 :                                                                         if(sequenceJSON[checkPos] == '\\' && insideQuote)
     167              :                                                                         {
     168            0 :                                                                                 ++checkPos;
     169            0 :                                                                                 continue;
     170              :                                                                         }
     171            0 :                                                                         if(sequenceJSON[checkPos] == '"')
     172            0 :                                                                                 insideQuote = !insideQuote;
     173            0 :                                                                         if(!insideQuote)
     174              :                                                                         {
     175            0 :                                                                                 if(sequenceJSON[checkPos] == '{')
     176            0 :                                                                                         ++depth;
     177            0 :                                                                                 else if(sequenceJSON[checkPos] == '}')
     178              :                                                                                 {
     179            0 :                                                                                         --depth;
     180            0 :                                                                                         if(depth <= 0)
     181              :                                                                                         {
     182            0 :                                                                                                 leftBlock = true;
     183            0 :                                                                                                 break;
     184              :                                                                                         }
     185              :                                                                                 }
     186              :                                                                         }
     187              :                                                                 }
     188            0 :                                                                 if(leftBlock)
     189            0 :                                                                         break;
     190              : 
     191            0 :                                                                 size_t nameEnd = std::string::npos;
     192            0 :                                                                 for(size_t i = nameStart + 1; i < sequenceJSON.size();
     193              :                                                                     ++i)
     194              :                                                                 {
     195            0 :                                                                         if(sequenceJSON[i] == '\\')
     196              :                                                                         {
     197            0 :                                                                                 ++i;
     198            0 :                                                                                 continue;
     199              :                                                                         }
     200            0 :                                                                         if(sequenceJSON[i] == '"')
     201              :                                                                         {
     202            0 :                                                                                 nameEnd = i;
     203            0 :                                                                                 break;
     204              :                                                                         }
     205              :                                                                 }
     206            0 :                                                                 if(nameEnd == std::string::npos)
     207            0 :                                                                         break;
     208              : 
     209              :                                                                 std::string variableName = sequenceJSON.substr(
     210            0 :                                                                     nameStart + 1, nameEnd - nameStart - 1);
     211              : 
     212              :                                                                 // skip past the value object {value, step, max}
     213            0 :                                                                 size_t objectStart = sequenceJSON.find('{', nameEnd + 1);
     214            0 :                                                                 if(objectStart == std::string::npos)
     215            0 :                                                                         break;
     216            0 :                                                                 int    objectDepth = 1;
     217            0 :                                                                 bool   objectQuote = false;
     218            0 :                                                                 size_t objectEnd   = std::string::npos;
     219            0 :                                                                 for(size_t i = objectStart + 1; i < sequenceJSON.size();
     220              :                                                                     ++i)
     221              :                                                                 {
     222            0 :                                                                         if(sequenceJSON[i] == '\\' && objectQuote)
     223              :                                                                         {
     224            0 :                                                                                 ++i;
     225            0 :                                                                                 continue;
     226              :                                                                         }
     227            0 :                                                                         if(sequenceJSON[i] == '"')
     228            0 :                                                                                 objectQuote = !objectQuote;
     229            0 :                                                                         if(!objectQuote)
     230              :                                                                         {
     231            0 :                                                                                 if(sequenceJSON[i] == '{')
     232            0 :                                                                                         ++objectDepth;
     233            0 :                                                                                 else if(sequenceJSON[i] == '}')
     234              :                                                                                 {
     235            0 :                                                                                         --objectDepth;
     236            0 :                                                                                         if(objectDepth == 0)
     237              :                                                                                         {
     238            0 :                                                                                                 objectEnd = i;
     239            0 :                                                                                                 break;
     240              :                                                                                         }
     241              :                                                                                 }
     242              :                                                                         }
     243              :                                                                 }
     244            0 :                                                                 if(objectEnd == std::string::npos)
     245            0 :                                                                         break;
     246              : 
     247            0 :                                                                 variableNamesInOrder.push_back(variableName);
     248            0 :                                                                 scanPosition = objectEnd + 1;
     249            0 :                                                         }
     250              :                                                 }
     251              :                                         }
     252              :                                 }
     253              : 
     254              :                                 // Parse [$varName,value,step,max] arguments from argv[5..argc-1]
     255            0 :                                 unsigned int numberOfOverrides = argc - 5;
     256              : 
     257              :                                 // Build variablesJSON from overrides
     258            0 :                                 std::string variablesJSON;
     259            0 :                                 if(numberOfOverrides > 0)
     260              :                                 {
     261            0 :                                         variablesJSON                   = "{";
     262            0 :                                         unsigned int validOverrideCount = 0;
     263            0 :                                         for(unsigned int overrideIndex = 0; overrideIndex < numberOfOverrides;
     264              :                                             ++overrideIndex)
     265              :                                         {
     266            0 :                                                 std::string overrideArg = argv[5 + overrideIndex];
     267              : 
     268              :                                                 // Strip brackets
     269            0 :                                                 if(overrideArg.size() >= 2 && overrideArg[0] == '[' &&
     270            0 :                                                    overrideArg[overrideArg.size() - 1] == ']')
     271            0 :                                                         overrideArg = overrideArg.substr(1, overrideArg.size() - 2);
     272              : 
     273              :                                                 std::vector<std::string> overrideParts =
     274            0 :                                                     getVectorFromString(overrideArg, {','}, {} /*whitespace*/);
     275              : 
     276            0 :                                                 if(overrideParts.size() < 2)
     277              :                                                 {
     278            0 :                                                         __COUT_ERR__ << "Invalid variable override: '"
     279            0 :                                                                      << argv[5 + overrideIndex]
     280            0 :                                                                      << "'. Expected [varName,value,step,max]."
     281            0 :                                                                      << __E__;
     282            0 :                                                         return 1;
     283              :                                                 }
     284              : 
     285            0 :                                                 std::string overrideName = overrideParts[0];
     286            0 :                                                 if(!overrideName.empty() && overrideName[0] != '$')
     287            0 :                                                         overrideName = "$" + overrideName;
     288              :                                                 std::string overrideValue =
     289            0 :                                                     overrideParts.size() > 1 ? overrideParts[1] : "0";
     290              :                                                 std::string overrideStep =
     291            0 :                                                     overrideParts.size() > 2 ? overrideParts[2] : "0";
     292              :                                                 std::string overrideMax =
     293            0 :                                                     overrideParts.size() > 3 ? overrideParts[3] : "0";
     294              : 
     295              :                                                 // Verify the variable name exists in the sequence
     296            0 :                                                 bool foundVariable = false;
     297            0 :                                                 for(size_t variableIndex = 0;
     298            0 :                                                     variableIndex < variableNamesInOrder.size();
     299              :                                                     ++variableIndex)
     300              :                                                 {
     301            0 :                                                         if(variableNamesInOrder[variableIndex] == overrideName)
     302              :                                                         {
     303            0 :                                                                 foundVariable = true;
     304            0 :                                                                 break;
     305              :                                                         }
     306              :                                                 }
     307            0 :                                                 if(!foundVariable)
     308              :                                                 {
     309            0 :                                                         __COUT_ERR__ << "Unknown variable '" << overrideName
     310            0 :                                                                      << "'. Available variables:" << __E__;
     311            0 :                                                         for(size_t variableIndex = 0;
     312            0 :                                                             variableIndex < variableNamesInOrder.size();
     313              :                                                             ++variableIndex)
     314            0 :                                                                 __COUT_ERR__ << "\t"
     315            0 :                                                                              << variableNamesInOrder[variableIndex]
     316            0 :                                                                              << __E__;
     317            0 :                                                         return 1;
     318              :                                                 }
     319              : 
     320            0 :                                                 if(validOverrideCount > 0)
     321            0 :                                                         variablesJSON += ",";
     322              :                                                 variablesJSON +=
     323            0 :                                                     "\"" + ots_mm_udp_interface::escapeJsonString(overrideName) +
     324            0 :                                                     "\":{\"value\":\"" +
     325            0 :                                                     ots_mm_udp_interface::escapeJsonString(overrideValue) +
     326            0 :                                                     "\",\"step\":\"" +
     327            0 :                                                     ots_mm_udp_interface::escapeJsonString(overrideStep) +
     328            0 :                                                     "\",\"max\":\"" +
     329            0 :                                                     ots_mm_udp_interface::escapeJsonString(overrideMax) + "\"}";
     330            0 :                                                 ++validOverrideCount;
     331            0 :                                         }
     332            0 :                                         variablesJSON += "}";
     333              :                                 }
     334              : 
     335            0 :                                 __COUT_INFO__ << "Running sequence '" << sequenceName << "' for "
     336            0 :                                               << iterationCount << " iteration(s)" << __E__;
     337              : 
     338            0 :                                 if(numberOfOverrides > 0)
     339              :                                 {
     340            0 :                                         __COUT_INFO__ << "Variable overrides:" << __E__;
     341            0 :                                         for(unsigned int overrideIndex = 0; overrideIndex < numberOfOverrides;
     342              :                                             ++overrideIndex)
     343            0 :                                                 __COUT_INFO__ << "\t" << argv[5 + overrideIndex] << __E__;
     344              :                                 }
     345              : 
     346            0 :                                 mm.runSequence(sequenceName, variablesJSON, iterationCount);
     347              : 
     348            0 :                                 __COUT_INFO__ << "Done." << __E__;
     349            0 :                                 return 0;
     350            0 :                         }
     351              : 
     352              :                         // neither FE UID nor sequence name
     353            0 :                         __COUT_ERR__ << "'" << target_fe
     354            0 :                                      << "' not found as a front-end UID or MoM sequence name."
     355            0 :                                      << __E__;
     356            0 :                         __COUT_INFO__ << "\nAvailable Front-end UIDs:" << __E__;
     357            0 :                         for(size_t feIndex = 0; feIndex < fes.size(); ++feIndex)
     358            0 :                                 __COUT_INFO__ << "\t\t" << fes[feIndex] << __E__;
     359              : 
     360            0 :                         __COUT_INFO__ << "\nAvailable MoM Sequences:" << __E__;
     361            0 :                         for(size_t sequenceIndex = 0; sequenceIndex < sequenceNames.size();
     362              :                             ++sequenceIndex)
     363              :                         {
     364            0 :                                 if(sequenceNames[sequenceIndex].empty() ||
     365            0 :                                    sequenceNames[sequenceIndex] == "." ||
     366            0 :                                    sequenceNames[sequenceIndex] == "..")
     367            0 :                                         continue;
     368            0 :                                 __COUT_INFO__ << "\t\t" << sequenceNames[sequenceIndex] << __E__;
     369              :                         }
     370            0 :                         return 1;
     371            0 :                 }
     372            0 :         }
     373              :         else
     374              :         {
     375            0 :                 __COUT_INFO__
     376            0 :                     << "No front-end UID specified, here is the list of existing Front-end UIDs:"
     377            0 :                     << __E__;
     378            0 :                 for(fe = 0; fe < fes.size(); ++fe)
     379            0 :                         __COUT_INFO__ << "\t\t" << fes[fe] << __E__;
     380              : 
     381              :                 // Also list available sequences
     382              :                 try
     383              :                 {
     384            0 :                         std::string              sequenceListStr = mm.getSequenceList();
     385              :                         std::vector<std::string> sequenceNames =
     386            0 :                             getVectorFromString(sequenceListStr, {';'});
     387              : 
     388            0 :                         bool hasSequences = false;
     389            0 :                         for(size_t sequenceIndex = 0; sequenceIndex < sequenceNames.size();
     390              :                             ++sequenceIndex)
     391              :                         {
     392            0 :                                 if(sequenceNames[sequenceIndex].empty() ||
     393            0 :                                    sequenceNames[sequenceIndex] == "." ||
     394            0 :                                    sequenceNames[sequenceIndex] == "..")
     395            0 :                                         continue;
     396            0 :                                 if(!hasSequences)
     397              :                                 {
     398            0 :                                         __COUT_INFO__ << "\nAvailable MoM Sequences:" << __E__;
     399            0 :                                         hasSequences = true;
     400              :                                 }
     401            0 :                                 __COUT_INFO__ << "\t\t" << sequenceNames[sequenceIndex] << __E__;
     402              :                         }
     403            0 :                 }
     404            0 :                 catch(const std::runtime_error& sequenceListError)
     405              :                 {
     406            0 :                         __COUT_WARN__ << "Could not retrieve sequence list: "
     407            0 :                                       << sequenceListError.what() << __E__;
     408            0 :                 }
     409              : 
     410            0 :                 return 0;
     411              :         }
     412              : 
     413            0 :         if(fe >= fes.size())
     414              :         {
     415            0 :                 __COUT_ERR__ << "Illegal front-end index " << fe << " vs " << fes.size()
     416            0 :                              << " count." << __E__;
     417            0 :                 return 1;
     418              :         }
     419              : 
     420              :         __COUTV__(fes[fe]);
     421            0 :         std::string commandStr = mm.getCommandList(fes[fe]);
     422              :         __COUTV__(commandStr);
     423              : 
     424            0 :         std::vector<std::string> commands = getVectorFromString(commandStr, {';'});
     425              : 
     426            0 :         if(argc >= 5)
     427              :         {
     428              :                 //look for command
     429            0 :                 std::string target_command = argv[4];
     430            0 :                 for(cmd = 0; cmd < commands.size(); ++cmd)
     431            0 :                         if(commands[cmd] == target_command)
     432            0 :                                 break;
     433            0 :                 if(cmd >= commands.size())
     434              :                 {
     435            0 :                         __COUT_ERR__ << "Illegal Front-end Macro Command name '" << target_command
     436            0 :                                      << "' not found in '" << fes[fe]
     437            0 :                                      << "' Command list: " << vectorToString(commands, {';'}) << "."
     438            0 :                                      << __E__;
     439            0 :                         return 1;
     440              :                 }
     441            0 :         }
     442              :         else
     443              :         {
     444            0 :                 __COUT_INFO__ << "No FE Macro Name specified, here is the list of existing FE "
     445              :                                  "Macro Names corresponding to the specified Front-end UID '"
     446            0 :                               << argv[3] << "':" << __E__;
     447            0 :                 for(cmd = 0; cmd < commands.size(); ++cmd)
     448            0 :                         __COUT_INFO__ << "\t\t" << commands[cmd] << __E__;
     449              : 
     450            0 :                 return 0;
     451              :         }
     452              : 
     453            0 :         if(cmd >= commands.size())
     454              :         {
     455            0 :                 __COUT_ERR__ << "Illegal command index " << cmd << " vs " << commands.size()
     456            0 :                              << " count." << __E__;
     457            0 :                 return 1;
     458              :         }
     459              : 
     460              :         __COUTV__(commands[cmd]);
     461              : 
     462            0 :         uint32_t numberOfInputs = mm.getCommandInputCount(fes[fe], commands[cmd]);
     463              :         __COUTV__(numberOfInputs);
     464              : 
     465            0 :         uint32_t numberOfOutputs = mm.getCommandOutputCount(fes[fe], commands[cmd]);
     466              :         __COUTV__(numberOfOutputs);
     467              : 
     468            0 :         std::vector<std::string> inputs;
     469            0 :         if(argc != int(5 + numberOfInputs))
     470              :         {
     471            0 :                 __COUT_WARN__
     472              :                     << "Incorrect number of inputs provided for Front-end Macro Command name '"
     473            0 :                     << commands[cmd] << "' on FE UID '" << fes[fe] << "': " << argc - 5 << " vs "
     474            0 :                     << numberOfInputs << " expected." << __E__;
     475            0 :                 __COUT_INFO__ << "Will not run command." << __E__;
     476              : 
     477            0 :                 for(uint32_t i = 0; i < numberOfInputs; ++i)
     478              :                 {
     479            0 :                         std::string inputName = mm.getCommandInputName(fes[fe], commands[cmd], i);
     480            0 :                         __COUT_INFO__ << "\tExpected input #" << i + 1 << ": " << inputName << __E__;
     481            0 :                 }
     482            0 :                 return 0;
     483              :         }
     484              : 
     485              :         __COUTV__(vectorToString(inputs, {';'}));
     486            0 :         for(uint32_t i = 0; i < numberOfInputs; ++i)
     487              :         {
     488            0 :                 inputs.push_back(ots_mm_udp_interface::encodeURIComponent(argv[5 + i]));
     489            0 :                 std::string inputName = mm.getCommandInputName(fes[fe], commands[cmd], i);
     490            0 :                 __COUT_INFO__ << "\tInput #" << i << ": " << inputName << " = "
     491            0 :                               << ots_mm_udp_interface::decodeURIComponent(inputs.back()) << __E__;
     492            0 :         }
     493              : 
     494            0 :         __COUT_INFO__ << "Running command with these expected outputs..." << __E__;
     495            0 :         for(uint32_t i = 0; i < numberOfOutputs; ++i)
     496              :         {
     497            0 :                 std::string outputName = mm.getCommandOutputName(fes[fe], commands[cmd], i);
     498            0 :                 __COUT_INFO__ << "\tOutput #" << i << ": " << outputName << __E__;
     499            0 :         }
     500              : 
     501              :         std::string commandResult =
     502            0 :             mm.runCommand(fes[fe], commands[cmd], vectorToString(inputs, {';'}));
     503              : 
     504            0 :         std::vector<std::string> outputs = getVectorFromString(commandResult, {';'});
     505              : 
     506            0 :         if(numberOfOutputs != outputs.size())
     507              :         {
     508              :                 __COUTV__(commandResult);
     509            0 :                 __COUT_ERR__ << "Illegal response, mismatch in output arguments returned: "
     510            0 :                              << outputs.size() << " vs " << numberOfOutputs << " expected."
     511            0 :                              << __E__;
     512            0 :                 return 1;
     513              :         }
     514              : 
     515              :         __COUTV__(vectorToString(outputs, {';'}));
     516            0 :         for(uint32_t i = 0; i < numberOfOutputs; ++i)
     517              :         {
     518            0 :                 std::string outputName = mm.getCommandOutputName(fes[fe], commands[cmd], i);
     519              :                 __COUT__ << "\tOutput #" << i << ": " << outputName << " = "
     520              :                          << mm.decodeURIComponent(outputs[i]) << __E__;
     521            0 :         }
     522            0 :         __COUT_INFO__ << "Done." << __E__;
     523            0 :         return 0;
     524            0 : }
     525            0 : catch(const std::runtime_error& e)
     526              : {
     527            0 :         __COUT_ERR__ << "Error caught during test execution: \n" << e.what() << __E__;
     528            0 :         return 1;
     529            0 : }
        

Generated by: LCOV version 2.0-1