]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1716] fixed unittests for BSD and Solaris
authorRazvan Becheriu <razvan@isc.org>
Sat, 9 Apr 2022 11:51:57 +0000 (14:51 +0300)
committerRazvan Becheriu <razvan@isc.org>
Sat, 9 Apr 2022 12:08:19 +0000 (15:08 +0300)
src/lib/dhcp/iface_mgr.cc
src/lib/dhcp/tests/iface_mgr_unittest.cc
src/lib/dhcpsrv/tests/cfg_iface_unittest.cc

index fc037dd474f983548a09b436f74a61afe13b7838..17ef182b29580510e7d8d2ff4948f3b0758793b7 100644 (file)
@@ -681,7 +681,12 @@ IfaceMgr::openSockets6(const uint16_t port,
         for (Iface::Address addr : iface->getUnicasts()) {
             // Skip the address that already has a bound socket. It allows
             // for preventing bind errors or re-opening sockets.
-            if (!skip_opened || !IfaceMgr::hasOpenSocket(addr)) {
+            // The @ref IfaceMgr::hasOpenSocket(addr) does match the "::"
+            // address on BSD and Solaris on any interface, so we make sure that
+            // that interface actually has opened sockets by checking the numner
+            // of sockets to be non zero.
+            if (!skip_opened || !IfaceMgr::hasOpenSocket(addr) ||
+                !iface->getSockets().size()) {
                 try {
                     IfaceMgr::openSocket(iface->getName(), addr, port, false, false);
                 } catch (const Exception& ex) {
@@ -718,7 +723,12 @@ IfaceMgr::openSockets6(const uint16_t port,
 
             // Skip the address that already has a bound socket. It allows
             // for preventing bind errors or re-opening sockets.
-            if (!skip_opened || !IfaceMgr::hasOpenSocket(addr)) {
+            // The @ref IfaceMgr::hasOpenSocket(addr) does match the "::"
+            // address on BSD and Solaris on any interface, so we make sure that
+            // the interface actually has opened sockets by checking the numner
+            // of sockets to be non zero.
+            if (!skip_opened || !IfaceMgr::hasOpenSocket(addr) ||
+                !iface->getSockets().size()) {
                 try {
                     // Pass a null pointer as an error handler to avoid
                     // suppressing an exception in a system-specific function.
index d5893d4d0ad2187ebc8b578d7d96df2e0c3e7c44..535a74667383b74a066ab283eec3ebc6954be79f 100644 (file)
@@ -2004,8 +2004,6 @@ TEST_F(IfaceMgrTest, openSockets4SkipOpen) {
     // Open socket on eth1. The openSockets4 should detect that this
     // socket has been already open and an attempt to open another socket
     // and bind to this address and port should fail.
-    // This test checks if calling openSockets4 does not throw when sockets are
-    // already opened for the interface "eth1".
     ASSERT_NO_THROW(ifacemgr.openSocket("eth1", IOAddress("192.0.2.3"),
                                         DHCP4_SERVER_PORT));
 
@@ -2499,17 +2497,9 @@ TEST_F(IfaceMgrTest, openSockets6SkipOpen) {
     // Open socket on eth0. The openSockets6 should detect that this
     // socket has been already open and an attempt to open another socket
     // and bind to this address and port should fail.
-    // This test checks if calling openSockets6 does not throw when sockets are
-    // already opened for the interface "eth0".
-    // Because the @ref IfaceMgr::hasOpenSocket(addr) does match the "::"
-    // address on BSD and Solaris on any interface, we make sure that the
-    // interface "eth0" does not join the multicast group. Otherwise the
-    // @ref IfaceMgr::openSockets6 will see that at least one socket for address
-    // "::" has been opened for interface "eth1" and will not try to open the
-    // rest of the sockets.
     ASSERT_NO_THROW(ifacemgr.openSocket("eth0",
                                         IOAddress("fe80::3a60:77ff:fed5:cdef"),
-                                        DHCP6_SERVER_PORT, false));
+                                        DHCP6_SERVER_PORT, true));
 
     // The function doesn't throw an exception when it tries to open a socket
     // and bind it to the address in use but the skip open flag is provided.
index f1e3cbdcb457e014bbf77b53b0fc1375a5ec5a23..c0a775b653406d39e25addaa06479e15dcea5d02 100644 (file)
@@ -690,9 +690,6 @@ TEST_F(CfgIfaceTest, retryOpenServiceSockets4OmitBound) {
     ASSERT_NO_THROW(cfg4.use(AF_INET, "eth0"));
     ASSERT_NO_THROW(cfg4.use(AF_INET, "eth1/192.0.2.3"));
 
-    // This test checks if calling @ref CfgIface::openSockets does activate the
-    // retry mechanism for the interface "eth1".
-
     // Parameters
     const uint16_t RETRIES = 5;
     const uint16_t WAIT_TIME = 10; // miliseconds
@@ -889,17 +886,6 @@ TEST_F(CfgIfaceTest, retryOpenServiceSockets6OmitBound) {
     ASSERT_NO_THROW(cfg6.use(AF_INET6, "eth0/2001:db8:1::1"));
     ASSERT_NO_THROW(cfg6.use(AF_INET6, "eth1"));
 
-    // This test checks if calling @ref CfgIface::openSockets does activate the
-    // retry mechanism for the interface "eth1".
-    // Because the @ref IfaceMgr::hasOpenSocket(addr) does match the "::"
-    // address on BSD and Solaris on any interface, we make sure that the
-    // interface "eth0" does not join the multicast group. Otherwise the
-    // @ref IfaceMgr::openSockets6 will see that at least one socket for address
-    // "::" has been opened for interface "eth1" and will not try to open the
-    // rest of the sockets.
-    // Make eth0 multicast-incapable.
-    IfaceMgr::instance().getIface("eth0")->flag_multicast_ = false;
-
     // Parameters
     const uint16_t RETRIES = 5;
     const uint16_t WAIT_TIME = 10; // miliseconds
@@ -908,12 +894,18 @@ TEST_F(CfgIfaceTest, retryOpenServiceSockets6OmitBound) {
     cfg6.setServiceSocketsMaxRetries(RETRIES);
     cfg6.setServiceSocketsRetryWaitTime(WAIT_TIME);
 
+#if defined OS_LINUX
+    const uint32_t opened_by_eth0 = 3;
+#else
+    const uint32_t opened_by_eth0 = 2;
+#endif
+
     // Set the callback to count calls and check wait time
     size_t total_calls = 0;
     auto last_call_time = std::chrono::system_clock::time_point::min();
     auto open_callback = [&total_calls, &last_call_time, WAIT_TIME](uint16_t) {
         auto now = std::chrono::system_clock::now();
-        bool is_eth0 = total_calls < 2;
+        bool is_eth0 = total_calls < opened_by_eth0;
 
         // Skip the wait time check for the socket when two sockets are
         // binding in a single attempt.
@@ -921,8 +913,10 @@ TEST_F(CfgIfaceTest, retryOpenServiceSockets6OmitBound) {
         // Don't check the waiting time for initial calls.
         // iface: eth0 addr: 2001:db8:1::1 port: 547 multicast: 0
         // iface: eth0 addr: fe80::3a60:77ff:fed5:cdef port: 547 multicast: 1
+        // iface: eth0 addr: ff02::1:2 port: 547 multicast: 0 --- only on Linux systems
         // iface: eth1 addr: fe80::3a60:77ff:fed5:abcd port: 547 multicast: 1 - fails
-        if (total_calls > 3) {
+
+        if (total_calls > (opened_by_eth0 + 1)) {
             auto interval = now - last_call_time;
             auto interval_ms =
                 std::chrono::duration_cast<std::chrono::milliseconds>(
@@ -957,9 +951,9 @@ TEST_F(CfgIfaceTest, retryOpenServiceSockets6OmitBound) {
     // Wait for a finish sockets binding (with a safe margin).
     doWait(RETRIES * WAIT_TIME * 2);
 
-    // For eth0 interface perform only 2 init open,
+    // For eth0 interface perform only 3 (on Linux Systems or 2 otherwise) init open,
     // for eth1 interface perform 1 init open and a few retries.
-    EXPECT_EQ((RETRIES + 1) + 2, total_calls);
+    EXPECT_EQ((RETRIES + 1) + opened_by_eth0, total_calls);
 }
 
 // Test that only one reopen timer is active simultaneously. If a new opening