2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #ifndef BOOST_TEST_DYN_LINK
23 #define BOOST_TEST_DYN_LINK
26 #define BOOST_TEST_NO_MAIN
31 #include <boost/test/unit_test.hpp>
32 #include <boost/assign/list_of.hpp>
34 #include <boost/tuple/tuple.hpp>
35 #include "pdns/namespaces.hh"
36 #include "pdns/dns.hh"
37 #include "pdns/dnsbackend.hh"
38 #include "pdns/dnspacket.hh"
39 #include "pdns/pdnsexception.hh"
40 #include "pdns/logger.hh"
41 #include "pdns/arguments.hh"
42 #include "pdns/json.hh"
43 #include "pdns/statbag.hh"
45 #include "test-remotebackend-keys.hh"
47 extern std::unique_ptr
<DNSBackend
> backendUnderTest
;
49 BOOST_AUTO_TEST_SUITE(test_remotebackend_so
)
51 BOOST_AUTO_TEST_CASE(test_method_lookup
)
53 BOOST_TEST_MESSAGE("Testing lookup method");
54 DNSResourceRecord resourceRecord
;
55 backendUnderTest
->lookup(QType(QType::SOA
), DNSName("unit.test."));
57 BOOST_CHECK(backendUnderTest
->get(resourceRecord
)); // and this should be TRUE.
58 // then we check rr contains what we expect
59 BOOST_CHECK_EQUAL(resourceRecord
.qname
.toString(), "unit.test.");
60 BOOST_CHECK_MESSAGE(resourceRecord
.qtype
== QType::SOA
, "returned qtype was not SOA");
61 BOOST_CHECK_EQUAL(resourceRecord
.content
, "ns.unit.test. hostmaster.unit.test. 1 2 3 4 5");
62 BOOST_CHECK_EQUAL(resourceRecord
.ttl
, 300);
65 BOOST_AUTO_TEST_CASE(test_method_lookup_empty
)
67 BOOST_TEST_MESSAGE("Testing lookup method with empty result");
68 DNSResourceRecord resourceRecord
;
69 backendUnderTest
->lookup(QType(QType::SOA
), DNSName("empty.unit.test."));
71 BOOST_CHECK(!backendUnderTest
->get(resourceRecord
)); // and this should be FALSE
74 BOOST_AUTO_TEST_CASE(test_method_list
)
77 DNSResourceRecord resourceRecord
;
79 BOOST_TEST_MESSAGE("Testing list method");
80 backendUnderTest
->list(DNSName("unit.test."), -1);
81 while (backendUnderTest
->get(resourceRecord
)) {
85 BOOST_CHECK_EQUAL(record_count
, 5); // number of records our test domain has
88 BOOST_AUTO_TEST_CASE(test_method_doesDNSSEC
)
90 BOOST_TEST_MESSAGE("Testing doesDNSSEC method");
91 BOOST_CHECK(backendUnderTest
->doesDNSSEC()); // should be true
94 BOOST_AUTO_TEST_CASE(test_method_setDomainMetadata
)
96 std::vector
<std::string
> meta
;
97 meta
.emplace_back("VALUE");
98 BOOST_TEST_MESSAGE("Testing setDomainMetadata method");
99 BOOST_CHECK(backendUnderTest
->setDomainMetadata(DNSName("unit.test."), "TEST", meta
));
102 BOOST_AUTO_TEST_CASE(test_method_alsoNotifies
)
104 BOOST_CHECK(backendUnderTest
->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", {"192.0.2.1"}));
105 std::set
<std::string
> alsoNotifies
;
106 BOOST_TEST_MESSAGE("Testing alsoNotifies method");
107 backendUnderTest
->alsoNotifies(DNSName("unit.test."), &alsoNotifies
);
108 BOOST_CHECK_EQUAL(alsoNotifies
.size(), 1);
109 if (!alsoNotifies
.empty()) {
110 BOOST_CHECK_EQUAL(alsoNotifies
.count("192.0.2.1"), 1);
112 BOOST_CHECK(backendUnderTest
->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", std::vector
<std::string
>()));
115 BOOST_AUTO_TEST_CASE(test_method_getDomainMetadata
)
117 std::vector
<std::string
> meta
;
118 BOOST_TEST_MESSAGE("Testing getDomainMetadata method");
119 backendUnderTest
->getDomainMetadata(DNSName("unit.test."), "TEST", meta
);
120 BOOST_CHECK_EQUAL(meta
.size(), 1);
121 // in case we got more than one value, which would be unexpected
124 BOOST_CHECK_EQUAL(meta
[0], "VALUE");
128 BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata
)
130 std::map
<std::string
, std::vector
<std::string
>> meta
;
131 BOOST_TEST_MESSAGE("Testing getAllDomainMetadata method");
132 backendUnderTest
->getAllDomainMetadata(DNSName("unit.test."), meta
);
133 BOOST_CHECK_EQUAL(meta
.size(), 1);
134 // in case we got more than one value, which would be unexpected
137 BOOST_CHECK_EQUAL(meta
["TEST"][0], "VALUE");
141 BOOST_AUTO_TEST_CASE(test_method_addDomainKey
)
143 BOOST_TEST_MESSAGE("Testing addDomainKey method");
145 backendUnderTest
->addDomainKey(DNSName("unit.test."), k1
, keyID
);
146 BOOST_CHECK_EQUAL(keyID
, 1);
147 backendUnderTest
->addDomainKey(DNSName("unit.test."), k2
, keyID
);
148 BOOST_CHECK_EQUAL(keyID
, 2);
151 BOOST_AUTO_TEST_CASE(test_method_getDomainKeys
)
153 std::vector
<DNSBackend::KeyData
> keys
;
154 BOOST_TEST_MESSAGE("Testing getDomainKeys method");
155 // we expect to get two keys
156 backendUnderTest
->getDomainKeys(DNSName("unit.test."), keys
);
157 BOOST_CHECK_EQUAL(keys
.size(), 2);
158 // in case we got more than 2 keys, which would be unexpected
160 if (keys
.size() > 1) {
161 // check that we have two keys
162 for (DNSBackend::KeyData
& keyData
: keys
) {
163 BOOST_CHECK(keyData
.id
> 0);
164 BOOST_CHECK(keyData
.flags
== 256 || keyData
.flags
== 257);
165 BOOST_CHECK(keyData
.active
== true);
166 BOOST_CHECK(keyData
.published
== true);
167 BOOST_CHECK(keyData
.content
.size() > 500);
172 BOOST_AUTO_TEST_CASE(test_method_deactivateDomainKey
)
174 BOOST_TEST_MESSAGE("Testing deactivateDomainKey method");
175 BOOST_CHECK(backendUnderTest
->deactivateDomainKey(DNSName("unit.test."), 1));
178 BOOST_AUTO_TEST_CASE(test_method_activateDomainKey
)
180 BOOST_TEST_MESSAGE("Testing activateDomainKey method");
181 BOOST_CHECK(backendUnderTest
->activateDomainKey(DNSName("unit.test."), 1));
184 BOOST_AUTO_TEST_CASE(test_method_removeDomainKey
)
186 BOOST_CHECK(backendUnderTest
->removeDomainKey(DNSName("unit.test."), 2));
187 BOOST_CHECK(backendUnderTest
->removeDomainKey(DNSName("unit.test."), 1));
190 BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute
)
195 BOOST_TEST_MESSAGE("Testing getBeforeAndAfterNamesAbsolute method");
197 backendUnderTest
->getBeforeAndAfterNamesAbsolute(1, DNSName("middle.unit.test."), unhashed
, before
, after
);
198 BOOST_CHECK_EQUAL(unhashed
.toString(), "middle.");
199 BOOST_CHECK_EQUAL(before
.toString(), "begin.");
200 BOOST_CHECK_EQUAL(after
.toString(), "stop.");
203 BOOST_AUTO_TEST_CASE(test_method_setTSIGKey
)
205 std::string algorithm
;
207 BOOST_TEST_MESSAGE("Testing setTSIGKey method");
208 BOOST_CHECK_MESSAGE(backendUnderTest
->setTSIGKey(DNSName("unit.test."), DNSName("hmac-md5."), "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys="), "did not return true");
211 BOOST_AUTO_TEST_CASE(test_method_getTSIGKey
)
215 BOOST_TEST_MESSAGE("Testing getTSIGKey method");
216 backendUnderTest
->getTSIGKey(DNSName("unit.test."), algorithm
, content
);
217 BOOST_CHECK_EQUAL(algorithm
.toString(), "hmac-md5.");
218 BOOST_CHECK_EQUAL(content
, "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys=");
221 BOOST_AUTO_TEST_CASE(test_method_deleteTSIGKey
)
223 std::string algorithm
;
225 BOOST_TEST_MESSAGE("Testing deleteTSIGKey method");
226 BOOST_CHECK_MESSAGE(backendUnderTest
->deleteTSIGKey(DNSName("unit.test.")), "did not return true");
229 BOOST_AUTO_TEST_CASE(test_method_getTSIGKeys
)
231 std::vector
<struct TSIGKey
> keys
;
232 BOOST_TEST_MESSAGE("Testing getTSIGKeys method");
233 backendUnderTest
->getTSIGKeys(keys
);
234 BOOST_CHECK(!keys
.empty());
236 BOOST_CHECK_EQUAL(keys
[0].name
.toString(), "test.");
237 BOOST_CHECK_EQUAL(keys
[0].algorithm
.toString(), "NULL.");
238 BOOST_CHECK_EQUAL(keys
[0].key
, "NULL");
242 BOOST_AUTO_TEST_CASE(test_method_setNotified
)
244 BOOST_TEST_MESSAGE("Testing setNotified method");
245 backendUnderTest
->setNotified(1, 2);
246 BOOST_CHECK(true); // we check this on next step
249 BOOST_AUTO_TEST_CASE(test_method_getDomainInfo
)
251 DomainInfo domainInfo
;
252 BOOST_TEST_MESSAGE("Testing getDomainInfo method");
253 backendUnderTest
->getDomainInfo(DNSName("unit.test."), domainInfo
);
254 BOOST_CHECK_EQUAL(domainInfo
.zone
.toString(), "unit.test.");
255 BOOST_CHECK_EQUAL(domainInfo
.serial
, 2);
256 BOOST_CHECK_EQUAL(domainInfo
.notified_serial
, 2);
257 BOOST_CHECK_EQUAL(domainInfo
.kind
, DomainInfo::Native
);
258 BOOST_CHECK_EQUAL(domainInfo
.backend
, backendUnderTest
.get());
261 BOOST_AUTO_TEST_CASE(test_method_getAllDomains
)
263 DomainInfo domainInfo
;
264 BOOST_TEST_MESSAGE("Testing getAllDomains method");
265 vector
<DomainInfo
> result
;
267 backendUnderTest
->getAllDomains(&result
, true, true);
269 BOOST_REQUIRE(!result
.empty());
270 domainInfo
= result
.at(0);
271 BOOST_CHECK_EQUAL(domainInfo
.zone
.toString(), "unit.test.");
272 BOOST_CHECK_EQUAL(domainInfo
.serial
, 2);
273 BOOST_CHECK_EQUAL(domainInfo
.notified_serial
, 2);
274 BOOST_CHECK_EQUAL(domainInfo
.kind
, DomainInfo::Native
);
275 BOOST_CHECK_EQUAL(domainInfo
.backend
, backendUnderTest
.get());
278 BOOST_AUTO_TEST_CASE(test_method_autoPrimaryBackend
)
280 DNSResourceRecord resourceRecord
;
281 std::vector
<DNSResourceRecord
> nsset
;
282 DNSBackend
* dbd
= nullptr;
283 BOOST_TEST_MESSAGE("Testing autoPrimaryBackend method");
285 resourceRecord
.qname
= DNSName("example.com.");
286 resourceRecord
.qtype
= QType::NS
;
287 resourceRecord
.qclass
= QClass::IN
;
288 resourceRecord
.ttl
= 300;
289 resourceRecord
.content
= "ns1.example.com.";
290 nsset
.push_back(resourceRecord
);
291 resourceRecord
.qname
= DNSName("example.com.");
292 resourceRecord
.qtype
= QType::NS
;
293 resourceRecord
.qclass
= QClass::IN
;
294 resourceRecord
.ttl
= 300;
295 resourceRecord
.content
= "ns2.example.com.";
296 nsset
.push_back(resourceRecord
);
298 BOOST_CHECK(backendUnderTest
->autoPrimaryBackend("10.0.0.1", DNSName("example.com."), nsset
, nullptr, nullptr, &dbd
));
300 // let's see what we got
301 BOOST_CHECK_EQUAL(dbd
, backendUnderTest
.get());
304 BOOST_AUTO_TEST_CASE(test_method_createSecondaryDomain
)
306 BOOST_TEST_MESSAGE("Testing createSecondaryDomain method");
307 BOOST_CHECK(backendUnderTest
->createSecondaryDomain("10.0.0.1", DNSName("pirate.unit.test."), "", ""));
310 BOOST_AUTO_TEST_CASE(test_method_feedRecord
)
312 DNSResourceRecord resourceRecord
;
313 BOOST_TEST_MESSAGE("Testing feedRecord method");
314 backendUnderTest
->startTransaction(DNSName("example.com."), 2);
315 resourceRecord
.qname
= DNSName("example.com.");
316 resourceRecord
.qtype
= QType::SOA
;
317 resourceRecord
.qclass
= QClass::IN
;
318 resourceRecord
.ttl
= 300;
319 resourceRecord
.content
= "ns1.example.com. hostmaster.example.com. 2013013441 7200 3600 1209600 300";
320 BOOST_CHECK(backendUnderTest
->feedRecord(resourceRecord
, DNSName()));
321 resourceRecord
.qname
= DNSName("replace.example.com.");
322 resourceRecord
.qtype
= QType::A
;
323 resourceRecord
.qclass
= QClass::IN
;
324 resourceRecord
.ttl
= 300;
325 resourceRecord
.content
= "127.0.0.1";
326 BOOST_CHECK(backendUnderTest
->feedRecord(resourceRecord
, DNSName()));
327 backendUnderTest
->commitTransaction();
330 BOOST_AUTO_TEST_CASE(test_method_replaceRRSet
)
332 backendUnderTest
->startTransaction(DNSName("example.com."), 2);
333 DNSResourceRecord resourceRecord
;
334 std::vector
<DNSResourceRecord
> rrset
;
335 BOOST_TEST_MESSAGE("Testing replaceRRSet method");
336 resourceRecord
.qname
= DNSName("replace.example.com.");
337 resourceRecord
.qtype
= QType::A
;
338 resourceRecord
.qclass
= QClass::IN
;
339 resourceRecord
.ttl
= 300;
340 resourceRecord
.content
= "1.1.1.1";
341 rrset
.push_back(resourceRecord
);
342 BOOST_CHECK(backendUnderTest
->replaceRRSet(2, DNSName("replace.example.com."), QType(QType::A
), rrset
));
343 backendUnderTest
->commitTransaction();
346 BOOST_AUTO_TEST_CASE(test_method_feedEnts
)
348 BOOST_TEST_MESSAGE("Testing feedEnts method");
349 backendUnderTest
->startTransaction(DNSName("example.com."), 2);
350 map
<DNSName
, bool> nonterm
= boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
351 BOOST_CHECK(backendUnderTest
->feedEnts(2, nonterm
));
352 backendUnderTest
->commitTransaction();
355 BOOST_AUTO_TEST_CASE(test_method_feedEnts3
)
357 BOOST_TEST_MESSAGE("Testing feedEnts3 method");
358 backendUnderTest
->startTransaction(DNSName("example.com"), 2);
359 NSEC3PARAMRecordContent ns3prc
;
360 ns3prc
.d_iterations
= 1;
361 ns3prc
.d_salt
= "\u00aa\u00bb\u00cc\u00dd";
362 map
<DNSName
, bool> nonterm
= boost::assign::map_list_of(DNSName("_udp"), true)(DNSName("_sip._udp"), true);
363 BOOST_CHECK(backendUnderTest
->feedEnts3(2, DNSName("example.com."), nonterm
, ns3prc
, 0));
364 backendUnderTest
->commitTransaction();
367 BOOST_AUTO_TEST_CASE(test_method_abortTransaction
)
369 BOOST_TEST_MESSAGE("Testing abortTransaction method");
370 backendUnderTest
->startTransaction(DNSName("example.com."), 2);
371 BOOST_CHECK(backendUnderTest
->abortTransaction());
374 BOOST_AUTO_TEST_CASE(test_method_directBackendCmd
)
376 BOOST_TEST_MESSAGE("Testing directBackendCmd method");
377 BOOST_CHECK_EQUAL(backendUnderTest
->directBackendCmd("PING 1234"), "PING 1234");
380 BOOST_AUTO_TEST_CASE(test_method_getUpdatedPrimaries
)
382 DomainInfo domainInfo
;
383 BOOST_TEST_MESSAGE("Testing getUpdatedPrimaries method");
384 vector
<DomainInfo
> result
;
385 std::unordered_set
<DNSName
> catalogs
;
386 CatalogHashMap hashes
;
388 backendUnderTest
->getUpdatedPrimaries(result
, catalogs
, hashes
);
390 BOOST_REQUIRE(!result
.empty());
392 domainInfo
= result
.at(0);
393 BOOST_CHECK_EQUAL(domainInfo
.zone
.toString(), "master.test.");
394 BOOST_CHECK_EQUAL(domainInfo
.serial
, 2);
395 BOOST_CHECK_EQUAL(domainInfo
.notified_serial
, 2);
396 BOOST_CHECK_EQUAL(domainInfo
.kind
, DomainInfo::Primary
);
397 BOOST_CHECK_EQUAL(domainInfo
.backend
, backendUnderTest
.get());
400 BOOST_AUTO_TEST_SUITE_END();