BIND 10 master, updated. b321b2e7708069b82bae12eb1b4461f4eb9e4a03 Merge #2835

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Mar 27 09:41:33 UTC 2013


The branch, master has been updated
       via  b321b2e7708069b82bae12eb1b4461f4eb9e4a03 (commit)
       via  fe630ca4be50f0f0bd048eec264b8a21df9c6b38 (commit)
       via  7f62c19c5d561e755570b8aeab625dd275ecae3a (commit)
       via  4c90b6cf817c2087052ea8b22e91a3b7f8ae39f0 (commit)
       via  946126b36db6b9cd21c194a84a61417dd6bd567c (commit)
       via  8c6afd880d47f33174b656ed12a2e5e4c821e14b (commit)
       via  22407c48db5999e77a6fbd6e4f42ba2a3fe36762 (commit)
       via  bc87d1113832e7900d3627663c0a1203c3e7b2da (commit)
       via  6fadd98cb5a9beeb79c58ba0a2768d9ad895c210 (commit)
       via  e1c60036dfd2d4e1fcd372807e4a3f0f201028cb (commit)
       via  6e0725b08ad12bafcc939622daa5a2f7b734ecbe (commit)
       via  8377d0dcf3c758cc50111a98a7a9dafdc3237c44 (commit)
       via  5e9811640dc3e514ee012b16287522f7993ade46 (commit)
       via  d007842f66f874ad8ceacf664f8c0645d2ec4226 (commit)
       via  d25f0e1e01a6cc3991ae63f0957c61ec171395ce (commit)
       via  0be5bed016c3b12abf5e7049ab7b63d2d474efc0 (commit)
       via  2e6d5f8d602a632d8a770c13d7ccbc09a25825ad (commit)
       via  7642e09748501d041309b84de9d46b3aeab74a63 (commit)
       via  9dd3b10a7ce79fb1b1289136987f82c2bf9c2310 (commit)
       via  739735c08bb30957be78506bc4cf0d6c5f01745d (commit)
       via  01e052f372b1878b9bc40bfcea80d37e408a58ca (commit)
       via  25b99148984082fd818624cd74cde2d86d428c2b (commit)
       via  97a7be5ddb8f5a89206912eae174bacf3d230a8e (commit)
       via  f37600d5ae721b626b9e9323dbff17a404908e46 (commit)
      from  0107d1f09fb6075c9fc2ea6a162c85d4a89a8e85 (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 b321b2e7708069b82bae12eb1b4461f4eb9e4a03
Merge: 0107d1f fe630ca
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Wed Mar 27 10:14:58 2013 +0100

    Merge #2835
    
    The interface to get cache properties from the client list.

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

Summary of changes:
 src/bin/auth/tests/auth_srv_unittest.cc       |    2 +-
 src/bin/cfgmgr/plugins/datasrc.spec.pre.in    |    5 ++
 src/bin/cfgmgr/plugins/tests/datasrc_test.py  |   95 +++++++++++++++++++++++++
 src/lib/cc/data.h                             |    2 +-
 src/lib/datasrc/client_list.cc                |   38 ++++++++--
 src/lib/datasrc/client_list.h                 |   85 +++++++++++++++++++++-
 src/lib/datasrc/tests/client_list_unittest.cc |   95 +++++++++++++++++++++++--
 7 files changed, 308 insertions(+), 14 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index 931d1e2..de148bc 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -1759,7 +1759,7 @@ public:
              data_sources_.push_back(
                  DataSourceInfo(client.get(),
                                 isc::datasrc::DataSourceClientContainerPtr(),
-                                false, RRClass::IN(), ztable_segment_));
+                                false, RRClass::IN(), ztable_segment_, ""));
         }
     }
 private:
diff --git a/src/bin/cfgmgr/plugins/datasrc.spec.pre.in b/src/bin/cfgmgr/plugins/datasrc.spec.pre.in
index 6d5bd77..e7bc6ae 100644
--- a/src/bin/cfgmgr/plugins/datasrc.spec.pre.in
+++ b/src/bin/cfgmgr/plugins/datasrc.spec.pre.in
@@ -63,6 +63,11 @@
                                     "item_optional": false,
                                     "item_default": ""
                                 }
+                            },
+                            {
+                                "item_name": "name",
+                                "item_type": "string",
+                                "item_optional": true
                             }
                         ]
                     }
