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