1 #define BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_NO_MAIN
8 #include <unordered_map>
10 #include <boost/test/unit_test.hpp>
12 #include <boost/multi_index_container.hpp>
13 #include <boost/multi_index/ordered_index.hpp>
14 #include <boost/multi_index/hashed_index.hpp>
15 #include <boost/multi_index/key_extractors.hpp>
17 #include "arguments.hh"
18 #include "auth-querycache.hh"
19 #include "auth-zonecache.hh"
20 #include "ueberbackend.hh"
22 class SimpleBackend
: public DNSBackend
25 struct SimpleDNSRecord
27 SimpleDNSRecord(const DNSName
& name
, uint16_t type
, const std::string
& content
, uint32_t ttl
): d_content(content
), d_name(name
), d_ttl(ttl
), d_type(type
)
31 std::string d_content
;
37 struct OrderedNameTypeTag
;
39 typedef multi_index_container
<
42 ordered_non_unique
<tag
<OrderedNameTypeTag
>,
45 member
<SimpleDNSRecord
, DNSName
, &SimpleDNSRecord::d_name
>,
46 member
<SimpleDNSRecord
, uint16_t, &SimpleDNSRecord::d_type
>
48 composite_key_compare
<CanonDNSNameCompare
, std::less
<uint16_t> >
55 SimpleDNSZone(const DNSName
& name
, uint64_t id
): d_records(std::make_shared
<RecordStorage
>()), d_name(name
), d_id(id
)
58 std::shared_ptr
<RecordStorage
> d_records
;
63 struct HashedNameTag
{};
66 typedef multi_index_container
<
69 ordered_unique
<tag
<IDTag
>, member
<SimpleDNSZone
, uint64_t, &SimpleDNSZone::d_id
> >,
70 hashed_unique
<tag
<HashedNameTag
>, member
<SimpleDNSZone
, DNSName
, &SimpleDNSZone::d_name
> >
76 SimpleMetaData(const DNSName
& name
, const std::string
& kind
, const std::vector
<std::string
>& values
): d_name(name
), d_kind(kind
), d_values(values
)
82 std::vector
<std::string
> d_values
;
85 struct OrderedNameKindTag
{};
87 typedef multi_index_container
<
90 ordered_unique
<tag
<OrderedNameKindTag
>,
93 member
<SimpleMetaData
, DNSName
, &SimpleMetaData::d_name
>,
94 member
<SimpleMetaData
, std::string
, &SimpleMetaData::d_kind
>
96 composite_key_compare
<CanonDNSNameCompare
, std::less
<std::string
> >
101 // Initialize our backend ID from the suffix, skipping the '-' that DNSBackend adds there
102 SimpleBackend(const std::string
& suffix
): d_suffix(suffix
), d_backendId(pdns_stou(suffix
.substr(1)))
106 bool findZone(const DNSName
& qdomain
, int zoneId
, std::shared_ptr
<RecordStorage
>& records
, uint64_t& currentZoneId
) const
112 const auto& idx
= boost::multi_index::get
<IDTag
>(s_zones
.at(d_backendId
));
113 auto it
= idx
.find(zoneId
);
114 if (it
== idx
.end()) {
117 records
= it
->d_records
;
118 currentZoneId
= it
->d_id
;
121 const auto& idx
= boost::multi_index::get
<HashedNameTag
>(s_zones
.at(d_backendId
));
122 auto it
= idx
.find(qdomain
);
123 if (it
== idx
.end()) {
126 records
= it
->d_records
;
127 currentZoneId
= it
->d_id
;
133 void lookup(const QType
& qtype
, const DNSName
& qdomain
, int zoneId
= -1, DNSPacket
*pkt_p
= nullptr) override
135 d_currentScopeMask
= 0;
136 findZone(qdomain
, zoneId
, d_records
, d_currentZone
);
139 if (qdomain
== DNSName("geo.powerdns.com.") && pkt_p
!= nullptr) {
140 if (pkt_p
->getRealRemote() == Netmask("192.0.2.1")) {
141 d_currentScopeMask
= 32;
143 else if (pkt_p
->getRealRemote() == Netmask("198.51.100.1")) {
144 d_currentScopeMask
= 24;
148 auto& idx
= d_records
->get
<OrderedNameTypeTag
>();
149 if (qtype
== QType::ANY
) {
150 auto range
= idx
.equal_range(qdomain
);
151 d_iter
= range
.first
;
152 d_end
= range
.second
;
155 auto range
= idx
.equal_range(std::make_tuple(qdomain
, qtype
.getCode()));
156 d_iter
= range
.first
;
157 d_end
= range
.second
;
162 bool get(DNSResourceRecord
& drr
) override
168 if (d_iter
== d_end
) {
172 drr
.qname
= d_iter
->d_name
;
173 drr
.domain_id
= d_currentZone
;
174 drr
.content
= d_iter
->d_content
;
175 drr
.qtype
= d_iter
->d_type
;
176 drr
.ttl
= d_iter
->d_ttl
;
178 // drr.auth = d_iter->auth; might bring pain at some point, let's not cross that bridge until then
180 drr
.scopeMask
= d_currentScopeMask
;
186 bool list(const DNSName
& target
, int zoneId
, bool include_disabled
= false) override
188 findZone(target
, zoneId
, d_records
, d_currentZone
);
191 d_iter
= d_records
->begin();
192 d_end
= d_records
->end();
199 bool getDomainMetadata(const DNSName
& name
, const std::string
& kind
, std::vector
<std::string
>& meta
) override
201 const auto& idx
= boost::multi_index::get
<OrderedNameKindTag
>(s_metadata
.at(d_backendId
));
202 auto it
= idx
.find(std::make_tuple(name
, kind
));
203 if (it
== idx
.end()) {
204 /* funnily enough, we are expected to return true even though we might not know that zone */
212 bool setDomainMetadata(const DNSName
& name
, const std::string
& kind
, const std::vector
<std::string
>& meta
) override
214 auto& idx
= boost::multi_index::get
<OrderedNameKindTag
>(s_metadata
.at(d_backendId
));
215 auto it
= idx
.find(std::make_tuple(name
, kind
));
216 if (it
== idx
.end()) {
217 s_metadata
.at(d_backendId
).insert(SimpleMetaData(name
, kind
, meta
));
220 idx
.replace(it
, SimpleMetaData(name
, kind
, meta
));
224 /* this is not thread-safe */
225 static std::unordered_map
<uint64_t, ZoneStorage
> s_zones
;
226 static std::unordered_map
<uint64_t, MetaDataStorage
> s_metadata
;
229 std::string d_suffix
;
230 std::shared_ptr
<RecordStorage
> d_records
{nullptr};
231 RecordStorage::index
<OrderedNameTypeTag
>::type::const_iterator d_iter
;
232 RecordStorage::index
<OrderedNameTypeTag
>::type::const_iterator d_end
;
233 const uint64_t d_backendId
;
234 uint64_t d_currentZone
{0};
235 uint8_t d_currentScopeMask
{0};
238 class SimpleBackendBestAuth
: public SimpleBackend
241 SimpleBackendBestAuth(const std::string
& suffix
): SimpleBackend(suffix
)
245 bool getAuth(const DNSName
& target
, SOAData
* sd
) override
247 static const DNSName
best("d.0.1.0.0.2.ip6.arpa.");
251 if (target
.isPartOf(best
)) {
252 /* return the best SOA right away */
253 std::shared_ptr
<RecordStorage
> records
;
255 if (!findZone(best
, -1, records
, zoneId
)) {
259 auto& idx
= records
->get
<OrderedNameTypeTag
>();
260 auto range
= idx
.equal_range(std::make_tuple(best
, QType::SOA
));
261 if (range
.first
== range
.second
) {
265 fillSOAData(range
.first
->d_content
, *sd
);
266 sd
->ttl
= range
.first
->d_ttl
;
268 sd
->domain_id
= zoneId
;
272 return getSOA(target
, *sd
);
275 size_t d_authLookupCount
{0};
278 class SimpleBackendNoMeta
: public SimpleBackend
281 SimpleBackendNoMeta(const std::string
& suffix
): SimpleBackend(suffix
)
285 bool getDomainMetadata(const DNSName
& name
, const std::string
& kind
, std::vector
<std::string
>& meta
) override
290 bool setDomainMetadata(const DNSName
& name
, const std::string
& kind
, const std::vector
<std::string
>& meta
) override
296 std::unordered_map
<uint64_t, SimpleBackend::ZoneStorage
> SimpleBackend::s_zones
;
297 std::unordered_map
<uint64_t, SimpleBackend::MetaDataStorage
> SimpleBackend::s_metadata
;
299 class SimpleBackendFactory
: public BackendFactory
302 SimpleBackendFactory(): BackendFactory("SimpleBackend")
306 DNSBackend
*make(const string
& suffix
="") override
308 return new SimpleBackend(suffix
);
312 class SimpleBackendBestAuthFactory
: public BackendFactory
315 SimpleBackendBestAuthFactory(): BackendFactory("SimpleBackendBestAuth")
319 DNSBackend
*make(const string
& suffix
="") override
321 return new SimpleBackendBestAuth(suffix
);
325 class SimpleBackendNoMetaFactory
: public BackendFactory
328 SimpleBackendNoMetaFactory(): BackendFactory("SimpleBackendNoMeta")
332 DNSBackend
*make(const string
& suffix
="") override
334 return new SimpleBackendNoMeta(suffix
);
338 struct UeberBackendSetupArgFixture
{
339 UeberBackendSetupArgFixture() {
340 extern AuthQueryCache QC
;
341 ::arg().set("query-cache-ttl")="0";
342 ::arg().set("negquery-cache-ttl")="0";
343 ::arg().set("consistent-backends")="no";
345 g_zoneCache
.setRefreshInterval(0);
347 BackendMakers().clear();
348 SimpleBackend::s_zones
.clear();
349 SimpleBackend::s_metadata
.clear();
353 static void testWithoutThenWithAuthCache(std::function
<void(UeberBackend
& ub
)> func
)
355 extern AuthQueryCache QC
;
358 /* disable the cache */
359 ::arg().set("query-cache-ttl")="0";
360 ::arg().set("negquery-cache-ttl")="0";
363 /* keep zone cache disabled */
364 g_zoneCache
.setRefreshInterval(0);
372 /* enable the cache */
373 ::arg().set("query-cache-ttl")="20";
374 ::arg().set("negquery-cache-ttl")="60";
376 QC
.setMaxEntries(100000);
377 /* keep zone cache disabled */
378 g_zoneCache
.setRefreshInterval(0);
382 /* a first time to fill the cache */
384 /* a second time to make sure every call has been tried with the cache filled */
389 static void testWithoutThenWithZoneCache(std::function
<void(UeberBackend
& ub
)> func
)
391 extern AuthQueryCache QC
;
394 /* disable zone cache */
395 g_zoneCache
.setRefreshInterval(0);
397 /* keep auth caches disabled */
398 ::arg().set("query-cache-ttl")="0";
399 ::arg().set("negquery-cache-ttl")="0";
407 // This test is broken without getAllDomains() in SimpleBackend
409 // /* enable zone cache */
410 // //g_zoneCache.setRefreshInterval(60);
411 // g_zoneCache.clear();
412 // /* keep auth caches disabled */
413 // ::arg().set("query-cache-ttl")="0";
414 // ::arg().set("negquery-cache-ttl")="0";
416 // QC.setMaxEntries(0);
419 // ub.updateZoneCache();
424 BOOST_FIXTURE_TEST_SUITE(test_ueberbackend_cc
, UeberBackendSetupArgFixture
)
426 static std::vector
<DNSZoneRecord
> getRecords(UeberBackend
& ub
, const DNSName
& name
, uint16_t qtype
, int zoneId
, const DNSPacket
* pkt
)
428 std::vector
<DNSZoneRecord
> result
;
430 ub
.lookup(QType(qtype
), name
, zoneId
, const_cast<DNSPacket
*>(pkt
));
435 result
.push_back(std::move(dzr
));
441 static void checkRecordExists(const std::vector
<DNSZoneRecord
>& records
, const DNSName
& name
, uint16_t type
, int zoneId
, uint8_t scopeMask
, bool auth
)
443 BOOST_REQUIRE_GE(records
.size(), 1U);
444 for (const auto& record
: records
) {
445 if (record
.domain_id
== zoneId
&&
446 record
.dr
.d_type
== type
&&
447 record
.dr
.d_name
== name
&&
448 record
.auth
== auth
&&
449 record
.scopeMask
== scopeMask
) {
453 BOOST_CHECK_MESSAGE(false, "Record " + name
.toString() + "/" + QType(type
).toString() + " - " + std::to_string(zoneId
) + " not found");
456 BOOST_AUTO_TEST_CASE(test_simple
) {
459 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
460 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
461 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
462 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
463 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
464 SimpleBackend::s_zones
[1].insert(zoneA
);
466 BackendMakers().report(new SimpleBackendFactory());
467 BackendMakers().launch("SimpleBackend:1");
470 auto testFunction
= [](UeberBackend
& ub
) -> void {
472 // test SOA with unknown zone id == -1
473 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
474 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
475 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
479 // test ANY with zone id == -1
480 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
481 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
482 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
483 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
487 // test AAAA with zone id == -1
488 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
489 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
490 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
494 // test NODATA with zone id == -1
495 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
496 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
500 // test ANY with zone id set
501 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
502 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
503 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
504 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
508 // test AAAA with zone id set
509 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
510 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
511 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
515 // test NODATA with zone id set
516 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
517 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
521 // test ANY with wrong zone id
522 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 65535, nullptr);
523 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
527 // test a DNS packet is correctly passed and that the corresponding scope is passed back
529 ComboAddress
remote("192.0.2.1");
530 pkt
.setRemote(&remote
);
531 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
532 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
533 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
534 // and that we don't get the same result for a different client
535 remote
= ComboAddress("198.51.100.1");
536 pkt
.setRemote(&remote
);
537 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
538 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
539 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
543 testWithoutThenWithAuthCache(testFunction
);
544 testWithoutThenWithZoneCache(testFunction
);
546 catch(const PDNSException
& e
) {
547 cerr
<<e
.reason
<<endl
;
550 catch(const std::exception
& e
) {
551 cerr
<<e
.what()<<endl
;
555 cerr
<<"An unexpected error occurred.."<<endl
;
560 BOOST_AUTO_TEST_CASE(test_multi_backends_separate_zones
) {
561 // one zone in backend 1, a second zone in backend 2
565 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
566 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
567 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
568 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
569 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
570 SimpleBackend::s_zones
[1].insert(zoneA
);
572 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.org."), 2);
573 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::SOA
, "ns1.powerdns.org. powerdns.org. 3 600 600 3600000 604800", 3600));
574 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
575 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
576 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.org."), QType::AAAA
, "2001:db8::42", 60));
577 SimpleBackend::s_zones
[2].insert(zoneB
);
579 BackendMakers().report(new SimpleBackendFactory());
580 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
583 auto testFunction
= [](UeberBackend
& ub
) -> void {
585 // test SOA with unknown zone id == -1
586 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
587 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
588 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
590 records
= getRecords(ub
, DNSName("powerdns.org."), QType::SOA
, -1, nullptr);
591 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
592 checkRecordExists(records
, DNSName("powerdns.org."), QType::SOA
, 2, 0, true);
596 // test ANY with zone id == -1
597 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
598 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
599 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
600 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
602 records
= getRecords(ub
, DNSName("powerdns.org."), QType::ANY
, -1, nullptr);
603 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
604 checkRecordExists(records
, DNSName("powerdns.org."), QType::SOA
, 2, 0, true);
605 checkRecordExists(records
, DNSName("powerdns.org."), QType::AAAA
, 2, 0, true);
609 // test AAAA with zone id == -1
610 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
611 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
612 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
614 records
= getRecords(ub
, DNSName("powerdns.org."), QType::AAAA
, -1, nullptr);
615 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
616 checkRecordExists(records
, DNSName("powerdns.org."), QType::AAAA
, 2, 0, true);
620 // test NODATA with zone id == -1
621 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
622 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
624 records
= getRecords(ub
, DNSName("powerdns.org."), QType::PTR
, -1, nullptr);
625 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
629 // test ANY with zone id set
630 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
631 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
632 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
633 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
635 records
= getRecords(ub
, DNSName("powerdns.org."), QType::ANY
, 2, nullptr);
636 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
637 checkRecordExists(records
, DNSName("powerdns.org."), QType::SOA
, 2, 0, true);
638 checkRecordExists(records
, DNSName("powerdns.org."), QType::AAAA
, 2, 0, true);
642 // test AAAA with zone id set
643 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
644 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
645 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
647 records
= getRecords(ub
, DNSName("www.powerdns.org."), QType::AAAA
, 2, nullptr);
648 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
649 checkRecordExists(records
, DNSName("www.powerdns.org."), QType::AAAA
, 2, 0, true);
653 // test NODATA with zone id set
654 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
655 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
657 records
= getRecords(ub
, DNSName("powerdns.org."), QType::PTR
, 2, nullptr);
658 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
662 // test ANY with wrong zone id
663 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 2, nullptr);
664 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
666 records
= getRecords(ub
, DNSName("powerdns.org."), QType::ANY
, 1, nullptr);
667 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
669 records
= getRecords(ub
, DNSName("not-powerdns.com."), QType::ANY
, 65535, nullptr);
670 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
674 // test a DNS packet is correctly passed and that the corresponding scope is passed back
676 ComboAddress
remote("192.0.2.1");
677 pkt
.setRemote(&remote
);
678 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
679 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
680 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
681 // and that we don't get the same result for a different client
682 remote
= ComboAddress("198.51.100.1");
683 pkt
.setRemote(&remote
);
684 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
685 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
686 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
690 testWithoutThenWithAuthCache(testFunction
);
691 testWithoutThenWithZoneCache(testFunction
);
693 catch(const PDNSException
& e
) {
694 cerr
<<e
.reason
<<endl
;
697 catch(const std::exception
& e
) {
698 cerr
<<e
.what()<<endl
;
702 cerr
<<"An unexpected error occurred.."<<endl
;
707 BOOST_AUTO_TEST_CASE(test_multi_backends_overlay
) {
708 // one backend holds the SOA, NS and one A
709 // a second backend holds another A and AAAA
711 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
712 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
713 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
714 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.1", 60));
715 SimpleBackend::s_zones
[1].insert(zoneA
);
717 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.com."), 1);
718 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.2", 60));
719 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
720 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
721 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
722 SimpleBackend::s_zones
[2].insert(zoneB
);
724 BackendMakers().report(new SimpleBackendFactory());
725 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
728 auto testFunction
= [](UeberBackend
& ub
) -> void {
730 // test SOA with unknown zone id == -1
731 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
732 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
733 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
737 // test ANY with zone id == -1
738 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
739 // /!\ only 3 records are returned since we don't allow spreading the same name over several backends
740 BOOST_REQUIRE_EQUAL(records
.size(), 3U);
741 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
742 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
743 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
744 //checkRecordExists(records, DNSName("powerdns.com."), QType::AAAA, 1, 0, true);
748 // test AAAA with zone id == -1
749 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
750 // /!\ the AAAA will be found on an exact search, but not on an ANY one
751 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
752 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
756 // test NODATA with zone id == -1
757 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
758 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
762 // test ANY with zone id set
763 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
764 // /!\ only 3 records are returned since we don't allow spreading the same name over several backends
765 BOOST_REQUIRE_EQUAL(records
.size(), 3U);
766 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
767 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
768 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
769 //checkRecordExists(records, DNSName("powerdns.com."), QType::AAAA, 1, 0, true);
773 // test AAAA with zone id set
774 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
775 // /!\ the AAAA will be found on an exact search, but not on an ANY one
776 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
777 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
781 // test www - A with zone id set (only in the second backend)
782 auto records
= getRecords(ub
, DNSName("www.powerdns.com."), QType::A
, 1, nullptr);
783 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
784 checkRecordExists(records
, DNSName("www.powerdns.com."), QType::A
, 1, 0, true);
788 // test NODATA with zone id set
789 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
790 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
794 // test ANY with wrong zone id
795 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 2, nullptr);
796 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
800 // test a DNS packet is correctly passed and that the corresponding scope is passed back
802 ComboAddress
remote("192.0.2.1");
803 pkt
.setRemote(&remote
);
804 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
805 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
806 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
807 // and that we don't get the same result for a different client
808 remote
= ComboAddress("198.51.100.1");
809 pkt
.setRemote(&remote
);
810 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
811 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
812 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
816 testWithoutThenWithAuthCache(testFunction
);
817 testWithoutThenWithZoneCache(testFunction
);
819 catch(const PDNSException
& e
) {
820 cerr
<<e
.reason
<<endl
;
823 catch(const std::exception
& e
) {
824 cerr
<<e
.what()<<endl
;
828 cerr
<<"An unexpected error occurred.."<<endl
;
833 BOOST_AUTO_TEST_CASE(test_multi_backends_overlay_name
) {
834 // one backend holds the apex with SOA, NS and one A
835 // a second backend holds others names
837 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
838 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
839 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
840 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.1", 60));
841 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.2", 60));
842 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
843 SimpleBackend::s_zones
[1].insert(zoneA
);
845 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.com."), 1);
846 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
847 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::AAAA
, "192.168.0.1", 60));
848 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
849 SimpleBackend::s_zones
[2].insert(zoneB
);
851 BackendMakers().report(new SimpleBackendFactory());
852 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
855 auto testFunction
= [](UeberBackend
& ub
) -> void {
857 // test SOA with unknown zone id == -1
858 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
859 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
860 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
864 // test ANY with zone id == -1
865 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
866 BOOST_REQUIRE_EQUAL(records
.size(), 5U);
867 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
868 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
869 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
870 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
874 // test AAAA with zone id == -1
875 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
876 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
877 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
881 // test NODATA with zone id == -1
882 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
883 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
887 // test ANY with zone id set
888 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
889 BOOST_REQUIRE_EQUAL(records
.size(), 5U);
890 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
891 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
892 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
893 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
897 // test AAAA with zone id set
898 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
899 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
900 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
904 // test www - A with zone id set (only in the second backend)
905 auto records
= getRecords(ub
, DNSName("www.powerdns.com."), QType::A
, 1, nullptr);
906 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
907 checkRecordExists(records
, DNSName("www.powerdns.com."), QType::A
, 1, 0, true);
911 // test NODATA with zone id set
912 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
913 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
917 // test ANY with wrong zone id
918 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 2, nullptr);
919 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
923 // test a DNS packet is correctly passed and that the corresponding scope is passed back
925 ComboAddress
remote("192.0.2.1");
926 pkt
.setRemote(&remote
);
927 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
928 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
929 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
930 // and that we don't get the same result for a different client
931 remote
= ComboAddress("198.51.100.1");
932 pkt
.setRemote(&remote
);
933 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
934 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
935 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
939 testWithoutThenWithAuthCache(testFunction
);
940 testWithoutThenWithZoneCache(testFunction
);
942 catch(const PDNSException
& e
) {
943 cerr
<<e
.reason
<<endl
;
946 catch(const std::exception
& e
) {
947 cerr
<<e
.what()<<endl
;
951 cerr
<<"An unexpected error occurred.."<<endl
;
956 BOOST_AUTO_TEST_CASE(test_child_zone
) {
957 // Backend 1 holds zone A "com" while backend 2 holds zone B "powerdns.com"
958 // Check that DS queries are correctly handled
961 SimpleBackend::SimpleDNSZone
zoneA(DNSName("com."), 1);
962 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("com."), QType::SOA
, "a.gtld-servers.net. nstld.verisign-grs.com. 3 600 600 3600000 604800", 3600));
963 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
964 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::DS
, "44030 8 3 7DD75AE1565051F9563CF8DF976AC99CDCA51E3463019C81BD2BB083 82F3854E", 3600));
965 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("ns1.powerdns.com."), QType::A
, "192.0.2.1", 3600));
966 SimpleBackend::s_zones
[1].insert(zoneA
);
968 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.com."), 2);
969 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
970 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::2", 60));
971 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
972 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("ns1.powerdns.com."), QType::A
, "192.0.2.1", 3600));
973 SimpleBackend::s_zones
[2].insert(zoneB
);
975 BackendMakers().report(new SimpleBackendFactory());
976 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
979 auto testFunction
= [](UeberBackend
& ub
) -> void {
981 // test SOA with unknown zone id == -1
982 auto records
= getRecords(ub
, DNSName("com."), QType::SOA
, -1, nullptr);
983 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
984 checkRecordExists(records
, DNSName("com."), QType::SOA
, 1, 0, true);
986 records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
987 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
988 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 2, 0, true);
992 // test ANY with zone id == -1
993 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
994 BOOST_REQUIRE_EQUAL(records
.size(), 3U);
995 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 2, 0, true);
996 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 2, 0, true);
997 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 2, 0, true);
1001 // test getAuth() for DS
1003 BOOST_REQUIRE(ub
.getAuth(DNSName("powerdns.com."), QType::DS
, &sd
));
1004 BOOST_CHECK_EQUAL(sd
.qname
.toString(), "com.");
1005 BOOST_CHECK_EQUAL(sd
.domain_id
, 1);
1009 // test getAuth() for A
1011 BOOST_REQUIRE(ub
.getAuth(DNSName("powerdns.com."), QType::A
, &sd
));
1012 BOOST_CHECK_EQUAL(sd
.qname
.toString(), "powerdns.com.");
1013 BOOST_CHECK_EQUAL(sd
.domain_id
, 2);
1017 testWithoutThenWithAuthCache(testFunction
);
1018 testWithoutThenWithZoneCache(testFunction
);
1020 catch(const PDNSException
& e
) {
1021 cerr
<<e
.reason
<<endl
;
1024 catch(const std::exception
& e
) {
1025 cerr
<<e
.what()<<endl
;
1029 cerr
<<"An unexpected error occurred.."<<endl
;
1034 BOOST_AUTO_TEST_CASE(test_multi_backends_best_soa
) {
1035 // several backends, one returns the best SOA it has right away
1036 // while the others do simple lookups
1039 SimpleBackend::SimpleDNSZone
zoneA(DNSName("d.0.1.0.0.2.ip6.arpa."), 1);
1040 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("d.0.1.0.0.2.ip6.arpa."), QType::SOA
, "ns.apnic.net. read-txt-record-of-zone-first-dns-admin.apnic.net. 3005126844 7200 1800 604800 3600", 3600));
1041 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("2.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa."), QType::PTR
, "a.reverse.", 3600));
1042 SimpleBackend::s_zones
[1].insert(zoneA
);
1044 SimpleBackend::SimpleDNSZone
zoneB(DNSName("0.1.0.0.2.ip6.arpa."), 2);
1045 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("0.1.0.0.2.ip6.arpa."), QType::SOA
, "ns.apnic.net. read-txt-record-of-zone-first-dns-admin.apnic.net. 3005126844 7200 1800 604800 3600", 3600));
1046 SimpleBackend::s_zones
[2].insert(zoneB
);
1048 BackendMakers().report(new SimpleBackendFactory());
1049 BackendMakers().report(new SimpleBackendBestAuthFactory());
1050 BackendMakers().launch("SimpleBackendBestAuth:1, SimpleBackend:2");
1053 auto testFunction
= [](UeberBackend
& ub
) -> void {
1055 auto sbba
= dynamic_cast<SimpleBackendBestAuth
*>(ub
.backends
.at(0));
1056 BOOST_REQUIRE(sbba
!= nullptr);
1057 sbba
->d_authLookupCount
= 0;
1061 BOOST_REQUIRE(ub
.getAuth(DNSName("2.4.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa."), QType::PTR
, &sd
));
1062 BOOST_CHECK_EQUAL(sd
.qname
.toString(), "d.0.1.0.0.2.ip6.arpa.");
1063 BOOST_CHECK_EQUAL(sd
.domain_id
, 1);
1065 // check that at most one auth lookup occurred to this backend (O with caching enabled)
1066 BOOST_CHECK_LE(sbba
->d_authLookupCount
, 1U);
1070 testWithoutThenWithAuthCache(testFunction
);
1071 testWithoutThenWithZoneCache(testFunction
);
1073 catch(const PDNSException
& e
) {
1074 cerr
<<e
.reason
<<endl
;
1077 catch(const std::exception
& e
) {
1078 cerr
<<e
.what()<<endl
;
1082 cerr
<<"An unexpected error occurred.."<<endl
;
1087 BOOST_AUTO_TEST_CASE(test_multi_backends_metadata
) {
1088 // we have metadata stored in the first and second backend.
1089 // We can read from the first backend but not from the second, since the first will return "true" even though it has nothing
1090 // Updating will insert into the first backend, leaving the first one untouched
1093 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
1094 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
1095 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
1096 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
1097 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
1098 SimpleBackend::s_zones
[1].insert(zoneA
);
1099 SimpleBackend::s_metadata
[1].insert(SimpleBackend::SimpleMetaData(DNSName("powerdns.com."), "test-data-a", { "value1", "value2"}));
1101 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.org."), 2);
1102 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::SOA
, "ns1.powerdns.org. powerdns.org. 3 600 600 3600000 604800", 3600));
1103 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
1104 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
1105 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.org."), QType::AAAA
, "2001:db8::42", 60));
1106 SimpleBackend::s_zones
[2].insert(zoneB
);
1107 SimpleBackend::s_metadata
[2].insert(SimpleBackend::SimpleMetaData(DNSName("powerdns.org."), "test-data-b", { "value1", "value2"}));
1109 BackendMakers().report(new SimpleBackendFactory());
1110 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
1113 auto testFunction
= [](UeberBackend
& ub
) -> void {
1115 // check the initial values
1116 std::vector
<std::string
> values
;
1117 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.com."), "test-data-a", values
));
1118 BOOST_REQUIRE_EQUAL(values
.size(), 2U);
1119 BOOST_CHECK_EQUAL(values
.at(0), "value1");
1120 BOOST_CHECK_EQUAL(values
.at(1), "value2");
1122 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.com."), "test-data-b", values
));
1123 BOOST_CHECK_EQUAL(values
.size(), 0U);
1125 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-a", values
));
1126 BOOST_CHECK_EQUAL(values
.size(), 0U);
1128 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-b", values
));
1129 BOOST_CHECK_EQUAL(values
.size(), 0U);
1133 // update the values
1134 BOOST_CHECK(ub
.setDomainMetadata(DNSName("powerdns.com."), "test-data-a", { "value3" }));
1135 BOOST_CHECK(ub
.setDomainMetadata(DNSName("powerdns.org."), "test-data-a", { "value4" }));
1136 BOOST_CHECK(ub
.setDomainMetadata(DNSName("powerdns.org."), "test-data-b", { "value5" }));
1139 // check the updated values
1141 std::vector
<std::string
> values
;
1142 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.com."), "test-data-a", values
));
1143 BOOST_REQUIRE_EQUAL(values
.size(), 1U);
1144 BOOST_CHECK_EQUAL(values
.at(0), "value3");
1146 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-a", values
));
1147 BOOST_REQUIRE_EQUAL(values
.size(), 1U);
1148 BOOST_CHECK_EQUAL(values
.at(0), "value4");
1150 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-b", values
));
1151 BOOST_REQUIRE_EQUAL(values
.size(), 1U);
1152 BOOST_CHECK_EQUAL(values
.at(0), "value5");
1156 // check that it has not been updated in the second backend
1157 const auto& it
= SimpleBackend::s_metadata
[2].find(std::make_tuple(DNSName("powerdns.org."), "test-data-b"));
1158 BOOST_REQUIRE(it
!= SimpleBackend::s_metadata
[2].end());
1159 BOOST_REQUIRE_EQUAL(it
->d_values
.size(), 2U);
1160 BOOST_CHECK_EQUAL(it
->d_values
.at(0), "value1");
1161 BOOST_CHECK_EQUAL(it
->d_values
.at(1), "value2");
1168 catch(const PDNSException
& e
) {
1169 cerr
<<e
.reason
<<endl
;
1172 catch(const std::exception
& e
) {
1173 cerr
<<e
.what()<<endl
;
1177 cerr
<<"An unexpected error occurred.."<<endl
;
1183 BOOST_AUTO_TEST_SUITE_END();