+// 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 ®exp) 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