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
19 #include <anna/core/DataBlock.hpp>
20 #include <anna/testing/TestDiameterCondition.hpp>
21 #include <anna/core/util/Millisecond.hpp>
48 int a_number; // step number used for xml (informational)
49 anna::Millisecond a_beginTimestamp; // unix time
50 anna::Millisecond a_endTimestamp; // unix time
51 bool a_executed; // used for interactive mode in order to not repeat a execution step if before completing, the user add interactive amount
53 void setBeginTimestamp(const anna::Millisecond &t) { a_beginTimestamp = t; }
54 const anna::Millisecond &getBeginTimestamp() const { return a_beginTimestamp; }
55 void setEndTimestamp(const anna::Millisecond &t) { a_endTimestamp = t; }
56 const anna::Millisecond &getEndTimestamp() const { return a_endTimestamp; }
58 void initialize(TestCase *testCase);
61 struct Type { enum _v { Unconfigured, Timeout, Sendxml2e, Sendxml2c, Delay, Wait, Cmd, IpLimit }; };
62 static const char* asText(const Type::_v type) ;
64 TestStep(TestCase *testCase) : a_message(true), a_messageCodec(NULL), a_executed(false) { initialize(testCase); }
65 virtual ~TestStep() {;}
68 const Type::_v &getType() const { return a_type; }
69 const int &getNumber() const { return a_number; }
70 bool isCompleted() const { return a_completed; }
71 anna::Millisecond getLapseMs() const { return a_endTimestamp - a_beginTimestamp; }
77 virtual anna::xml::Node* asXML(anna::xml::Node* parent) ;
78 std::string asXMLString() ;
85 // Message (not for all step types)
86 anna::DataBlock a_message;
87 anna::diameter::codec::Message *a_messageCodec; // used as helper and for traffic logs
88 bool decodeMessage(bool trust = false) ; // If trust=true: decoding the previously encoded message (sendxml sentences).
89 // The only error would be validation ones, and we are going to ignore them here.
91 virtual bool do_execute() = 0; // returns true if next step must be executed
92 virtual void do_complete() = 0; // end of transaction (delay/timeout expired, wait condition fulfilled, sending done)
93 // In all cases, the next step will be executed except 'timeout' which is asynchronous
94 // and will move to the next step just after timer creation (no complete waited)
95 virtual void do_reset() = 0;
99 class TestStepTimeout : public TestStep {
101 anna::Millisecond a_timeout;
102 TestTimer *a_timer; // just in case i would need to cancel
105 TestStepTimeout(TestCase *testCase) : TestStep(testCase), a_timeout(0), a_timer(NULL) { a_type = Type::Timeout; }
106 ~TestStepTimeout() { do_reset(); }
109 void setTimeout(const anna::Millisecond &t) { a_timeout = t; }
110 const anna::Millisecond &getTimeout() const { return a_timeout; }
114 void do_complete() ; // timeout reached, test case failed
117 anna::xml::Node* asXML(anna::xml::Node* parent) ;
121 class TestStepSendDiameterXml : public TestStep {
124 // possible end points:
125 anna::diameter::comm::OriginHost *a_originHost;
127 // Step number reference ('wait for request' step)
128 int a_waitForRequestStepNumber;
131 bool a_expired; // a_endTimestamp will be the expiration reception timestamp
134 TestStepSendDiameterXml(TestCase *testCase) : TestStep(testCase),
137 a_waitForRequestStepNumber(-1) {;}
138 ~TestStepSendDiameterXml() { do_reset(); }
141 void setOriginHost(anna::diameter::comm::OriginHost *host) { a_originHost = host; }
142 anna::diameter::comm::OriginHost *getOriginHost() const { return a_originHost; }
143 void setWaitForRequestStepNumber(int stepNumber) { a_waitForRequestStepNumber = stepNumber; }
144 int getWaitForRequestStepNumber() const { return a_waitForRequestStepNumber; }
145 void setMsgDataBlock(const anna::DataBlock &db) { a_message = db; }
146 const anna::DataBlock &getMsgDataBlock() const { return a_message; }
150 void do_complete() {;}
152 anna::xml::Node* asXML(anna::xml::Node* parent) ;
155 class TestStepSendDiameterXml2e : public TestStepSendDiameterXml {
157 TestStepSendDiameterXml2e(TestCase *testCase) : TestStepSendDiameterXml(testCase) { a_type = Type::Sendxml2e; }
160 class TestStepSendDiameterXml2c : public TestStepSendDiameterXml {
162 TestStepSendDiameterXml2c(TestCase *testCase) : TestStepSendDiameterXml(testCase) { a_type = Type::Sendxml2c; }
166 class TestStepDelay : public TestStep {
167 anna::Millisecond a_delay;
168 TestTimer *a_timer; // just in case i would need to cancel
171 TestStepDelay(TestCase *testCase) : TestStep(testCase), a_delay(0), a_timer(NULL) { a_type = Type::Delay; }
172 ~TestStepDelay() { do_reset(); }
175 void setDelay(const anna::Millisecond &d) { a_delay = d; }
176 const anna::Millisecond &getDelay() const { return a_delay; }
180 void do_complete() ; // delay reached
183 anna::xml::Node* asXML(anna::xml::Node* parent) ;
187 class TestStepWaitDiameter : public TestStep {
189 TestDiameterCondition a_condition;
190 anna::diameter::comm::ClientSession *a_clientSession;
191 anna::diameter::comm::ServerSession *a_serverSession;
194 TestStepWaitDiameter(TestCase *testCase) : TestStep(testCase) {
196 a_clientSession = NULL;
197 a_serverSession = NULL;
199 ~TestStepWaitDiameter() { do_reset(); }
202 void setCondition(bool fromEntity,
203 const std::string &code, const std::string &bitR, const std::string &hopByHop, const std::string &applicationId,
204 const std::string &sessionId, const std::string &resultCode,
205 const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) ;
206 void setConditionRegexpXml(bool fromEntity, const std::string ®exp) ;
207 void setConditionRegexpHex(bool fromEntity, const std::string ®exp) ;
209 void setClientSession(anna::diameter::comm::ClientSession *cs) { a_clientSession = cs; }
210 void setServerSession(anna::diameter::comm::ServerSession *ss) { a_serverSession = ss; }
211 anna::diameter::comm::ClientSession *getClientSession() const { return a_clientSession; }
212 anna::diameter::comm::ServerSession *getServerSession() const { return a_serverSession; }
214 const TestDiameterCondition &getCondition() const { return a_condition; }
215 //void setMsgDataBlock(const anna::DataBlock &db) { a_message = db; }
216 bool fulfilled(const anna::DataBlock &db/*, bool matchSessionId = true*/) ;
217 const anna::DataBlock &getMsgDataBlock() const { return a_message; }
221 bool do_execute() ; // this will be executed when test case starts (at least we could measure the time until condition is fulfilled)
222 void do_complete() ; // condition fulfilled
224 anna::xml::Node* asXML(anna::xml::Node* parent) ;
228 class TestStepCmd : public TestStep {
230 std::string a_script;
231 std::thread a_thread;
232 std::atomic<bool> a_threadRunning;
233 bool a_threadDeprecated;
235 std::string a_errorMsg;
236 //std::string a_output; // for POPEN
241 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; }
242 ~TestStepCmd() { do_reset(); }
245 void setThreadRunning() { a_threadRunning = true; }
246 void setThreadNotRunning() { a_threadRunning = false; }
247 bool threadRunning() const { return a_threadRunning; }
248 bool threadNotRunning() const { return !a_threadRunning; }
250 void setResultCode(int rc) { a_resultCode = rc; }
251 int getResultCode() const { return a_resultCode; }
252 void setErrorMsg(const std::string &em) { a_errorMsg = em; }
253 const std::string &getErrorMsg() const { return a_errorMsg; }
254 //void appendOutput(const std::string &output) { a_output += output; }
255 //const std::string &getOutput() const { return a_output; }
256 void setChildPid(pid_t pid) { a_childPid = pid; }
257 const pid_t &getChildPid() const { return a_childPid; }
259 void setScript(const std::string &script) { a_script = script; }
260 const std::string &getScript() const { return a_script; }
266 anna::xml::Node* asXML(anna::xml::Node* parent) ;
270 class TestStepIpLimit : public TestStep {
272 unsigned int a_ipLimit;
275 TestStepIpLimit(TestCase *testCase) : TestStep(testCase), a_ipLimit(1) { a_type = Type::IpLimit; }
276 ~TestStepIpLimit() { do_reset(); }
279 void setIpLimit(unsigned int limit) { a_ipLimit = limit; }
280 unsigned int getIpLimit() const { return a_ipLimit; }
286 anna::xml::Node* asXML(anna::xml::Node* parent) ;