Defaults for test|report (all) and test|reset (soft). Improvs for operation (signal...
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Thu, 17 Dec 2015 01:04:08 +0000 (02:04 +0100)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Thu, 17 Dec 2015 01:04:08 +0000 (02:04 +0100)
example/diameter/launcher/Launcher.cpp
example/diameter/launcher/Launcher.hpp
example/diameter/launcher/resources/scripts/operation_signal.sh

index 0faafe2..1ebf492 100644 (file)
@@ -11,6 +11,7 @@
 #include <iostream>     // std::cout
 #include <math.h> // ceil
 #include <climits>
+#include <unistd.h> // chdir
 
 // Project
 #include <anna/timex/Engine.hpp>
@@ -33,8 +34,8 @@
 #include <TestCase.hpp>
 
 
-#define SIGUSR2_TASKS_INPUT_FILENAME "./sigusr2.in"
-#define SIGUSR2_TASKS_OUTPUT_FILENAME "./sigusr2.out"
+#define SIGUSR2_TASKS_INPUT_FILENAME "sigusr2.in"
+#define SIGUSR2_TASKS_OUTPUT_FILENAME "sigusr2.out"
 
 
 const char *ServicesDTD = "\
@@ -129,6 +130,13 @@ Launcher::Launcher() : anna::comm::Application("launcher", "DiameterLauncher", "
 }
 
 
