BIND 10 master, updated. 146b5941b9f3d09537b56eb83df14355c2edde59 Merge branch 'master' of git+ssh://git.bind10.isc.org/var/bind10/git/bind10

BIND 10 source code commits bind10-changes at lists.isc.org
Thu Apr 19 15:24:17 UTC 2012


The branch, master has been updated
       via  146b5941b9f3d09537b56eb83df14355c2edde59 (commit)
       via  e4fd9934de5258ad1668c4cbba408fe59427c040 (commit)
       via  5b37859360df57221621144d34119fcc7e417099 (commit)
       via  6e05014aa5bd412778a0927ac1babff042e5f46f (commit)
       via  264691395b76a2a6f18b02dbd43c78f6e9de83ff (commit)
       via  438b5b183c82b04d74be71c7cc396d6393d215b6 (commit)
       via  52707b19511b499401a61b42eb3a03207f79b0c6 (commit)
       via  f782145ec0759ef8e595c87d4baf15de89624ea7 (commit)
       via  4deb49cf84c399a0ca1a84fef1cd0dee4ca4d5d5 (commit)
       via  f00dd21c6c495e180feb855139d36fc7f99f23d8 (commit)
       via  7f108b1ad180d002ff6bc2d4be26b6a93ead8c99 (commit)
       via  a93523dfcf7d640b15d9af71596caa09362cbbfd (commit)
      from  c8e538c10d73ea56f079fcb8f3c6f99e5407bdef (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 146b5941b9f3d09537b56eb83df14355c2edde59
Merge: e4fd9934de5258ad1668c4cbba408fe59427c040 c8e538c10d73ea56f079fcb8f3c6f99e5407bdef
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu Apr 19 17:24:10 2012 +0200

    Merge branch 'master' of git+ssh://git.bind10.isc.org/var/bind10/git/bind10

commit e4fd9934de5258ad1668c4cbba408fe59427c040
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu Apr 19 15:48:45 2012 +0200

    Fix makefile
    
    The run_unittests should be linked only if it is compiled. Confirmed on
    jabber this was a mistake.

commit 5b37859360df57221621144d34119fcc7e417099
Merge: da4d8df9ee0412d3717f1009ecccac58736313b8 6e05014aa5bd412778a0927ac1babff042e5f46f
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu Apr 19 12:12:12 2012 +0200

    Merge #1793

commit 6e05014aa5bd412778a0927ac1babff042e5f46f
Author: JINMEI Tatuya <jinmei at isc.org>
Date:   Thu Apr 19 12:11:42 2012 +0200

    [1793] Fix a comment
    
    The old version is a result of copy-paste and is wrong.

commit 264691395b76a2a6f18b02dbd43c78f6e9de83ff
Author: JINMEI Tatuya <jinmei at isc.org>
Date:   Thu Apr 19 12:09:57 2012 +0200

    [1793] Eliminate several state variables
    
    The values are deduced from something else, no need to keep them. This
    eliminates the ugly initialization with wrong values.

commit 438b5b183c82b04d74be71c7cc396d6393d215b6
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Thu Apr 19 11:07:35 2012 +0200

    [1793] Fix variable name
    
    We have camelCase in many places, but variable names are not one of
    those.

-----------------------------------------------------------------------

Summary of changes:
 src/bin/auth/command.cc                |   96 +++++++++++++++++++++---
 src/bin/auth/tests/Makefile.am         |    3 +-
 src/bin/auth/tests/command_unittest.cc |  127 ++++++++++++++++++++++++++++++++
 src/bin/auth/tests/datasrc_util.h      |    5 +-
 4 files changed, 215 insertions(+), 16 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc
index ad0d134..055c73a 100644
--- a/src/bin/auth/command.cc
+++ b/src/bin/auth/command.cc
@@ -18,6 +18,7 @@
 
 #include <cc/data.h>
 #include <datasrc/memory_datasrc.h>
+#include <datasrc/factory.h>
 #include <config/ccsession.h>
 #include <exceptions/exceptions.h>
 #include <dns/rrclass.h>
@@ -149,26 +150,39 @@ public:
             return;
         }
 
+        const ConstElementPtr zone_config = getZoneConfig(server);
+
         // Load a new zone and replace the current zone with the new one.
         // TODO: eventually this should be incremental or done in some way
         // that doesn't block other server operations.
         // TODO: we may (should?) want to check the "last load time" and
         // the timestamp of the file and skip loading if the file isn't newer.
