Commit 2f0e203d authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2905] add an "empty zone" in the auth query test setup, fixing a test bug.

the mock findZone() implementation was buggy and wouldn't work correctly
if there were actually more than one zone.  fixed it by porting
MockDataSourceClient::findZone() from datasrc/tests/
parent 46d8b003
......@@ -133,6 +133,12 @@ const char* const unsigned_delegation_nsec3_txt =
" 3600 IN NSEC3 1 1 12 "
"aabbccdd 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom NS RRSIG\n";
// Name of an "empty" zone: used to simulate the case of
// configured-but-available zone (due to load errors, etc).
// Each tested data source client is expected to have this zone (SQLite3
// currently doesn't have this concept so it's skipped)
const char* const EMPTY_ZONE_NAME = "";
// A helper function that generates a textual representation of RRSIG RDATA
// for the given covered type. The resulting RRSIG may not necessarily make
// sense in terms of the DNSSEC protocol, but for our testing purposes it's
......@@ -799,11 +805,14 @@ createDataSrcClientList(DataSrcType type, DataSourceClient& client) {
return (boost::shared_ptr<ClientList>(new SingletonList(client)));
list.reset(new ConfigurableClientList(RRClass::IN()));
// Configure one normal zone and one "empty" zone.
"[{\"type\": \"MasterFiles\","
" \"cache-enable\": true, "
" \"params\": {\"\": \"" +
string(TEST_OWN_DATA_BUILDDIR "/\",") +
+ "\"" + EMPTY_ZONE_NAME + "\": \"" +
"\"}}]"), true);
return (list);
case SQLITE3:
......@@ -834,39 +843,38 @@ createDataSrcClientList(DataSrcType type, DataSourceClient& client) {
class MockClient : public DataSourceClient {
virtual FindResult findZone(const isc::dns::Name& origin) const {
const Name r_origin(origin.reverse());
std::map<Name, ZoneFinderPtr>::const_iterator it =
if (it != zone_finders_.end()) {
const NameComparisonResult result =>first).reverse());
if (result.getRelation() == NameComparisonResult::EQUAL) {
return (FindResult(result::SUCCESS, it->second));
} else if (result.getRelation() == NameComparisonResult::SUBDOMAIN) {
return (FindResult(result::PARTIALMATCH, it->second));
// Identify the next (strictly) larger name than the given 'origin' in
// the map. Its predecessor (if any) is the longest matching name
// if it's either an exact match or a super domain; otherwise there's
// no match in the map. See also datasrc/tests/
// If it is at the beginning of the map, then the name was not
// found (we have already handled the element the iterator
// points to).
if (it == zone_finders_.begin()) {
// Eliminate the case of empty map to simply the rest of the code
if (zone_finders_.empty()) {
return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
// Check if the previous element is a partial match.
const NameComparisonResult result =>first).reverse());
if (result.getRelation() == NameComparisonResult::SUBDOMAIN) {
return (FindResult(result::PARTIALMATCH, it->second));
std::map<Name, ZoneFinderPtr>::const_iterator it =
if (it == zone_finders_.begin()) { // no predecessor
return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
--it; // get the predecessor
const result::ResultFlags flags =
it->second ? result::FLAGS_DEFAULT : result::ZONE_EMPTY;
const NameComparisonResult compar(it->;
switch (compar.getRelation()) {
case NameComparisonResult::EQUAL:
return (FindResult(result::SUCCESS, it->second, flags));
case NameComparisonResult::SUPERDOMAIN:
return (FindResult(result::PARTIALMATCH, it->second, flags));
return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
virtual ZoneUpdaterPtr getUpdater(const isc::dns::Name&, bool, bool) const {
virtual ZoneUpdaterPtr getUpdater(const isc::dns::Name&, bool, bool) const
"Updater isn't supported in the MockClient");
......@@ -878,18 +886,21 @@ public:
result::Result addZone(ZoneFinderPtr finder) {
// Use the reverse of the name as the key, so we can quickly
// find partial matches in the map.
zone_finders_[finder->getOrigin().reverse()] = finder;
zone_finders_[finder->getOrigin()] = finder;
return (result::SUCCESS);
// "configure" a zone with no data. This will cause the ZONE_EMPTY flag
// on in finZone().
result::Result addEmptyZone(const Name& zone_name) {
zone_finders_[zone_name] = ZoneFinderPtr();
return (result::SUCCESS);
// Note that because we no longer have the old RBTree, and the new
// in-memory DomainTree is not useful as it returns const nodes, we
// use a std::map instead. In this map, the key is a name stored in
// reverse order of labels to aid in finding partial matches
// quickly.
// use a std::map instead.
std::map<Name, ZoneFinderPtr> zone_finders_;
......@@ -916,9 +927,10 @@ protected:
// create and add a matching zone.
// create and add a matching zone. One is a "broken, empty" zone.
mock_finder = new MockZoneFinder();
virtual void SetUp() {
......@@ -1144,8 +1156,7 @@ TEST_P(QueryTest, noZone) {
MockClient empty_mock_client;
SingletonList empty_list(empty_mock_client);
EXPECT_NO_THROW(query.process(empty_list, qname, qtype,
EXPECT_NO_THROW(query.process(empty_list, qname, qtype, response));
EXPECT_EQ(Rcode::REFUSED(), response.getRcode());
......@@ -1400,7 +1411,6 @@ TEST_F(QueryTestForMockOnly, badSecureDelegation) {
qtype, response));
TEST_P(QueryTest, nxdomain) {
Name(""), qtype,
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment