Browse Source

[trac575] Test for installing of addresses

Michal 'vorner' Vaner 14 years ago
parent
commit
71c4e3cb8c

+ 3 - 0
src/lib/server_common/portconfig.cc

@@ -61,6 +61,9 @@ parseAddresses(isc::data::ConstElementPtr addresses,
     return (result);
     return (result);
 }
 }
 
 
+void
+installListenAddresses(const AddressList&, AddressList&, asiolink::DNSService&) {}
+
 }
 }
 }
 }
 }
 }

+ 35 - 0
src/lib/server_common/portconfig.h

@@ -22,6 +22,13 @@
 
 
 #include <cc/data.h>
 #include <cc/data.h>
 
 
+/*
+ * Some forward declarations.
+ */
+namespace asiolink {
+class DNSService;
+}
+
 namespace isc {
 namespace isc {
 namespace server_common {
 namespace server_common {
 /**
 /**
@@ -79,6 +86,34 @@ AddressList
 parseAddresses(isc::data::ConstElementPtr addresses,
 parseAddresses(isc::data::ConstElementPtr addresses,
                const std::string& elemName);
                const std::string& elemName);
 
 
+/**
+ * \brief Changes current listening addresses and ports.
+ *
+ * Removes all sockets we currently listen on and starts listening on the
+ * addresses and ports requested in newAddresses.
+ *
+ * If it fails to set up the new addresses, it attempts to roll back to the
+ * previous addresses (but it still propagates the exception). If the rollback
+ * fails as well, it aborts the application (it assumes if it can't listen
+ * on the new addresses nor on the old ones, the application is useless anyway
+ * and should be restarted by Boss, not to mention that the internal state is
+ * probably broken).
+ *
+ * \param newAddresses are the addresses you want to listen on.
+ * \param addressStore is the place you store your current addresses. It is
+ *     used when there's a need for rollback. The newAddresses are copied here
+ *     when the change is successful.
+ * \param dnsService is the DNSService object we use now. The requests from
+ *     the new sockets are handled using this dnsService (and all current
+ *     sockets on the service are closed first).
+ * \throw asiolink::IOError when initialization or closing of socket fails.
+ * \throw std::bad_alloc when allocation fails.
+ */
+void
+installListenAddresses(const AddressList& newAddresses,
+                       AddressList& addressStore,
+                       asiolink::DNSService& dnsService);
+
 }
 }
 }
 }
 }
 }

+ 54 - 0
src/lib/server_common/tests/portconfig_unittest.cc

@@ -103,4 +103,58 @@ TEST_F(ParseAddresses, invalid) {
                                    "}]", "Bad address");
                                    "}]", "Bad address");
 }
 }
 
 
+// Test fixture for installListenAddresses
+struct InstallListenAddresses : public ::testing::Test {
+    InstallListenAddresses() :
+        dnss_(ios_, NULL, NULL, NULL)
+    {
+        valid_.push_back(AddressPair("127.0.0.1", 5288));
+        valid_.push_back(AddressPair("::1", 5288));
+        invalid_.push_back(AddressPair("192.0.2.2", 1));
+    }
+    IOService ios_;
+    DNSService dnss_;
+    AddressList store_;
+    // We should be able to bind to these addresses
+    AddressList valid_;
+    // But this shouldn't work
+    AddressList invalid_;
+    // Check that the store_ addresses are the same as expected
+    void checkAddresses(const AddressList& expected, const string& name) {
+        SCOPED_TRACE(name);
+
+        ASSERT_EQ(expected.size(), store_.size()) <<
+            "Different amount of elements, not checking content";
+        // Run in parallel trough the vectors
+        for (AddressList::const_iterator ei(expected.begin()),
+             si(store_.begin()); ei != expected.end(); ++ei, ++si) {
+            EXPECT_EQ(ei->first, si->first);
+            EXPECT_EQ(ei->second, si->second);
+        }
+    }
+};
+
+// Try switching valid addresses
+TEST_F(InstallListenAddresses, valid) {
+    // First, bind to the valid addresses
+    EXPECT_NO_THROW(installListenAddresses(valid_, store_, dnss_));
+    checkAddresses(valid_, "Valid addresses");
+    // TODO Maybe some test to actually connect to them
+    // Try setting it back to nothing
+    EXPECT_NO_THROW(installListenAddresses(AddressList(), store_, dnss_));
+    checkAddresses(AddressList(), "No addresses");
+    // TODO: Once #338 is solved, try switching back to valid addresses
+}
+
+// Try if rollback works
+// TODO Enable after #338
+TEST_F(InstallListenAddresses, DISABLED_rollback) {
+    // Set some addresses
+    EXPECT_NO_THROW(installListenAddresses(valid_, store_, dnss_));
+    checkAddresses(valid_, "Before rollback");
+    // This should not bind them, but should leave the original addresses
+    EXPECT_THROW(installListenAddresses(invalid_, store_, dnss_), IOError);
+    checkAddresses(valid_, "After rollback");
+}
+
 }
 }