d17a9f86a3eb6127298bc8a0b2dae55be5f8847e
[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/core/DataBlock.hpp>
19 #include <anna/core/util/Millisecond.hpp>
20
21 // Diameter-specific
22 #include <anna/diameter/defines.hpp>
23 #include <anna/testing/TestDiameterCondition.hpp>
24
25
26 namespace anna {
27   class Millisecond;
28
29   namespace xml {
30     class Node;
31   }
32   namespace diameter {
33     namespace comm {
34       class OriginHost;
35     }
36   }
37
38 namespace testing {
39
40   class TestStep;
41   class TestStepWaitDiameter;
42 class TestCase {
43
44   void assertInitialized() const noexcept(false);
45   std::string assertMessage(const anna::DataBlock &db, bool toEntity) noexcept(false);
46
47 public:
48
49   // Debug summary:
50   class DebugSummary {
51
52     typedef struct {
53       anna::Millisecond Timestamp;
54       std::string Hint;
55     } event_t;
56
57     std::vector<event_t> a_events;
58   public:
59     void addHint(const std::string &hint) ;
60     void clear() ;
61     int events() const { return a_events.size(); }
62     anna::xml::Node* asXML(anna::xml::Node* parent) const ;
63     std::string asString() const ;
64   };
65
66   TestCase(unsigned int id, const std::string &description = "");
67   ~TestCase();
68
69   struct State { enum _v { Initialized, InProgress, Failed, Success }; };
70   static const char* asText(const State::_v state) ;
71   const State::_v &getState() const { return a_state; }
72   const anna::Millisecond &getStartTimestamp() const { return a_startTimestamp; }
73   const anna::Millisecond &getFinishTimestamp() const { return a_finishTimestamp; }
74   anna::Millisecond getLapseMs() const ;
75   anna::Millisecond getProcessingTimeMs() const ;
76   void addDebugSummaryHint(const std::string &hint) { a_debugSummary.addHint(hint); }
77   void setState(const State::_v &state) ;
78   bool isFinished() const { return (getState() == State::Failed || getState() == State::Success); }
79   bool inProgress() const { return (getState() == State::InProgress); }
80   bool isFailed() const { return (getState() == State::Failed); }
81   bool isSuccess() const { return (getState() == State::Success); }
82   bool hasSameCondition(const TestDiameterCondition &condition) const ;
83   const DebugSummary & getDebugSummary() const { return a_debugSummary; }
84
85   // Interactivity:
86   void makeInteractive(bool yes = true) { a_interactiveAmount = (yes ? 0:-1); }
87   void addInteractiveAmount(unsigned int amount) {
88     if (a_interactiveAmount == -1) makeInteractive();
89     if (amount == 0) return;
90     a_interactiveAmount += amount;
91     process();
92   }
93   int interactiveAmount() const { return a_interactiveAmount; }
94   void interactiveExecution() { a_interactiveAmount --; }
95
96   // Step type & information
97   void addTimeout(const anna::Millisecond &timeout) noexcept(false);
98   void addDelay(const anna::Millisecond &delay) noexcept(false);
99   void addWaitDiameter(bool fromEntity,
100                 const std::string &code, const std::string &bitR, const std::string &hopByHop, const std::string &applicationId,
101                 const std::string &sessionId, const std::string &resultCode,
102                 const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) noexcept(false);
103   void addCommand(const std::string &cmd) noexcept(false);
104   void addIpLimit(unsigned int ipLimit) noexcept(false);
105
106   // Diameter-specifc
107   void addSendDiameterXml2e(const anna::DataBlock &db, anna::diameter::comm::OriginHost *host, int stepNumber) noexcept(false);
108   void addSendDiameterXml2c(const anna::DataBlock &db, anna::diameter::comm::OriginHost *host, int stepNumber) noexcept(false);
109   void addWaitDiameterAnswer(bool fromEntity, int stepNumber) noexcept(false);
110   void addWaitDiameterRegexpHex(bool fromEntity, const std::string &regexp) noexcept(false);
111   void addWaitDiameterRegexpXml(bool fromEntity, const std::string &regexp) noexcept(false);
112
113
114   // Process:
115   void nextStep() { a_stepsIt++; }
116   bool done() ;
117   bool process() ; // false to stop
118
119   // Reset test case and underlaying information (steps context)
120   bool reset(bool hard /* hard reset includes in-progress test cases */) ;
121
122   // Check for clear (destroy steps)
123   bool safeToClear(); // false if something pending (running threads steps)
124
125   // getters
126   const unsigned int &getId() const { return a_id; }
127   const std::string &getKey() const { return a_key; }
128   const std::string &getDescription() const { return a_description; }
129
130   // setters
131   void setDescription(const std::string &description) { a_description = description; }
132
133   //helpers
134   int steps() const { return a_steps.size(); }
135   void addStep(TestStep *step) { a_steps.push_back(step); }
136
137   TestStepWaitDiameter *searchNextWaitConditionFulfilled(const anna::DataBlock &message, bool waitFromEntity) ;
138       // When a message arrives, we identify the test case by mean the Session-Id. Then, from the current step iterator (included),
139       //  we search for a fulfilling condition for that message. The first found, is 'completed' and then breaks the search.
140   const TestStep *getStep(int stepNumber) const ;
141
142   anna::xml::Node* asXML(anna::xml::Node* parent) const ;
143   std::string asXMLString() const ;
144
145
146 private:
147   // private members:
148   unsigned int a_id;
149   std::string a_key;
150   std::string a_description;
151   std::vector<TestStep*> a_steps;
152   std::vector<TestStep*>::const_iterator a_stepsIt;
153   std::map<anna::diameter::HopByHop, TestStep*> a_hopByHops; // for wait-answer
154   State::_v a_state;
155   anna::Millisecond a_startTimestamp;
156   anna::Millisecond a_finishTimestamp;
157   DebugSummary a_debugSummary; // used when a test case has failed, uncovered message conditions, and any other hint.
158   int a_interactiveAmount;
159
160   friend class TestStep;
161 };
162
163 }
164 }
165
166 #endif