Fix bug while getting step number.
authorEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Mon, 5 Oct 2015 17:12:00 +0000 (19:12 +0200)
committerEduardo Ramos Testillano <eduardo.ramos.testillano@ericsson.com>
Mon, 5 Oct 2015 17:12:00 +0000 (19:12 +0200)
Converting vector into map

example/diameter/launcher/testing/TestCase.cpp
example/diameter/launcher/testing/TestCase.hpp
example/diameter/launcher/testing/TestStep.cpp

index 63851f7..e95a670 100644 (file)
@@ -11,7 +11,8 @@
 #include <fstream>
 #include <sstream>
 #include <cmath>
-
+#include <iterator>
+#include <vector>
 #include <iostream>
 
 // Project
@@ -56,8 +57,8 @@ anna::xml::Node* TestCase::DebugSummary::asXML(anna::xml::Node* parent) const th
 
 TestCase::~TestCase() {
   reset(true); // hard reset
-  std::vector<TestStep*>::const_iterator it;
-  for (it = a_steps.begin(); it != a_steps.end(); it++) delete (*it);
+  std::map<int/* step number*/, TestStep*>::const_iterator it;
+  for (it = a_steps.begin(); it != a_steps.end(); it++) delete (it->second);
 }
 
 const char* TestCase::asText(const State::_v state)