diff --git a/src/bin/cfgmgr/plugins/tests/datasrc_test.py b/src/bin/cfgmgr/plugins/tests/datasrc_test.py
index 83ec4ca..3c714c6 100644
--- a/src/bin/cfgmgr/plugins/tests/datasrc_test.py
+++ b/src/bin/cfgmgr/plugins/tests/datasrc_test.py
@@ -153,6 +153,101 @@ class DatasrcTest(unittest.TestCase):
             }
         }]})
 
+    def test_names_present(self):
+        """
+        Test we don't choke on configuration with the "name" being present on
+        some items.
+        """
+        self.accept({"IN": [{
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {},
+            "name": "Whatever"
+        }]})
+
+    def test_names_default_classes(self):
+        """
+        Test we can have a client of the same type in different classes
+        without specified name. The defaults should be derived both from
+        the type and the class.
+        """
+        self.accept({
+        "IN": [{
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {}
+        }],
+        "CH": [{
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {}
+        }]})
+
+    def test_names_collision(self):
+        """
+        Reject when two names are the same.
+
+        Cases are:
+        - Explicit names.
+        - Two default names turn out to be the same (same type and class).
+        - One explicit is set to the same as the default one.
+        """
+        self.reject({"IN": [
+        {
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {},
+            "name": "Whatever"
+        },
+        {
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {},
+            "name": "Whatever"
+        }]})
+        # The same, but across different classes is allowed (we would
+        # identify the data source by class+name tuple)
+        self.accept({
+        "IN": [
+            {
+                "type": "MasterFiles",
+                "cache-enable": True,
+                "params": {},
+                "name": "Whatever"
+            }
+        ],
+        "CH": [
+            {
+                "type": "MasterFiles",
+                "cache-enable": True,
+                "params": {},
+                "name": "Whatever"
+            }
+        ]})
+        self.reject({"IN": [
+        {
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {}
+        },
+        {
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {}
+        }]})
+        self.reject({"IN": [
+        {
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {},
+            "name": "MasterFiles"
+        },
+        {
+            "type": "MasterFiles",
+            "cache-enable": True,
+            "params": {}
+        }]})
+
 if __name__ == '__main__':
     isc.log.init("bind10")
     isc.log.resetUnitTestRootLogger()
diff --git a/src/lib/cc/data.h b/src/lib/cc/data.h
index 74e5c12..d0e0d03 100644
--- a/src/lib/cc/data.h
+++ b/src/lib/cc/data.h
@@ -216,7 +216,7 @@ public:
     //@{
     /// Returns the ElementPtr at the given key
     /// \param name The key of the Element to return
-    /// \return The ElementPtr at the given key
+    /// \return The ElementPtr at the given key, or null if not present
     virtual ConstElementPtr get(const std::string& name) const;
 
     /// Sets the ElementPtr at the given key
diff --git a/src/lib/datasrc/client_list.cc b/src/lib/datasrc/client_list.cc
index 0750fb6..eb60a96 100644
--- a/src/lib/datasrc/client_list.cc
+++ b/src/lib/datasrc/client_list.cc
@@ -27,6 +27,7 @@
 #include <util/memory_segment_local.h>
 
 #include <memory>
+#include <set>
 #include <boost/foreach.hpp>
 #include <boost/bind.hpp>
 
@@ -47,9 +48,11 @@ namespace datasrc {
 ConfigurableClientList::DataSourceInfo::DataSourceInfo(
     DataSourceClient* data_src_client,
     const DataSourceClientContainerPtr& container, bool has_cache,
-    const RRClass& rrclass, const shared_ptr<ZoneTableSegment>& segment) :
+    const RRClass& rrclass, const shared_ptr<ZoneTableSegment>& segment,
+    const string& name) :
     data_src_client_(data_src_client),
