1 #define BOOST_TEST_DYN_LINK
2 #include <boost/test/unit_test.hpp>
6 #include "test-syncres_cc.hh"
7 #include "reczones-helpers.hh"
9 BOOST_AUTO_TEST_SUITE(reczones_helpers
)
11 static const std::array
<std::string
, 10> hostLines
= {
12 "192.168.0.1 foo bar\n",
13 "192.168.0.1 dupfoo\n",
16 "2.2.2.2 more.fancy\n",
17 "2001:db8::567:89ab foo6 bar6\n",
18 "2001:db8::567:89ab dupfoo6\n",
19 "127.0.0.1 localhost\n",
20 "::1 localhost self\n",
21 "2001:db8::567:89ac some.address.somewhere some some.address\n",
26 static std::shared_ptr
<DNSRecordContent
> makeLocalhostRootDRC()
28 return DNSRecordContent::make(QType::SOA
, QClass::IN
, "localhost. root 1 604800 86400 2419200 604800");
31 static std::shared_ptr
<DNSRecordContent
> makeLocalhostDRC()
33 return DNSRecordContent::make(QType::NS
, QClass::IN
, "localhost.");
36 static std::shared_ptr
<DNSRecordContent
> makePtrDRC(const std::string
& name
)
38 return DNSRecordContent::make(QType::PTR
, QClass::IN
, name
);
41 static void addDomainMapFixtureEntry(SyncRes::domainmap_t
& domainMap
,
42 const std::string
& name
,
43 const SyncRes::AuthDomain::records_t
& records
)
45 domainMap
[DNSName
{name
}] = SyncRes::AuthDomain
{
48 .d_name
= DNSName
{name
},
53 static void addDomainMapFixtureEntry(SyncRes::domainmap_t
& domainMap
,
54 const std::string
& name
,
56 const std::string
& address
)
58 domainMap
[DNSName
{name
}] = SyncRes::AuthDomain
{
60 DNSRecord(name
, DNSRecordContent::make(type
, QClass::IN
, address
), type
),
61 DNSRecord(name
, makeLocalhostDRC(), QType::NS
),
62 DNSRecord(name
, makeLocalhostRootDRC(), QType::SOA
),
65 .d_name
= DNSName
{name
},
70 static void populateDomainMapFixture(SyncRes::domainmap_t
& domainMap
,
71 const std::string
& searchSuffix
= "")
73 const auto actualSearchSuffix
= searchSuffix
.empty() ? "" : "." + searchSuffix
;
75 addDomainMapFixtureEntry(domainMap
, "foo" + actualSearchSuffix
, QType::A
, "192.168.0.1");
76 addDomainMapFixtureEntry(domainMap
, "bar" + actualSearchSuffix
, QType::A
, "192.168.0.1");
77 addDomainMapFixtureEntry(domainMap
, "dupfoo" + actualSearchSuffix
, QType::A
, "192.168.0.1");
78 addDomainMapFixtureEntry(
80 "1.0.168.192.in-addr.arpa",
82 DNSRecord("1.0.168.192.in-addr.arpa", makeLocalhostDRC(), QType::NS
),
83 DNSRecord("1.0.168.192.in-addr.arpa", makeLocalhostRootDRC(), QType::SOA
),
84 DNSRecord("1.0.168.192.in-addr.arpa", makePtrDRC("foo" + actualSearchSuffix
), QType::PTR
),
86 addDomainMapFixtureEntry(domainMap
, "baz" + actualSearchSuffix
, QType::A
, "192.168.0.2");
87 addDomainMapFixtureEntry(
89 "2.0.168.192.in-addr.arpa",
91 DNSRecord("2.0.168.192.in-addr.arpa", makeLocalhostDRC(), QType::NS
),
92 DNSRecord("2.0.168.192.in-addr.arpa", makeLocalhostRootDRC(), QType::SOA
),
93 DNSRecord("2.0.168.192.in-addr.arpa", makePtrDRC("baz" + actualSearchSuffix
), QType::PTR
),
95 addDomainMapFixtureEntry(domainMap
, "fancy" + actualSearchSuffix
, QType::A
, "1.1.1.1");
96 addDomainMapFixtureEntry(
98 "1.1.1.1.in-addr.arpa",
100 DNSRecord("1.1.1.1.in-addr.arpa", makeLocalhostDRC(), QType::NS
),
101 DNSRecord("1.1.1.1.in-addr.arpa", makeLocalhostRootDRC(), QType::SOA
),
102 DNSRecord("1.1.1.1.in-addr.arpa", makePtrDRC("fancy" + actualSearchSuffix
), QType::PTR
),
104 addDomainMapFixtureEntry(domainMap
, "more.fancy", QType::A
, "2.2.2.2");
105 addDomainMapFixtureEntry(
107 "2.2.2.2.in-addr.arpa",
109 DNSRecord("2.2.2.2.in-addr.arpa", makeLocalhostDRC(), QType::NS
),
110 DNSRecord("2.2.2.2.in-addr.arpa", makeLocalhostRootDRC(), QType::SOA
),
111 DNSRecord("2.2.2.2.in-addr.arpa", makePtrDRC("more.fancy."), QType::PTR
),
114 addDomainMapFixtureEntry(domainMap
, "foo6" + actualSearchSuffix
, QType::AAAA
, "2001:db8::567:89ab");
115 addDomainMapFixtureEntry(domainMap
, "bar6" + actualSearchSuffix
, QType::AAAA
, "2001:db8::567:89ab");
116 addDomainMapFixtureEntry(domainMap
, "dupfoo6" + actualSearchSuffix
, QType::AAAA
, "2001:db8::567:89ab");
117 addDomainMapFixtureEntry(
119 "b.a.9.8.7.6.5.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",
121 DNSRecord("b.a.9.8.7.6.5.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", makeLocalhostDRC(), QType::NS
),
122 DNSRecord("b.a.9.8.7.6.5.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", makeLocalhostRootDRC(), QType::SOA
),
123 DNSRecord("b.a.9.8.7.6.5.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", makePtrDRC("foo6" + actualSearchSuffix
), QType::PTR
),
126 addDomainMapFixtureEntry(
128 "localhost" + actualSearchSuffix
,
129 {DNSRecord("localhost" + actualSearchSuffix
, makeLocalhostDRC(), QType::NS
),
130 DNSRecord("localhost" + actualSearchSuffix
, makeLocalhostRootDRC(), QType::SOA
),
131 DNSRecord("localhost" + actualSearchSuffix
, DNSRecordContent::make(QType::AAAA
, QClass::IN
, "::1"), QType::AAAA
),
132 DNSRecord("localhost" + actualSearchSuffix
, DNSRecordContent::make(QType::A
, QClass::IN
, "127.0.0.1"), QType::A
)});
133 addDomainMapFixtureEntry(domainMap
, "self" + actualSearchSuffix
, QType::AAAA
, "::1");
134 addDomainMapFixtureEntry(
136 "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa",
138 DNSRecord("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa", makeLocalhostDRC(), QType::NS
),
139 DNSRecord("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa", makeLocalhostRootDRC(), QType::SOA
),
140 DNSRecord("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa", makePtrDRC("localhost" + actualSearchSuffix
), QType::PTR
),
142 addDomainMapFixtureEntry(
144 "1.0.0.127.in-addr.arpa",
146 DNSRecord("1.0.0.127.in-addr.arpa", makeLocalhostDRC(), QType::NS
),
147 DNSRecord("1.0.0.127.in-addr.arpa", makeLocalhostRootDRC(), QType::SOA
),
148 DNSRecord("1.0.0.127.in-addr.arpa", makePtrDRC("localhost" + actualSearchSuffix
), QType::PTR
),
151 addDomainMapFixtureEntry(domainMap
, "some" + actualSearchSuffix
, QType::AAAA
, "2001:db8::567:89ac");
152 addDomainMapFixtureEntry(domainMap
, "some.address.somewhere", QType::AAAA
, "2001:db8::567:89ac");
153 addDomainMapFixtureEntry(domainMap
, "some.address", QType::AAAA
, "2001:db8::567:89ac");
154 addDomainMapFixtureEntry(
156 "c.a.9.8.7.6.5.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",
158 DNSRecord("c.a.9.8.7.6.5.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", makeLocalhostDRC(), QType::NS
),
159 DNSRecord("c.a.9.8.7.6.5.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", makeLocalhostRootDRC(), QType::SOA
),
160 DNSRecord("c.a.9.8.7.6.5.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", makePtrDRC("some.address.somewhere."), QType::PTR
),
166 populateDomainMapFixture(domainMapFixture
);
167 populateDomainMapFixture(domainMapFixtureWithSearchSuffix
, "search.suffix");
170 using DomainMapEntry
= std::pair
<DNSName
, SyncRes::AuthDomain
>;
172 static std::vector
<DomainMapEntry
> sortDomainMap(const SyncRes::domainmap_t
& domainMap
)
174 std::vector
<DomainMapEntry
> sorted
{};
175 sorted
.reserve(domainMap
.size());
176 for (const auto& pair
: domainMap
) {
177 sorted
.emplace_back(pair
.first
, pair
.second
);
179 std::stable_sort(std::begin(sorted
), std::end(sorted
), [](const DomainMapEntry
& a
, const DomainMapEntry
& b
) {
180 return a
.first
< b
.first
&& a
.second
.d_name
< b
.second
.d_name
;
185 static std::string
printDomainMap(const std::vector
<DomainMapEntry
>& domainMap
)
187 std::stringstream s
{};
188 for (const auto& entry
: domainMap
) {
189 s
<< "Entry `" << entry
.first
<< "` {" << std::endl
;
190 s
<< entry
.second
.print(" ");
191 s
<< "}" << std::endl
;
196 std::vector
<DomainMapEntry
> getDomainMapFixture() const
198 return sortDomainMap(domainMapFixture
);
201 std::vector
<DomainMapEntry
> getDomainMapFixtureWithSearchSuffix() const
203 return sortDomainMap(domainMapFixtureWithSearchSuffix
);
207 SyncRes::domainmap_t domainMapFixture
{};
208 SyncRes::domainmap_t domainMapFixtureWithSearchSuffix
{};
211 BOOST_FIXTURE_TEST_CASE(test_loading_etc_hosts
, Fixture
)
213 auto log
= g_slog
->withName("config");
215 auto domainMap
= std::make_shared
<SyncRes::domainmap_t
>();
216 auto domainMapWithSearchSuffix
= std::make_shared
<SyncRes::domainmap_t
>();
217 std::vector
<std::string
> parts
{};
218 for (auto line
: hostLines
) {
219 BOOST_REQUIRE(parseEtcHostsLine(parts
, line
));
220 addForwardAndReverseLookupEntries(*domainMap
, "", parts
, log
);
221 addForwardAndReverseLookupEntries(*domainMapWithSearchSuffix
, "search.suffix", parts
, log
);
224 BOOST_TEST_MESSAGE("Actual and expected outputs without search suffixes:");
226 auto actual
= sortDomainMap(*domainMap
);
227 BOOST_TEST_MESSAGE("Actual:");
228 BOOST_TEST_MESSAGE(printDomainMap(actual
));
230 auto expected
= getDomainMapFixture();
231 BOOST_TEST_MESSAGE("Expected:");
232 BOOST_TEST_MESSAGE(printDomainMap(expected
));
234 BOOST_CHECK_EQUAL(actual
.size(), expected
.size());
235 for (std::vector
<DomainMapEntry
>::size_type i
= 0; i
< actual
.size(); i
++) {
236 BOOST_CHECK(actual
[i
].first
== expected
[i
].first
);
237 BOOST_CHECK(actual
[i
].second
== expected
[i
].second
);
240 BOOST_TEST_MESSAGE("-----------------------------------------------------");
242 BOOST_TEST_MESSAGE("Actual and expected outputs with search suffixes:");
244 auto actualSearchSuffix
= sortDomainMap(*domainMapWithSearchSuffix
);
245 BOOST_TEST_MESSAGE("Actual (with search suffix):");
246 BOOST_TEST_MESSAGE(printDomainMap(actualSearchSuffix
));
248 auto expectedSearchSuffix
= getDomainMapFixtureWithSearchSuffix();
249 BOOST_TEST_MESSAGE("Expected (with search suffix):");
250 BOOST_TEST_MESSAGE(printDomainMap(expectedSearchSuffix
));
252 BOOST_CHECK_EQUAL(actualSearchSuffix
.size(), expectedSearchSuffix
.size());
253 for (std::vector
<DomainMapEntry
>::size_type i
= 0; i
< actualSearchSuffix
.size(); i
++) {
254 BOOST_CHECK(actualSearchSuffix
[i
].first
== expectedSearchSuffix
[i
].first
);
255 BOOST_CHECK(actualSearchSuffix
[i
].second
== expectedSearchSuffix
[i
].second
);
258 BOOST_TEST_MESSAGE("-----------------------------------------------------");
261 const std::string hints
= ". 3600 IN NS ns.\n"
262 ". 3600 IN NS ns1.\n"
263 "ns. 3600 IN A 192.168.178.16\n"
264 "ns. 3600 IN A 192.168.178.17\n"
265 "ns. 3600 IN A 192.168.178.18\n"
266 "ns. 3600 IN AAAA 1::2\n"
267 "ns. 3600 IN AAAA 1::3\n"
268 "ns1. 3600 IN A 192.168.178.18\n";
270 BOOST_AUTO_TEST_CASE(test_UserHints
)
273 g_recCache
= make_unique
<MemRecursorCache
>();
275 ::arg().set("max-generate-steps") = "0";
276 ::arg().set("max-include-depth") = "0";
277 char temp
[] = "/tmp/hintsXXXXXXXXXX";
278 int fd
= mkstemp(temp
);
279 BOOST_REQUIRE(fd
> 0);
280 FILE* fp
= fdopen(fd
, "w");
281 BOOST_REQUIRE(fp
!= nullptr);
282 size_t written
= fwrite(hints
.data(), 1, hints
.length(), fp
);
283 BOOST_REQUIRE(written
== hints
.length());
284 BOOST_REQUIRE(fclose(fp
) == 0);
286 time_t now
= time(nullptr);
287 std::vector
<DNSRecord
> nsvec
;
289 auto ok
= readHintsIntoCache(now
, std::string(temp
), nsvec
);
291 BOOST_CHECK_EQUAL(nsvec
.size(), 2U);
293 const MemRecursorCache::Flags flags
= 0;
295 BOOST_CHECK(g_recCache
->get(now
, DNSName("ns"), QType::A
, flags
, &nsvec
, ComboAddress()) > 0);
296 BOOST_CHECK_EQUAL(nsvec
.size(), 3U);
298 BOOST_CHECK(g_recCache
->get(now
, DNSName("ns"), QType::AAAA
, flags
, &nsvec
, ComboAddress()) > 0);
299 BOOST_CHECK_EQUAL(nsvec
.size(), 2U);
301 BOOST_CHECK(g_recCache
->get(now
, DNSName("ns1"), QType::A
, flags
, &nsvec
, ComboAddress()) > 0);
302 BOOST_CHECK_EQUAL(nsvec
.size(), 1U);
305 BOOST_AUTO_TEST_SUITE_END()