From: JINMEI Tatuya Date: Tue, 21 May 2013 17:50:21 +0000 (-0700) Subject: [2905] add an "empty zone" in the auth query test setup, fixing a test bug. X-Git-Tag: bind10-1.2.0beta1-release~434^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2f0e203d44adda18249239ff33a75102a8477e82;p=thirdparty%2Fkea.git [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/mock_client.cc. --- diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc index 9bf1358ca2..0c11dcd591 100644 --- a/src/bin/auth/tests/query_unittest.cc +++ b/src/bin/auth/tests/query_unittest.cc @@ -133,6 +133,12 @@ const char* const unsigned_delegation_nsec3_txt = "q81r598950igr1eqvc60aedlq66425b5.example.com. 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 = "empty.example.org"; + // 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(new SingletonList(client))); case INMEMORY: list.reset(new ConfigurableClientList(RRClass::IN())); + // Configure one normal zone and one "empty" zone. list->configure(isc::data::Element::fromJSON( "[{\"type\": \"MasterFiles\"," " \"cache-enable\": true, " " \"params\": {\"example.com\": \"" + - string(TEST_OWN_DATA_BUILDDIR "/example.zone") + + string(TEST_OWN_DATA_BUILDDIR "/example.zone\",") + + + "\"" + EMPTY_ZONE_NAME + "\": \"" + + string(TEST_OWN_DATA_BUILDDIR "/nosuchfile.zone") + "\"}}]"), true); return (list); case SQLITE3: @@ -834,39 +843,38 @@ createDataSrcClientList(DataSrcType type, DataSourceClient& client) { class MockClient : public DataSourceClient { public: virtual FindResult findZone(const isc::dns::Name& origin) const { - const Name r_origin(origin.reverse()); - std::map::const_iterator it = - zone_finders_.lower_bound(r_origin); - - if (it != zone_finders_.end()) { - const NameComparisonResult result = - origin.compare((it->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/mock_client.cc. - // 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. - --it; - const NameComparisonResult result = - origin.compare((it->first).reverse()); - if (result.getRelation() == NameComparisonResult::SUBDOMAIN) { - return (FindResult(result::PARTIALMATCH, it->second)); + std::map::const_iterator it = + zone_finders_.upper_bound(origin); + 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->first.compare(origin)); + switch (compar.getRelation()) { + case NameComparisonResult::EQUAL: + return (FindResult(result::SUCCESS, it->second, flags)); + case NameComparisonResult::SUPERDOMAIN: + return (FindResult(result::PARTIALMATCH, it->second, flags)); + default: + 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 + { isc_throw(isc::NotImplemented, "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); } private: // 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 zone_finders_; }; @@ -916,9 +927,10 @@ protected: response.setRcode(Rcode::NOERROR()); response.setOpcode(Opcode::QUERY()); - // create and add a matching zone. + // create and add a matching zone. One is a "broken, empty" zone. mock_finder = new MockZoneFinder(); mock_client.addZone(ZoneFinderPtr(mock_finder)); + mock_client.addEmptyZone(Name(EMPTY_ZONE_NAME)); } virtual void SetUp() { @@ -1144,8 +1156,7 @@ TEST_P(QueryTest, noZone) { // REFUSED. MockClient empty_mock_client; SingletonList empty_list(empty_mock_client); - EXPECT_NO_THROW(query.process(empty_list, qname, qtype, - response)); + 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) { EXPECT_NO_THROW(query.process(*list_, Name("nxdomain.example.com"), qtype,