-    container_(container)
+    container_(container),
+    name_(name)
 {
     if (has_cache) {
         cache_.reset(new InMemoryClient(segment, rrclass));
@@ -59,8 +62,9 @@ ConfigurableClientList::DataSourceInfo::DataSourceInfo(
 
 ConfigurableClientList::DataSourceInfo::DataSourceInfo(
     const RRClass& rrclass, const shared_ptr<ZoneTableSegment>& segment,
-    bool has_cache) :
-    data_src_client_(NULL)
+    bool has_cache, const string& name) :
+    data_src_client_(NULL),
+    name_(name)
 {
     if (has_cache) {
         cache_.reset(new InMemoryClient(segment, rrclass));
@@ -92,6 +96,7 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
         vector<DataSourceInfo> new_data_sources;
         shared_ptr<ZoneTableSegment> ztable_segment(
             ZoneTableSegment::create(*config, rrclass_));
+        set<string> used_names;
         for (; i < config->size(); ++i) {
             // Extract the parameters
             const ConstElementPtr dconf(config->get(i));
@@ -108,6 +113,13 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
             const bool want_cache(allow_cache &&
                                   dconf->contains("cache-enable") &&
                                   dconf->get("cache-enable")->boolValue());
+            // Get the name (either explicit, or guess)
+            const ConstElementPtr name_elem(dconf->get("name"));
+            const string name(name_elem ? name_elem->stringValue() : type);
+            if (!used_names.insert(name).second) {
+                isc_throw(ConfigurationError, "Duplicit name in client list: "
+                          << name);
+            }
 
             if (type == "MasterFiles") {
                 // In case the cache is not allowed, we just skip the master
@@ -130,7 +142,7 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
                 }
                 new_data_sources.push_back(DataSourceInfo(rrclass_,
                                                           ztable_segment,
-                                                          true));
+                                                          true, name));
             } else {
                 // Ask the factory to create the data source for us
                 const DataSourcePair ds(this->getDataSourceClient(type,
@@ -138,7 +150,8 @@ ConfigurableClientList::configure(const ConstElementPtr& config,
                 // And put it into the vector
                 new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
                                                           want_cache, rrclass_,
-                                                          ztable_segment));
+                                                          ztable_segment,
+                                                          name));
             }
 
             if (want_cache) {
@@ -462,5 +475,18 @@ ConfigurableClientList::getDataSourceClient(const string& type,
     return (DataSourcePair(&container->getInstance(), container));
 }
 
+vector<DataSourceStatus>
+ConfigurableClientList::getStatus() const {
+    vector<DataSourceStatus> result;
+    BOOST_FOREACH(const DataSourceInfo& info, data_sources_) {
+        // TODO: Once we support mapped cache, decide when we need the
+        // SEGMENT_WAITING.
+        result.push_back(DataSourceStatus(info.name_, info.cache_ ?
+                                          SEGMENT_INUSE : SEGMENT_UNUSED,
+                                          "local"));
+    }
+    return (result);
+}
+
 }
 }
diff --git a/src/lib/datasrc/client_list.h b/src/lib/datasrc/client_list.h
index d1a35b5..256ad36 100644
--- a/src/lib/datasrc/client_list.h
+++ b/src/lib/datasrc/client_list.h
@@ -46,6 +46,76 @@ class InMemoryClient;
 class ZoneWriter;
 }
 
+/// \brief Segment status of the cache
+///
+/// Describes the status in which the memory segment for the in-memory cache of
+// /given data source is.
+enum MemorySegmentState {
+    /// \brief No segment used for this data source.
+    ///
+    /// This is usually a result of the cache being disabled.
+    SEGMENT_UNUSED,
+
+    /// \brief It is a mapped segment and we wait for information how to map
+    ///     it.
+    SEGMENT_WAITING,
+
+    /// \brief The segment is ready to be used.
+    SEGMENT_INUSE
+};
+
+/// \brief Status of one data source.
+///
+/// This indicates the status a data soure is in. It is used with segment
+/// and cache management, to discover the data sources that need external
+/// mapping or local loading.
+///
+/// In future, it may be extended for other purposes, such as performing an
+/// operation on named data source.
+class DataSourceStatus {
+public:
+    /// \brief Constructor
+    ///
+    /// Sets initial values. It doesn't matter what is provided for the type
+    /// if state is SEGMENT_UNUSED, the value is effectively ignored.
+    DataSourceStatus(const std::string& name, MemorySegmentState state,
+                     const std::string& type) :
+        name_(name),
+        type_(type),
+        state_(state)
+    {}
+
+    /// \brief Get the segment state
+    MemorySegmentState getSegmentState() const {
+        return (state_);
+    }
+
+    /// \brief Get the segment type
+    ///
+    /// \note Specific values of the type are only meaningful for the
+    ///     corresponding memory segment implementation and modules that
+    ///     directly manage the segments. Other normal applications should
+    ///     treat them as opaque identifiers.
+    ///
+    /// \throw isc::InvalidOperation if called and state is SEGMENT_UNUSED.
+    const std::string& getSegmentType() const {
+        if (getSegmentState() == SEGMENT_UNUSED) {
+            isc_throw(isc::InvalidOperation,
+                      "No segment used, no type therefore.");
+        }
+        return (type_);
+    }
+
+    /// \brief Get the name.
+    const std::string& getName() const {
+        return (name_);
+    }
+private:
+    std::string name_;
+    std::string type_;
+    MemorySegmentState state_;
+};
+
 /// \brief The list of data source clients.
 ///
 /// The purpose of this class is to hold several data source clients and search