+std::string Launcher::getSignalUSR2InputFile() const throw() {
+  return (a_initialWorkingDirectory + "/" + SIGUSR2_TASKS_INPUT_FILENAME);
+}
+
+std::string Launcher::getSignalUSR2OutputFile() const throw() {
+  return (a_initialWorkingDirectory + "/" + SIGUSR2_TASKS_OUTPUT_FILENAME);
+}
 
 
 void Launcher::servicesFromXML(const anna::xml::Node* servicesNode, bool eventOperation) throw(anna::RuntimeException) {
@@ -566,6 +574,13 @@ throw(anna::RuntimeException) {
 
   // Start time:
   a_start_time.setNow();
+
+  // Initial working directory:
+  char cwd[1024];
+  if (getcwd(cwd, sizeof(cwd)) == NULL)
+    throw anna::RuntimeException("Cannot retrieve initial working directory !!", ANNA_FILE_LOCATION);
+  a_initialWorkingDirectory = cwd;
+
   // Statistics:
   anna::statistics::Engine::instantiate().enable();
 
@@ -801,11 +816,15 @@ void Launcher::resetCounters() throw() {
 }
 
 void Launcher::signalUSR2() throw(anna::RuntimeException) {
+
+  std::string inputFile = getSignalUSR2InputFile();
+  std::string outputFile = getSignalUSR2OutputFile();
+
   LOGNOTICE(
   std::string msg = "Captured signal SIGUSR2. Reading tasks at '";
-  msg += SIGUSR2_TASKS_INPUT_FILENAME;
+  msg += inputFile;
   msg += "' (results will be written at '";
-  msg += SIGUSR2_TASKS_OUTPUT_FILENAME;
+  msg += outputFile;
   msg += "')";
   anna::Logger::notice(msg, ANNA_FILE_LOCATION);
   );
@@ -813,13 +832,18 @@ void Launcher::signalUSR2() throw(anna::RuntimeException) {
   // Operation:
   std::string line;
   std::string response_content;
-  std::ifstream in_file(SIGUSR2_TASKS_INPUT_FILENAME);
-  std::ofstream out_file(SIGUSR2_TASKS_OUTPUT_FILENAME);
+  std::ifstream in_file(inputFile);
+  std::ofstream out_file(outputFile);
 
   if(!in_file.is_open()) throw RuntimeException("Unable to read tasks", ANNA_FILE_LOCATION);
   if(!out_file.is_open()) throw RuntimeException("Unable to write tasks", ANNA_FILE_LOCATION);
 
   while(getline(in_file, line)) {
+
+    // Ignore comments and blank lines:
+    if (line[0] == '#')  continue;
+    if (std::string::npos == line.find_first_not_of(" \t")) continue;
+
     LOGDEBUG(
         std::string msg = "Processing line: ";
     msg += line;
@@ -994,6 +1018,11 @@ std::string Launcher::help() const throw() {
   result += "\n                                     This operation applies over all the registered host nodes";
   result += "\n                                      except if one specific working node has been set.";
   result += "\nforceCountersRecord                  Forces dump to file the current counters of the process.";
+  result += "\nchange-dir[|directory]               Changes the execution point which could be fine to ease some";
+  result += "\n                                     file system interaction tasks. Be care about some requirements";
+  result += "\n                                     (for example if you have a user defined counters directory as";
+  result += "\n                                     relative path this must exists from the new execution directory).";
+  result += "\n                                     If nothing provided, initial working directory will be restored.";
   result += "\nshow-oam                             Dumps current counters of the process. This is also done at";
   result += "\n                                      process context dump.";
   result += "\nshow-stats                           Dumps statistics of the process. This is also done at process";
@@ -1347,7 +1376,7 @@ std::string Launcher::help() const throw() {
   result += "\n                                 steps margin, which could be useful to 'freeze' a test in the middle of its execution.";
   result += "\n                                 You could also provide -1 to make it non-interactive resuming it from the current step.";
   result += "\n";
-  result += "\n   test|reset|<soft/hard>[|id]   Reset the test case for id provided, all the tests when missing. It could be hard/soft:";
+  result += "\n   test|reset|<[soft]/hard>[|id] Reset the test case for id provided, all the tests when missing. It could be hard/soft:";
   result += "\n                                 - hard: you probably may need to stop the load rate before. This operation initializes";
   result += "\n                                         all test cases regardless their states.";
   result += "\n                                 - soft: only for finished cases (those with 'Success' or 'Failed' states). It does not";
@@ -1366,7 +1395,7 @@ std::string Launcher::help() const throw() {
   result += "\n                                 enabled because the programmed test cases dumps could be heavy (anyway you could enable the";
   result += "\n                                 dumps separately, for any of the possible states: Initialized, InProgress, Failed, Success).";
   result += "\n";
-  result += "\n   test|report|<initialized/in-progress/failed/success/all/none>[|[yes]|no]";
+  result += "\n   test|report|<initialized/in-progress/failed/success/[all]/none>[|[yes]|no]";
   result += "\n";
   result += "\n                                 Enables/disables report generation for a certain test case state: initialized, in-progress,";
   result += "\n                                 failed or success (also 'all' and 'none' reserved words could be used). This applies to report";
@@ -1404,13 +1433,13 @@ std::string Launcher::help() const throw() {
   result += "\n";
   result += "\nThe alternative using SIGUSR2 signal requires the creation of the task(s) file which will be read at";
   result += "\n signal event:";
-  result += "\n   echo \"<<operation>\" > "; result += SIGUSR2_TASKS_INPUT_FILENAME;
+  result += "\n   echo \"<<operation>\" > "; result += getSignalUSR2InputFile();
   result += "\n    then";
   result += "\n   kill -12 <pid>";
   result += "\n    or";
   result += "\n   kill -s SIGUSR2 <pid>";
   result += "\n    and then see the results:";
-  result += "\n   cat "; result += SIGUSR2_TASKS_OUTPUT_FILENAME;
+  result += "\n   cat "; result += getSignalUSR2OutputFile();
   result += "\n";
   result += "\n   (this file is ended with EOF final line, useful managing huge batch files to ensure the job completion)";
   result += "\n";
@@ -1430,7 +1459,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
   LOGDEBUG(anna::Logger::debug(operation, ANNA_FILE_LOCATION));
 
   // Default response:
-  response_content = "Operation processed with exception (see traces): ";
+  response_content = "Operation processed with exception: ";
   response_content += operation;
   std::string opt_response_content = ""; // aditional response content
   anna::DataBlock db_aux(true);
@@ -1520,7 +1549,9 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
   // Check the number of parameters:
   bool wrongBody = false;
 
+  if((opType == "change-dir") && (numParams > 1)) wrongBody = true;
   if((opType == "node") && (numParams > 1)) wrongBody = true;
+
   if((opType == "node_auto") && (numParams > 0)) wrongBody = true;
 
   if(((opType == "code") || (opType == "decode")) && (numParams != 2)) wrongBody = true;
@@ -1549,6 +1580,18 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     return;
   }
 
+  // Change execution directory:
+  if(opType == "change-dir") {
+    if (param1 == "") param1 = a_initialWorkingDirectory;
+    if (chdir(param1.c_str()) == 0)
+      response_content = "New execution directory configured: ";
+    else
+      response_content = "Cannot assign provided execution directory: ";
+
+    response_content += param1;
+    return;
+  }
+
   if(opType == "services") {
     std::string servicesFile = ((numParams == 1) ? param1 : "services.xml");
     try {
@@ -1782,13 +1825,13 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     // test|next[|<sync-amount>]                Forces the execution of the next test case(s) without waiting for test manager tick ...
     // test|ip-limit[|amount]                   In-progress limit of test cases. No new test cases will be launched over this value ...
     // test|repeats|<amount>                    Restarts the whole programmed test list when finished the amount number of times ...
-    // test|report|<initialized/in-progress/failed/success/all/none>[|[yes]|no]
+    // test|report|<initialized/in-progress/failed/success/[all]/none>[|[yes]|no]
     //                                          Enables/disables report generation for a certain test case state: initialized, in-progress ...
     // test|report-hex[|[yes]|no]               Reports could include the diameter messages in hexadecimal format. Disabled by default.
     // test|goto|<id>                           Updates current test pointer position.
     // test|look[|id]                           Show programmed test case for id provided, current when missing ...
     // test|interact|amount|id                  Makes interactive a specific test case id. The amount is the margin of execution steps ...
-    // test|reset|<soft/hard>[|id]              Reset the test case for id provided, all the tests when missing ...
+    // test|reset|<[soft]/hard>[|id]            Reset the test case for id provided, all the tests when missing ...
     // test|clear                               Clears all the programmed test cases.
     // test|summary                             Test manager general report (number of test cases, counts by state ...
 
@@ -1856,6 +1899,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       if (numParams > 3)
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
 
+      if(param2 == "") param2 = "all";
       if(param3 == "") param3 = "yes";
       bool enable = (param3 == "yes");
 
@@ -1964,7 +2008,8 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       if (numParams > 3)
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
 
-      if (param2 != "soft" && param2 != "hard")
+      if(param2 == "") param2 = "soft";
+     if (param2 != "soft" && param2 != "hard")
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
 
       int id = ((param3 != "") ? atoi(param3.c_str()) : -1);
@@ -1981,7 +2026,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       else {
         if (id == -1) {
           bool anyReset = testManager.resetPool((param2 == "hard") ? true:false);
-          opt_response_content = "reset have been sent to all programmed tests: "; opt_response_content += anyReset ? "some/all have been reset" : "nothing was reset";
+          opt_response_content = param2; opt_response_content += " reset have been sent to all programmed tests: "; opt_response_content += anyReset ? "some/all have been reset" : "nothing was reset";
         }
         else {
           opt_response_content = "cannot found test id (";
@@ -2197,6 +2242,7 @@ throw() {
   anna::comm::Application::asXML(result);
   // Timming:
   result->createAttribute("StartTime", a_start_time.asString());
+  result->createAttribute("InitialWorkingDirectory", a_initialWorkingDirectory);
   result->createAttribute("SecondsLifeTime", anna::time::functions::lapsedMilliseconds() / 1000);
   // Diameter:
   for (origin_hosts_it it = a_originHosts.begin(); it != a_originHosts.end(); it++) {
index af8a07a..14ea762 100644 (file)
@@ -59,6 +59,7 @@ class Launcher : public anna::comm::Application {
 
   // Start time:
   anna::time::Date a_start_time;
+  std::string a_initialWorkingDirectory;
 
   // Core engines:
   MyCommunicator *a_communicator;
@@ -77,11 +78,16 @@ class Launcher : public anna::comm::Application {
 
   const anna::Millisecond &getADMLMinResolution() const throw() { return a_admlMinResolution; }
 
+  std::string getSignalUSR2InputFile() const throw();
+  std::string getSignalUSR2OutputFile() const throw();
+
   void servicesFromXML(const anna::xml::Node* servicesNode, bool eventOperation) throw(anna::RuntimeException);
   anna::Millisecond checkTimeMeasure(const std::string &parameter, const std::string &value) throw(anna::RuntimeException);
   void initialize() throw(anna::RuntimeException); // HTTP
   void run() throw(anna::RuntimeException);
 
+
+
 public:
   Launcher();
   //~Launcher(); TODO
index 11cd8e5..da0449b 100755 (executable)
@@ -20,7 +20,7 @@ usage() {
   echo
   echo "       -h|--help:     this usage help."
   echo "       -t|--timeout:  timeout for operation in seconds."
-  echo "                      Defaults to 2 seconds if not provided."
+  echo "                      Defaults to $TIMEOUT__dflt seconds if not provided."
   echo
   echo "       -f|--file:     the parameter 'data' will be interpreted as a file"
   echo "                      with one operation per line. If missing, it will be"
@@ -94,11 +94,11 @@ parse_arguments $@
 # Send operation:
 if [ -n "$is_file" ]
 then
-  grep -v "^#" $data | sed '/^[ \t]*$/d' > sigusr2.in
+  cp $data sigusr2.in
 else
   echo $data > sigusr2.in
 fi
-0> sigusr2.out
+0>sigusr2.out
 check_pid $PID
 kill -s SIGUSR2 $PID
 
@@ -122,7 +122,7 @@ else
   _exit "Operation error: timeout expired ($timeout seconds)"
 fi
 
-exception=$(grep exception sigusr2.out)
-[ $? -eq 0 -a "$data" != "help" ] && _exit "(detected 'exception' within operation output)"
+exception=$(grep "^Operation processed with exception: " sigusr2.out)
+[ $? -eq 0 ] && _exit "(detected 'exception' within operation output: see 'launcher.trace')"
 exit 0