@@ -76,9 +77,9 @@ throw() {
   int steps = a_steps.size();
   if (steps != 0) {
     result->createAttribute("NumberOfTestSteps", steps);
-    std::vector<TestStep*>::const_iterator it;
+    std::map<int/* step number*/, TestStep*>::const_iterator it;
     for (it = a_steps.begin(); it != a_steps.end(); it++) {
-      (*it)->asXML(result);
+      it->second->asXML(result);
     }
   }
 
@@ -97,11 +98,11 @@ std::string TestCase::asXMLString() const throw() {
 }
 
 bool TestCase::hasSameCondition(const TestCondition &condition) const throw() {
-  std::vector<TestStep*>::const_iterator it;
+  std::map<int/* step number*/, TestStep*>::const_iterator it;
   TestStepWait *step;
   for (it = a_steps.begin(); it != a_steps.end(); it++) {
-    if ((*it)->getType() != TestStep::Type::Wait) continue;
-    step = (TestStepWait *)(*it);
+    if (it->second->getType() != TestStep::Type::Wait) continue;
+    step = (TestStepWait *)(it->second);
     if (step->getCondition() == condition) return true;
   }
   return false;
@@ -182,7 +183,7 @@ bool TestCase::process() throw() {
   if (done()) return false;
 
   bool somethingDone = false;
-  while ((*a_stepsIt)->execute()) { // executes returns 'true' if the next step must be also executed (execute until can't stand no more)
+  while (a_stepsIt->second->execute()) { // executes returns 'true' if the next step must be also executed (execute until can't stand no more)
     nextStep();
     // Check end of the test case:
     if (done()) return false;
@@ -199,9 +200,9 @@ bool TestCase::reset(bool hard) throw() {
 
   // Clean stage ////////////////////////////
   // id is kept
-  std::vector<TestStep*>::iterator it;
+  std::map<int/* step number*/, TestStep*>::iterator it;
   for (it = a_steps.begin(); it != a_steps.end(); it++)
-    (*it)->reset();
+    it->second->reset();
 
   a_debugSummary.clear();
   a_startTime = 0;
@@ -240,7 +241,7 @@ void TestCase::addTimeout(const anna::Millisecond &timeout) throw(anna::RuntimeE
   assertInitialized();
   TestStepTimeout *step = new TestStepTimeout(this);
   step->setTimeout(timeout);
-  a_steps.push_back(step);
+  addStep(step);
 }
 
 void TestCase::addSendxml2e(const anna::DataBlock &db, RealmNode *realm, int stepNumber) throw(anna::RuntimeException) {
@@ -248,16 +249,14 @@ void TestCase::addSendxml2e(const anna::DataBlock &db, RealmNode *realm, int ste
   assertMessage(db, true /* to entity */);
 
   if (stepNumber != -1) {
-    int steps = a_steps.size();
-    int stepIndx = stepNumber - 1;
-    if ((stepIndx < 0) || (stepIndx > (a_steps.size()-1)))
-      throw anna::RuntimeException(anna::functions::asString("Step number (%d) out of range (test case %llu)", stepNumber, a_id), ANNA_FILE_LOCATION);
+    const TestStep *stepReferred = getStep(stepNumber);
+    if (!stepReferred)
+      throw anna::RuntimeException(anna::functions::asString("Step number (%d) do not exists (test case %llu)", stepNumber, a_id), ANNA_FILE_LOCATION);
 
-    TestStep *stepReferred = a_steps[stepIndx];
     if (stepReferred->getType() != TestStep::Type::Wait)
       throw anna::RuntimeException(anna::functions::asString("Step number (%d) must refer to a 'wait' step (test case %llu)", stepNumber, a_id), ANNA_FILE_LOCATION);
 
-    const TestCondition &tc = (static_cast<TestStepWait*>(stepReferred))->getCondition();
+    const TestCondition &tc = (static_cast<const TestStepWait*>(stepReferred))->getCondition();
     if (tc.getCode() == "0") { // if regexp used, is not possible to detect this kind of errors
       throw anna::RuntimeException(anna::functions::asString("Step number (%d) must refer to a 'wait for request' step (test case %llu)", stepNumber, a_id), ANNA_FILE_LOCATION);
     }
@@ -267,7 +266,7 @@ void TestCase::addSendxml2e(const anna::DataBlock &db, RealmNode *realm, int ste
   step->setMsgDataBlock(db);
   step->setRealmNode(realm);
   step->setWaitForRequestStepNumber(stepNumber); // -1 means, no reference
-  a_steps.push_back(step);
+  addStep(step);
 }
 
 void TestCase::addSendxml2c(const anna::DataBlock &db, RealmNode *realm, int stepNumber) throw(anna::RuntimeException) {
@@ -277,14 +276,14 @@ void TestCase::addSendxml2c(const anna::DataBlock &db, RealmNode *realm, int ste
   TestStepSendxml2c *step = new TestStepSendxml2c(this);
   step->setMsgDataBlock(db);
   step->setRealmNode(realm);
-  a_steps.push_back(step);
+  addStep(step);
 }
 
 void TestCase::addDelay(const anna::Millisecond &delay) throw(anna::RuntimeException) {
   assertInitialized();
   TestStepDelay *step = new TestStepDelay(this);
   step->setDelay(delay);
-  a_steps.push_back(step);
+  addStep(step);
 }
 
 void TestCase::addWait(bool fromEntity,
@@ -305,20 +304,19 @@ void TestCase::addWait(bool fromEntity,
   else {
     if (hopByHop != "") {
       if (hopByHop[0] == '#') {
-        int steps = a_steps.size();
-        if (steps == 0)
+        if (steps() == 0)
           throw anna::RuntimeException(anna::functions::asString("No steps has been programmed, step reference is nonsense (test case %llu)", a_id), ANNA_FILE_LOCATION);
 
         int stepNumber = atoi(hopByHop.substr(1).c_str());
-        int stepIndx = stepNumber - 1;
-        if ((stepIndx < 0) || (stepIndx > (steps-1)))
-          throw anna::RuntimeException(anna::functions::asString("Step reference number %d out of range [1-%d]", stepNumber, steps), ANNA_FILE_LOCATION);
 
-        TestStep *stepReferred = a_steps[stepIndx];
+        const TestStep *stepReferred = getStep(stepNumber);
+        if (!stepReferred)
+          throw anna::RuntimeException(anna::functions::asString("Step reference number (%d) do not exists (test case %llu)", stepNumber, a_id), ANNA_FILE_LOCATION);
+
         if (stepReferred->getType() != TestStep::Type::Sendxml2e && stepReferred->getType() != TestStep::Type::Sendxml2c)
           throw anna::RuntimeException(anna::functions::asString("Step number must refer to a 'sendxml2e' or 'sendxml2c' step (test case %llu)", a_id), ANNA_FILE_LOCATION);
 
-        const anna::DataBlock &db = (static_cast<TestStepSendxml*>(stepReferred))->getMsgDataBlock();
+        const anna::DataBlock &db = (static_cast<const TestStepSendxml*>(stepReferred))->getMsgDataBlock();
         bool isAnswer = anna::diameter::codec::functions::isAnswer(db);
         if (isAnswer)
           throw anna::RuntimeException(anna::functions::asString("Step number must refer to a request message (test case %llu)", a_id), ANNA_FILE_LOCATION);
@@ -340,7 +338,7 @@ void TestCase::addWait(bool fromEntity,
       anna::Logger::warning(anna::functions::asString("The same wait condition has already been programmed in this test case (%llu). Are you sure ?", a_id), ANNA_FILE_LOCATION);
   );
 
-  a_steps.push_back(step);
+  addStep(step);
 }
 
 void TestCase::addWaitRegexp(bool fromEntity, const std::string &regexp) throw(anna::RuntimeException) {
@@ -354,7 +352,7 @@ void TestCase::addWaitRegexp(bool fromEntity, const std::string &regexp) throw(a
       anna::Logger::warning(anna::functions::asString("The same wait condition has already been programmed in this test case (%llu). Are you sure ?", a_id), ANNA_FILE_LOCATION);
   );
 
-  a_steps.push_back(step);
+  addStep(step);
 }
 
 void TestCase::addCommand(const std::string &cmd) throw(anna::RuntimeException) {
@@ -363,16 +361,16 @@ void TestCase::addCommand(const std::string &cmd) throw(anna::RuntimeException)
   TestStepCmd *step = new TestStepCmd(this);
   step->setScript(cmd);
 
-  a_steps.push_back(step);
+  addStep(step);
 }
 
 TestStepWait *TestCase::searchNextWaitConditionFulfilled(const anna::DataBlock &message, bool waitFromEntity) throw() {
 
   TestStepWait *result;
-  for (std::vector<TestStep*>::const_iterator it = a_stepsIt /* current */; it != a_steps.end(); it++) {
-    if ((*it)->getType() != TestStep::Type::Wait) continue;
-    if ((*it)->isCompleted()) continue;
-    result = (TestStepWait*)(*it);
+  for (std::map<int/* step number*/, TestStep*>::const_iterator it = a_stepsIt /* current */; it != a_steps.end(); it++) {
+    if (it->second->getType() != TestStep::Type::Wait) continue;
+    if (it->second->isCompleted()) continue;
+    result = (TestStepWait*)(it->second);
     if ((result->getCondition().receivedFromEntity() == waitFromEntity) && (result->fulfilled(message)))
       return result;
   }
@@ -381,8 +379,7 @@ TestStepWait *TestCase::searchNextWaitConditionFulfilled(const anna::DataBlock &
 }
 
 const TestStep *TestCase::getStep(int stepNumber) const throw() {
-  int stepIndx = stepNumber - 1;
-  if ((stepIndx < 0) || (stepIndx > (a_steps.size()-1))) return NULL;
-  std::vector<TestStep*>::const_iterator it = (a_steps.begin() + stepNumber);
-  return (*it);
+  std::map<int/* step number*/, TestStep*>::const_iterator it = a_steps.find(stepNumber);
+  if (it != a_steps.end()) return it->second;
+  return NULL;
 }
index a3b653d..ab8e4a3 100644 (file)
@@ -12,6 +12,7 @@
 // Standard
 #include <string>
 #include <vector>
+#include <map>
 
 // Project
 #include <anna/core/DataBlock.hpp>
@@ -108,6 +109,8 @@ public:
 
   //helpers
   int steps() const throw() { return a_steps.size(); }
+  void addStep(TestStep *step) throw() { a_steps[1+steps()] = step; }
+
   TestStepWait *searchNextWaitConditionFulfilled(const anna::DataBlock &message, bool waitFromEntity) throw();
       // When a message arrives, we identify the test case by mean the Session-Id. Then, from the current step iterator (included),
       //  we search for a fulfilling condition for that message. The first found, is 'completed' and then breaks the search.
@@ -120,8 +123,8 @@ public:
 private:
   // private members:
   unsigned int a_id;
-  std::vector<TestStep*> a_steps;
-  std::vector<TestStep*>::const_iterator a_stepsIt;
+  std::map<int/* step number*/, TestStep*> a_steps;
+  std::map<int/* step number*/, TestStep*>::const_iterator a_stepsIt;
   std::map<anna::diameter::HopByHop, TestStep*> a_hopByHops; // for wait-answer
   State::_v a_state;
   anna::Millisecond a_startTime;
index 75ede74..018dfcd 100644 (file)
@@ -231,21 +231,21 @@ bool TestStep::execute() throw() {
     if (a_executed) return false; // avoid repeating (this implies amount consumption)
   }
 
-  LOGDEBUG(anna::Logger::debug(anna::functions::asString("EXECUTING %s (step number %d) for Test Case %llu (%p) (%p)", asText(a_type), a_number, a_testCase->getId(), (TestCaseStep*)this, this), ANNA_FILE_LOCATION));
+  LOGDEBUG(anna::Logger::debug(anna::functions::asString("EXECUTING %s (step number %d) for Test Case %llu (%p)", asText(a_type), a_number, a_testCase->getId(), this), ANNA_FILE_LOCATION));
   setBeginTimestamp(anna::functions::millisecond());
   a_executed = true;
   return do_execute();
 }
 
 void TestStep::complete() throw() {
-  LOGDEBUG(anna::Logger::debug(anna::functions::asString("COMPLETE %s (step number %d) for Test Case %llu (%p) (%p)", asText(a_type), a_number, a_testCase->getId(), (TestCaseStep*)this, this), ANNA_FILE_LOCATION));
+  LOGDEBUG(anna::Logger::debug(anna::functions::asString("COMPLETE %s (step number %d) for Test Case %llu (%p)", asText(a_type), a_number, a_testCase->getId(), this), ANNA_FILE_LOCATION));
   a_completed = true;
   setEndTimestamp(anna::functions::millisecond());
   do_complete();
 }
 
 void TestStep::reset() throw() {
-  LOGDEBUG(anna::Logger::debug(anna::functions::asString("RESET %s (step number %d) for Test Case %llu (%p) (%p)", asText(a_type), a_number, a_testCase->getId(), (TestCaseStep*)this, this), ANNA_FILE_LOCATION));
+  LOGDEBUG(anna::Logger::debug(anna::functions::asString("RESET %s (step number %d) for Test Case %llu (%p)", asText(a_type), a_number, a_testCase->getId(), this), ANNA_FILE_LOCATION));
   // type and testCase kept
   a_completed = false;
   a_executed = false;
@@ -300,8 +300,6 @@ void TestStepTimeout::do_complete() throw() {
 }
 
 void TestStepTimeout::do_reset() throw() {
-  LOGDEBUG(anna::Logger::debug(anna::functions::asString("REXXXXXET %s for Test Case %llu (%p) (%p) (a_timer %p)", asText(a_type), a_testCase->getId(), (TestCaseStep*)this, this, a_timer), ANNA_FILE_LOCATION));
-
   try {
     TestManager::instantiate().cancelTimer(a_timer);
   }
@@ -362,10 +360,12 @@ bool TestStepSendxml::do_execute() throw() {
     // Update sequence for answers:
     if (a_waitForRequestStepNumber != -1) { // is an answer: try to copy sequence information; alert about Session-Id discrepance
       // Request which was received:
-      tsw = (const TestStepWait*)(a_testCase->getStep(a_waitForRequestStepNumber));
+      tsw = static_cast<const TestStepWait*>(a_testCase->getStep(a_waitForRequestStepNumber));
+
       const anna::DataBlock &request = tsw->getMsgDataBlock();
       anna::diameter::HopByHop hbh = anna::diameter::codec::functions::getHopByHop(request);
       anna::diameter::EndToEnd ete = anna::diameter::codec::functions::getEndToEnd(request);
+
       // Update sequence:
       anna::diameter::codec::functions::setHopByHop(a_message, hbh);
       anna::diameter::codec::functions::setEndToEnd(a_message, ete);
@@ -373,6 +373,7 @@ bool TestStepSendxml::do_execute() throw() {
       // Check Session-Id for warning ...
       std::string sessionIdAnswer = anna::diameter::helpers::base::functions::getSessionId(a_message);
       std::string sessionIdRequest = anna::diameter::helpers::base::functions::getSessionId(request);
+
       if (sessionIdRequest != sessionIdAnswer) {
         s_warn = anna::functions::asString("Sending an answer which Session-Id (%s) is different than supposed corresponding request (%s)", sessionIdAnswer.c_str(), sessionIdRequest.c_str());
         LOGWARNING(anna::Logger::warning(s_warn, ANNA_FILE_LOCATION));
@@ -569,6 +570,8 @@ throw() {
 
   if (msg != "") result->createAttribute("MatchedMessage", msg);
   if (xmlmsg != "") result->createAttribute("MatchedXMLMessage", xmlmsg);
+  if (a_clientSession) result->createAttribute("ClientSessionOrigin", anna::functions::asString("%p", a_clientSession));
+  if (a_serverSession) result->createAttribute("ServerSessionOrigin", anna::functions::asString("%p", a_serverSession));
 
   return result;
 }