From: Tomek Mrugalski Date: Mon, 3 Feb 2014 15:25:43 +0000 (+0100) Subject: [3315] IPv6 tests for external sockets implemented. X-Git-Tag: bind10-1.2.0beta1-release~78^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d17da3a2be2c2649652b4dd0ae5d3d11ba9cc21b;p=thirdparty%2Fkea.git [3315] IPv6 tests for external sockets implemented. --- diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc index ae58c7e7f5..64892b5d9b 100644 --- a/src/lib/dhcp/iface_mgr.cc +++ b/src/lib/dhcp/iface_mgr.cc @@ -973,14 +973,17 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */ // Let's find out which socket has the data for (SocketCallbackContainer::iterator s = callbacks_.begin(); s != callbacks_.end(); ++s) { - if (FD_ISSET(s->socket_, &sockets)) { - // something received over external socket - if (s->callback_) { - // Calling the external socket's callback provides its service - // layer access without integrating any specific features - // in IfaceMgr - s->callback_(); - } + if (!FD_ISSET(s->socket_, &sockets)) { + continue; + } + + // something received over external socket + + // Calling the external socket's callback provides its service + // layer access without integrating any specific features + // in IfaceMgr + if (s->callback_) { + s->callback_(); } return (Pkt6Ptr()); diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc index 3f7add8897..a8cb0cd6a1 100644 --- a/src/lib/dhcp/tests/iface_mgr_unittest.cc +++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc @@ -2603,7 +2603,7 @@ void my_callback2(void) { // Tests if a single external socket and its callback can be passed and // it is supported properly by receive4() method. -TEST_F(IfaceMgrTest, SingleExternalSocket) { +TEST_F(IfaceMgrTest, SingleExternalSocket4) { callback_ok = false; @@ -2642,7 +2642,7 @@ TEST_F(IfaceMgrTest, SingleExternalSocket) { // Tests if multiple external sockets and their callbacks can be passed and // it is supported properly by receive4() method. -TEST_F(IfaceMgrTest, MiltipleExternalSockets) { +TEST_F(IfaceMgrTest, MiltipleExternalSockets4) { callback_ok = false; callback2_ok = false; @@ -2714,8 +2714,8 @@ TEST_F(IfaceMgrTest, MiltipleExternalSockets) { } // Tests if existing external socket can be deleted and that such deletion does -// not affect any other existing sockets. -TEST_F(IfaceMgrTest, DeleteExternalSockets) { +// not affect any other existing sockets. Tests uses receive4() +TEST_F(IfaceMgrTest, DeleteExternalSockets4) { callback_ok = false; callback2_ok = false; @@ -2770,6 +2770,175 @@ TEST_F(IfaceMgrTest, DeleteExternalSockets) { } +// Tests if a single external socket and its callback can be passed and +// it is supported properly by receive6() method. +TEST_F(IfaceMgrTest, SingleExternalSocket6) { + + callback_ok = false; + + scoped_ptr ifacemgr(new NakedIfaceMgr()); + + // Create pipe and register it as extra socket + int pipefd[2]; + EXPECT_TRUE(pipe(pipefd) == 0); + EXPECT_NO_THROW(ifacemgr->addExternalSocket(pipefd[0], my_callback)); + + Pkt6Ptr pkt6; + ASSERT_NO_THROW(pkt6 = ifacemgr->receive6(1)); + + // Our callback should not be called this time (there was no data) + EXPECT_FALSE(callback_ok); + + // IfaceMgr should not process control socket data as incoming packets + EXPECT_FALSE(pkt6); + + // Now, send some data over pipe (38 bytes) + EXPECT_EQ(38, write(pipefd[1], "Hi, this is a message sent over a pipe", 38)); + + // ... and repeat + ASSERT_NO_THROW(pkt6 = ifacemgr->receive6(1)); + + // IfaceMgr should not process control socket data as incoming packets + EXPECT_FALSE(pkt6); + + // There was some data, so this time callback should be called + EXPECT_TRUE(callback_ok); + + // close both pipe ends + close(pipefd[1]); + close(pipefd[0]); +} + +// Tests if multiple external sockets and their callbacks can be passed and +// it is supported properly by receive6() method. +TEST_F(IfaceMgrTest, MiltipleExternalSockets6) { + + callback_ok = false; + callback2_ok = false; + + scoped_ptr ifacemgr(new NakedIfaceMgr()); + + // Create first pipe and register it as extra socket + int pipefd[2]; + EXPECT_TRUE(pipe(pipefd) == 0); + EXPECT_NO_THROW(ifacemgr->addExternalSocket(pipefd[0], my_callback)); + + // Let's create a second pipe and register it as well + int secondpipe[2]; + EXPECT_TRUE(pipe(secondpipe) == 0); + EXPECT_NO_THROW(ifacemgr->addExternalSocket(secondpipe[0], my_callback2)); + + Pkt6Ptr pkt6; + ASSERT_NO_THROW(pkt6 = ifacemgr->receive6(1)); + + // Our callbacks should not be called this time (there was no data) + EXPECT_FALSE(callback_ok); + EXPECT_FALSE(callback2_ok); + + // IfaceMgr should not process control socket data as incoming packets + EXPECT_FALSE(pkt6); + + // Now, send some data over the first pipe (38 bytes) + EXPECT_EQ(38, write(pipefd[1], "Hi, this is a message sent over a pipe", 38)); + + // ... and repeat + ASSERT_NO_THROW(pkt6 = ifacemgr->receive6(1)); + + // IfaceMgr should not process control socket data as incoming packets + EXPECT_FALSE(pkt6); + + // There was some data, so this time callback should be called + EXPECT_TRUE(callback_ok); + EXPECT_FALSE(callback2_ok); + + // Read the data sent, because our test callbacks are too dumb to actually + // do it. We don't care about the content read, because we're testing + // the callbacks, not pipes. + char buf[80]; + read(pipefd[0], buf, 80); + + // Clear the status... + callback_ok = false; + callback2_ok = false; + + // And try again, using the second pipe + EXPECT_EQ(38, write(secondpipe[1], "Hi, this is a message sent over a pipe", 38)); + + // ... and repeat + ASSERT_NO_THROW(pkt6 = ifacemgr->receive6(1)); + + // IfaceMgr should not process control socket data as incoming packets + EXPECT_FALSE(pkt6); + + // There was some data, so this time callback should be called + EXPECT_FALSE(callback_ok); + EXPECT_TRUE(callback2_ok); + + // close both pipe ends + close(pipefd[1]); + close(pipefd[0]); + + close(secondpipe[1]); + close(secondpipe[0]); +} + +// Tests if existing external socket can be deleted and that such deletion does +// not affect any other existing sockets. Tests uses receive6() +TEST_F(IfaceMgrTest, DeleteExternalSockets6) { + + callback_ok = false; + callback2_ok = false; + + scoped_ptr ifacemgr(new NakedIfaceMgr()); + + // Create first pipe and register it as extra socket + int pipefd[2]; + EXPECT_TRUE(pipe(pipefd) == 0); + EXPECT_NO_THROW(ifacemgr->addExternalSocket(pipefd[0], my_callback)); + + // Let's create a second pipe and register it as well + int secondpipe[2]; + EXPECT_TRUE(pipe(secondpipe) == 0); + EXPECT_NO_THROW(ifacemgr->addExternalSocket(secondpipe[0], my_callback2)); + + // Now delete the first session socket + EXPECT_NO_THROW(ifacemgr->deleteExternalSocket(pipefd[0])); + + // Now check whether the second callback is still functional + EXPECT_EQ(38, write(secondpipe[1], "Hi, this is a message sent over a pipe", 38)); + + // ... and repeat + Pkt6Ptr pkt6; + ASSERT_NO_THROW(pkt6 = ifacemgr->receive6(1)); + + // IfaceMgr should not process control socket data as incoming packets + EXPECT_FALSE(pkt6); + + // There was some data, so this time callback should be called + EXPECT_FALSE(callback_ok); + EXPECT_TRUE(callback2_ok); + + // Let's reset the status + callback_ok = false; + callback2_ok = false; + + // Now let's send something over the first callback that was unregistered. + // We should NOT receive any callback. + EXPECT_EQ(38, write(pipefd[1], "Hi, this is a message sent over a pipe", 38)); + + // Now check that the first callback is NOT called. + ASSERT_NO_THROW(pkt6 = ifacemgr->receive6(1)); + EXPECT_FALSE(callback_ok); + + // close both pipe ends + close(pipefd[1]); + close(pipefd[0]); + + close(secondpipe[1]); + close(secondpipe[0]); +} + + // Test checks if the unicast sockets can be opened. // This test is now disabled, because there is no reliable way to test it. We // can't even use loopback, beacuse openSockets() skips loopback interface