@@ -332,13 +402,14 @@ public:
                        const boost::shared_ptr
                            <isc::datasrc::memory::ZoneTableSegment>&
                                ztable_segment,
-                       bool has_cache = false);
+                       bool has_cache = false,
+                       const std::string& name = std::string());
         DataSourceInfo(DataSourceClient* data_src_client,
                        const DataSourceClientContainerPtr& container,
                        bool has_cache, const dns::RRClass& rrclass,
                        const boost::shared_ptr
                            <isc::datasrc::memory::ZoneTableSegment>&
-                               ztable_segment);
+                               ztable_segment, const std::string& name);
         DataSourceClient* data_src_client_;
         DataSourceClientContainerPtr container_;
 
@@ -350,6 +421,7 @@ public:
         const DataSourceClient* getCacheClient() const;
         boost::shared_ptr<memory::InMemoryClient> cache_;
         boost::shared_ptr<memory::ZoneTableSegment> ztable_segment_;
+        std::string name_;
     };
 
     /// \brief The collection of data sources.
@@ -379,6 +451,15 @@ public:
     virtual DataSourcePair getDataSourceClient(const std::string& type,
                                                const data::ConstElementPtr&
                                                configuration);
+
+    /// \brief Get status information of all internal data sources.
+    ///
+    /// Get a DataSourceStatus for current state of each data source client
+    /// in this list.
+    ///
+    /// This may throw standard exceptions, such as std::bad_alloc. Otherwise,
+    /// it is exception free.
+    std::vector<DataSourceStatus> getStatus() const;
 public:
     /// \brief Access to the data source clients.
     ///
diff --git a/src/lib/datasrc/tests/client_list_unittest.cc b/src/lib/datasrc/tests/client_list_unittest.cc
index 3d78138..bc2d4f1 100644
--- a/src/lib/datasrc/tests/client_list_unittest.cc
+++ b/src/lib/datasrc/tests/client_list_unittest.cc
@@ -278,7 +278,7 @@ public:
             ds_.push_back(ds);
             ds_info_.push_back(ConfigurableClientList::DataSourceInfo(
                                    ds.get(), DataSourceClientContainerPtr(),
-                                   false, rrclass_, ztable_segment_));
+                                   false, rrclass_, ztable_segment_, ""));
         }
     }
 
