]> git.ipfire.org Git - thirdparty/pdns.git/blob - modules/remotebackend/test-remotebackend.cc
4cebc2c16dd7bde733caa4ab1041b7779794640e
[thirdparty/pdns.git] / modules / remotebackend / test-remotebackend.cc
1 /*
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
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.
8 *
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.
12 *
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.
17 *
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.
21 */
22 #ifndef BOOST_TEST_DYN_LINK
23 #define BOOST_TEST_DYN_LINK
24 #endif
25
26 #define BOOST_TEST_NO_MAIN
27
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 #include <boost/test/unit_test.hpp>
32 #include <boost/assign/list_of.hpp>
33
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"
44
45 #include "test-remotebackend-keys.hh"
46
47 extern std::unique_ptr<DNSBackend> backendUnderTest;
48
49 BOOST_AUTO_TEST_SUITE(test_remotebackend_so)
50
51 BOOST_AUTO_TEST_CASE(test_method_lookup)
52 {
53 BOOST_TEST_MESSAGE("Testing lookup method");
54 DNSResourceRecord resourceRecord;
55 backendUnderTest->lookup(QType(QType::SOA), DNSName("unit.test."));
56 // then try to get()
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);
63 }
64
65 BOOST_AUTO_TEST_CASE(test_method_lookup_empty)
66 {
67 BOOST_TEST_MESSAGE("Testing lookup method with empty result");
68 DNSResourceRecord resourceRecord;
69 backendUnderTest->lookup(QType(QType::SOA), DNSName("empty.unit.test."));
70 // then try to get()
71 BOOST_CHECK(!backendUnderTest->get(resourceRecord)); // and this should be FALSE
72 }
73
74 BOOST_AUTO_TEST_CASE(test_method_list)
75 {
76 int record_count = 0;
77 DNSResourceRecord resourceRecord;
78
79 BOOST_TEST_MESSAGE("Testing list method");
80 backendUnderTest->list(DNSName("unit.test."), -1);
81 while (backendUnderTest->get(resourceRecord)) {
82 record_count++;
83 }
84
85 BOOST_CHECK_EQUAL(record_count, 5); // number of records our test domain has
86 }
87
88 BOOST_AUTO_TEST_CASE(test_method_doesDNSSEC)
89 {
90 BOOST_TEST_MESSAGE("Testing doesDNSSEC method");
91 BOOST_CHECK(backendUnderTest->doesDNSSEC()); // should be true
92 }
93
94 BOOST_AUTO_TEST_CASE(test_method_setDomainMetadata)
95 {
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));
100 }
101
102 BOOST_AUTO_TEST_CASE(test_method_alsoNotifies)
103 {
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);
111 }
112 BOOST_CHECK(backendUnderTest->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", std::vector<std::string>()));
113 }
114
115 BOOST_AUTO_TEST_CASE(test_method_getDomainMetadata)
116 {
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
122 // but not fatal
123 if (!meta.empty()) {
124 BOOST_CHECK_EQUAL(meta[0], "VALUE");
125 }
126 }
127
128 BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata)
129 {
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
135 // but not fatal
136 if (!meta.empty()) {
137 BOOST_CHECK_EQUAL(meta["TEST"][0], "VALUE");
138 }
139 }
140
141 BOOST_AUTO_TEST_CASE(test_method_addDomainKey)
142 {
143 BOOST_TEST_MESSAGE("Testing addDomainKey method");
144 int64_t keyID = 0;
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);
149 }
150
151 BOOST_AUTO_TEST_CASE(test_method_getDomainKeys)
152 {
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
159 // but not fatal
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);
168 }
169 }
170 }
171
172 BOOST_AUTO_TEST_CASE(test_method_deactivateDomainKey)
173 {
174 BOOST_TEST_MESSAGE("Testing deactivateDomainKey method");
175 BOOST_CHECK(backendUnderTest->deactivateDomainKey(DNSName("unit.test."), 1));
176 }
177
178 BOOST_AUTO_TEST_CASE(test_method_activateDomainKey)
179 {
180 BOOST_TEST_MESSAGE("Testing activateDomainKey method");
181 BOOST_CHECK(backendUnderTest->activateDomainKey(DNSName("unit.test."), 1));
182 }
183
184 BOOST_AUTO_TEST_CASE(test_method_removeDomainKey)
185 {
186 BOOST_CHECK(backendUnderTest->removeDomainKey(DNSName("unit.test."), 2));
187 BOOST_CHECK(backendUnderTest->removeDomainKey(DNSName("unit.test."), 1));
188 }
189
190 BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute)
191 {
192 DNSName unhashed;
193 DNSName before;
194 DNSName after;
195 BOOST_TEST_MESSAGE("Testing getBeforeAndAfterNamesAbsolute method");
196
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.");
201 }
202
203 BOOST_AUTO_TEST_CASE(test_method_setTSIGKey)
204 {
205 std::string algorithm;
206 std::string content;
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");
209 }
210
211 BOOST_AUTO_TEST_CASE(test_method_getTSIGKey)
212 {
213 DNSName algorithm;
214 std::string content;
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=");
219 }
220
221 BOOST_AUTO_TEST_CASE(test_method_deleteTSIGKey)
222 {
223 std::string algorithm;
224 std::string content;
225 BOOST_TEST_MESSAGE("Testing deleteTSIGKey method");
226 BOOST_CHECK_MESSAGE(backendUnderTest->deleteTSIGKey(DNSName("unit.test.")), "did not return true");
227 }
228
229 BOOST_AUTO_TEST_CASE(test_method_getTSIGKeys)
230 {
231 std::vector<struct TSIGKey> keys;
232 BOOST_TEST_MESSAGE("Testing getTSIGKeys method");
233 backendUnderTest->getTSIGKeys(keys);
234 BOOST_CHECK(!keys.empty());
235 if (!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");
239 }
240 }
241
242 BOOST_AUTO_TEST_CASE(test_method_setNotified)
243 {
244 BOOST_TEST_MESSAGE("Testing setNotified method");
245 backendUnderTest->setNotified(1, 2);
246 BOOST_CHECK(true); // we check this on next step
247 }
248
249 BOOST_AUTO_TEST_CASE(test_method_getDomainInfo)
250 {
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());
259 }
260
261 BOOST_AUTO_TEST_CASE(test_method_getAllDomains)
262 {
263 DomainInfo domainInfo;
264 BOOST_TEST_MESSAGE("Testing getAllDomains method");
265 vector<DomainInfo> result;
266
267 backendUnderTest->getAllDomains(&result, true, true);
268
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());
276 }
277
278 BOOST_AUTO_TEST_CASE(test_method_autoPrimaryBackend)
279 {
280 DNSResourceRecord resourceRecord;
281 std::vector<DNSResourceRecord> nsset;
282 DNSBackend* dbd = nullptr;
283 BOOST_TEST_MESSAGE("Testing autoPrimaryBackend method");
284
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);
297
298 BOOST_CHECK(backendUnderTest->autoPrimaryBackend("10.0.0.1", DNSName("example.com."), nsset, nullptr, nullptr, &dbd));
299
300 // let's see what we got
301 BOOST_CHECK_EQUAL(dbd, backendUnderTest.get());
302 }
303
304 BOOST_AUTO_TEST_CASE(test_method_createSecondaryDomain)
305 {
306 BOOST_TEST_MESSAGE("Testing createSecondaryDomain method");
307 BOOST_CHECK(backendUnderTest->createSecondaryDomain("10.0.0.1", DNSName("pirate.unit.test."), "", ""));
308 }
309
310 BOOST_AUTO_TEST_CASE(test_method_feedRecord)
311 {
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();
328 }
329
330 BOOST_AUTO_TEST_CASE(test_method_replaceRRSet)
331 {
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();
344 }
345
346 BOOST_AUTO_TEST_CASE(test_method_feedEnts)
347 {
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();
353 }
354
355 BOOST_AUTO_TEST_CASE(test_method_feedEnts3)
356 {
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();
365 }
366
367 BOOST_AUTO_TEST_CASE(test_method_abortTransaction)
368 {
369 BOOST_TEST_MESSAGE("Testing abortTransaction method");
370 backendUnderTest->startTransaction(DNSName("example.com."), 2);
371 BOOST_CHECK(backendUnderTest->abortTransaction());
372 }
373
374 BOOST_AUTO_TEST_CASE(test_method_directBackendCmd)
375 {
376 BOOST_TEST_MESSAGE("Testing directBackendCmd method");
377 BOOST_CHECK_EQUAL(backendUnderTest->directBackendCmd("PING 1234"), "PING 1234");
378 }
379
380 BOOST_AUTO_TEST_CASE(test_method_getUpdatedPrimaries)
381 {
382 DomainInfo domainInfo;
383 BOOST_TEST_MESSAGE("Testing getUpdatedPrimaries method");
384 vector<DomainInfo> result;
385 std::unordered_set<DNSName> catalogs;
386 CatalogHashMap hashes;
387
388 backendUnderTest->getUpdatedPrimaries(result, catalogs, hashes);
389
390 BOOST_REQUIRE(!result.empty());
391
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());
398 }
399
400 BOOST_AUTO_TEST_SUITE_END();