+        const ConstElementPtr type(zone_config->get("filetype"));
         boost::shared_ptr<InMemoryZoneFinder> zone_finder(
-            new InMemoryZoneFinder(old_zone_finder->getClass(),
-                                   old_zone_finder->getOrigin()));
-        zone_finder->load(old_zone_finder->getFileName());
-        old_zone_finder->swap(*zone_finder);
+            new InMemoryZoneFinder(old_zone_finder_->getClass(),
+                                   old_zone_finder_->getOrigin()));
+        if (type && type->stringValue() == "sqlite3") {
+            scoped_ptr<DataSourceClientContainer>
+                container(new DataSourceClientContainer("sqlite3",
+                                                        Element::fromJSON(
+                    "{\"database_file\": \"" +
+                    zone_config->get("file")->stringValue() + "\"}")));
+            zone_finder->load(*container->getInstance().getIterator(
+                old_zone_finder_->getOrigin()));
+        } else {
+            zone_finder->load(old_zone_finder_->getFileName());
+        }
+        old_zone_finder_->swap(*zone_finder);
         LOG_DEBUG(auth_logger, DBG_AUTH_OPS, AUTH_LOAD_ZONE)
                   .arg(zone_finder->getOrigin()).arg(zone_finder->getClass());
     }
 
 private:
     // zone finder to be updated with the new file.
-    boost::shared_ptr<InMemoryZoneFinder> old_zone_finder;
+    boost::shared_ptr<InMemoryZoneFinder> old_zone_finder_;
 
     // A helper private method to parse and validate command parameters.
-    // On success, it sets 'old_zone_finder' to the zone to be updated.
+    // On success, it sets 'old_zone_finder_' to the zone to be updated.
     // It returns true if everything is okay; and false if the command is
     // valid but there's no need for further process.
     bool validate(AuthSrv& server, isc::data::ConstElementPtr args) {
@@ -193,10 +207,11 @@ private:
         }
 
         ConstElementPtr class_elem = args->get("class");
-        const RRClass zone_class = class_elem ?
-            RRClass(class_elem->stringValue()) : RRClass::IN();
+        const RRClass zone_class =
+            class_elem ? RRClass(class_elem->stringValue()) : RRClass::IN();
 
-        AuthSrv::InMemoryClientPtr datasrc(server.getInMemoryClient(zone_class));
+        AuthSrv::InMemoryClientPtr datasrc(server.
+                                           getInMemoryClient(zone_class));
         if (datasrc == NULL) {
             isc_throw(AuthCommandError, "Memory data source is disabled");
         }
@@ -205,7 +220,7 @@ private:
         if (!origin_elem) {
             isc_throw(AuthCommandError, "Zone origin is missing");
         }
-        const Name origin(origin_elem->stringValue());
+        const Name origin = Name(origin_elem->stringValue());
 
         // Get the current zone
         const InMemoryClient::FindResult result = datasrc->findZone(origin);
@@ -214,11 +229,70 @@ private:
                       " is not found in data source");
         }
 
-        old_zone_finder = boost::dynamic_pointer_cast<InMemoryZoneFinder>(
+        old_zone_finder_ = boost::dynamic_pointer_cast<InMemoryZoneFinder>(
             result.zone_finder);
 
         return (true);
     }
+
+    ConstElementPtr getZoneConfig(const AuthSrv &server) {
+        if (!server.getConfigSession()) {
+            // FIXME: This is a hack to make older tests pass. We should
+            // update these tests as well sometime and remove this hack.
+            // (note that under normal situation, the
+            // server.getConfigSession() does not return NULL)
+
+            // We provide an empty map, which means no configuration --
+            // defaults.
+            return (ConstElementPtr(new MapElement()));
+        }
+
+        // Find the config corresponding to the zone.
+        // We expect the configuration to be valid, as we have it and we
+        // accepted it before, therefore it must be validated.
+        const ConstElementPtr config(server.getConfigSession()->
+                                     getValue("datasources"));
+        ConstElementPtr zone_list;
+        // Unfortunately, we need to walk the list to find the correct data
+        // source.
+        // TODO: Make it named sets. These lists are uncomfortable.
+        for (size_t i(0); i < config->size(); ++i) {
+            // We use the getValue to get defaults as well
+            const ConstElementPtr dsrc_config(config->get(i));
+            const ConstElementPtr class_config(dsrc_config->get("class"));
+            const string class_type(class_config ?
+                                    class_config->stringValue() : "IN");
+            // It is in-memory and our class matches.
+            // FIXME: Is it allowed to have two datasources for the same
+            // type and class at once? It probably would not work now
+            // anyway and we may want to change the configuration of
+            // datasources somehow.
+            if (dsrc_config->get("type")->stringValue() == "memory" &&
+                RRClass(class_type) == old_zone_finder_->getClass()) {
+                zone_list = dsrc_config->get("zones");
+                break;
+            }
+        }
+
+        if (!zone_list) {
+            isc_throw(AuthCommandError,
+                      "Corresponding data source configuration was not found");
+        }
+
+        // Now we need to walk the zones and find the correct one.
+        for (size_t i(0); i < zone_list->size(); ++i) {
+            const ConstElementPtr zone_config(zone_list->get(i));
+            if (Name(zone_config->get("origin")->stringValue()) ==
+                old_zone_finder_->getOrigin()) {
+                // The origins are the same, so we consider this config to be
+                // for the zone.
+                return (zone_config);
+            }
+        }
+
+        isc_throw(AuthCommandError,
+                  "Corresponding zone configuration was not found");
+    }
 };
 
 // The factory of command objects.
