Auto-reset hard/soft for further cycles
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Tue, 27 Jun 2017 17:45:09 +0000 (19:45 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Tue, 27 Jun 2017 17:45:09 +0000 (19:45 +0200)
If no timeout is configured for a TC, it could happen that next
cycle reach the same TC still in progress. Auto-reset is soft by
default, but you could configure for this kind of scenarios.

Then, auto-reset will hard reset the TC dumping a Failed report
(hint is about hard reset of in-progress TC) and then will be
initialized and started again.

example/diameter/launcher/Launcher.cpp
example/diameter/launcher/deployments/st-client/program.sh
include/anna/testing/TestManager.hpp
source/testing/TestCase.cpp
source/testing/TestManager.cpp
source/testing/TestStep.cpp

index cd20991..eabf635 100644 (file)
@@ -1457,6 +1457,10 @@ std::string Launcher::help() const throw() {
   result += "\n                                 been done before. Test cases state & data will be reset (when achieved again), but general";
   result += "\n                                 statistics and counters will continue measuring until reset with 'collect' operation.";
   result += "\n";
+  result += "\n   test|auto-reset|<soft|hard>   When cycling, current test cases can be soft (default) or hard reset. If no timeout has";
+  result += "\n                                 been configured for the test case, hard reset could prevent stuck on the next cycle for";
+  result += "\n                                 those test cases still in progress.";
+  result += "\n";
   result += "\n   test|clear                    Clears all the programmed test cases and stop testing (if in progress).";
   result += "\n";
   result += "\n   test|summary                  Test manager general report (number of test cases, counts by state, global configuration,";
@@ -1978,6 +1982,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
     // 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|auto-reset|<soft|hard>              When cycling, current test cases can be soft (default) or hard reset ...
     // test|clear                               Clears all the programmed test cases.
     // test|summary                             Test manager general report (number of test cases, counts by state ...
 
@@ -2162,7 +2167,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       anna::testing::TestCase *testCase = ((id != -1) ? testManager.findTestCase(id) : NULL);
 
       if (testCase) {
-        bool done = testCase->reset((param2 == "hard") ? true:false);
+        bool done = testCase->reset(param2 == "hard");
         opt_response_content = "test ";
         opt_response_content += param2;
         opt_response_content += " reset for id ";
@@ -2171,7 +2176,7 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
       }
       else {
         if (id == -1) {
-          bool anyReset = testManager.resetPool((param2 == "hard") ? true:false);
+          bool anyReset = testManager.resetPool(param2 == "hard");
           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 {
@@ -2181,6 +2186,16 @@ void Launcher::eventOperation(const std::string &operation, std::string &respons
         }
       }
     }
+    else if(param1 == "auto-reset") {
+      if (numParams != 2)
+        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")
+        throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
+
+      testManager.setAutoResetHard(param2 == "hard");
+      opt_response_content += anna::functions::asString("Auto-reset configured to '%s'", param2.c_str());
+    }
     else if(param1 == "clear") {
       if (numParams > 1)
         throw anna::RuntimeException("Wrong body content format on HTTP Request. Use 'help' management command to see more information.", ANNA_FILE_LOCATION);
index a5f1ae1..e5f3b35 100755 (executable)
@@ -220,6 +220,17 @@ else
       echo
       read dynamic_suffix
       while [ -z "$dynamic_suffix" ]; do read dynamic_suffix ; done
+      timeout=$(echo $dynamic_suffix | cut -d\| -f1)
+      if [ "$timeout" = "0" ]
+      then
+        echo
+        echo "Zero-timeout will configure 'auto-reset' as 'hard' in order"
+        echo " to reset properly the test cases in further cycles ..."
+        ./operation.sh "test|auto-reset|hard" >/dev/null
+        echo
+        echo "Press ENTER to continue ..."
+        read dummy
+      fi
     fi
   fi
 
index 40bdfda..979941f 100644 (file)
@@ -84,6 +84,7 @@ class TestManager : public anna::timex::TimeEventObserver, public anna::Singleto
   int a_poolRepeats; // repeat pool N times
   int a_poolCycle; // current cycle, from 1 to N
   unsigned int a_inProgressLimit; // limit load to have this value
+  bool a_autoResetHard; // automatic reset on next cycle (soft by default, false)
 
   // Test clock
   int a_synchronousAmount;
@@ -156,6 +157,10 @@ class TestManager : public anna::timex::TimeEventObserver, public anna::Singleto
     int getPoolRepeats() const throw() { return a_poolRepeats; }
     int getPoolCycle() const throw() { return a_poolCycle; }
 
+    bool getAutoResetHard() const throw() { return a_autoResetHard; }
+    void setAutoResetHard(bool hard = true) throw() { a_autoResetHard = hard; }
+
+
     unsigned int getInProgressCount() const throw() { return a_statSummary.getInProgressCount(); }
     unsigned int getInProgressLimit() const throw() { return a_inProgressLimit; }
     void setInProgressLimit(unsigned int limit) throw() { a_inProgressLimit = limit; } // 0 = UINT_MAX (no limit)
index f8d7a98..d048dfc 100644 (file)
@@ -211,6 +211,12 @@ bool TestCase::reset(bool hard) throw() {
   // Soft reset if finished:
   if (!hard /* is soft reset */  && !isFinished()) return false;
 
+  // Dump as failed if still in progress (hard reset):
+  if (getState() == State::InProgress) {
+    addDebugSummaryHint("Testcase hard reset while in progress");
+    setState(State::Failed);
+  }
+
   // Clean stage ////////////////////////////
   // id is kept
   std::vector<TestStep*>::iterator it;
index 8c0ea81..6aeae9f 100644 (file)
@@ -98,6 +98,9 @@ TestManager::TestManager() :
   a_clock = NULL;
   //a_testPool.clear();
   //a_statSummary.clear();
+
+  a_autoResetHard = false;
+
   a_currentTestIt = a_testPool.end();
 }
 
@@ -358,8 +361,8 @@ bool TestManager::nextTestCase() throw() {
       }
     }
 
-    // Soft reset to initialize already finished (in previous cycle) test cases:
-    a_currentTestIt->second->reset(false);
+    // Hard reset or soft reset to initialize already finished (in previous cycle) test cases:
+    a_currentTestIt->second->reset(a_autoResetHard);
 
     // Process test case:
     LOGDEBUG(anna::Logger::debug(anna::functions::asString("Processing test case id = %llu, currently '%s' state", a_currentTestIt->first, TestCase::asText(a_currentTestIt->second->getState())), ANNA_FILE_LOCATION));
@@ -509,6 +512,7 @@ throw() {
   result->createAttribute("DumpFailedReports", (a_dumpFailedReports ? "yes":"no"));
   result->createAttribute("DumpSuccessReports", (a_dumpSuccessReports ? "yes":"no"));
   result->createAttribute("DumpHexMessages", (a_dumpHexMessages ? "yes":"no"));
+  result->createAttribute("AutoResetHard", (a_autoResetHard ? "yes":"no"));
   result->createAttribute("ReportsDirectory", a_reportsDirectory);
   if (a_clock) {
     result->createAttribute("AsynchronousSendings", a_synchronousAmount);
index 413ad28..4a75f3b 100644 (file)
@@ -359,7 +359,7 @@ throw() {
 
 bool TestStepSendxml::do_execute() throw() {
   bool success = false;
-  std::string failReason;
+  std::string failReason = "Error sending diameter message";
   anna::diameter::comm::Entity *entity = a_originHost->getEntity(); // by default
   anna::diameter::comm::LocalServer *localServer = a_originHost->getDiameterServer(); // by default
   const TestStepWait *tsw = NULL;