ebded3252b28a8d920b1418a87c70072e5e916e8
[anna.git] / example / diameter / launcher / testing / TestStep.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 example_diameter_launcher_TestStep_hpp
10 #define example_diameter_launcher_TestStep_hpp
11
12 // Standard
13 #include <string>
14 #include <vector>
15 #include <thread>
16
17 // Project
18 #include <anna/core/DataBlock.hpp>
19 #include <anna/xml/Node.hpp>
20 #include <anna/diameter/codec/Message.hpp>
21
22 // Process
23 #include <TestCondition.hpp>
24
25
26
27
28 namespace anna {
29   class Millisecond;
30
31   namespace xml {
32     class Node;
33   }
34   namespace diameter {
35     namespace codec {
36       class Message;
37     }
38     namespace comm {
39       class ClientSession;
40       class ServerSession;
41     }
42   }
43 }
44
45 class TestCase;
46 class TestTimer;
47 class OriginHost;
48
49 class TestStep {
50
51     int a_number; // step number used for xml (informational)
52     anna::Millisecond a_beginTimestamp; // unix time
53     anna::Millisecond a_endTimestamp; // unix time
54     bool a_executed; // used for interactive mode in order to not repeat a execution step if before completing, the user add interactive amount
55
56     void setBeginTimestamp(const anna::Millisecond &t) throw() { a_beginTimestamp = t; }
57     const anna::Millisecond &getBeginTimestamp() const throw() { return a_beginTimestamp; }
58     void setEndTimestamp(const anna::Millisecond &t) throw() { a_endTimestamp = t; }
59     const anna::Millisecond &getEndTimestamp() const throw() { return a_endTimestamp; }
60
61     void initialize(TestCase *testCase);
62
63   public:
64     struct Type { enum _v { Unconfigured, Timeout, Sendxml2e, Sendxml2c, Delay, Wait, Cmd }; };
65     static const char* asText(const Type::_v type) throw();
66
67     TestStep(TestCase *testCase) : a_message(true), a_messageCodec(NULL), a_executed(false) { initialize(testCase); }
68     virtual ~TestStep() {;}
69
70     // setter & getters
71     const Type::_v &getType() const throw() { return a_type; }
72     const int &getNumber() const throw() { return a_number; }
73     bool isCompleted() const throw() { return a_completed; }
74
75     bool execute() throw();
76     void complete() throw();
77     void reset() throw();
78     void next() throw();
79     virtual anna::xml::Node* asXML(anna::xml::Node* parent) throw();
80     std::string asXMLString() throw();
81
82   protected:
83     TestCase *a_testCase;
84     bool a_completed;
85     Type::_v a_type;
86
87     // Message (not for all step types)
88     anna::DataBlock a_message;
89     anna::diameter::codec::Message *a_messageCodec; // used as helper and for traffic logs
90     bool decodeMessage() throw();
91
92     virtual bool do_execute() throw() = 0; // returns true if next step must be executed
93     virtual void do_complete() throw() = 0; // end of transaction (delay/timeout expired, wait condition fulfilled, sending done)
94                                             // In all cases, the next step will be executed except 'timeout' which is asynchronous
95                                             //  and will move to the next step just after timer creation (no complete waited)
96     virtual void do_reset() throw() = 0;
97 };
98
99
100 class TestStepTimeout : public TestStep {
101
102     anna::Millisecond a_timeout;
103     TestTimer *a_timer; // just in case i would need to cancel
104
105   public:
106     TestStepTimeout(TestCase *testCase) : TestStep(testCase), a_timeout(0), a_timer(NULL) { a_type = Type::Timeout; }
107
108     // setter & getters
109     void setTimeout(const anna::Millisecond &t) throw() { a_timeout = t; }
110     const anna::Millisecond &getTimeout() const throw() { return a_timeout; }
111
112     // virtuals
113     bool do_execute() throw();
114     void do_complete() throw(); // timeout reached, test case failed
115     void do_reset() throw();
116     anna::xml::Node* asXML(anna::xml::Node* parent) throw();
117 };
118
119
120 class TestStepSendxml : public TestStep {
121
122   protected:
123     // possible end points:
124     OriginHost *a_originHost;
125
126     // Step number reference ('wait for request' step)
127     int a_waitForRequestStepNumber;
128
129     // Expired ?
130     bool a_expired; // a_endTimestamp will be the expiration reception timestamp
131
132   public:
133     TestStepSendxml(TestCase *testCase) : TestStep(testCase),
134       a_expired(false),
135       a_originHost(NULL),
136       a_waitForRequestStepNumber(-1) {;}
137     ~TestStepSendxml() {;}
138
139     // setter & getters
140     void setOriginHost(OriginHost *host) throw() { a_originHost = host; }
141     OriginHost *getOriginHost() const throw() { return a_originHost; }
142     void setWaitForRequestStepNumber(int stepNumber) throw() { a_waitForRequestStepNumber = stepNumber; }
143     int getWaitForRequestStepNumber() const throw() { return a_waitForRequestStepNumber; }
144     void setMsgDataBlock(const anna::DataBlock &db) throw() { a_message = db; }
145     const anna::DataBlock &getMsgDataBlock() const throw() { return a_message; }
146
147     // virtuals
148     bool do_execute() throw();
149     void do_complete() throw() {;}
150     void do_reset() throw();
151     anna::xml::Node* asXML(anna::xml::Node* parent) throw();
152 };
153
154 class TestStepSendxml2e : public TestStepSendxml {
155   public:
156     TestStepSendxml2e(TestCase *testCase) : TestStepSendxml(testCase) { a_type = Type::Sendxml2e; }
157 };
158
159 class TestStepSendxml2c : public TestStepSendxml {
160   public:
161     TestStepSendxml2c(TestCase *testCase) : TestStepSendxml(testCase) { a_type = Type::Sendxml2c; }
162 };
163
164
165 class TestStepDelay : public TestStep {
166     anna::Millisecond a_delay;
167     TestTimer *a_timer; // just in case i would need to cancel
168
169   public:
170     TestStepDelay(TestCase *testCase) : TestStep(testCase), a_delay(0), a_timer(NULL) { a_type = Type::Delay; }
171
172     // setter & getters
173     void setDelay(const anna::Millisecond &d) throw() { a_delay = d; }
174     const anna::Millisecond &getDelay() const throw() { return a_delay; }
175
176     // virtuals
177     bool do_execute() throw();
178     void do_complete() throw(); // delay reached
179     void do_reset() throw();
180     anna::xml::Node* asXML(anna::xml::Node* parent) throw();
181 };
182
183
184 class TestStepWait : public TestStep {
185
186     TestCondition a_condition;
187     anna::diameter::comm::ClientSession *a_clientSession;
188     anna::diameter::comm::ServerSession *a_serverSession;
189
190   public:
191     TestStepWait(TestCase *testCase) : TestStep(testCase) {
192       a_type = Type::Wait;
193       a_clientSession = NULL;
194       a_serverSession = NULL;
195     }
196     ~TestStepWait() {;}
197
198     // setter & getters
199     void setCondition(bool fromEntity,
200                         const std::string &code, const std::string &bitR, const std::string &hopByHop, const std::string &applicationId,
201                         const std::string &sessionId, const std::string &resultCode,
202                         const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) throw();
203     void setCondition(bool fromEntity, const std::string &regexp) throw();
204
205     void setClientSession(anna::diameter::comm::ClientSession *cs) throw() { a_clientSession = cs; }
206     void setServerSession(anna::diameter::comm::ServerSession *ss) throw() { a_serverSession = ss; }
207     anna::diameter::comm::ClientSession *getClientSession() const throw() { return a_clientSession; }
208     anna::diameter::comm::ServerSession *getServerSession() const throw() { return a_serverSession; }
209
210     const TestCondition &getCondition() const throw() { return a_condition; }
211     //void setMsgDataBlock(const anna::DataBlock &db) throw() { a_message = db; }
212     bool fulfilled(const anna::DataBlock &db/*, bool matchSessionId = true*/) throw();
213     const anna::DataBlock &getMsgDataBlock() const throw() { return a_message; }
214
215
216     // virtuals
217     bool do_execute() throw(); // this will be executed when test case starts (at least we could measure the time until condition is fulfilled)
218     void do_complete() throw(); // condition fulfilled
219     void do_reset() throw();
220     anna::xml::Node* asXML(anna::xml::Node* parent) throw();
221 };
222
223
224 class TestStepCmd : public TestStep {
225
226   std::string a_script;
227   std::thread a_thread;
228   bool a_threadRunning;
229   bool a_threadDeprecated;
230   int a_resultCode;
231   std::string a_errorMsg;
232   //std::string a_output; // for POPEN
233
234   pid_t a_childPid;
235
236   public:
237     TestStepCmd(TestCase *testCase) : TestStep(testCase), a_threadRunning(false), a_threadDeprecated(false), a_resultCode(-2)/*, a_output("")*/, a_errorMsg(""), a_childPid(-1) { a_type = Type::Cmd; }
238
239     // setter & getters
240     void setThreadRunning(bool running) throw() { a_threadRunning = running; }
241
242     void setResultCode(int rc) throw() { a_resultCode = rc; }
243     int getResultCode() const throw() { return a_resultCode; }
244     void setErrorMsg(const std::string &em) throw() { a_errorMsg = em; }
245     const std::string &getErrorMsg() const throw() { return a_errorMsg; }
246     //void appendOutput(const std::string &output) throw() { a_output += output; }
247     //const std::string &getOutput() const throw() { return a_output; }
248     void setChildPid(pid_t pid) throw() { a_childPid = pid; }
249     const pid_t &getChildPid() const throw() { return a_childPid; }
250
251     void setScript(const std::string &script) throw() { a_script = script; }
252     const std::string &getScript() const throw() { return a_script; }
253
254     // virtuals
255     bool do_execute() throw();
256     void do_complete() throw();
257     void do_reset() throw();
258     anna::xml::Node* asXML(anna::xml::Node* parent) throw();
259 };
260
261
262 #endif