diff --git a/src/bin/auth/tests/Makefile.am b/src/bin/auth/tests/Makefile.am
index 56010c5..f9fac2f 100644
--- a/src/bin/auth/tests/Makefile.am
+++ b/src/bin/auth/tests/Makefile.am
@@ -74,6 +74,7 @@ run_unittests_LDADD += $(top_builddir)/src/lib/statistics/libstatistics.la
 
 check-local:
 	B10_FROM_BUILD=${abs_top_builddir} ./run_unittests
-endif
 
 noinst_PROGRAMS = run_unittests
+
+endif
diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc
index 376087b..fe315c2 100644
--- a/src/bin/auth/tests/command_unittest.cc
+++ b/src/bin/auth/tests/command_unittest.cc
@@ -14,6 +14,8 @@
 
 #include <config.h>
 
+#include "datasrc_util.h"
+
 #include <auth/auth_srv.h>
 #include <auth/auth_config.h>
 #include <auth/command.h>
@@ -50,8 +52,10 @@ using namespace isc::data;
 using namespace isc::datasrc;
 using namespace isc::config;
 using namespace isc::testutils;
+using namespace isc::auth::unittest;
 
 namespace {
+
 class AuthCommandTest : public ::testing::Test {
 protected:
     AuthCommandTest() :
@@ -246,6 +250,129 @@ TEST_F(AuthCommandTest, loadZone) {
     newZoneChecks(server_);
 }
 
+// This test uses dynamic load of a data source module, and won't work when
+// statically linked.
+TEST_F(AuthCommandTest,
+#ifdef USE_STATIC_LINK
+       DISABLED_loadZoneSQLite3
+#else
+       loadZoneSQLite3
+#endif
+    )
+{
+    const char* const SPEC_FILE = AUTH_OBJ_DIR "/auth.spec";
+
+    // Prepare the database first
+    const string test_db = TEST_DATA_BUILDDIR "/auth_test.sqlite3.copied";
+    const string bad_db = TEST_DATA_BUILDDIR "/does-not-exist.sqlite3";
+    stringstream ss("example.org. 3600 IN SOA . . 0 0 0 0 0\n");
+    createSQLite3DB(RRClass::IN(), Name("example.org"), test_db.c_str(), ss);
+
+    // Then store a config of the zone to the auth server
+    // This omits many config options of the auth server, but these are
+    // not read now.
+    isc::testutils::MockSession session;
+    // The session should not take care of anything or start anything, we
+    // need it only to hold the config we're going to put into it.
+    ModuleCCSession module_session(SPEC_FILE, session, NULL, NULL, false,
+                                  false);
+    // This describes the data source in the configuration
+    const ElementPtr
+        map(Element::fromJSON("{\"datasources\": ["
+                              "  {"
+                              "    \"type\": \"memory\","
+                              "    \"zones\": ["
+                              "      {"
+                              "        \"origin\": \"example.org\","
+                              "        \"file\": \"" + test_db + "\","
+                              "        \"filetype\": \"sqlite3\""
+                              "      }"
+                              "    ]"
+                              "  }"
+                              "]}"));
+    module_session.setLocalConfig(map);
+    server_.setConfigSession(&module_session);
+
+    // The loadzone command needs the zone to be already loaded, because
+    // it is used for reloading only
+    AuthSrv::InMemoryClientPtr dsrc(new InMemoryClient());
+    dsrc->addZone(ZoneFinderPtr(new InMemoryZoneFinder(RRClass::IN(),
+                                                       Name("example.org"))));
+    server_.setInMemoryClient(RRClass::IN(), dsrc);
+
+    // Now send the command to reload it
+    result_ = execAuthServerCommand(server_, "loadzone",
+        Element::fromJSON("{\"origin\": \"example.org\"}"));
+    checkAnswer(0);
+
+    // Get the zone and look if there are data in it (the original one was
+    // empty)
+    ASSERT_TRUE(server_.getInMemoryClient(RRClass::IN()));
+    EXPECT_EQ(ZoneFinder::SUCCESS, server_.getInMemoryClient(RRClass::IN())->
+              findZone(Name("example.org")).zone_finder->
+              find(Name("example.org"), RRType::SOA())->code);
+
+    // Some error cases. First, the zone has no configuration.
+    dsrc->addZone(ZoneFinderPtr(new InMemoryZoneFinder(RRClass::IN(),
+                                                       Name("example.com"))));
+    result_ = execAuthServerCommand(server_, "loadzone",
+        Element::fromJSON("{\"origin\": \"example.com\"}"));
+    checkAnswer(1);
+
+    // The previous zone is not hurt in any way
+    EXPECT_EQ(ZoneFinder::SUCCESS, server_.getInMemoryClient(RRClass::IN())->
+              findZone(Name("example.org")).zone_finder->
+              find(Name("example.org"), RRType::SOA())->code);
+
+    module_session.setLocalConfig(Element::fromJSON("{\"datasources\": []}"));
+    result_ = execAuthServerCommand(server_, "loadzone",
+        Element::fromJSON("{\"origin\": \"example.org\"}"));
+    checkAnswer(1);
+
+    // The previous zone is not hurt in any way
+    EXPECT_EQ(ZoneFinder::SUCCESS, server_.getInMemoryClient(RRClass::IN())->
+              findZone(Name("example.org")).zone_finder->
+              find(Name("example.org"), RRType::SOA())->code);
+    // Configure an unreadable zone. Should fail, but leave the original zone
+    // data there
+    const ElementPtr
+        mapBad(Element::fromJSON("{\"datasources\": ["
+                                 "  {"
+                                 "    \"type\": \"memory\","
+                                 "    \"zones\": ["
+                                 "      {"
+                                 "        \"origin\": \"example.org\","
+                                 "        \"file\": \"" + bad_db + "\","
+                                 "        \"filetype\": \"sqlite3\""
+                                 "      }"
+                                 "    ]"
+                                 "  }"
+                                 "]}"));
+    module_session.setLocalConfig(mapBad);
+    result_ = execAuthServerCommand(server_, "loadzone",
+        Element::fromJSON("{\"origin\": \"example.com\"}"));
+    checkAnswer(1);
+    // The previous zone is not hurt in any way
+    EXPECT_EQ(ZoneFinder::SUCCESS, server_.getInMemoryClient(RRClass::IN())->
+              findZone(Name("example.org")).zone_finder->
+              find(Name("example.org"), RRType::SOA())->code);
+
+    // Broken configuration (not valid against the spec)
+    const ElementPtr
+        broken(Element::fromJSON("{\"datasources\": ["
+                                 "  {"
+                                 "    \"type\": \"memory\","
+                                 "    \"zones\": [[]]"
+                                 "  }"
+                                 "]}"));
+    module_session.setLocalConfig(broken);
+    checkAnswer(1);
+    // The previous zone is not hurt in any way
+    EXPECT_EQ(ZoneFinder::SUCCESS, server_.getInMemoryClient(RRClass::IN())->
+              findZone(Name("example.org")).zone_finder->
+              find(Name("example.org"), RRType::SOA())->code);
+}
+
 TEST_F(AuthCommandTest, loadBrokenZone) {
     configureZones(server_);
 
diff --git a/src/bin/auth/tests/datasrc_util.h b/src/bin/auth/tests/datasrc_util.h
index fc4109b..07ebc0c 100644
--- a/src/bin/auth/tests/datasrc_util.h
+++ b/src/bin/auth/tests/datasrc_util.h
@@ -24,10 +24,7 @@ namespace isc {
 namespace auth {
 namespace unittest {
 
-// Here we define utility modules for the convenience of tests that create
-// a data source client according to the specified conditions.
-
-/// \brief Create an SQLite3 data source client from a stream.
+/// \brief Create an SQLite3 database file for a given zone from a stream.
 ///
 /// This function creates an SQLite3 DB file for the specified zone
 /// with specified content.  The zone will be created in the given



More information about the bind10-changes mailing list