Browse Source

Added a single unit test to partly cover the case of a recursive
query send. More work is needed here.

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac327@3128 e5f2f494-b856-4b98-b285-d166d9295462

Evan Hunt 14 years ago
parent
commit
ced315637a
1 changed files with 31 additions and 13 deletions
  1. 31 13
      src/lib/asiolink/tests/asio_link_unittest.cc

+ 31 - 13
src/lib/asiolink/tests/asio_link_unittest.cc

@@ -41,7 +41,7 @@ using namespace isc::dns;
 
 namespace {
 const char* const TEST_SERVER_PORT = "53535";
-const char* const TEST_CLIENT_PORT = "53535";
+const char* const TEST_CLIENT_PORT = "53536";
 const char* const TEST_IPV6_ADDR = "::1";
 const char* const TEST_IPV4_ADDR = "127.0.0.1";
 // This data is intended to be valid as a DNS/TCP-like message: the first
@@ -190,6 +190,7 @@ resolveAddress(const int family, const int sock_type, const int protocol,
     hints.ai_family = family;
     hints.ai_socktype = sock_type;
     hints.ai_protocol = protocol;
+    hints.ai_flags = AI_NUMERICSERV;
 
     struct addrinfo* res;
     const int error = getaddrinfo(addr, port, &hints, &res);
@@ -259,7 +260,7 @@ protected:
         }
         io_service_->run();
     }
-    void recvUDP(const int family, void* buffer, size_t size) {
+    void recvUDP(const int family, void* buffer, size_t& size) {
         res_ = resolveAddress(family, SOCK_DGRAM, IPPROTO_UDP, true);
 
         sock_ = socket(res_->ai_family, res_->ai_socktype, res_->ai_protocol);
@@ -268,7 +269,7 @@ protected:
         }
 
         if (bind(sock_, res_->ai_addr, res_->ai_addrlen) < 0) {
-            isc_throw(IOError, "bind failed: " << gai_strerror(errno));
+            isc_throw(IOError, "bind failed: " << strerror(errno));
         }
 
         // The IO service queue should have a RecursiveQuery object scheduled
@@ -276,18 +277,17 @@ protected:
         // async send, then return.
         io_service_->run_one();
 
-        // ... and this completes the send().
+        // ... and this one will block until the send has completed
         io_service_->run_one();
 
         // Now we attempt to recv() whatever was sent
-        struct sockaddr addr;
-        socklen_t addrlen;
-        fcntl(sock_, F_SETFD, O_NONBLOCK);
-        const int cc = recvfrom(sock_, buffer, size, MSG_DONTWAIT,
-                                &addr, &addrlen);
-        if (cc < 0) {
+        const int ret = recv(sock_, buffer, size, MSG_DONTWAIT);
+        if (ret < 0) {
             isc_throw(IOError, "recvfrom failed");
         }
+        
+        // Pass the message size back via the size parameter
+        size = ret;
     }
     void setIOService(const char& address) {
         delete io_service_;
@@ -486,8 +486,12 @@ TEST_F(ASIOLinkTest, recursiveSetupV6) {
     EXPECT_NO_THROW(RecursiveQuery(*io_service_, *TEST_IPV6_ADDR, port));
 }
 
-// Test disabled because recvUDP() isn't working yet
-TEST_F(ASIOLinkTest, DISABLED_recursiveSend) {
+// XXX:
+// This is very inadequate unit testing.  It should be generalized into
+// a routine that can do this with variable address family, address, and
+// port, and with the various callbacks defined in such a way as to ensure
+// full code coverage including error cases.
+TEST_F(ASIOLinkTest, recursiveSend) {
     setIOService(true, false);
     asio::io_service& io = io_service_->get_io_service();
 
@@ -504,7 +508,21 @@ TEST_F(ASIOLinkTest, DISABLED_recursiveSend) {
     rq.sendQuery(q, buffer, &server);
 
     char data[4096];
-    EXPECT_NO_THROW(recvUDP(AF_INET, data, sizeof(data)));
+    size_t size = sizeof(data);
+    EXPECT_NO_THROW(recvUDP(AF_INET, data, size));
+
+    Message m(Message::PARSE);
+    InputBuffer ibuf(data, size);
+
+    // Make sure we can parse the message that was sent
+    EXPECT_NO_THROW(m.parseHeader(ibuf));
+    EXPECT_NO_THROW(m.fromWire(ibuf));
+
+    // Check that the question sent matches the one we wanted
+    QuestionPtr q2 = *m.beginQuestion();
+    EXPECT_EQ(q.getName(), q2->getName());
+    EXPECT_EQ(q.getType(), q2->getType());
+    EXPECT_EQ(q.getClass(), q2->getClass());
 }
 
 }