|
@@ -21,6 +21,8 @@
|
|
|
#include <datasrc/memory/zone_finder.h>
|
|
|
#include <datasrc/memory/zone_writer.h>
|
|
|
|
|
|
+#include <datasrc/tests/mock_client.h>
|
|
|
+
|
|
|
#include <dns/rrclass.h>
|
|
|
#include <dns/rrttl.h>
|
|
|
#include <dns/rdataclass.h>
|
|
@@ -33,6 +35,7 @@
|
|
|
#include <fstream>
|
|
|
|
|
|
using namespace isc::datasrc;
|
|
|
+using isc::datasrc::unittest::MockDataSourceClient;
|
|
|
using isc::datasrc::memory::InMemoryClient;
|
|
|
using isc::datasrc::memory::ZoneTableSegment;
|
|
|
using isc::datasrc::memory::InMemoryZoneFinder;
|
|
@@ -45,162 +48,6 @@ using namespace std;
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
-// A test data source. It pretends it has some zones.
|
|
|
-class MockDataSourceClient : public DataSourceClient {
|
|
|
-public:
|
|
|
- class Finder : public ZoneFinder {
|
|
|
- public:
|
|
|
- Finder(const Name& origin) :
|
|
|
- origin_(origin)
|
|
|
- {}
|
|
|
- Name getOrigin() const { return (origin_); }
|
|
|
- // The rest is not to be called, so just have them
|
|
|
- RRClass getClass() const {
|
|
|
- isc_throw(isc::NotImplemented, "Not implemented");
|
|
|
- }
|
|
|
- shared_ptr<Context> find(const Name&, const RRType&,
|
|
|
- const FindOptions)
|
|
|
- {
|
|
|
- isc_throw(isc::NotImplemented, "Not implemented");
|
|
|
- }
|
|
|
- shared_ptr<Context> findAll(const Name&,
|
|
|
- vector<ConstRRsetPtr>&,
|
|
|
- const FindOptions)
|
|
|
- {
|
|
|
- isc_throw(isc::NotImplemented, "Not implemented");
|
|
|
- }
|
|
|
- FindNSEC3Result findNSEC3(const Name&, bool) {
|
|
|
- isc_throw(isc::NotImplemented, "Not implemented");
|
|
|
- }
|
|
|
- private:
|
|
|
- Name origin_;
|
|
|
- };
|
|
|
- class Iterator : public ZoneIterator {
|
|
|
- public:
|
|
|
- Iterator(const Name& origin, bool include_a) :
|
|
|
- origin_(origin),
|
|
|
- soa_(new RRset(origin_, RRClass::IN(), RRType::SOA(),
|
|
|
- RRTTL(3600)))
|
|
|
- {
|
|
|
- // The RData here is bogus, but it is not used to anything. There
|
|
|
- // just needs to be some.
|
|
|
- soa_->addRdata(rdata::generic::SOA(Name::ROOT_NAME(),
|
|
|
- Name::ROOT_NAME(),
|
|
|
- 0, 0, 0, 0, 0));
|
|
|
- rrsets_.push_back(soa_);
|
|
|
-
|
|
|
- RRsetPtr rrset(new RRset(origin_, RRClass::IN(), RRType::NS(),
|
|
|
- RRTTL(3600)));
|
|
|
- rrset->addRdata(rdata::generic::NS(Name::ROOT_NAME()));
|
|
|
- rrsets_.push_back(rrset);
|
|
|
-
|
|
|
- if (include_a) {
|
|
|
- // Dummy A rrset. This is used for checking zone data
|
|
|
- // after reload.
|
|
|
- rrset.reset(new RRset(Name("tstzonedata").concatenate(origin_),
|
|
|
- RRClass::IN(), RRType::A(),
|
|
|
- RRTTL(3600)));
|
|
|
- rrset->addRdata(rdata::in::A("192.0.2.1"));
|
|
|
- rrsets_.push_back(rrset);
|
|
|
- }
|
|
|
-
|
|
|
- rrsets_.push_back(ConstRRsetPtr());
|
|
|
-
|
|
|
- it_ = rrsets_.begin();
|
|
|
- }
|
|
|
- virtual isc::dns::ConstRRsetPtr getNextRRset() {
|
|
|
- ConstRRsetPtr result = *it_;
|
|
|
- ++it_;
|
|
|
- return (result);
|
|
|
- }
|
|
|
- virtual isc::dns::ConstRRsetPtr getSOA() const {
|
|
|
- return (soa_);
|
|
|
- }
|
|
|
- private:
|
|
|
- const Name origin_;
|
|
|
- const RRsetPtr soa_;
|
|
|
- std::vector<ConstRRsetPtr> rrsets_;
|
|
|
- std::vector<ConstRRsetPtr>::const_iterator it_;
|
|
|
- };
|
|
|
- // Constructor from a list of zones.
|
|
|
- MockDataSourceClient(const char* zone_names[]) :
|
|
|
- have_a_(true), use_baditerator_(true)
|
|
|
- {
|
|
|
- for (const char** zone(zone_names); *zone; ++zone) {
|
|
|
- zones.insert(Name(*zone));
|
|
|
- }
|
|
|
- }
|
|
|
- // Constructor from configuration. The list of zones will be empty, but
|
|
|
- // it will keep the configuration inside for further inspection.
|
|
|
- MockDataSourceClient(const string& type,
|
|
|
- const ConstElementPtr& configuration) :
|
|
|
- type_(type),
|
|
|
- configuration_(configuration),
|
|
|
- have_a_(true), use_baditerator_(true)
|
|
|
- {
|
|
|
- EXPECT_NE("MasterFiles", type) << "MasterFiles is a special case "
|
|
|
- "and it never should be created as a data source client";
|
|
|
- if (configuration_->getType() == Element::list) {
|
|
|
- for (size_t i(0); i < configuration_->size(); ++i) {
|
|
|
- zones.insert(Name(configuration_->get(i)->stringValue()));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- virtual FindResult findZone(const Name& name) const {
|
|
|
- if (zones.empty()) {
|
|
|
- return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
|
|
|
- }
|
|
|
- set<Name>::const_iterator it(zones.upper_bound(name));
|
|
|
- if (it == zones.begin()) {
|
|
|
- return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
|
|
|
- }
|
|
|
- --it;
|
|
|
- NameComparisonResult compar(it->compare(name));
|
|
|
- const ZoneFinderPtr finder(new Finder(*it));
|
|
|
- switch (compar.getRelation()) {
|
|
|
- case NameComparisonResult::EQUAL:
|
|
|
- return (FindResult(result::SUCCESS, finder));
|
|
|
- case NameComparisonResult::SUPERDOMAIN:
|
|
|
- return (FindResult(result::PARTIALMATCH, finder));
|
|
|
- default:
|
|
|
- return (FindResult(result::NOTFOUND, ZoneFinderPtr()));
|
|
|
- }
|
|
|
- }
|
|
|
- // These methods are not used. They just need to be there to have
|
|
|
- // complete vtable.
|
|
|
- virtual ZoneUpdaterPtr getUpdater(const Name&, bool, bool) const {
|
|
|
- isc_throw(isc::NotImplemented, "Not implemented");
|
|
|
- }
|
|
|
- virtual pair<ZoneJournalReader::Result, ZoneJournalReaderPtr>
|
|
|
- getJournalReader(const Name&, uint32_t, uint32_t) const
|
|
|
- {
|
|
|
- isc_throw(isc::NotImplemented, "Not implemented");
|
|
|
- }
|
|
|
- virtual ZoneIteratorPtr getIterator(const Name& name, bool) const {
|
|
|
- if (use_baditerator_ && name == Name("noiter.org")) {
|
|
|
- isc_throw(isc::NotImplemented, "Asked not to be implemented");
|
|
|
- } else if (use_baditerator_ && name == Name("null.org")) {
|
|
|
- return (ZoneIteratorPtr());
|
|
|
- } else {
|
|
|
- FindResult result(findZone(name));
|
|
|
- if (result.code == isc::datasrc::result::SUCCESS) {
|
|
|
- return (ZoneIteratorPtr(new Iterator(name, have_a_)));
|
|
|
- } else {
|
|
|
- isc_throw(DataSourceError, "No such zone");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- void disableA() { have_a_ = false; }
|
|
|
- void disableBadIterator() { use_baditerator_ = false; }
|
|
|
- const string type_;
|
|
|
- const ConstElementPtr configuration_;
|
|
|
-private:
|
|
|
- set<Name> zones;
|
|
|
- bool have_a_; // control the iterator behavior whether to include A record
|
|
|
- bool use_baditerator_; // whether to use bogus zone iterators for tests
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
// The test version is the same as the normal version. We, however, add
|
|
|
// some methods to dig directly in the internals, for the tests.
|
|
|
class TestedList : public ConfigurableClientList {
|