1 // ANNA - Anna is Not Nothingness Anymore //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo //
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 //
9 #ifndef anna_testing_TestStep_hpp
10 #define anna_testing_TestStep_hpp
18 #include <anna/core/DataBlock.hpp>
19 #include <anna/testing/TestCondition.hpp>
20 #include <anna/core/util/Millisecond.hpp>
47 int a_number; // step number used for xml (informational)
48 anna::Millisecond a_beginTimestamp; // unix time
49 anna::Millisecond a_endTimestamp; // unix time
50 bool a_executed; // used for interactive mode in order to not repeat a execution step if before completing, the user add interactive amount
52 void setBeginTimestamp(const anna::Millisecond &t) throw() { a_beginTimestamp = t; }
53 const anna::Millisecond &getBeginTimestamp() const throw() { return a_beginTimestamp; }
54 void setEndTimestamp(const anna::Millisecond &t) throw() { a_endTimestamp = t; }
55 const anna::Millisecond &getEndTimestamp() const throw() { return a_endTimestamp; }
57 void initialize(TestCase *testCase);
60 struct Type { enum _v { Unconfigured, Timeout, Sendxml2e, Sendxml2c, Delay, Wait, Cmd }; };
61 static const char* asText(const Type::_v type) throw();
63 TestStep(TestCase *testCase) : a_message(true), a_messageCodec(NULL), a_executed(false) { initialize(testCase); }
64 virtual ~TestStep() {;}
67 const Type::_v &getType() const throw() { return a_type; }
68 const int &getNumber() const throw() { return a_number; }
69 bool isCompleted() const throw() { return a_completed; }
71 bool execute() throw();
72 void complete() throw();
75 virtual anna::xml::Node* asXML(anna::xml::Node* parent) throw();
76 std::string asXMLString() throw();
83 // Message (not for all step types)
84 anna::DataBlock a_message;
85 anna::diameter::codec::Message *a_messageCodec; // used as helper and for traffic logs
86 bool decodeMessage(bool trust = false) throw(); // If trust=true: decoding the previously encoded message (sendxml sentences).
87 // The only error would be validation ones, and we are going to ignore them here.
89 virtual bool do_execute() throw() = 0; // returns true if next step must be executed
90 virtual void do_complete() throw() = 0; // end of transaction (delay/timeout expired, wait condition fulfilled, sending done)
91 // In all cases, the next step will be executed except 'timeout' which is asynchronous
92 // and will move to the next step just after timer creation (no complete waited)
93 virtual void do_reset() throw() = 0;
97 class TestStepTimeout : public TestStep {
99 anna::Millisecond a_timeout;
100 TestTimer *a_timer; // just in case i would need to cancel
103 TestStepTimeout(TestCase *testCase) : TestStep(testCase), a_timeout(0), a_timer(NULL) { a_type = Type::Timeout; }
106 void setTimeout(const anna::Millisecond &t) throw() { a_timeout = t; }
107 const anna::Millisecond &getTimeout() const throw() { return a_timeout; }
110 bool do_execute() throw();
111 void do_complete() throw(); // timeout reached, test case failed
112 void do_reset() throw();
113 anna::xml::Node* asXML(anna::xml::Node* parent) throw();
117 class TestStepSendxml : public TestStep {
120 // possible end points:
121 anna::diameter::comm::OriginHost *a_originHost;
123 // Step number reference ('wait for request' step)
124 int a_waitForRequestStepNumber;
127 bool a_expired; // a_endTimestamp will be the expiration reception timestamp
130 TestStepSendxml(TestCase *testCase) : TestStep(testCase),
133 a_waitForRequestStepNumber(-1) {;}
134 ~TestStepSendxml() {;}
137 void setOriginHost(anna::diameter::comm::OriginHost *host) throw() { a_originHost = host; }
138 anna::diameter::comm::OriginHost *getOriginHost() const throw() { return a_originHost; }
139 void setWaitForRequestStepNumber(int stepNumber) throw() { a_waitForRequestStepNumber = stepNumber; }
140 int getWaitForRequestStepNumber() const throw() { return a_waitForRequestStepNumber; }
141 void setMsgDataBlock(const anna::DataBlock &db) throw() { a_message = db; }
142 const anna::DataBlock &getMsgDataBlock() const throw() { return a_message; }
145 bool do_execute() throw();
146 void do_complete() throw() {;}
147 void do_reset() throw();
148 anna::xml::Node* asXML(anna::xml::Node* parent) throw();
151 class TestStepSendxml2e : public TestStepSendxml {
153 TestStepSendxml2e(TestCase *testCase) : TestStepSendxml(testCase) { a_type = Type::Sendxml2e; }
156 class TestStepSendxml2c : public TestStepSendxml {
158 TestStepSendxml2c(TestCase *testCase) : TestStepSendxml(testCase) { a_type = Type::Sendxml2c; }
162 class TestStepDelay : public TestStep {
163 anna::Millisecond a_delay;
164 TestTimer *a_timer; // just in case i would need to cancel
167 TestStepDelay(TestCase *testCase) : TestStep(testCase), a_delay(0), a_timer(NULL) { a_type = Type::Delay; }
170 void setDelay(const anna::Millisecond &d) throw() { a_delay = d; }
171 const anna::Millisecond &getDelay() const throw() { return a_delay; }
174 bool do_execute() throw();
175 void do_complete() throw(); // delay reached
176 void do_reset() throw();
177 anna::xml::Node* asXML(anna::xml::Node* parent) throw();
181 class TestStepWait : public TestStep {
183 TestCondition a_condition;
184 anna::diameter::comm::ClientSession *a_clientSession;
185 anna::diameter::comm::ServerSession *a_serverSession;
188 TestStepWait(TestCase *testCase) : TestStep(testCase) {
190 a_clientSession = NULL;
191 a_serverSession = NULL;
196 void setCondition(bool fromEntity,
197 const std::string &code, const std::string &bitR, const std::string &hopByHop, const std::string &applicationId,
198 const std::string &sessionId, const std::string &resultCode,
199 const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) throw();
200 void setConditionRegexpXml(bool fromEntity, const std::string ®exp) throw();
201 void setConditionRegexpHex(bool fromEntity, const std::string ®exp) throw();
203 void setClientSession(anna::diameter::comm::ClientSession *cs) throw() { a_clientSession = cs; }
204 void setServerSession(anna::diameter::comm::ServerSession *ss) throw() { a_serverSession = ss; }
205 anna::diameter::comm::ClientSession *getClientSession() const throw() { return a_clientSession; }
206 anna::diameter::comm::ServerSession *getServerSession() const throw() { return a_serverSession; }
208 const TestCondition &getCondition() const throw() { return a_condition; }
209 //void setMsgDataBlock(const anna::DataBlock &db) throw() { a_message = db; }
210 bool fulfilled(const anna::DataBlock &db/*, bool matchSessionId = true*/) throw();
211 const anna::DataBlock &getMsgDataBlock() const throw() { return a_message; }
215 bool do_execute() throw(); // this will be executed when test case starts (at least we could measure the time until condition is fulfilled)
216 void do_complete() throw(); // condition fulfilled
217 void do_reset() throw();
218 anna::xml::Node* asXML(anna::xml::Node* parent) throw();
222 class TestStepCmd : public TestStep {
224 std::string a_script;
225 std::thread a_thread;
226 bool a_threadRunning;
227 bool a_threadDeprecated;
229 std::string a_errorMsg;
230 //std::string a_output; // for POPEN
235 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 void setThreadRunning(bool running) throw() { a_threadRunning = running; }
240 void setResultCode(int rc) throw() { a_resultCode = rc; }
241 int getResultCode() const throw() { return a_resultCode; }
242 void setErrorMsg(const std::string &em) throw() { a_errorMsg = em; }
243 const std::string &getErrorMsg() const throw() { return a_errorMsg; }
244 //void appendOutput(const std::string &output) throw() { a_output += output; }
245 //const std::string &getOutput() const throw() { return a_output; }
246 void setChildPid(pid_t pid) throw() { a_childPid = pid; }
247 const pid_t &getChildPid() const throw() { return a_childPid; }
249 void setScript(const std::string &script) throw() { a_script = script; }
250 const std::string &getScript() const throw() { return a_script; }
253 bool do_execute() throw();
254 void do_complete() throw();
255 void do_reset() throw();
256 anna::xml::Node* asXML(anna::xml::Node* parent) throw();