Fix bug when removing test case keys
[anna.git] / source / testing / TestManager.cpp
index c8c65e3..beb0d93 100644 (file)
@@ -35,7 +35,7 @@ using namespace anna::testing;
 
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-void TestManager::StatSummary::newTCState(const TestCase::State::_v beginState, const TestCase::State::_v endState) throw() {
+void TestManager::StatSummary::newTCState(const TestCase::State::_v beginState, const TestCase::State::_v endState) {
 
   if ((beginState == TestCase::State::Initialized)&&(endState == TestCase::State::Initialized)) { // special case (new test case provisioning)
     a_initializedTcs++;
@@ -58,14 +58,14 @@ void TestManager::StatSummary::newTCState(const TestCase::State::_v beginState,
   }
 }
 
-void TestManager::StatSummary::clear() throw() {
+void TestManager::StatSummary::clear() {
   a_initializedTcs = 0;
   a_inprogressTcs = 0;
   a_failedTcs = 0;
   a_sucessTcs = 0;
 }
 
-anna::xml::Node *TestManager::StatSummary::asXML(anna::xml::Node* parent) const throw() {
+anna::xml::Node *TestManager::StatSummary::asXML(anna::xml::Node* parent) const {
   anna::xml::Node* result = parent->createChild("StatSummary");
 
   anna::xml::Node* tcs = result->createChild("TestCasesCounts");
@@ -106,7 +106,7 @@ TestManager::TestManager() :
   a_currentTestIt = a_testPool.end();
 }
 
-void TestManager::registerKey1(const std::string &key, const TestCase *testCase)  throw(anna::RuntimeException) {
+void TestManager::registerKey1(const std::string &key, const TestCase *testCase)  noexcept(false) {
 
   auto it = a_key1TestCaseMap.find(key);
   if (it != a_key1TestCaseMap.end()) { // found
@@ -121,7 +121,7 @@ void TestManager::registerKey1(const std::string &key, const TestCase *testCase)
   }
 }
 
-void TestManager::registerKey2(const std::string &key, const TestCase *testCase)  throw(anna::RuntimeException) {
+void TestManager::registerKey2(const std::string &key, const TestCase *testCase)  noexcept(false) {
 
   auto it = a_key2TestCaseMap.find(key);
   if (it != a_key2TestCaseMap.end()) { // found
@@ -137,7 +137,7 @@ void TestManager::registerKey2(const std::string &key, const TestCase *testCase)
 }
 
 TestTimer* TestManager::createTimer(TestCaseStep* testCaseStep, const anna::Millisecond &timeout, const TestTimer::Type::_v type)
-throw(anna::RuntimeException) {
+noexcept(false) {
   TestTimer* result(NULL);
 
   if(a_timeController == NULL)
@@ -162,7 +162,7 @@ throw(anna::RuntimeException) {
 }
 
 void TestManager::cancelTimer(TestTimer* timer)
-throw() {
+{
   if(timer == NULL)
     return;
 
@@ -186,13 +186,13 @@ throw() {
 // Se invoca automaticamente desde anna::timex::Engine
 //------------------------------------------------------------------------------------------
 void TestManager::release(anna::timex::TimeEvent* timeEvent)
-throw() {
+{
   TestTimer* timer = static_cast <TestTimer*>(timeEvent);
   timer->setContext(NULL);
   a_timers.release(timer);
 }
 
-bool TestManager::configureTTPS(int testTicksPerSecond) throw() {
+bool TestManager::configureTTPS(int testTicksPerSecond) {
 
   if (testTicksPerSecond == 0) {
     if (a_clock) {
@@ -250,7 +250,7 @@ bool TestManager::configureTTPS(int testTicksPerSecond) throw() {
   return true;
 }
 
-bool TestManager::gotoTestCase(unsigned int id) throw() {
+bool TestManager::gotoTestCase(unsigned int id) {
   test_pool_it it = a_testPool.find(id);
   if (it != a_testPool.end()) {
     a_currentTestIt = it;
@@ -260,7 +260,7 @@ bool TestManager::gotoTestCase(unsigned int id) throw() {
   return false;
 }
 
-bool TestManager::runTestCase(unsigned int id) throw() {
+bool TestManager::runTestCase(unsigned int id) {
   test_pool_it it = a_testPool.find(id);
   if (it != a_testPool.end()) {
     a_currentTestIt = it;
@@ -277,7 +277,7 @@ bool TestManager::runTestCase(unsigned int id) throw() {
   return false;
 }
 
-TestCase *TestManager::findTestCase(unsigned int id) const throw() { // id = -1 provides current test case triggered
+TestCase *TestManager::findTestCase(unsigned int id) const { // id = -1 provides current test case triggered
 
   if (!tests()) return NULL;
   test_pool_it it = ((id != -1) ? a_testPool.find(id) : a_currentTestIt);
@@ -285,7 +285,11 @@ TestCase *TestManager::findTestCase(unsigned int id) const throw() { // id = -1
   return NULL;
 }
 
-TestCase *TestManager::getTestCase(unsigned int id, const std::string &description) throw() {
+TestCase *TestManager::getTestCase(unsigned int id, const std::string &description) {
+
+  if (id == 0) { // 0 is used to sequence automatically and get the value of 'tests() + 1'
+    id = tests() + 1;
+  }
 
   test_pool_nc_it it = a_testPool.find(id);
   if (it != a_testPool.end()) return it->second;
@@ -295,7 +299,57 @@ TestCase *TestManager::getTestCase(unsigned int id, const std::string &descripti
   return result;
 }
 
-bool TestManager::clearPool(std::string &result) throw() {
+bool TestManager::clearTestCase(std::string &result, unsigned int id) {
+  result = "";
+
+  if (!tests()) {
+    result = "There are not programmed test cases to be removed";
+    return false;
+  }
+
+  test_pool_it it = ((id != -1) ? a_testPool.find(id) : a_currentTestIt);
+  if (it == a_testPool.end()) {
+    result = "Test case id provided not found";
+    return false;
+  }
+
+  if (!it->second->safeToClear()) {
+    result = "Test case id provided has running-thread steps. Check for stuck external procedures or try later.";
+    return false;
+  }
+
+  a_testPool.erase(it);
+
+  result = "Provided test case has been dropped";
+  bool something_removed = false;
+
+  auto key1_it = a_key1TestCaseMap.find(it->second->getKey1());
+  if (key1_it != a_key1TestCaseMap.end()) {
+    a_key1TestCaseMap.erase(key1_it);
+    result += " | Removed key1 = ";
+    result += it->second->getKey1();
+    something_removed = true;
+  }
+  auto key2_it = a_key2TestCaseMap.find(it->second->getKey2());
+  if (key2_it != a_key2TestCaseMap.end()) {
+    a_key2TestCaseMap.erase(key2_it);
+    result += " | Removed key2 = ";
+    result += it->second->getKey2();
+    something_removed = true;
+  }
+
+  if (something_removed) return true;
+
+  result = "Provided test case has been dropped, but key1 = '";
+  result += it->second->getKey1();
+  result += "' was not found, and also key2 = '";
+  result += it->second->getKey2();
+  result += "' was not found";
+
+  return false;
+}
+
+bool TestManager::clearPool(std::string &result) {
 
   result = "";
 
@@ -340,7 +394,7 @@ bool TestManager::clearPool(std::string &result) throw() {
   return true;
 }
 
-bool TestManager::resetPool(bool hard) throw() {
+bool TestManager::resetPool(bool hard) {
   bool result = false; // any reset
 
   if (!tests()) return result;
@@ -353,12 +407,12 @@ bool TestManager::resetPool(bool hard) throw() {
   return result;
 }
 
-bool TestManager::tick() throw() {
+bool TestManager::tick() {
   LOGDEBUG(anna::Logger::debug("New test clock tick !", ANNA_FILE_LOCATION));
   return execTestCases(a_synchronousAmount);
 }
 
-bool TestManager::execTestCases(int sync_amount) throw() {
+bool TestManager::execTestCases(int sync_amount) {
 
   if (!tests()) {
     LOGWARNING(anna::Logger::warning("Testing pool is empty. You need programming", ANNA_FILE_LOCATION));
@@ -375,7 +429,7 @@ bool TestManager::execTestCases(int sync_amount) throw() {
   return true;
 }
 
-bool TestManager::nextTestCase() throw() {
+bool TestManager::nextTestCase() {
 
   while (true) {
 
@@ -424,7 +478,7 @@ bool TestManager::nextTestCase() throw() {
   }
 }
 
-TestCase *TestManager::getDiameterTestCaseFromSessionId(const anna::DataBlock &message, std::string &sessionId) throw() {
+TestCase *TestManager::getDiameterTestCaseFromSessionId(const anna::DataBlock &message, std::string &sessionId) {
   try {
     sessionId = anna::diameter::helpers::base::functions::getSessionId(message);
   }
@@ -441,7 +495,7 @@ TestCase *TestManager::getDiameterTestCaseFromSessionId(const anna::DataBlock &m
   return NULL;
 }
 
-TestCase *TestManager::getDiameterTestCaseFromSubscriberId(const anna::DataBlock &message, std::string &subscriberId) throw() {
+TestCase *TestManager::getDiameterTestCaseFromSubscriberId(const anna::DataBlock &message, std::string &subscriberId) {
   try {
     subscriberId = anna::diameter::helpers::dcca::functions::getSubscriptionIdData(message, anna::diameter::helpers::dcca::AVPVALUES__Subscription_Id_Type::END_USER_E164);
     if (subscriberId == "") // try with IMSI
@@ -460,7 +514,7 @@ TestCase *TestManager::getDiameterTestCaseFromSubscriberId(const anna::DataBlock
   return NULL;
 }
 
-void TestManager::receiveDiameterMessage(const anna::DataBlock &message, const anna::diameter::comm::ClientSession *clientSession) throw(anna::RuntimeException) {
+void TestManager::receiveDiameterMessage(const anna::DataBlock &message, const anna::diameter::comm::ClientSession *clientSession) noexcept(false) {
 
   // Testing disabled:
   if (!tests()) return;
@@ -501,7 +555,7 @@ void TestManager::receiveDiameterMessage(const anna::DataBlock &message, const a
   }
 }
 
-void TestManager::receiveDiameterMessage(const anna::DataBlock &message, const anna::diameter::comm::ServerSession *serverSession) throw(anna::RuntimeException) {
+void TestManager::receiveDiameterMessage(const anna::DataBlock &message, const anna::diameter::comm::ServerSession *serverSession) noexcept(false) {
 
   // Testing disabled:
   if (!tests()) return;
@@ -543,7 +597,7 @@ void TestManager::receiveDiameterMessage(const anna::DataBlock &message, const a
 }
 
 anna::xml::Node* TestManager::asXML(anna::xml::Node* parent) const
-throw() {
+{
   anna::xml::Node* result = parent->createChild("TestManager");
 
   int poolSize = a_testPool.size();
@@ -553,7 +607,7 @@ throw() {
   result->createAttribute("PoolCycle", a_poolCycle);
   a_statSummary.asXML(result);
   if (a_inProgressLimit == UINT_MAX)
-    result->createAttribute("InProgressLimit", "<no limit>");
+    result->createAttribute("InProgressLimit", "[no limit]");
   else
     result->createAttribute("InProgressLimit", a_inProgressLimit);
   result->createAttribute("DumpInitializedReports", (a_dumpInitializedReports ? "yes":"no"));
@@ -587,7 +641,7 @@ throw() {
 }
 
 anna::xml::Node* TestManager::junitAsXML(anna::xml::Node* parent) const
-throw() {
+{
   // if only a single testsuite element is present, the testsuites element can be omitted
   //anna::xml::Node* result = parent->createChild("testsuites");
   anna::xml::Node* result = parent->createChild("testsuite");
@@ -729,17 +783,17 @@ Each testcase element can have multiple error, failure, system-out, or system-er
   return result;
 }
 
-std::string TestManager::asXMLString() const throw() {
+std::string TestManager::asXMLString() const {
   anna::xml::Node root("root");
   return anna::xml::Compiler().apply(asXML(&root));
 }
 
-std::string TestManager::junitAsXMLString() const throw() {
+std::string TestManager::junitAsXMLString() const {
   anna::xml::Node root("root");
   return anna::xml::Compiler().apply(junitAsXML(&root));
 }
 
-std::string TestManager::summaryCounts() const throw() {
+std::string TestManager::summaryCounts() const {
 
   std::string result= "\nSummary Counts:\n";
   unsigned int total = a_statSummary.getTotal();
@@ -758,7 +812,7 @@ std::string TestManager::summaryCounts() const throw() {
   return result;
 }
 
-std::string TestManager::summaryStates() const throw() {
+std::string TestManager::summaryStates() const {
 
   std::string result = "\nSummary States:\n";
   const char *literal = "\n[%s] %s";