System test feature
[anna.git] / example / diameter / launcher / testing / TestCase.hpp
diff --git a/example/diameter/launcher/testing/TestCase.hpp b/example/diameter/launcher/testing/TestCase.hpp
new file mode 100644 (file)
index 0000000..a3c48f0
--- /dev/null
@@ -0,0 +1,119 @@
+// ANNA - Anna is Not Nothingness Anymore                                                         //
+//                                                                                                //
+// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
+//                                                                                                //
+// See project site at http://redmine.teslayout.com/projects/anna-suite                           //
+// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
+
+
+#ifndef example_diameter_launcher_TestCase_hpp
+#define example_diameter_launcher_TestCase_hpp
+
+// Standard
+#include <string>
+#include <vector>
+
+// Project
+#include <anna/core/DataBlock.hpp>
+#include <anna/xml/Node.hpp>
+#include <anna/diameter/defines.hpp>
+
+// Process
+#include <TestStep.hpp>
+
+
+namespace anna {
+  class Millisecond;
+
+  namespace xml {
+    class Node;
+  }
+}
+
+class RealmNode;
+
+
+class TestCase {
+
+  void assertInitialized() const throw(anna::RuntimeException);
+  void assertMessage(const anna::DataBlock &db, bool toEntity) throw(anna::RuntimeException);
+
+public:
+
+  // Debug summary:
+  class DebugSummary {
+
+    typedef struct {
+      anna::Millisecond Timestamp;
+      std::string Hint;
+    } event_t;
+
+    std::vector<event_t> a_events;
+  public:
+    void addHint(const std::string &hint) throw();
+    void clear() throw();
+    int events() const throw() { return a_events.size(); }
+    anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+  };
+
+  TestCase(unsigned int id) : a_id(id), a_state(State::Initialized), a_startTime(0) { /*a_stepsIt = a_steps.end()*/;}
+  ~TestCase();
+
+  struct State { enum _v { Initialized, InProgress, Failed, Success }; };
+  static const char* asText(const State::_v state) throw();
+  const State::_v &getState() const throw() { return a_state; }
+  const anna::Millisecond &getStartTimestamp() const throw() { return a_startTime; }
+  void addDebugSummaryHint(const std::string &hint) throw() { a_debugSummary.addHint(hint); }
+  void setState(const State::_v &state) throw();
+  bool isFinished() const throw() { return (getState() == State::Failed || getState() == State::Success); }
+  bool inProgress() const throw() { return (getState() == State::InProgress); }
+  bool hasSameCondition(const TestCondition &condition) const throw();
+
+  // Step type & information
+  void addTimeout(const anna::Millisecond &timeout) throw(anna::RuntimeException);
+  void addSendxml2e(const anna::DataBlock &db, RealmNode *realm, int stepNumber) throw(anna::RuntimeException);
+  void addSendxml2c(const anna::DataBlock &db, RealmNode *realm, int stepNumber) throw(anna::RuntimeException);
+  void addDelay(const anna::Millisecond &delay) throw(anna::RuntimeException);
+  void addWait(bool fromEntity,
+                const std::string &code, const std::string &bitR, const std::string &resultCode, const std::string &sessionId,
+                const std::string &hopByHop, const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) throw(anna::RuntimeException);
+  void addWaitAnswer(bool fromEntity, int stepNumber) throw(anna::RuntimeException);
+  void addWaitRegexp(bool fromEntity, const std::string &regexp) throw(anna::RuntimeException);
+
+  // Process:
+  void nextStep() throw() { a_stepsIt++; }
+  bool done() throw();
+  bool process() throw(); // false to stop
+
+  // Reset test case and underlaying information (steps context)
+  bool reset(bool hard /* hard reset includes in-progress test cases */) throw();
+
+  // getters
+  const anna::Millisecond &getStartTime() const throw() { return a_startTime; }
+  const unsigned int &getId() const throw() { return a_id; }
+
+  //helpers
+  int steps() const throw() { return a_steps.size(); }
+  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.
+  const TestStep *getStep(int stepNumber) const throw();
+
+  anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+  std::string asXMLString() const throw();
+
+
+private:
+  // private members:
+  unsigned int a_id;
+  std::vector<TestStep*> a_steps;
+  std::vector<TestStep*>::const_iterator a_stepsIt;
+  std::map<anna::diameter::HopByHop, TestStep*> a_hopByHops; // for wait-answer
+  State::_v a_state;
+  anna::Millisecond a_startTime;
+  DebugSummary a_debugSummary; // used when a test case has failed, uncovered message conditions, and any other hint.
+
+  friend class TestStep;
+};
+
+#endif