Dynamic lib selection and deployment
[anna.git] / example / diameter / launcher / testing / TestStep.hpp
index 3473c54..75cbae3 100644 (file)
 // Standard
 #include <string>
 #include <vector>
+#include <thread>
 
 // Project
 #include <anna/core/DataBlock.hpp>
 #include <anna/xml/Node.hpp>
+#include <anna/diameter/codec/Message.hpp>
 
 // Process
 #include <TestCondition.hpp>
 
 
+
+
 namespace anna {
   class Millisecond;
 
@@ -28,6 +32,9 @@ namespace anna {
     class Node;
   }
   namespace diameter {
+    namespace codec {
+      class Message;
+    }
     namespace comm {
       class ClientSession;
       class ServerSession;
@@ -37,13 +44,14 @@ namespace anna {
 
 class TestCase;
 class TestTimer;
-class RealmNode;
+class OriginHost;
 
 class TestStep {
 
     int a_number; // step number used for xml (informational)
     anna::Millisecond a_beginTimestamp; // unix time
     anna::Millisecond a_endTimestamp; // unix time
+    bool a_executed; // used for interactive mode in order to not repeat a execution step if before completing, the user add interactive amount
 
     void setBeginTimestamp(const anna::Millisecond &t) throw() { a_beginTimestamp = t; }
     const anna::Millisecond &getBeginTimestamp() const throw() { return a_beginTimestamp; }
@@ -53,10 +61,10 @@ class TestStep {
     void initialize(TestCase *testCase);
 
   public:
-    struct Type { enum _v { Unconfigured, Timeout, Sendxml2e, Sendxml2c, Delay, Wait }; };
+    struct Type { enum _v { Unconfigured, Timeout, Sendxml2e, Sendxml2c, Delay, Wait, Cmd }; };
     static const char* asText(const Type::_v type) throw();
 
-    TestStep(TestCase *testCase) { initialize(testCase); }
+    TestStep(TestCase *testCase) : a_message(true), a_messageCodec(NULL), a_executed(false) { initialize(testCase); }
     virtual ~TestStep() {;}
 
     // setter & getters
@@ -68,14 +76,20 @@ class TestStep {
     void complete() throw();
     void reset() throw();
     void next() throw();
-    virtual anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
-    std::string asXMLString() const throw();
+    virtual anna::xml::Node* asXML(anna::xml::Node* parent) throw();
+    std::string asXMLString() throw();
 
   protected:
     TestCase *a_testCase;
     bool a_completed;
     Type::_v a_type;
 
+    // Message (not for all step types)
+    anna::DataBlock a_message;
+    anna::diameter::codec::Message *a_messageCodec; // used as helper and for traffic logs
+    bool decodeMessage(bool trust = false) throw(); // If trust=true: decoding the previously encoded message (sendxml sentences).
+                                                    // The only error would be validation ones, and we are going to ignore them here.
+
     virtual bool do_execute() throw() = 0; // returns true if next step must be executed
     virtual void do_complete() throw() = 0; // end of transaction (delay/timeout expired, wait condition fulfilled, sending done)
                                             // In all cases, the next step will be executed except 'timeout' which is asynchronous
@@ -100,7 +114,7 @@ class TestStepTimeout : public TestStep {
     bool do_execute() throw();
     void do_complete() throw(); // timeout reached, test case failed
     void do_reset() throw();
-    anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+    anna::xml::Node* asXML(anna::xml::Node* parent) throw();
 };
 
 
@@ -108,23 +122,24 @@ class TestStepSendxml : public TestStep {
 
   protected:
     // possible end points:
-    RealmNode *a_realmNode;
+    OriginHost *a_originHost;
 
     // Step number reference ('wait for request' step)
     int a_waitForRequestStepNumber;
 
-    // Message
-    anna::DataBlock a_message;
-
     // Expired ?
     bool a_expired; // a_endTimestamp will be the expiration reception timestamp
 
   public:
-    TestStepSendxml(TestCase *testCase) : TestStep(testCase), a_message(true), a_expired(false), a_realmNode(NULL), a_waitForRequestStepNumber(-1) {;}
+    TestStepSendxml(TestCase *testCase) : TestStep(testCase),
+      a_expired(false),
+      a_originHost(NULL),
+      a_waitForRequestStepNumber(-1) {;}
+    ~TestStepSendxml() {;}
 
     // setter & getters
-    void setRealmNode(RealmNode *realm) throw() { a_realmNode = realm; }
-    RealmNode *getRealmNode() const throw() { return a_realmNode; }
+    void setOriginHost(OriginHost *host) throw() { a_originHost = host; }
+    OriginHost *getOriginHost() const throw() { return a_originHost; }
     void setWaitForRequestStepNumber(int stepNumber) throw() { a_waitForRequestStepNumber = stepNumber; }
     int getWaitForRequestStepNumber() const throw() { return a_waitForRequestStepNumber; }
     void setMsgDataBlock(const anna::DataBlock &db) throw() { a_message = db; }
@@ -134,7 +149,7 @@ class TestStepSendxml : public TestStep {
     bool do_execute() throw();
     void do_complete() throw() {;}
     void do_reset() throw();
-    anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+    anna::xml::Node* asXML(anna::xml::Node* parent) throw();
 };
 
 class TestStepSendxml2e : public TestStepSendxml {
@@ -163,29 +178,35 @@ class TestStepDelay : public TestStep {
     bool do_execute() throw();
     void do_complete() throw(); // delay reached
     void do_reset() throw();
-    anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+    anna::xml::Node* asXML(anna::xml::Node* parent) throw();
 };
 
 
 class TestStepWait : public TestStep {
 
     TestCondition a_condition;
-    anna::DataBlock a_message; // message which complies with condition
     anna::diameter::comm::ClientSession *a_clientSession;
     anna::diameter::comm::ServerSession *a_serverSession;
 
   public:
-    TestStepWait(TestCase *testCase) : TestStep(testCase) { a_type = Type::Wait; a_clientSession = NULL; a_serverSession = NULL; }
+    TestStepWait(TestCase *testCase) : TestStep(testCase) {
+      a_type = Type::Wait;
+      a_clientSession = NULL;
+      a_serverSession = NULL;
+    }
     ~TestStepWait() {;}
 
     // setter & getters
     void setCondition(bool fromEntity,
-                        const std::string &code, const std::string &bitR, const std::string &resultCode, const std::string &sessionId,
-                        const std::string &hopByHop, const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) throw();
+                        const std::string &code, const std::string &bitR, const std::string &hopByHop, const std::string &applicationId,
+                        const std::string &sessionId, const std::string &resultCode,
+                        const std::string &msisdn, const std::string &imsi, const std::string &serviceContextId) throw();
     void setCondition(bool fromEntity, const std::string &regexp) throw();
 
     void setClientSession(anna::diameter::comm::ClientSession *cs) throw() { a_clientSession = cs; }
     void setServerSession(anna::diameter::comm::ServerSession *ss) throw() { a_serverSession = ss; }
+    anna::diameter::comm::ClientSession *getClientSession() const throw() { return a_clientSession; }
+    anna::diameter::comm::ServerSession *getServerSession() const throw() { return a_serverSession; }
 
     const TestCondition &getCondition() const throw() { return a_condition; }
     //void setMsgDataBlock(const anna::DataBlock &db) throw() { a_message = db; }
@@ -197,7 +218,45 @@ class TestStepWait : public TestStep {
     bool do_execute() throw(); // this will be executed when test case starts (at least we could measure the time until condition is fulfilled)
     void do_complete() throw(); // condition fulfilled
     void do_reset() throw();
-    anna::xml::Node* asXML(anna::xml::Node* parent) const throw();
+    anna::xml::Node* asXML(anna::xml::Node* parent) throw();
+};
+
+
+class TestStepCmd : public TestStep {
+
+  std::string a_script;
+  std::thread a_thread;
+  bool a_threadRunning;
+  bool a_threadDeprecated;
+  int a_resultCode;
+  std::string a_errorMsg;
+  //std::string a_output; // for POPEN
+
+  pid_t a_childPid;
+
+  public:
+    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; }
+
+    // setter & getters
+    void setThreadRunning(bool running) throw() { a_threadRunning = running; }
+
+    void setResultCode(int rc) throw() { a_resultCode = rc; }
+    int getResultCode() const throw() { return a_resultCode; }
+    void setErrorMsg(const std::string &em) throw() { a_errorMsg = em; }
+    const std::string &getErrorMsg() const throw() { return a_errorMsg; }
+    //void appendOutput(const std::string &output) throw() { a_output += output; }
+    //const std::string &getOutput() const throw() { return a_output; }
+    void setChildPid(pid_t pid) throw() { a_childPid = pid; }
+    const pid_t &getChildPid() const throw() { return a_childPid; }
+
+    void setScript(const std::string &script) throw() { a_script = script; }
+    const std::string &getScript() const throw() { return a_script; }
+
+    // virtuals
+    bool do_execute() throw();
+    void do_complete() throw();
+    void do_reset() throw();
+    anna::xml::Node* asXML(anna::xml::Node* parent) throw();
 };