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
) :
103 d_suffix(suffix
), d_backendId(pdns::checked_stoi
<decltype(d_backendId
)>(suffix
.substr(1)))
107 bool findZone(const DNSName
& qdomain
, int zoneId
, std::shared_ptr
<RecordStorage
>& records
, uint64_t& currentZoneId
) const
113 const auto& idx
= boost::multi_index::get
<IDTag
>(s_zones
.at(d_backendId
));
114 auto it
= idx
.find(zoneId
);
115 if (it
== idx
.end()) {
118 records
= it
->d_records
;
119 currentZoneId
= it
->d_id
;
122 const auto& idx
= boost::multi_index::get
<HashedNameTag
>(s_zones
.at(d_backendId
));
123 auto it
= idx
.find(qdomain
);
124 if (it
== idx
.end()) {
127 records
= it
->d_records
;
128 currentZoneId
= it
->d_id
;
134 void lookup(const QType
& qtype
, const DNSName
& qdomain
, int zoneId
= -1, DNSPacket
*pkt_p
= nullptr) override
136 d_currentScopeMask
= 0;
137 findZone(qdomain
, zoneId
, d_records
, d_currentZone
);
140 if (qdomain
== DNSName("geo.powerdns.com.") && pkt_p
!= nullptr) {
141 if (pkt_p
->getRealRemote() == Netmask("192.0.2.1")) {
142 d_currentScopeMask
= 32;
144 else if (pkt_p
->getRealRemote() == Netmask("198.51.100.1")) {
145 d_currentScopeMask
= 24;
149 auto& idx
= d_records
->get
<OrderedNameTypeTag
>();
150 if (qtype
== QType::ANY
) {
151 auto range
= idx
.equal_range(qdomain
);
152 d_iter
= range
.first
;
153 d_end
= range
.second
;
156 auto range
= idx
.equal_range(std::make_tuple(qdomain
, qtype
.getCode()));
157 d_iter
= range
.first
;
158 d_end
= range
.second
;
163 bool get(DNSResourceRecord
& drr
) override
169 if (d_iter
== d_end
) {
173 drr
.qname
= d_iter
->d_name
;
174 drr
.domain_id
= d_currentZone
;
175 drr
.content
= d_iter
->d_content
;
176 drr
.qtype
= d_iter
->d_type
;
177 drr
.ttl
= d_iter
->d_ttl
;
179 // drr.auth = d_iter->auth; might bring pain at some point, let's not cross that bridge until then
181 drr
.scopeMask
= d_currentScopeMask
;
187 bool list(const DNSName
& target
, int zoneId
, bool include_disabled
= false) override
189 findZone(target
, zoneId
, d_records
, d_currentZone
);
192 d_iter
= d_records
->begin();
193 d_end
= d_records
->end();
200 bool getDomainMetadata(const DNSName
& name
, const std::string
& kind
, std::vector
<std::string
>& meta
) override
202 const auto& idx
= boost::multi_index::get
<OrderedNameKindTag
>(s_metadata
.at(d_backendId
));
203 auto it
= idx
.find(std::make_tuple(name
, kind
));
204 if (it
== idx
.end()) {
205 /* funnily enough, we are expected to return true even though we might not know that zone */
213 bool setDomainMetadata(const DNSName
& name
, const std::string
& kind
, const std::vector
<std::string
>& meta
) override
215 auto& idx
= boost::multi_index::get
<OrderedNameKindTag
>(s_metadata
.at(d_backendId
));
216 auto it
= idx
.find(std::make_tuple(name
, kind
));
217 if (it
== idx
.end()) {
218 s_metadata
.at(d_backendId
).insert(SimpleMetaData(name
, kind
, meta
));
221 idx
.replace(it
, SimpleMetaData(name
, kind
, meta
));
225 /* this is not thread-safe */
226 static std::unordered_map
<uint64_t, ZoneStorage
> s_zones
;
227 static std::unordered_map
<uint64_t, MetaDataStorage
> s_metadata
;
230 std::string d_suffix
;
231 std::shared_ptr
<RecordStorage
> d_records
{nullptr};
232 RecordStorage::index
<OrderedNameTypeTag
>::type::const_iterator d_iter
;
233 RecordStorage::index
<OrderedNameTypeTag
>::type::const_iterator d_end
;
234 const uint64_t d_backendId
;
235 uint64_t d_currentZone
{0};
236 uint8_t d_currentScopeMask
{0};
239 class SimpleBackendBestAuth
: public SimpleBackend
242 SimpleBackendBestAuth(const std::string
& suffix
): SimpleBackend(suffix
)
246 bool getAuth(const DNSName
& target
, SOAData
* sd
) override
248 static const DNSName
best("d.0.1.0.0.2.ip6.arpa.");
252 if (target
.isPartOf(best
)) {
253 /* return the best SOA right away */
254 std::shared_ptr
<RecordStorage
> records
;
256 if (!findZone(best
, -1, records
, zoneId
)) {
260 auto& idx
= records
->get
<OrderedNameTypeTag
>();
261 auto range
= idx
.equal_range(std::make_tuple(best
, QType::SOA
));
262 if (range
.first
== range
.second
) {
266 fillSOAData(range
.first
->d_content
, *sd
);
267 sd
->ttl
= range
.first
->d_ttl
;
269 sd
->domain_id
= zoneId
;
273 return getSOA(target
, *sd
);
276 size_t d_authLookupCount
{0};
279 class SimpleBackendNoMeta
: public SimpleBackend
282 SimpleBackendNoMeta(const std::string
& suffix
): SimpleBackend(suffix
)
286 bool getDomainMetadata(const DNSName
& name
, const std::string
& kind
, std::vector
<std::string
>& meta
) override
291 bool setDomainMetadata(const DNSName
& name
, const std::string
& kind
, const std::vector
<std::string
>& meta
) override
297 std::unordered_map
<uint64_t, SimpleBackend::ZoneStorage
> SimpleBackend::s_zones
;
298 std::unordered_map
<uint64_t, SimpleBackend::MetaDataStorage
> SimpleBackend::s_metadata
;
300 class SimpleBackendFactory
: public BackendFactory
303 SimpleBackendFactory(): BackendFactory("SimpleBackend")
307 DNSBackend
*make(const string
& suffix
="") override
309 return new SimpleBackend(suffix
);
313 class SimpleBackendBestAuthFactory
: public BackendFactory
316 SimpleBackendBestAuthFactory(): BackendFactory("SimpleBackendBestAuth")
320 DNSBackend
*make(const string
& suffix
="") override
322 return new SimpleBackendBestAuth(suffix
);
326 class SimpleBackendNoMetaFactory
: public BackendFactory
329 SimpleBackendNoMetaFactory(): BackendFactory("SimpleBackendNoMeta")
333 DNSBackend
*make(const string
& suffix
="") override
335 return new SimpleBackendNoMeta(suffix
);
339 struct UeberBackendSetupArgFixture
{
340 UeberBackendSetupArgFixture() {
341 extern AuthQueryCache QC
;
342 ::arg().set("query-cache-ttl")="0";
343 ::arg().set("negquery-cache-ttl")="0";
344 ::arg().set("consistent-backends")="no";
346 g_zoneCache
.setRefreshInterval(0);
348 BackendMakers().clear();
349 SimpleBackend::s_zones
.clear();
350 SimpleBackend::s_metadata
.clear();
354 static void testWithoutThenWithAuthCache(std::function
<void(UeberBackend
& ub
)> func
)
356 extern AuthQueryCache QC
;
359 /* disable the cache */
360 ::arg().set("query-cache-ttl")="0";
361 ::arg().set("negquery-cache-ttl")="0";
364 /* keep zone cache disabled */
365 g_zoneCache
.setRefreshInterval(0);
373 /* enable the cache */
374 ::arg().set("query-cache-ttl")="20";
375 ::arg().set("negquery-cache-ttl")="60";
377 QC
.setMaxEntries(100000);
378 /* keep zone cache disabled */
379 g_zoneCache
.setRefreshInterval(0);
383 /* a first time to fill the cache */
385 /* a second time to make sure every call has been tried with the cache filled */
390 static void testWithoutThenWithZoneCache(std::function
<void(UeberBackend
& ub
)> func
)
392 extern AuthQueryCache QC
;
395 /* disable zone cache */
396 g_zoneCache
.setRefreshInterval(0);
398 /* keep auth caches disabled */
399 ::arg().set("query-cache-ttl")="0";
400 ::arg().set("negquery-cache-ttl")="0";
408 // This test is broken without getAllDomains() in SimpleBackend
410 // /* enable zone cache */
411 // //g_zoneCache.setRefreshInterval(60);
412 // g_zoneCache.clear();
413 // /* keep auth caches disabled */
414 // ::arg().set("query-cache-ttl")="0";
415 // ::arg().set("negquery-cache-ttl")="0";
417 // QC.setMaxEntries(0);
420 // ub.updateZoneCache();
425 BOOST_FIXTURE_TEST_SUITE(test_ueberbackend_cc
, UeberBackendSetupArgFixture
)
427 static std::vector
<DNSZoneRecord
> getRecords(UeberBackend
& ub
, const DNSName
& name
, uint16_t qtype
, int zoneId
, const DNSPacket
* pkt
)
429 std::vector
<DNSZoneRecord
> result
;
431 ub
.lookup(QType(qtype
), name
, zoneId
, const_cast<DNSPacket
*>(pkt
));
436 result
.push_back(std::move(dzr
));
442 static void checkRecordExists(const std::vector
<DNSZoneRecord
>& records
, const DNSName
& name
, uint16_t type
, int zoneId
, uint8_t scopeMask
, bool auth
)
444 BOOST_REQUIRE_GE(records
.size(), 1U);
445 for (const auto& record
: records
) {
446 if (record
.domain_id
== zoneId
&&
447 record
.dr
.d_type
== type
&&
448 record
.dr
.d_name
== name
&&
449 record
.auth
== auth
&&
450 record
.scopeMask
== scopeMask
) {
454 BOOST_CHECK_MESSAGE(false, "Record " + name
.toString() + "/" + QType(type
).toString() + " - " + std::to_string(zoneId
) + " not found");
457 BOOST_AUTO_TEST_CASE(test_simple
) {
460 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
461 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
462 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
463 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
464 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
465 SimpleBackend::s_zones
[1].insert(zoneA
);
467 BackendMakers().report(new SimpleBackendFactory());
468 BackendMakers().launch("SimpleBackend:1");
471 auto testFunction
= [](UeberBackend
& ub
) -> void {
473 // test SOA with unknown zone id == -1
474 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
475 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
476 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
480 // test ANY with zone id == -1
481 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
482 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
483 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
484 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
488 // test AAAA with zone id == -1
489 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
490 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
491 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
495 // test NODATA with zone id == -1
496 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
497 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
501 // test ANY with zone id set
502 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
503 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
504 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
505 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
509 // test AAAA with zone id set
510 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
511 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
512 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
516 // test NODATA with zone id set
517 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
518 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
522 // test ANY with wrong zone id
523 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 65535, nullptr);
524 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
528 // test a DNS packet is correctly passed and that the corresponding scope is passed back
530 ComboAddress
remote("192.0.2.1");
531 pkt
.setRemote(&remote
);
532 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
533 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
534 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
535 // and that we don't get the same result for a different client
536 remote
= ComboAddress("198.51.100.1");
537 pkt
.setRemote(&remote
);
538 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
539 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
540 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
544 testWithoutThenWithAuthCache(testFunction
);
545 testWithoutThenWithZoneCache(testFunction
);
547 catch(const PDNSException
& e
) {
548 cerr
<<e
.reason
<<endl
;
551 catch(const std::exception
& e
) {
552 cerr
<<e
.what()<<endl
;
556 cerr
<<"An unexpected error occurred.."<<endl
;
561 BOOST_AUTO_TEST_CASE(test_multi_backends_separate_zones
) {
562 // one zone in backend 1, a second zone in backend 2
566 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
567 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
568 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
569 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
570 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
571 SimpleBackend::s_zones
[1].insert(zoneA
);
573 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.org."), 2);
574 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::SOA
, "ns1.powerdns.org. powerdns.org. 3 600 600 3600000 604800", 3600));
575 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
576 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
577 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.org."), QType::AAAA
, "2001:db8::42", 60));
578 SimpleBackend::s_zones
[2].insert(zoneB
);
580 BackendMakers().report(new SimpleBackendFactory());
581 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
584 auto testFunction
= [](UeberBackend
& ub
) -> void {
586 // test SOA with unknown zone id == -1
587 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
588 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
589 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
591 records
= getRecords(ub
, DNSName("powerdns.org."), QType::SOA
, -1, nullptr);
592 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
593 checkRecordExists(records
, DNSName("powerdns.org."), QType::SOA
, 2, 0, true);
597 // test ANY with zone id == -1
598 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
599 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
600 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
601 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
603 records
= getRecords(ub
, DNSName("powerdns.org."), QType::ANY
, -1, nullptr);
604 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
605 checkRecordExists(records
, DNSName("powerdns.org."), QType::SOA
, 2, 0, true);
606 checkRecordExists(records
, DNSName("powerdns.org."), QType::AAAA
, 2, 0, true);
610 // test AAAA with zone id == -1
611 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
612 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
613 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
615 records
= getRecords(ub
, DNSName("powerdns.org."), QType::AAAA
, -1, nullptr);
616 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
617 checkRecordExists(records
, DNSName("powerdns.org."), QType::AAAA
, 2, 0, true);
621 // test NODATA with zone id == -1
622 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
623 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
625 records
= getRecords(ub
, DNSName("powerdns.org."), QType::PTR
, -1, nullptr);
626 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
630 // test ANY with zone id set
631 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
632 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
633 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
634 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
636 records
= getRecords(ub
, DNSName("powerdns.org."), QType::ANY
, 2, nullptr);
637 BOOST_REQUIRE_EQUAL(records
.size(), 2U);
638 checkRecordExists(records
, DNSName("powerdns.org."), QType::SOA
, 2, 0, true);
639 checkRecordExists(records
, DNSName("powerdns.org."), QType::AAAA
, 2, 0, true);
643 // test AAAA with zone id set
644 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
645 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
646 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
648 records
= getRecords(ub
, DNSName("www.powerdns.org."), QType::AAAA
, 2, nullptr);
649 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
650 checkRecordExists(records
, DNSName("www.powerdns.org."), QType::AAAA
, 2, 0, true);
654 // test NODATA with zone id set
655 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
656 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
658 records
= getRecords(ub
, DNSName("powerdns.org."), QType::PTR
, 2, nullptr);
659 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
663 // test ANY with wrong zone id
664 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 2, nullptr);
665 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
667 records
= getRecords(ub
, DNSName("powerdns.org."), QType::ANY
, 1, nullptr);
668 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
670 records
= getRecords(ub
, DNSName("not-powerdns.com."), QType::ANY
, 65535, nullptr);
671 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
675 // test a DNS packet is correctly passed and that the corresponding scope is passed back
677 ComboAddress
remote("192.0.2.1");
678 pkt
.setRemote(&remote
);
679 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
680 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
681 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
682 // and that we don't get the same result for a different client
683 remote
= ComboAddress("198.51.100.1");
684 pkt
.setRemote(&remote
);
685 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
686 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
687 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
691 testWithoutThenWithAuthCache(testFunction
);
692 testWithoutThenWithZoneCache(testFunction
);
694 catch(const PDNSException
& e
) {
695 cerr
<<e
.reason
<<endl
;
698 catch(const std::exception
& e
) {
699 cerr
<<e
.what()<<endl
;
703 cerr
<<"An unexpected error occurred.."<<endl
;
708 BOOST_AUTO_TEST_CASE(test_multi_backends_overlay
) {
709 // one backend holds the SOA, NS and one A
710 // a second backend holds another A and AAAA
712 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
713 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
714 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
715 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.1", 60));
716 SimpleBackend::s_zones
[1].insert(zoneA
);
718 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.com."), 1);
719 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.2", 60));
720 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
721 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
722 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
723 SimpleBackend::s_zones
[2].insert(zoneB
);
725 BackendMakers().report(new SimpleBackendFactory());
726 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
729 auto testFunction
= [](UeberBackend
& ub
) -> void {
731 // test SOA with unknown zone id == -1
732 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
733 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
734 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
738 // test ANY with zone id == -1
739 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
740 // /!\ only 3 records are returned since we don't allow spreading the same name over several backends
741 BOOST_REQUIRE_EQUAL(records
.size(), 3U);
742 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
743 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
744 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
745 //checkRecordExists(records, DNSName("powerdns.com."), QType::AAAA, 1, 0, true);
749 // test AAAA with zone id == -1
750 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
751 // /!\ the AAAA will be found on an exact search, but not on an ANY one
752 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
753 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
757 // test NODATA with zone id == -1
758 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
759 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
763 // test ANY with zone id set
764 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
765 // /!\ only 3 records are returned since we don't allow spreading the same name over several backends
766 BOOST_REQUIRE_EQUAL(records
.size(), 3U);
767 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
768 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
769 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
770 //checkRecordExists(records, DNSName("powerdns.com."), QType::AAAA, 1, 0, true);
774 // test AAAA with zone id set
775 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
776 // /!\ the AAAA will be found on an exact search, but not on an ANY one
777 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
778 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
782 // test www - A with zone id set (only in the second backend)
783 auto records
= getRecords(ub
, DNSName("www.powerdns.com."), QType::A
, 1, nullptr);
784 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
785 checkRecordExists(records
, DNSName("www.powerdns.com."), QType::A
, 1, 0, true);
789 // test NODATA with zone id set
790 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
791 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
795 // test ANY with wrong zone id
796 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 2, nullptr);
797 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
801 // test a DNS packet is correctly passed and that the corresponding scope is passed back
803 ComboAddress
remote("192.0.2.1");
804 pkt
.setRemote(&remote
);
805 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
806 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
807 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
808 // and that we don't get the same result for a different client
809 remote
= ComboAddress("198.51.100.1");
810 pkt
.setRemote(&remote
);
811 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
812 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
813 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
817 testWithoutThenWithAuthCache(testFunction
);
818 testWithoutThenWithZoneCache(testFunction
);
820 catch(const PDNSException
& e
) {
821 cerr
<<e
.reason
<<endl
;
824 catch(const std::exception
& e
) {
825 cerr
<<e
.what()<<endl
;
829 cerr
<<"An unexpected error occurred.."<<endl
;
834 BOOST_AUTO_TEST_CASE(test_multi_backends_overlay_name
) {
835 // one backend holds the apex with SOA, NS and one A
836 // a second backend holds others names
838 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
839 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
840 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
841 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.1", 60));
842 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::A
, "192.168.0.2", 60));
843 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
844 SimpleBackend::s_zones
[1].insert(zoneA
);
846 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.com."), 1);
847 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
848 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::AAAA
, "192.168.0.1", 60));
849 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
850 SimpleBackend::s_zones
[2].insert(zoneB
);
852 BackendMakers().report(new SimpleBackendFactory());
853 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
856 auto testFunction
= [](UeberBackend
& ub
) -> void {
858 // test SOA with unknown zone id == -1
859 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
860 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
861 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
865 // test ANY with zone id == -1
866 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
867 BOOST_REQUIRE_EQUAL(records
.size(), 5U);
868 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
869 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
870 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
871 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
875 // test AAAA with zone id == -1
876 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, -1, nullptr);
877 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
878 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
882 // test NODATA with zone id == -1
883 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, -1, nullptr);
884 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
888 // test ANY with zone id set
889 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 1, nullptr);
890 BOOST_REQUIRE_EQUAL(records
.size(), 5U);
891 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 1, 0, true);
892 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 1, 0, true);
893 checkRecordExists(records
, DNSName("powerdns.com."), QType::A
, 1, 0, true);
894 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
898 // test AAAA with zone id set
899 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::AAAA
, 1, nullptr);
900 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
901 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 1, 0, true);
905 // test www - A with zone id set (only in the second backend)
906 auto records
= getRecords(ub
, DNSName("www.powerdns.com."), QType::A
, 1, nullptr);
907 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
908 checkRecordExists(records
, DNSName("www.powerdns.com."), QType::A
, 1, 0, true);
912 // test NODATA with zone id set
913 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::PTR
, 1, nullptr);
914 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
918 // test ANY with wrong zone id
919 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, 2, nullptr);
920 BOOST_REQUIRE_EQUAL(records
.size(), 0U);
924 // test a DNS packet is correctly passed and that the corresponding scope is passed back
926 ComboAddress
remote("192.0.2.1");
927 pkt
.setRemote(&remote
);
928 auto records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
929 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
930 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 32, true);
931 // and that we don't get the same result for a different client
932 remote
= ComboAddress("198.51.100.1");
933 pkt
.setRemote(&remote
);
934 records
= getRecords(ub
, DNSName("geo.powerdns.com."), QType::ANY
, 1, &pkt
);
935 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
936 checkRecordExists(records
, DNSName("geo.powerdns.com."), QType::A
, 1, 24, true);
940 testWithoutThenWithAuthCache(testFunction
);
941 testWithoutThenWithZoneCache(testFunction
);
943 catch(const PDNSException
& e
) {
944 cerr
<<e
.reason
<<endl
;
947 catch(const std::exception
& e
) {
948 cerr
<<e
.what()<<endl
;
952 cerr
<<"An unexpected error occurred.."<<endl
;
957 BOOST_AUTO_TEST_CASE(test_child_zone
) {
958 // Backend 1 holds zone A "com" while backend 2 holds zone B "powerdns.com"
959 // Check that DS queries are correctly handled
962 SimpleBackend::SimpleDNSZone
zoneA(DNSName("com."), 1);
963 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("com."), QType::SOA
, "a.gtld-servers.net. nstld.verisign-grs.com. 3 600 600 3600000 604800", 3600));
964 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
965 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::DS
, "44030 8 3 7DD75AE1565051F9563CF8DF976AC99CDCA51E3463019C81BD2BB083 82F3854E", 3600));
966 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("ns1.powerdns.com."), QType::A
, "192.0.2.1", 3600));
967 SimpleBackend::s_zones
[1].insert(zoneA
);
969 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.com."), 2);
970 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
971 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::2", 60));
972 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::NS
, "ns1.powerdns.com.", 3600));
973 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("ns1.powerdns.com."), QType::A
, "192.0.2.1", 3600));
974 SimpleBackend::s_zones
[2].insert(zoneB
);
976 BackendMakers().report(new SimpleBackendFactory());
977 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
980 auto testFunction
= [](UeberBackend
& ub
) -> void {
982 // test SOA with unknown zone id == -1
983 auto records
= getRecords(ub
, DNSName("com."), QType::SOA
, -1, nullptr);
984 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
985 checkRecordExists(records
, DNSName("com."), QType::SOA
, 1, 0, true);
987 records
= getRecords(ub
, DNSName("powerdns.com."), QType::SOA
, -1, nullptr);
988 BOOST_REQUIRE_EQUAL(records
.size(), 1U);
989 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 2, 0, true);
993 // test ANY with zone id == -1
994 auto records
= getRecords(ub
, DNSName("powerdns.com."), QType::ANY
, -1, nullptr);
995 BOOST_REQUIRE_EQUAL(records
.size(), 3U);
996 checkRecordExists(records
, DNSName("powerdns.com."), QType::SOA
, 2, 0, true);
997 checkRecordExists(records
, DNSName("powerdns.com."), QType::NS
, 2, 0, true);
998 checkRecordExists(records
, DNSName("powerdns.com."), QType::AAAA
, 2, 0, true);
1002 // test getAuth() for DS
1004 BOOST_REQUIRE(ub
.getAuth(DNSName("powerdns.com."), QType::DS
, &sd
));
1005 BOOST_CHECK_EQUAL(sd
.qname
.toString(), "com.");
1006 BOOST_CHECK_EQUAL(sd
.domain_id
, 1);
1010 // test getAuth() for A
1012 BOOST_REQUIRE(ub
.getAuth(DNSName("powerdns.com."), QType::A
, &sd
));
1013 BOOST_CHECK_EQUAL(sd
.qname
.toString(), "powerdns.com.");
1014 BOOST_CHECK_EQUAL(sd
.domain_id
, 2);
1018 testWithoutThenWithAuthCache(testFunction
);
1019 testWithoutThenWithZoneCache(testFunction
);
1021 catch(const PDNSException
& e
) {
1022 cerr
<<e
.reason
<<endl
;
1025 catch(const std::exception
& e
) {
1026 cerr
<<e
.what()<<endl
;
1030 cerr
<<"An unexpected error occurred.."<<endl
;
1035 BOOST_AUTO_TEST_CASE(test_multi_backends_best_soa
) {
1036 // several backends, one returns the best SOA it has right away
1037 // while the others do simple lookups
1040 SimpleBackend::SimpleDNSZone
zoneA(DNSName("d.0.1.0.0.2.ip6.arpa."), 1);
1041 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));
1042 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));
1043 SimpleBackend::s_zones
[1].insert(zoneA
);
1045 SimpleBackend::SimpleDNSZone
zoneB(DNSName("0.1.0.0.2.ip6.arpa."), 2);
1046 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));
1047 SimpleBackend::s_zones
[2].insert(zoneB
);
1049 BackendMakers().report(new SimpleBackendFactory());
1050 BackendMakers().report(new SimpleBackendBestAuthFactory());
1051 BackendMakers().launch("SimpleBackendBestAuth:1, SimpleBackend:2");
1054 auto testFunction
= [](UeberBackend
& ub
) -> void {
1056 auto sbba
= dynamic_cast<SimpleBackendBestAuth
*>(ub
.backends
.at(0));
1057 BOOST_REQUIRE(sbba
!= nullptr);
1058 sbba
->d_authLookupCount
= 0;
1062 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
));
1063 BOOST_CHECK_EQUAL(sd
.qname
.toString(), "d.0.1.0.0.2.ip6.arpa.");
1064 BOOST_CHECK_EQUAL(sd
.domain_id
, 1);
1066 // check that at most one auth lookup occurred to this backend (O with caching enabled)
1067 BOOST_CHECK_LE(sbba
->d_authLookupCount
, 1U);
1071 testWithoutThenWithAuthCache(testFunction
);
1072 testWithoutThenWithZoneCache(testFunction
);
1074 catch(const PDNSException
& e
) {
1075 cerr
<<e
.reason
<<endl
;
1078 catch(const std::exception
& e
) {
1079 cerr
<<e
.what()<<endl
;
1083 cerr
<<"An unexpected error occurred.."<<endl
;
1088 BOOST_AUTO_TEST_CASE(test_multi_backends_metadata
) {
1089 // we have metadata stored in the first and second backend.
1090 // We can read from the first backend but not from the second, since the first will return "true" even though it has nothing
1091 // Updating will insert into the first backend, leaving the first one untouched
1094 SimpleBackend::SimpleDNSZone
zoneA(DNSName("powerdns.com."), 1);
1095 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::SOA
, "ns1.powerdns.com. powerdns.com. 3 600 600 3600000 604800", 3600));
1096 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.com."), QType::AAAA
, "2001:db8::1", 60));
1097 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.com."), QType::A
, "192.168.0.1", 60));
1098 zoneA
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.com."), QType::A
, "192.168.0.42", 60));
1099 SimpleBackend::s_zones
[1].insert(zoneA
);
1100 SimpleBackend::s_metadata
[1].insert(SimpleBackend::SimpleMetaData(DNSName("powerdns.com."), "test-data-a", { "value1", "value2"}));
1102 SimpleBackend::SimpleDNSZone
zoneB(DNSName("powerdns.org."), 2);
1103 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::SOA
, "ns1.powerdns.org. powerdns.org. 3 600 600 3600000 604800", 3600));
1104 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
1105 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("www.powerdns.org."), QType::AAAA
, "2001:db8::2", 60));
1106 zoneB
.d_records
->insert(SimpleBackend::SimpleDNSRecord(DNSName("geo.powerdns.org."), QType::AAAA
, "2001:db8::42", 60));
1107 SimpleBackend::s_zones
[2].insert(zoneB
);
1108 SimpleBackend::s_metadata
[2].insert(SimpleBackend::SimpleMetaData(DNSName("powerdns.org."), "test-data-b", { "value1", "value2"}));
1110 BackendMakers().report(new SimpleBackendFactory());
1111 BackendMakers().launch("SimpleBackend:1, SimpleBackend:2");
1114 auto testFunction
= [](UeberBackend
& ub
) -> void {
1116 // check the initial values
1117 std::vector
<std::string
> values
;
1118 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.com."), "test-data-a", values
));
1119 BOOST_REQUIRE_EQUAL(values
.size(), 2U);
1120 BOOST_CHECK_EQUAL(values
.at(0), "value1");
1121 BOOST_CHECK_EQUAL(values
.at(1), "value2");
1123 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.com."), "test-data-b", values
));
1124 BOOST_CHECK_EQUAL(values
.size(), 0U);
1126 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-a", values
));
1127 BOOST_CHECK_EQUAL(values
.size(), 0U);
1129 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-b", values
));
1130 BOOST_CHECK_EQUAL(values
.size(), 0U);
1134 // update the values
1135 BOOST_CHECK(ub
.setDomainMetadata(DNSName("powerdns.com."), "test-data-a", std::vector
<std::string
>({"value3"})));
1136 BOOST_CHECK(ub
.setDomainMetadata(DNSName("powerdns.org."), "test-data-a", std::vector
<std::string
>({"value4"})));
1137 BOOST_CHECK(ub
.setDomainMetadata(DNSName("powerdns.org."), "test-data-b", std::vector
<std::string
>({"value5"})));
1140 // check the updated values
1142 std::vector
<std::string
> values
;
1143 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.com."), "test-data-a", values
));
1144 BOOST_REQUIRE_EQUAL(values
.size(), 1U);
1145 BOOST_CHECK_EQUAL(values
.at(0), "value3");
1147 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-a", values
));
1148 BOOST_REQUIRE_EQUAL(values
.size(), 1U);
1149 BOOST_CHECK_EQUAL(values
.at(0), "value4");
1151 BOOST_CHECK(ub
.getDomainMetadata(DNSName("powerdns.org."), "test-data-b", values
));
1152 BOOST_REQUIRE_EQUAL(values
.size(), 1U);
1153 BOOST_CHECK_EQUAL(values
.at(0), "value5");
1157 // check that it has not been updated in the second backend
1158 const auto& it
= SimpleBackend::s_metadata
[2].find(std::make_tuple(DNSName("powerdns.org."), "test-data-b"));
1159 BOOST_REQUIRE(it
!= SimpleBackend::s_metadata
[2].end());
1160 BOOST_REQUIRE_EQUAL(it
->d_values
.size(), 2U);
1161 BOOST_CHECK_EQUAL(it
->d_values
.at(0), "value1");
1162 BOOST_CHECK_EQUAL(it
->d_values
.at(1), "value2");
1169 catch(const PDNSException
& e
) {
1170 cerr
<<e
.reason
<<endl
;
1173 catch(const std::exception
& e
) {
1174 cerr
<<e
.what()<<endl
;
1178 cerr
<<"An unexpected error occurred.."<<endl
;
1184 BOOST_AUTO_TEST_SUITE_END();