Browse Source

[1976] Test removal, addition and reconfiguration when not inited

Michal 'vorner' Vaner 13 years ago
parent
commit
59a8af594d

+ 18 - 10
src/bin/auth/datasrc_configurator.h

@@ -19,6 +19,7 @@
 
 #include <datasrc/client_list.h>
 #include <config/ccsession.h>
+#include <cc/data.h>
 
 /// \brief A class to configure the authoritative server's data source lists
 ///
@@ -110,20 +111,27 @@ public:
     ///     as an update from the config manager.
     /// \throw InvalidOperation if it is called when not initialized.
     static void reconfigure(const isc::data::ConstElementPtr& config) {
-        // TODO: The InvalidOperation thing
+        if (server_ == NULL) {
+            isc_throw(isc::InvalidOperation,
+                      "Can't reconfigure while not inited");
+        }
         typedef std::map<std::string, isc::data::ConstElementPtr> Map;
         const Map& map(config->mapValue());
         for (Map::const_iterator it(map.begin()); it != map.end(); ++ it) {
             isc::dns::RRClass rrclass(it->first);
-            ListPtr list(server_->getClientList(rrclass));
-            bool need_set(false);
-            if (!list) {
-                list.reset(new List);
-                need_set = true;
-            }
-            list->configure(*it->second, true);
-            if (need_set) {
-                server_->setClientList(rrclass, list);
+            if (it->second->getType() == isc::data::Element::null) {
+                server_->setClientList(rrclass, ListPtr());
+            } else {
+                ListPtr list(server_->getClientList(rrclass));
+                bool need_set(false);
+                if (!list) {
+                    list.reset(new List);
+                    need_set = true;
+                }
+                list->configure(*it->second, true);
+                if (need_set) {
+                    server_->setClientList(rrclass, list);
+                }
             }
         }
     }

+ 43 - 1
src/bin/auth/tests/datasrc_configurator_unittest.cc

@@ -61,7 +61,8 @@ public:
         return (lists_[rrclass]);
     }
     void setClientList(const RRClass& rrclass, const ListPtr& list) {
-        log_ += "set " + rrclass.toText() + " " + list->getConf() + "\n";
+        log_ += "set " + rrclass.toText() + " " +
+            (list ? list->getConf() : "") + "\n";
         lists_[rrclass] = list;
     }
 protected:
@@ -123,6 +124,9 @@ TEST_F(DatasrcConfiguratorTest, initialization) {
     // Deinitialize to make the tests reasonable
     Configurator::deinit();
     EXPECT_FALSE(session.haveSubscription("data_sources", "*"));
+    // We can't reconfigure now (not even manually)
+    EXPECT_THROW(Configurator::reconfigure(ElementPtr(new MapElement())),
+                 InvalidOperation);
     // If one of them is NULL, it does not work
     EXPECT_THROW(Configurator::init(NULL, this), InvalidParameter);
     EXPECT_FALSE(session.haveSubscription("data_sources", "*"));
@@ -170,4 +174,42 @@ TEST_F(DatasrcConfiguratorTest, multiple) {
     EXPECT_EQ(2, lists_.size());
 }
 
+// Check we can add another one later and the old one does not get
+// overwritten.
+TEST_F(DatasrcConfiguratorTest, updateAdd) {
+    // TODO: Make sure the communication protocol really works on
+    // the semi-diff principle here, not by sending everything.
+    // (actually, sending everything would work, as per above, two
+    // tests, but this test would be wrong).
+    doInInit();
+    const ElementPtr
+        config(Element::fromJSON("{\"CH\": [{\"type\": \"yyy\"}]}"));
+    session.addMessage(createCommand("config_update", config), "data_sources",
+                       "*");
+    log_ = "";
+    mccs->checkCommand();
+    // This one does not set
+    EXPECT_EQ("get CH\nset CH yyy\n", log_);
+    // But this should contain the yyy configuration
+    EXPECT_EQ("yyy", lists_[RRClass::CH()]->getConf());
+    EXPECT_EQ("xxx", lists_[RRClass::IN()]->getConf());
+    EXPECT_EQ(2, lists_.size());
+}
+
+// We delete a class list in this test.
+TEST_F(DatasrcConfiguratorTest, updateDelete) {
+    // TODO: Make sure the protocol sends the diff and a delete
+    // is done by a null element. Where is a documentation for this?
+    doInInit();
+    const ElementPtr
+        config(Element::fromJSON("{\"IN\": null}"));
+    session.addMessage(createCommand("config_update", config), "data_sources",
+                       "*");
+    log_ = "";
+    mccs->checkCommand();
+    // This one does not set
+    EXPECT_EQ("set IN \n", log_);
+}
+
+
 }