Browse Source

[4109a] Implemented receive unit test using buffer6_send hook

Francis Dupont 9 years ago
parent
commit
d3ac4aea37
1 changed files with 76 additions and 6 deletions
  1. 76 6
      src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc

+ 76 - 6
src/bin/dhcp6/tests/dhcp6to4_ipc_unittest.cc

@@ -5,6 +5,7 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #include <config.h>
+
 #include <asiolink/io_address.h>
 #include <dhcp/pkt6.h>
 #include <dhcp/iface_mgr.h>
@@ -13,6 +14,10 @@
 #include <dhcp6/dhcp6to4_ipc.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/testutils/dhcp4o6_test_ipc.h>
+#include <hooks/callout_handle.h>
+#include <hooks/hooks_manager.h>
+#include <hooks/library_handle.h>
+
 #include <gtest/gtest.h>
 #include <stdint.h>
 
@@ -20,6 +25,7 @@ using namespace isc;
 using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
+using namespace isc::hooks;
 using namespace isc::util;
 
 namespace {
@@ -42,6 +48,9 @@ public:
         : iface_mgr_test_config_(true) {
         IfaceMgr::instance().openSockets6();
         configurePort(TEST_PORT);
+        // Install buffer6_send_callout
+        EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().
+                    registerCallout("buffer6_send", buffer6_send_callout));
     }
 
     /// @brief Configure DHCP4o6 port.
@@ -57,12 +66,27 @@ public:
     /// @return Pointer to the instance of the DHCPv4-query Message option.
     OptionPtr createDHCPv4MsgOption() const;
 
+    /// @brief Handler for the buffer6_send hook
+    ///
+    /// @param callout_handle handle passed by the hooks framework
+    /// @return always 0
+    static int
+    buffer6_send_callout(CalloutHandle& callout_handle) {
+        callout_handle.getArgument("response6", callback_pkt_);
+        return (0);
+    }
+
+    /// @brief Response Pkt6 shared pointer returned in the callout
+    static Pkt6Ptr callback_pkt_;
+
 private:
 
     /// @brief Provides fake configuration of interfaces.
     IfaceMgrTestConfig iface_mgr_test_config_;
 };
 
+Pkt6Ptr Dhcp6to4IpcTest::callback_pkt_;
+
 void
 Dhcp6to4IpcTest::configurePort(const uint16_t port) {
     CfgMgr::instance().getStagingCfg()->setDhcp4o6Port(port);
@@ -111,16 +135,61 @@ TEST_F(Dhcp6to4IpcTest, receive) {
     pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
     ASSERT_NO_THROW(pkt->pack());
 
+    // Reset the callout cached packet
+    Dhcp6to4IpcTest::callback_pkt_.reset();
+
     // Send and wait up to 1 second to receive it.
     ASSERT_NO_THROW(src_ipc.send(pkt));
     ASSERT_NO_THROW(IfaceMgr::instance().receive6(1, 0));
 
+    // Get the forwarded packet from the callout
+    Pkt6Ptr forwarded = Dhcp6to4IpcTest::callback_pkt_;
+    ASSERT_TRUE(forwarded);
+
+    // Verify the packet received.
+    EXPECT_EQ(DHCP6_CLIENT_PORT, forwarded->getRemotePort());
+    EXPECT_EQ(forwarded->getType(), pkt->getType());
+    EXPECT_TRUE(forwarded->getOption(D6O_DHCPV4_MSG));
+    EXPECT_EQ("eth0", forwarded->getIface());
+    EXPECT_EQ("2001:db8:1::123", forwarded->getRemoteAddr().toText());
+}
+
+// #4296 addresses this
 #if 0
-    // The stub packet filter exposes static function to retrieve messages
-    // sent over the fake sockets/interfaces. This is the message that the
-    // IPC endpoint should forward to the client after receiving it
-    // from the DHCPv4 server.
-    Pkt6Ptr forwarded = PktFilter6TestStub::popSent();
+// This test verifies that the DHCPv4 endpoint of the DHCPv4o6 IPC can
+// receive relayed messages.
+TEST_F(Dhcp6to4IpcTest, receiveRelayed) {
+    // Create instance of the IPC endpoint under test.
+    Dhcp6to4Ipc& ipc = Dhcp6to4Ipc::instance();
+    // Create instance of the IPC endpoint being used as a source of messages.
+    TestIpc src_ipc(TEST_PORT, TestIpc::ENDPOINT_TYPE_V4);
+
+    // Open both endpoints.
+    ASSERT_NO_THROW(ipc.open());
+    ASSERT_NO_THROW(src_ipc.open());
+
+    // Create relayed message to be sent over IPC.
+    Pkt6Ptr pkt(new Pkt6(DHCPV6_DHCPV4_QUERY, 1234));
+    pkt->addOption(createDHCPv4MsgOption());
+    Pkt6::RelayInfo relay;
+    relay.linkaddr_ = IOAddress("3000:1::1");
+    relay.peeraddr_ = IOAddress("fe80::1");
+    relay.msg_type_ = DHCPV6_RELAY_FORW;
+    relay.hop_count_ = 1;
+    pkt->relay_info_.push_back(relay);
+    pkt->setIface("eth0");
+    pkt->setRemoteAddr(IOAddress("2001:db8:1::123"));
+    ASSERT_NO_THROW(pkt->pack());
+
+    // Reset the callout cached packet
+    Dhcp6to4IpcTest::callback_pkt_.reset();
+
+    // Send and wait up to 1 second to receive it.
+    ASSERT_NO_THROW(src_ipc.send(pkt));
+    ASSERT_NO_THROW(IfaceMgr::instance().receive6(1, 0));
+
+    // Get the forwarded packet from the callout
+    Pkt6Ptr forwarded = Dhcp6to4IpcTest::callback_pkt_;
     ASSERT_TRUE(forwarded);
 
     // Verify the packet received.
@@ -129,7 +198,8 @@ TEST_F(Dhcp6to4IpcTest, receive) {
     EXPECT_TRUE(forwarded->getOption(D6O_DHCPV4_MSG));
     EXPECT_EQ("eth0", forwarded->getIface());
     EXPECT_EQ("2001:db8:1::123", forwarded->getRemoteAddr().toText());
-#endif
+    EXPECT_EQ(DHCP6_CLIENT_PORT, forwarded->getRemotePort());
 }
+#endif
 
 } // end of anonymous namespace