@@ -512,12 +512,12 @@ TEST_F(ListTest, configureMulti) {
     const ConstElementPtr elem(Element::fromJSON("["
         "{"
         "   \"type\": \"type1\","
-        "   \"cache\": \"off\","
+        "   \"cache-enable\": false,"
         "   \"params\": {}"
         "},"
         "{"
         "   \"type\": \"type2\","
-        "   \"cache\": \"off\","
+        "   \"cache-enable\": false,"
         "   \"params\": {}"
         "}]"
     ));
@@ -546,7 +546,7 @@ TEST_F(ListTest, configureParams) {
         ConstElementPtr elem(Element::fromJSON(string("["
             "{"
             "   \"type\": \"t\","
-            "   \"cache\": \"off\","
+            "   \"cache-enable\": false,"
             "   \"params\": ") + *param +
             "}]"));
         list_->configure(elem, true);
@@ -555,6 +555,33 @@ TEST_F(ListTest, configureParams) {
     }
 }
 
+TEST_F(ListTest, status) {
+    EXPECT_TRUE(list_->getStatus().empty());
+    const ConstElementPtr elem(Element::fromJSON("["
+        "{"
+        "   \"type\": \"type1\","
+        "   \"cache-enable\": false,"
+        "   \"params\": {}"
+        "},"
+        "{"
+        "   \"type\": \"type2\","
+        "   \"cache-enable\": true,"
+        "   \"cache-zones\": [],"
+        "   \"name\": \"Test name\","
+        "   \"params\": {}"
+        "}]"
+    ));
+    list_->configure(elem, true);
+    const vector<DataSourceStatus> statuses(list_->getStatus());
+    ASSERT_EQ(2, statuses.size());
+    EXPECT_EQ("type1", statuses[0].getName());
+    EXPECT_EQ(SEGMENT_UNUSED, statuses[0].getSegmentState());
+    EXPECT_THROW(statuses[0].getSegmentType(), isc::InvalidOperation);
+    EXPECT_EQ("Test name", statuses[1].getName());
+    EXPECT_EQ(SEGMENT_INUSE, statuses[1].getSegmentState());
+    EXPECT_EQ("local", statuses[1].getSegmentType());
+}
+
 TEST_F(ListTest, wrongConfig) {
     const char* configs[] = {
         // A lot of stuff missing from there
@@ -834,6 +861,54 @@ TEST_F(ListTest, masterFiles) {
     EXPECT_EQ(0, list_->getDataSources().size());
 }
 
+// Test the names are set correctly and collission is detected.
+TEST_F(ListTest, names) {
+    // Explicit name
+    const ConstElementPtr elem1(Element::fromJSON("["
+        "{"
+        "   \"type\": \"MasterFiles\","
+        "   \"cache-enable\": true,"
+        "   \"params\": {"
+        "       \".\": \"" TEST_DATA_DIR "/root.zone\""
+        "   },"
+        "   \"name\": \"Whatever\""
+        "}]"));
+    list_->configure(elem1, true);
+    EXPECT_EQ("Whatever", list_->getDataSources()[0].name_);
+
+    // Default name
+    const ConstElementPtr elem2(Element::fromJSON("["
+        "{"
+        "   \"type\": \"MasterFiles\","
+        "   \"cache-enable\": true,"
+        "   \"params\": {"
+        "       \".\": \"" TEST_DATA_DIR "/root.zone\""
+        "   }"
+        "}]"));
+    list_->configure(elem2, true);
+    EXPECT_EQ("MasterFiles", list_->getDataSources()[0].name_);
+
+    // Collission
+    const ConstElementPtr elem3(Element::fromJSON("["
+        "{"
+        "   \"type\": \"MasterFiles\","
+        "   \"cache-enable\": true,"
+        "   \"params\": {"
+        "       \".\": \"" TEST_DATA_DIR "/root.zone\""
+        "   }"
+        "},"
+        "{"
+        "   \"type\": \"MasterFiles\","
+        "   \"cache-enable\": true,"
+        "   \"params\": {"
+        "       \".\": \"" TEST_DATA_DIR "/root.zone\""
+        "   },"
+        "   \"name\": \"MasterFiles\""
+        "}]"));
+    EXPECT_THROW(list_->configure(elem3, true),
+                 ConfigurableClientList::ConfigurationError);
+}
+
 TEST_F(ListTest, BadMasterFile) {
     // Configuration should succeed, and the good zones in the list
     // below should be loaded. No bad zones should be loaded.
@@ -1088,4 +1163,16 @@ TYPED_TEST(ReloadTest, reloadMasterFile) {
                                                          RRType::TXT())->code);
 }
 
+// Check the status holds data
+TEST(DataSourceStatus, status) {
+    const DataSourceStatus status("Test", SEGMENT_INUSE, "local");
+    EXPECT_EQ("Test", status.getName());
+    EXPECT_EQ(SEGMENT_INUSE, status.getSegmentState());
+    EXPECT_EQ("local", status.getSegmentType());
+    const DataSourceStatus status_unused("Unused", SEGMENT_UNUSED, "");
+    EXPECT_EQ("Unused", status_unused.getName());
+    EXPECT_EQ(SEGMENT_UNUSED, status_unused.getSegmentState());
+    EXPECT_THROW(status_unused.getSegmentType(), isc::InvalidOperation);
+}
+
 }



More information about the bind10-changes mailing list