Browse Source

[1924] Unittest for the original C++ group_sendmsg

Michal 'vorner' Vaner 12 years ago
parent
commit
9e8e9cb336
1 changed files with 74 additions and 29 deletions
  1. 74 29
      src/lib/cc/tests/session_unittests.cc

+ 74 - 29
src/lib/cc/tests/session_unittests.cc

@@ -31,6 +31,7 @@
 #include <utility>
 #include <vector>
 #include <string>
+#include <iostream>
 
 using namespace isc::cc;
 using std::pair;
@@ -61,6 +62,9 @@ TEST(AsioSession, establish) {
     );
 }
 
+/// \brief Pair holding header and data of a message sent over the wire.
+typedef pair<ConstElementPtr, ConstElementPtr> SentMessage;
+
 // This class sets up a domain socket for the session to connect to
 // it will impersonate the msgq a tiny bit (if setSendLname() has
 // been called, it will send an 'answer' to the lname query that is
@@ -103,12 +107,10 @@ public:
         socket_.send(asio::buffer(body_wire.data(), body_wire.length()));
     }
 
-    /// Pair holding header and data of a message sent over the wire.
-    typedef pair<ConstElementPtr, ConstElementPtr> SentMessage;
     /// \brief Read a message from the socket
     ///
     /// Read a message from the socket and parse it. Block until it is
-    /// read or error happens. If error happens, it throws isc::Unexpected.
+    /// read or error happens. If error happens, it asio::system_error.
     ///
     /// This method would block for ever if the sender is not sending.
     /// But the whole test has a timeout of 10 seconds (see the
@@ -125,36 +127,31 @@ public:
         // <uint16_t in net order = header length>
         // <char * header length = the header>
         // <char * the rest of the total length = the data>
+
+        // Read and convert the lengths first.
         uint32_t total_len_data;
-        if (asio::read(socket_, asio::buffer(&total_len_data,
-                                             sizeof total_len_data)) !=
-            sizeof total_len_data) {
-            isc_throw(isc::Unexpected, "Error while reading total length");
-        }
-        const uint32_t total_len = ntohl(total_len_data);
         uint16_t header_len_data;
-        if (asio::read(socket_, asio::buffer(&header_len_data,
-                                             sizeof header_len_data)) !=
-            sizeof header_len_data) {
-            isc_throw(isc::Unexpected, "Error while reading header length");
-        }
+        vector<asio::mutable_buffer> len_buffers;
+        len_buffers.push_back(asio::buffer(&total_len_data,
+                                           sizeof total_len_data));
+        len_buffers.push_back(asio::buffer(&header_len_data,
+                                           sizeof header_len_data));
+        asio::read(socket_, len_buffers);
+        const uint32_t total_len = ntohl(total_len_data);
         const uint16_t header_len = ntohs(header_len_data);
-        // We use char, not unsigned char, because we want to make a string
-        // out of it.
-        vector<char> raw_data;
-        raw_data.resize(total_len - sizeof header_len_data);
-        if (asio::read(socket_,
-                       asio::buffer(&raw_data[0],
-                                    total_len - sizeof header_len_data)) !=
-            total_len - header_len_data) {
-            isc_throw(isc::Unexpected, "Error while reading data");
+        string header, msg;
+        header.resize(header_len);
+        msg.resize(total_len - header_len - sizeof header_len_data);
+        vector<asio::mutable_buffer> data_buffers;
+        data_buffers.push_back(asio::buffer(&header[0], header.size()));
+        data_buffers.push_back(asio::buffer(&msg[0], msg.size()));
+        asio::read(socket_, data_buffers);
+        if (msg == "") { // The case of no msg present, for control messages
+            msg = "null";
         }
         // Extract the right data into each string and convert.
-        return (SentMessage(
-            Element::fromWire(string(raw_data.begin(),
-                                     raw_data.begin() + header_len)),
-            Element::fromWire(string(raw_data.begin() + header_len,
-                                     raw_data.end()))));
+        return (SentMessage(Element::fromWire(header),
+                            Element::fromWire(msg)));
     }
 
     void sendLname() {
@@ -198,7 +195,7 @@ protected:
         // 10 seconds per one test (which should really be enough even on
         // slow machines). If the timeout happens, it kills the test and
         // the whole test fails.
-        alarm(10);
+        //alarm(10);
     }
 
     void TearDown() {
@@ -207,6 +204,21 @@ protected:
         alarm(0);
     }
 
+    void elementsEqual(const ConstElementPtr& expected,
+                       const ConstElementPtr& actual)
+    {
+        EXPECT_TRUE(expected->equals(*actual)) <<
+            "Elements differ, expected: " << expected->toWire() <<
+            ", got: " << actual->toWire();
+    }
+
+    void elementsEqual(const string& expected,
+                       const ConstElementPtr& actual)
+    {
+        const ConstElementPtr expected_el(Element::fromJSON(expected));
+        elementsEqual(expected_el, actual);
+    }
+
 public:
     // used in the handler test
     // This handler first reads (and ignores) whatever message caused
@@ -322,3 +334,36 @@ TEST_F(SessionTest, get_socket_descr) {
     // expect actual socket handle to be returned, not 0
     EXPECT_LT(0, socket);
 }
+
+// Test the group_sendmsg sends the correct data.
+TEST_F(SessionTest, group_sendmsg) {
+    // Connect
+    tds->setSendLname();
+    sess.establish(BIND10_TEST_SOCKET_FILE);
+    elementsEqual("{\"type\": \"getlname\"}", tds->readmsg().first);
+
+    const ConstElementPtr msg(Element::fromJSON("{\"test\": 42}"));
+    sess.group_sendmsg(msg, "group");
+    const SentMessage m1(tds->readmsg());
+    elementsEqual("{"
+                  "   \"from\": \"foobar\","
+                  "   \"group\": \"group\","
+                  "   \"instance\": \"*\","
+                  "   \"seq\": 0,"
+                  "   \"to\": \"*\","
+                  "   \"type\": \"send\""
+                  "}", m1.first);
+    elementsEqual(msg, m1.second);
+    sess.group_sendmsg(msg, "group", "instance", "recipient");
+    const SentMessage m2(tds->readmsg());
+    elementsEqual("{"
+                  "   \"from\": \"foobar\","
+                  "   \"group\": \"group\","
+                  "   \"instance\": \"instance\","
+                  "   \"seq\": 1,"
+                  "   \"to\": \"recipient\","
+                  "   \"type\": \"send\""
+                  "}", m2.first);
+    elementsEqual(msg, m2.second);
+}
+