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