acd3a54e6cbe0409939b417a9782e817fc16afc8
[anna.git] / include / anna / testing / TestCase.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_testing_TestCase_hpp
10 #define anna_testing_TestCase_hpp
11
12 // Standard
13 #include <string>
14 #include <vector>
15 #include <map>
16
17 // Project
18 #include <anna/diameter/defines.hpp>
19 #include <anna/core/DataBlock.hpp>
20 #include <anna/core/util/Millisecond.hpp>
21 #include <anna/testing/TestCondition.hpp>
22
23
24
25 namespace anna {
26   class Millisecond;
27
28   namespace xml {
29     class Node;
30   }
31   namespace diameter {
32     namespace comm {
33       class OriginHost;
34     }
35   }
36
37 namespace testing {
38
39   class TestStep;
40   class TestStepWait;
41 class TestCase {
42
43   void assertInitialized() const throw(anna::RuntimeException);
44   void assertMessage(const anna::DataBlock &db, bool toEntity) throw(anna::RuntimeException);
45
46 public:
47
48   // Debug summary:
49   class DebugSummary {
50
51     typedef struct {
52       anna::Millisecond Timestamp;
53       std::string Hint;
54     } event_t;
55
56     std::vector<event_t> a_events;
57   public:
58     void addHint(const std::string &hint) throw();
59     void clear() throw();
60     int events() const throw() { return a_events.size(); }
61     anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
62   };
63
64   TestCase(unsigned int id);
65   ~TestCase();
66
67   struct State { enum _v { Initialized, InProgress, Failed, Success }; };
68   static const char* asText(const State::_v state) throw();
69   const State::_v &getState() const throw() { return a_state; }
70   const anna::Millisecond &getStartTimestamp() const throw() { return a_startTime; }
71   void addDebugSummaryHint(const std::string &hint) throw() { a_debugSummary.addHint(hint); }
72   void setState(const State::_v &state) throw();
73   bool isFinished() const throw() { return (getState() == State::Failed || getState() == State::Success); }
74   bool inProgress() const throw() { return (getState() == State::InProgress); }
75   bool hasSameCondition(const TestCondition &condition) const throw();
76
77   // Interactivity:
78   void makeInteractive(bool yes = true) throw() { a_interactiveAmount = (yes ? 0:-1); }
79   void addInteractiveAmount(unsigned int amount) throw() {
80     if (a_interactiveAmount == -1) makeInteractive();
81     if (amount == 0) return;
82     a_interactiveAmount += amount;
83     process();
84   }
85   int interactiveAmount() const throw() { return a_interactiveAmount; }
86   void interactiveExecution() throw() { a_interactiveAmount --; }
87
88   // Step type & information
89   void addTimeout(const anna::Millisecond &timeout) throw(anna::RuntimeException);
90   void addSendxml2e(const anna::DataBlock &db, anna::diameter::comm::OriginHost *host, int stepNumber) throw(anna::RuntimeException);
91   void addSendxml2c(const anna::DataBlock &db, anna::diameter::comm::OriginHost *host, int stepNumber) throw(anna::RuntimeException);
92   void addDelay(const anna::Millisecond &delay) throw(anna::RuntimeException);
93   void addWait(bool fromEntity,
94                 const std::string &code, const std::string &bitR, const std::string &hopByHop, const std::string &applicationId,
95                 const std::string &sessionId, const std::string &resultCode,
96                 const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) throw(anna::RuntimeException);
97   void addWaitAnswer(bool fromEntity, int stepNumber) throw(anna::RuntimeException);
98   void addWaitRegexpHex(bool fromEntity, const std::string &regexp) throw(anna::RuntimeException);
99   void addWaitRegexpXml(bool fromEntity, const std::string &regexp) throw(anna::RuntimeException);
100   void addCommand(const std::string &cmd) throw(anna::RuntimeException);
101
102
103   // Process:
104   void nextStep() throw() { a_stepsIt++; }
105   bool done() throw();
106   bool process() throw(); // false to stop
107
108   // Reset test case and underlaying information (steps context)
109   bool reset(bool hard /* hard reset includes in-progress test cases */) throw();
110
111   // getters
112   const anna::Millisecond &getStartTime() const throw() { return a_startTime; }
113   const unsigned int &getId() const throw() { return a_id; }
114
115   //helpers
116   int steps() const throw() { return a_steps.size(); }
117   void addStep(TestStep *step) throw() { a_steps.push_back(step); }
118
119   TestStepWait *searchNextWaitConditionFulfilled(const anna::DataBlock &message, bool waitFromEntity) throw();
120       // When a message arrives, we identify the test case by mean the Session-Id. Then, from the current step iterator (included),
121       //  we search for a fulfilling condition for that message. The first found, is 'completed' and then breaks the search.
122   const TestStep *getStep(int stepNumber) const throw();
123
124   anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
125   std::string asXMLString() const throw();
126
127
128 private:
129   // private members:
130   unsigned int a_id;
131   std::vector<TestStep*> a_steps;
132   std::vector<TestStep*>::const_iterator a_stepsIt;
133   std::map<anna::diameter::HopByHop, TestStep*> a_hopByHops; // for wait-answer
134   State::_v a_state;
135   anna::Millisecond a_startTime;
136   DebugSummary a_debugSummary; // used when a test case has failed, uncovered message conditions, and any other hint.
137   int a_interactiveAmount;
138
139   friend class TestStep;
140 };
141
142 }
143 }
144
145 #endif