BIND 10 master, updated. 686594e391c645279cc4a95e0e0020d1c01fba7e [master] Merge branch 'trac2213'
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Nov 1 10:51:18 UTC 2012
The branch, master has been updated
via 686594e391c645279cc4a95e0e0020d1c01fba7e (commit)
via 42298cee62c386318f248bcae47d99a39094a10a (commit)
via 0192fd73649d14ade8dc284c64f38d5e0d8b0705 (commit)
via 08baa5371d0939356ba56f24f2d537834f7e9bac (commit)
via d3bdb3c1c1dca514322fefdaac18a253364dfd2f (commit)
via 105208c1e8cd0a77cb8960013a391cc7b48f7a22 (commit)
via f4390da9f83529b6c3ed4383d7709e9ede1c3d5b (commit)
via 4965591081ad8457f5ff0f3fe3c581f8e1a4da54 (commit)
via 83a6c4414e87db481e684f8b6757182a5b8a2cae (commit)
via 7b11fd33ba9b3b0548a1b0e72b337fe5e3843b3b (commit)
via 7151128386c71f20f2e51a156d1fb1746fcd7bfa (commit)
from b1b6e109cda0458811ab61be4263a51b5520ce0b (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 686594e391c645279cc4a95e0e0020d1c01fba7e
Merge: b1b6e10 42298ce
Author: Jelte Jansen <jelte at isc.org>
Date: Thu Nov 1 11:50:19 2012 +0100
[master] Merge branch 'trac2213'
Conflicts:
src/bin/auth/command.cc
-----------------------------------------------------------------------
Summary of changes:
src/bin/auth/auth_messages.mes | 5 -
src/bin/auth/command.cc | 46 +---
src/bin/auth/datasrc_clients_mgr.h | 84 +++++-
src/bin/auth/tests/auth_srv_unittest.cc | 23 ++
src/bin/auth/tests/command_unittest.cc | 275 --------------------
.../auth/tests/datasrc_clients_builder_unittest.cc | 6 -
src/bin/auth/tests/datasrc_clients_mgr_unittest.cc | 49 ++++
tests/lettuce/features/ddns_system.feature | 8 +-
.../lettuce/features/inmemory_over_sqlite3.feature | 2 +-
9 files changed, 157 insertions(+), 341 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/auth/auth_messages.mes b/src/bin/auth/auth_messages.mes
index 163b6ba..221d122 100644
--- a/src/bin/auth/auth_messages.mes
+++ b/src/bin/auth/auth_messages.mes
@@ -178,11 +178,6 @@ has requested the keyring holding TSIG keys from the configuration
database. It is issued during server startup is an indication that the
initialization is proceeding normally.
-% AUTH_LOAD_ZONE loaded zone %1/%2
-This debug message is issued during the processing of the 'loadzone' command
-when the authoritative server has successfully loaded the named zone of the
-named class.
-
% AUTH_MEM_DATASRC_DISABLED memory data source is disabled for class %1
This is a debug message reporting that the authoritative server has
discovered that the memory data source is disabled for the given class.
diff --git a/src/bin/auth/command.cc b/src/bin/auth/command.cc
index 606fd3f..9fbfb42 100644
--- a/src/bin/auth/command.cc
+++ b/src/bin/auth/command.cc
@@ -176,51 +176,7 @@ public:
virtual ConstElementPtr exec(AuthSrv& server,
isc::data::ConstElementPtr args)
{
- if (args == NULL) {
- isc_throw(AuthCommandError, "Null argument");
- }
-
- ConstElementPtr class_elem = args->get("class");
- RRClass zone_class(class_elem ? RRClass(class_elem->stringValue()) :
- RRClass::IN());
-
- ConstElementPtr origin_elem = args->get("origin");
- if (!origin_elem) {
- isc_throw(AuthCommandError, "Zone origin is missing");
- }
- const Name origin(origin_elem->stringValue());
-
- DataSrcClientsMgr::Holder holder(server.getDataSrcClientsMgr());
- boost::shared_ptr<ConfigurableClientList> list =
- holder.findClientList(zone_class);
-
- if (!list) {
- isc_throw(AuthCommandError, "There's no client list for "
- "class " << zone_class);
- }
-
- switch (list->reload(origin)) {
- case ConfigurableClientList::ZONE_SUCCESS:
- // Everything worked fine.
- LOG_DEBUG(auth_logger, DBG_AUTH_OPS, AUTH_LOAD_ZONE)
- .arg(zone_class).arg(origin);
- return (createAnswer());
- case ConfigurableClientList::ZONE_NOT_FOUND:
- isc_throw(AuthCommandError, "Zone " << origin << "/" <<
- zone_class << " was not found in any configured "
- "data source. Configure it first.");
- case ConfigurableClientList::ZONE_NOT_CACHED:
- isc_throw(AuthCommandError, "Zone " << origin << "/" <<
- zone_class << " is not served from memory, but "
- "directly from the data source. It is not possible "
- "to reload it into memory. Configure it to be cached "
- "first.");
- case ConfigurableClientList::CACHE_DISABLED:
- // This is an internal error. Auth server must have the cache
- // enabled.
- isc_throw(isc::Unexpected, "Cache disabled in client list of "
- "class " << zone_class);
- }
+ server.getDataSrcClientsMgr().loadZone(args);
return (createAnswer());
}
};
diff --git a/src/bin/auth/datasrc_clients_mgr.h b/src/bin/auth/datasrc_clients_mgr.h
index 854b1fe..38bf162 100644
--- a/src/bin/auth/datasrc_clients_mgr.h
+++ b/src/bin/auth/datasrc_clients_mgr.h
@@ -45,6 +45,19 @@
namespace isc {
namespace auth {
+/// \brief An exception that is thrown if initial checks for a command fail
+///
+/// This is raised *before* the command to the thread is constructed and
+/// sent, so the application can still handle them (and therefore it is
+/// public, as opposed to InternalCommandError).
+///
+/// And example of its use is currently in loadZone().
+class CommandError : public isc::Exception {
+public:
+ CommandError(const char* file, size_t line, const char* what) :
+ isc::Exception(file, line, what) {}
+};
+
namespace datasrc_clientmgr_internal {
// This namespace is essentially private for DataSrcClientsMgr(Base) and
// DataSrcClientsBuilder(Base). This is exposed in the public header
@@ -239,6 +252,60 @@ public:
clients_map_ = new_lists;
}
+ /// \brief Instruct internal thread to (re)load a zone
+ ///
+ /// \param args Element argument that should be a map of the form
+ /// { "class": "IN", "origin": "example.com" }
+ /// (but class is optional and will default to IN)
+ ///
+ /// \exception CommandError if the args value is null, or not in
+ /// the expected format, or contains
+ /// a bad origin or class string
+ void
+ loadZone(data::ConstElementPtr args) {
+ if (!args) {
+ isc_throw(CommandError, "loadZone argument empty");
+ }
+ if (args->getType() != isc::data::Element::map) {
+ isc_throw(CommandError, "loadZone argument not a map");
+ }
+ if (!args->contains("origin")) {
+ isc_throw(CommandError,
+ "loadZone argument has no 'origin' value");
+ }
+ // Also check if it really is a valid name
+ try {
+ dns::Name(args->get("origin")->stringValue());
+ } catch (const isc::Exception& exc) {
+ isc_throw(CommandError, "bad origin: " << exc.what());
+ }
+
+ if (args->get("origin")->getType() != data::Element::string) {
+ isc_throw(CommandError,
+ "loadZone argument 'origin' value not a string");
+ }
+ if (args->contains("class")) {
+ if (args->get("class")->getType() != data::Element::string) {
+ isc_throw(CommandError,
+ "loadZone argument 'class' value not a string");
+ }
+ // Also check if it is a valid class
+ try {
+ dns::RRClass(args->get("class")->stringValue());
+ } catch (const isc::Exception& exc) {
+ isc_throw(CommandError, "bad class: " << exc.what());
+ }
+ }
+
+ // Note: we could do some more advanced checks here,
+ // e.g. check if the zone is known at all in the configuration.
+ // For now these are skipped, but one obvious way to
+ // implement it would be to factor out the code from
+ // the start of doLoadZone(), and call it here too
+
+ sendCommand(datasrc_clientmgr_internal::LOADZONE, args);
+ }
+
private:
// This is expected to be called at the end of the destructor. It
// actually does nothing, but provides a customization point for
@@ -316,9 +383,6 @@ public:
///
/// It simply sets up a local copy of shared data with the manager.
///
- /// Note: this will take actual set (map) of data source clients and
- /// a mutex object for it in #2210 or #2212.
- ///
/// \throw None
DataSrcClientsBuilderBase(std::list<Command>* command_queue,
CondVarType* cond, MutexType* queue_mutex,
@@ -489,10 +553,20 @@ DataSrcClientsBuilderBase<MutexType, CondVarType>::doLoadZone(
// called via the manager in practice. manager is expected to do the
// minimal validation.
assert(arg);
- assert(arg->get("class"));
assert(arg->get("origin"));
- const dns::RRClass rrclass(arg->get("class")->stringValue());
+ // TODO: currently, we hardcode IN as the default for the optional
+ // 'class' argument. We should really derive this from the specification,
+ // but at the moment the config/command API does not allow that to be
+ // done easily. Once that is in place (tickets have yet to be created,
+ // as we need to do a tiny bit of design work for that), this
+ // code can be replaced with the original part:
+ // assert(arg->get("class"));
+ // const dns::RRClass(arg->get("class")->stringValue());
+ isc::data::ConstElementPtr class_elem = arg->get("class");
+ const dns::RRClass rrclass(class_elem ?
+ dns::RRClass(class_elem->stringValue()) :
+ dns::RRClass::IN());
const dns::Name origin(arg->get("origin")->stringValue());
ClientListsMap::iterator found = (*clients_map_)->find(rrclass);
if (found == (*clients_map_)->end()) {
diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc
index 0cd3420..8015043 100644
--- a/src/bin/auth/tests/auth_srv_unittest.cc
+++ b/src/bin/auth/tests/auth_srv_unittest.cc
@@ -1839,6 +1839,15 @@ namespace {
isc::config::parseAnswer(command_result, response);
EXPECT_EQ(0, command_result);
}
+
+ void sendCommand(AuthSrv& server, const std::string& command,
+ ConstElementPtr args, int expected_result) {
+ ConstElementPtr response = execAuthServerCommand(server, command,
+ args);
+ int command_result = -1;
+ isc::config::parseAnswer(command_result, response);
+ EXPECT_EQ(expected_result, command_result);
+ }
} // end anonymous namespace
TEST_F(AuthSrvTest, DDNSForwardCreateDestroy) {
@@ -1910,4 +1919,18 @@ TEST_F(AuthSrvTest, DDNSForwardCreateDestroy) {
Opcode::UPDATE().getCode(), QR_FLAG, 0, 0, 0, 0);
}
+TEST_F(AuthSrvTest, loadZoneCommand) {
+ // Just some very basic tests, to check the command is accepted, and that
+ // it raises on bad arguments, but not on correct ones (full testing
+ // is handled in the unit tests for the corresponding classes)
+
+ // Empty map should fail
+ ElementPtr args(Element::createMap());
+ sendCommand(server, "loadzone", args, 1);
+ // Setting an origin should be enough (even if it isn't actually loaded,
+ // it should be initially accepted)
+ args->set("origin", Element::create("example.com"));
+ sendCommand(server, "loadzone", args, 0);
+}
+
}
diff --git a/src/bin/auth/tests/command_unittest.cc b/src/bin/auth/tests/command_unittest.cc
index 280def6..be90d73 100644
--- a/src/bin/auth/tests/command_unittest.cc
+++ b/src/bin/auth/tests/command_unittest.cc
@@ -169,281 +169,6 @@ TEST_F(AuthCommandTest, shutdownIncorrectPID) {
EXPECT_EQ(0, rcode_);
}
-// A helper function commonly used for the "loadzone" command tests.
-// It configures the server with a memory data source containing two
-// zones, and checks the zones are correctly loaded.
-void
-zoneChecks(AuthSrv& server) {
- const RRClass rrclass(RRClass::IN());
-
- DataSrcClientsMgr::Holder holder(server.getDataSrcClientsMgr());
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(rrclass)->find(Name("ns.test1.example"))
- .finder_->find(Name("ns.test1.example"), RRType::A())->code);
- EXPECT_EQ(ZoneFinder::NXRRSET,
- holder.findClientList(rrclass)->find(Name("ns.test1.example")).
- finder_->find(Name("ns.test1.example"), RRType::AAAA())->code);
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(rrclass)->find(Name("ns.test2.example")).
- finder_->find(Name("ns.test2.example"), RRType::A())->code);
- EXPECT_EQ(ZoneFinder::NXRRSET,
- holder.findClientList(rrclass)->find(Name("ns.test2.example")).
- finder_->find(Name("ns.test2.example"), RRType::AAAA())->code);
-}
-
-void
-installDataSrcClientLists(AuthSrv& server, ClientListMapPtr lists) {
- server.getDataSrcClientsMgr().setDataSrcClientLists(lists);
-}
-
-void
-configureZones(AuthSrv& server) {
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR "/test1.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR "/test2.zone.in "
- TEST_DATA_BUILDDIR "/test2.zone.copied"));
-
- const ConstElementPtr config(Element::fromJSON("{"
- "\"IN\": [{"
- " \"type\": \"MasterFiles\","
- " \"params\": {"
- " \"test1.example\": \"" +
- string(TEST_DATA_BUILDDIR "/test1.zone.copied") + "\","
- " \"test2.example\": \"" +
- string(TEST_DATA_BUILDDIR "/test2.zone.copied") + "\""
- " },"
- " \"cache-enable\": true"
- "}]}"));
-
- installDataSrcClientLists(server, configureDataSource(config));
-
- zoneChecks(server);
-}
-
-void
-newZoneChecks(AuthSrv& server) {
- const RRClass rrclass(RRClass::IN());
-
- DataSrcClientsMgr::Holder holder(server.getDataSrcClientsMgr());
- EXPECT_EQ(ZoneFinder::SUCCESS, holder.findClientList(rrclass)->
- find(Name("ns.test1.example")).finder_->
- find(Name("ns.test1.example"), RRType::A())->code);
-
- // now test1.example should have ns/AAAA
- EXPECT_EQ(ZoneFinder::SUCCESS, holder.findClientList(rrclass)->
- find(Name("ns.test1.example")).finder_->
- find(Name("ns.test1.example"), RRType::AAAA())->code);
-
- // test2.example shouldn't change
- EXPECT_EQ(ZoneFinder::SUCCESS, holder.findClientList(rrclass)->
- find(Name("ns.test2.example")).finder_->
- find(Name("ns.test2.example"), RRType::A())->code);
- EXPECT_EQ(ZoneFinder::NXRRSET,
- holder.findClientList(rrclass)->
- find(Name("ns.test2.example")).finder_->
- find(Name("ns.test2.example"), RRType::AAAA())->code);
-}
-
-TEST_F(AuthCommandTest, loadZone) {
- configureZones(server_);
-
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
- "/test1-new.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
- "/test2-new.zone.in "
- TEST_DATA_BUILDDIR "/test2.zone.copied"));
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(0);
- newZoneChecks(server_);
-}
-
-TEST_F(AuthCommandTest,
-#ifdef USE_STATIC_LINK
- DISABLED_loadZoneSQLite3
-#else
- loadZoneSQLite3
-#endif
- )
-{
- // 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);
- // This describes the data source in the configuration
- const ConstElementPtr config(Element::fromJSON("{"
- "\"IN\": [{"
- " \"type\": \"sqlite3\","
- " \"params\": {\"database_file\": \"" + test_db + "\"},"
- " \"cache-enable\": true,"
- " \"cache-zones\": [\"example.org\"]"
- "}]}"));
- installDataSrcClientLists(server_, configureDataSource(config));
-
- {
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
-
- // Check that the A record at www.example.org does not exist
- EXPECT_EQ(ZoneFinder::NXDOMAIN,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("www.example.org"), RRType::A())->code);
-
- // Add the record to the underlying sqlite database, by loading
- // it as a separate datasource, and updating it
- ConstElementPtr sql_cfg = Element::fromJSON("{ \"type\": \"sqlite3\","
- "\"database_file\": \""
- + test_db + "\"}");
- DataSourceClientContainer sql_ds("sqlite3", sql_cfg);
- ZoneUpdaterPtr sql_updater =
- sql_ds.getInstance().getUpdater(Name("example.org"), false);
- RRsetPtr rrset(new RRset(Name("www.example.org."), RRClass::IN(),
- RRType::A(), RRTTL(60)));
- rrset->addRdata(rdata::createRdata(rrset->getType(),
- rrset->getClass(),
- "192.0.2.1"));
- sql_updater->addRRset(*rrset);
- sql_updater->commit();
-
- EXPECT_EQ(ZoneFinder::NXDOMAIN,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("www.example.org"), RRType::A())->code);
- }
-
- // Now send the command to reload it
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"example.org\"}"));
- checkAnswer(0, "Successful load");
-
- {
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
- // And now it should be present too.
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("www.example.org"), RRType::A())->code);
- }
-
- // Some error cases. First, the zone has no configuration. (note .com here)
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": \"example.com\"}"));
- checkAnswer(1, "example.com");
-
- {
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
- // The previous zone is not hurt in any way
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("example.org"), RRType::SOA())->code);
- }
-
- const ConstElementPtr config2(Element::fromJSON("{"
- "\"IN\": [{"
- " \"type\": \"sqlite3\","
- " \"params\": {\"database_file\": \"" + bad_db + "\"},"
- " \"cache-enable\": true,"
- " \"cache-zones\": [\"example.com\"]"
- "}]}"));
- EXPECT_THROW(configureDataSource(config2),
- ConfigurableClientList::ConfigurationError);
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": \"example.com\"}"));
- checkAnswer(1, "Unreadable");
-
- DataSrcClientsMgr::Holder holder(server_.getDataSrcClientsMgr());
- // The previous zone is not hurt in any way
- EXPECT_EQ(ZoneFinder::SUCCESS,
- holder.findClientList(RRClass::IN())->
- find(Name("example.org")).finder_->
- find(Name("example.org"), RRType::SOA())->code);
-}
-
-TEST_F(AuthCommandTest, loadBrokenZone) {
- configureZones(server_);
-
- ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR
- "/test1-broken.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(1);
- zoneChecks(server_); // zone shouldn't be replaced
-}
-
-TEST_F(AuthCommandTest, loadUnreadableZone) {
- configureZones(server_);
-
- // install the zone file as unreadable
- ASSERT_EQ(0, system(INSTALL_PROG " -c -m 000 " TEST_DATA_DIR
- "/test1.zone.in "
- TEST_DATA_BUILDDIR "/test1.zone.copied"));
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(1);
- zoneChecks(server_); // zone shouldn't be replaced
-}
-
-TEST_F(AuthCommandTest, loadZoneWithoutDataSrc) {
- // try to execute load command without configuring the zone beforehand.
- // it should fail.
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}"));
- checkAnswer(1);
-}
-
-TEST_F(AuthCommandTest, loadZoneInvalidParams) {
- configureZones(server_);
-
- // null arg
- result_ = execAuthServerCommand(server_, "loadzone", ElementPtr());
- checkAnswer(1, "Null arg");
-
- // zone class is bogus
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\","
- " \"class\": \"no_such_class\"}"));
- checkAnswer(1, "No such class");
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"test1.example\","
- " \"class\": 1}"));
- checkAnswer(1, "Integral class");
-
-
- // origin is missing
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{}"));
- checkAnswer(1, "Missing origin");
-
- // zone doesn't exist in the data source
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": \"xx\"}"));
- checkAnswer(1, "No such zone");
-
- // origin is bogus
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON(
- "{\"origin\": \"...\"}"));
- checkAnswer(1, "Wrong name");
-
- result_ = execAuthServerCommand(server_, "loadzone",
- Element::fromJSON("{\"origin\": 10}"));
- checkAnswer(1, "Integral name");
-}
-
TEST_F(AuthCommandTest, getStats) {
result_ = execAuthServerCommand(server_, "getstats", ConstElementPtr());
parseAnswer(rcode_, result_);
diff --git a/src/bin/auth/tests/datasrc_clients_builder_unittest.cc b/src/bin/auth/tests/datasrc_clients_builder_unittest.cc
index 0712ef7..585e7c3 100644
--- a/src/bin/auth/tests/datasrc_clients_builder_unittest.cc
+++ b/src/bin/auth/tests/datasrc_clients_builder_unittest.cc
@@ -487,12 +487,6 @@ TEST_F(DataSrcClientsBuilderTest, loadZoneInvalidParams) {
// class or origin is missing: result in assertion failure
if (!isc::util::unittests::runningOnValgrind()) {
EXPECT_DEATH_IF_SUPPORTED({
- builder.handleCommand(
- Command(LOADZONE,
- Element::fromJSON(
- "{\"origin\": \"test1.example\"}")));
- }, "");
- EXPECT_DEATH_IF_SUPPORTED({
builder.handleCommand(Command(LOADZONE,
Element::fromJSON(
"{\"class\": \"IN\"}")));
diff --git a/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc b/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc
index 7d1eb4d..c37ef11 100644
--- a/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc
+++ b/src/bin/auth/tests/datasrc_clients_mgr_unittest.cc
@@ -196,6 +196,55 @@ TEST(DataSrcClientsMgrTest, holder) {
EXPECT_THROW(TestDataSrcClientsMgr::Holder holder2(mgr), isc::Unexpected);
}
+TEST(DataSrcClientsMgrTest, reload) {
+ TestDataSrcClientsMgr mgr;
+ EXPECT_TRUE(FakeDataSrcClientsBuilder::started);
+ EXPECT_TRUE(FakeDataSrcClientsBuilder::command_queue->empty());
+
+ isc::data::ElementPtr args =
+ isc::data::Element::fromJSON("{ \"class\": \"IN\","
+ " \"origin\": \"example.com\" }");
+ mgr.loadZone(args);
+ EXPECT_EQ(1, FakeDataSrcClientsBuilder::command_queue->size());
+ mgr.loadZone(args);
+ EXPECT_EQ(2, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // Should fail with non-string 'class' value
+ args->set("class", Element::create(1));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(2, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // And with badclass
+ args->set("class", Element::create("BADCLASS"));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(2, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // Should succeed without 'class'
+ args->remove("class");
+ mgr.loadZone(args);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // but fail without origin, without sending new commands
+ args->remove("origin");
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // And for 'origin' that is not a string
+ args->set("origin", Element::create(1));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // And origin that is not a correct name
+ args->set("origin", Element::create(".."));
+ EXPECT_THROW(mgr.loadZone(args), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+
+ // same for empty data and data that is not a map
+ EXPECT_THROW(mgr.loadZone(isc::data::ConstElementPtr()), CommandError);
+ EXPECT_THROW(mgr.loadZone(isc::data::Element::createList()), CommandError);
+ EXPECT_EQ(3, FakeDataSrcClientsBuilder::command_queue->size());
+}
+
TEST(DataSrcClientsMgrTest, realThread) {
// Using the non-test definition with a real thread. Just checking
// no disruption happens.
diff --git a/tests/lettuce/features/ddns_system.feature b/tests/lettuce/features/ddns_system.feature
index 4a80e14..8e279a7 100644
--- a/tests/lettuce/features/ddns_system.feature
+++ b/tests/lettuce/features/ddns_system.feature
@@ -39,7 +39,7 @@ Feature: DDNS System
# Test 5
When I use DDNS to set the SOA serial to 1237
# also check if Auth server reloaded
- And wait for new bind10 stderr message AUTH_LOAD_ZONE
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1237
@@ -53,12 +53,12 @@ Feature: DDNS System
# Test 8
When I use DDNS to set the SOA serial to 1238
- And wait for new bind10 stderr message AUTH_LOAD_ZONE
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1238
When I use DDNS to set the SOA serial to 1239
- And wait for new bind10 stderr message AUTH_LOAD_ZONE
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1239
@@ -70,7 +70,7 @@ Feature: DDNS System
# Test 10
When I use DDNS to set the SOA serial to 1240
- And wait for new bind10 stderr message AUTH_LOAD_ZONE
+ And wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
The DDNS response should be SUCCESS
And the SOA serial for example.org should be 1240
diff --git a/tests/lettuce/features/inmemory_over_sqlite3.feature b/tests/lettuce/features/inmemory_over_sqlite3.feature
index 851caca..7d8ad6d 100644
--- a/tests/lettuce/features/inmemory_over_sqlite3.feature
+++ b/tests/lettuce/features/inmemory_over_sqlite3.feature
@@ -33,7 +33,7 @@ Feature: In-memory zone using SQLite3 backend
A query for mail.example.org to [::1]:47806 should have rcode NXDOMAIN
When I send bind10 the command Xfrin retransfer example.org IN ::1 47807
Then wait for new bind10 stderr message XFRIN_TRANSFER_SUCCESS not XFRIN_XFR_PROCESS_FAILURE
- Then wait for new bind10 stderr message AUTH_LOAD_ZONE
+ Then wait for new bind10 stderr message AUTH_DATASRC_CLIENTS_BUILDER_LOAD_ZONE
A query for www.example.org to [::1]:47807 should have rcode NOERROR
The answer section of the last query response should be
More information about the bind10-changes
mailing list