1 #ifndef BOOST_TEST_DYN_LINK
2 #define BOOST_TEST_DYN_LINK
5 #define BOOST_TEST_NO_MAIN
10 #include <boost/test/unit_test.hpp>
11 #include "rcpgenerator.hh"
17 BOOST_AUTO_TEST_SUITE(test_rcpgenerator_cc
)
19 BOOST_AUTO_TEST_CASE(test_xfrIP6
) {
20 RecordTextReader
rtr("::1");
24 loopback6
.append(15, 0);
25 loopback6
.append(1,1);
26 BOOST_CHECK_EQUAL(makeHexDump(rawIPv6
), makeHexDump(loopback6
));
28 RecordTextReader
rtr2("2a01:4f8:d12:1880::5");
30 string
ip6("\x2a\x01\x04\xf8\x0d\x12\x18\x80\x00\x00\x00\x00\x00\x00\x00\x05", 16);
31 BOOST_CHECK_EQUAL(makeHexDump(rawIPv6
), makeHexDump(ip6
));
33 RecordTextReader
rtr3("::FFFF:192.0.2.0");
35 string
ip62("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xc0\x00\x02\x00", 16);
36 BOOST_CHECK_EQUAL(makeHexDump(rawIPv6
), makeHexDump(ip62
));
39 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_alpn
) {
40 string
source("alpn=h2");
41 RecordTextReader
rtr(source
);
43 rtr
.xfrSvcParamKeyVals(v
);
44 BOOST_CHECK_EQUAL(v
.size(), 1U);
45 auto alpn
= v
.begin()->getALPN();
46 BOOST_CHECK_EQUAL(alpn
.size(), 1U);
47 auto val
= alpn
.begin();
48 BOOST_CHECK_EQUAL(*val
, "h2");
52 RecordTextWriter
rtw(target
);
53 rtw
.xfrSvcParamKeyVals(v
);
54 BOOST_CHECK_EQUAL(target
, source
);
57 source
= "alpn=h2,h3";
58 RecordTextReader
rtr2(source
);
59 rtr2
.xfrSvcParamKeyVals(v
);
60 BOOST_CHECK_EQUAL(v
.size(), 1U);
61 alpn
= v
.begin()->getALPN();
62 BOOST_CHECK_EQUAL(alpn
.size(), 2U);
64 BOOST_CHECK_EQUAL(*val
, "h2");
66 BOOST_CHECK_EQUAL(*val
, "h3");
70 RecordTextWriter
rtw2(target
);
71 rtw2
.xfrSvcParamKeyVals(v
);
72 BOOST_CHECK_EQUAL(target
, source
);
76 source
="key1=\\002h2\\002h3";
77 RecordTextReader
rtr3(source
);
78 rtr3
.xfrSvcParamKeyVals(v
);
79 BOOST_CHECK_EQUAL(v
.size(), 1U);
80 alpn
= v
.begin()->getALPN();
81 BOOST_CHECK_EQUAL(alpn
.size(), 2U);
83 BOOST_CHECK_EQUAL(*val
, "h2");
85 BOOST_CHECK_EQUAL(*val
, "h3");
88 source
="key1=\\002h2\\003h3"; // Wrong length for 2nd argument
89 RecordTextReader
rtr4(source
);
90 BOOST_CHECK_THROW(rtr4
.xfrSvcParamKeyVals(v
), RecordTextException
);
92 source
="key1=\\002h2\\002h3foobar"; // extra data
93 RecordTextReader
rtr5(source
);
94 BOOST_CHECK_THROW(rtr5
.xfrSvcParamKeyVals(v
), RecordTextException
);
97 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_mandatory
) {
98 string
source("mandatory=alpn");
99 RecordTextReader
rtr(source
);
101 rtr
.xfrSvcParamKeyVals(v
);
102 BOOST_CHECK_EQUAL(v
.size(), 1U);
103 auto m
= v
.begin()->getMandatory();
104 BOOST_CHECK_EQUAL(m
.size(), 1U);
105 auto val
= m
.begin();
106 BOOST_CHECK(*val
== SvcParam::alpn
);
110 RecordTextWriter
rtw(target
);
111 rtw
.xfrSvcParamKeyVals(v
);
112 BOOST_CHECK_EQUAL(target
, source
);
115 source
= "mandatory=alpn,ipv4hint";
116 RecordTextReader
rtr2("mandatory=alpn,ipv4hint");
117 rtr2
.xfrSvcParamKeyVals(v
);
118 BOOST_CHECK_EQUAL(v
.size(), 1U);
119 m
= v
.begin()->getMandatory();
120 BOOST_CHECK_EQUAL(m
.size(), 2U);
122 BOOST_CHECK(*val
== SvcParam::alpn
);
124 BOOST_CHECK(*val
== SvcParam::ipv4hint
);
128 RecordTextWriter
rtw2(target
);
129 rtw2
.xfrSvcParamKeyVals(v
);
130 BOOST_CHECK_EQUAL(target
, source
);
134 source
= "key0=\\000\\001\\000\\004";
135 RecordTextReader
rtr3(source
);
136 rtr3
.xfrSvcParamKeyVals(v
);
137 BOOST_CHECK_EQUAL(v
.size(), 1U);
138 m
= v
.begin()->getMandatory();
139 BOOST_CHECK_EQUAL(m
.size(), 2U);
141 BOOST_CHECK(*val
== SvcParam::alpn
);
143 BOOST_CHECK(*val
== SvcParam::ipv4hint
);
147 source
= "key0=\\000\\001\\000";
148 RecordTextReader
rtr4(source
);
149 BOOST_CHECK_THROW(rtr4
.xfrSvcParamKeyVals(v
), RecordTextException
);
153 RecordTextReader
rtr5(source
);
154 BOOST_CHECK_THROW(rtr5
.xfrSvcParamKeyVals(v
), RecordTextException
);
158 RecordTextReader
rtr6(source
);
159 BOOST_CHECK_THROW(rtr6
.xfrSvcParamKeyVals(v
), RecordTextException
);
162 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_no_default_alpn
) {
163 string
source("no-default-alpn");
164 RecordTextReader
rtr(source
);
166 rtr
.xfrSvcParamKeyVals(v
);
167 BOOST_CHECK_EQUAL(v
.size(), 1U);
168 auto k
= v
.begin()->getKey();
169 BOOST_CHECK(k
== SvcParam::no_default_alpn
);
173 RecordTextWriter
rtw(target
);
174 rtw
.xfrSvcParamKeyVals(v
);
175 BOOST_CHECK_EQUAL(target
, source
);
177 RecordTextReader
rtr2("no-default-alpn=");
179 BOOST_CHECK_THROW(rtr2
.xfrSvcParamKeyVals(v
), RecordTextException
);
184 RecordTextReader
rtr3(source
);
185 rtr3
.xfrSvcParamKeyVals(v
);
186 BOOST_CHECK_EQUAL(v
.size(), 1U);
187 k
= v
.begin()->getKey();
188 BOOST_CHECK(k
== SvcParam::no_default_alpn
);
191 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ipv4hint
) {
192 string
source("ipv4hint=192.0.2.1");
193 RecordTextReader
rtr(source
);
195 rtr
.xfrSvcParamKeyVals(v
);
196 BOOST_CHECK_EQUAL(v
.size(), 1U);
197 auto k
= v
.begin()->getKey();
198 BOOST_CHECK(k
== SvcParam::ipv4hint
);
199 auto val
= v
.begin()->getIPHints();
200 BOOST_CHECK_EQUAL(val
.size(), 1U);
201 BOOST_CHECK_EQUAL(val
.begin()->toString(), "192.0.2.1");
205 RecordTextWriter
rtw(target
);
206 rtw
.xfrSvcParamKeyVals(v
);
207 BOOST_CHECK_EQUAL(target
, source
);
210 source
= "ipv4hint=192.0.2.1,192.0.2.2,192.0.2.3";
211 RecordTextReader
rtr2(source
);
212 rtr2
.xfrSvcParamKeyVals(v
);
213 BOOST_CHECK_EQUAL(v
.size(), 1U);
214 k
= v
.begin()->getKey();
215 BOOST_CHECK(k
== SvcParam::ipv4hint
);
217 val
= v
.begin()->getIPHints();
218 BOOST_CHECK_EQUAL(val
.size(), 3U);
219 auto valit
= val
.begin();
220 BOOST_CHECK_EQUAL(valit
->toString(), "192.0.2.1");
222 BOOST_CHECK_EQUAL(valit
->toString(), "192.0.2.2");
224 BOOST_CHECK_EQUAL(valit
->toString(), "192.0.2.3");
228 RecordTextWriter
rtw2(target
);
229 rtw2
.xfrSvcParamKeyVals(v
);
230 BOOST_CHECK_EQUAL(target
, source
);
233 RecordTextReader
rtr3("ipv4hint=2001:db8::1");
234 BOOST_CHECK_THROW(rtr3
.xfrSvcParamKeyVals(v
), RecordTextException
);
237 RecordTextReader
rtr4("ipv4hint=192.0.2.1,2001:db8::1");
238 BOOST_CHECK_THROW(rtr4
.xfrSvcParamKeyVals(v
), RecordTextException
);
240 // Check if we can parse the generic format
242 source
= "key4=\\192\\000\\002\\015";
243 RecordTextReader
rtr5(source
);
244 rtr5
.xfrSvcParamKeyVals(v
);
245 BOOST_CHECK_EQUAL(v
.size(), 1U);
246 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().size(), 1U);
247 k
= v
.begin()->getKey();
248 BOOST_CHECK(k
== SvcParam::ipv4hint
);
249 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().begin()->toString(), "192.0.2.15");
252 source
= "key4=\\192\\000\\002\\015\\192\\000\\002\\222";
253 RecordTextReader
rtr6(source
);
254 rtr6
.xfrSvcParamKeyVals(v
);
255 BOOST_CHECK_EQUAL(v
.size(), 1U);
256 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().size(), 2U);
257 k
= v
.begin()->getKey();
258 BOOST_CHECK(k
== SvcParam::ipv4hint
);
259 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().begin()->toString(), "192.0.2.15");
260 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().at(1).toString(), "192.0.2.222");
263 source
= "key4=\\192\\000\\222"; // Wrong number of octets
264 RecordTextReader
rtr7(source
);
265 BOOST_CHECK_THROW(rtr7
.xfrSvcParamKeyVals(v
), RecordTextException
);
268 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ipv6hint
) {
269 string
source("ipv6hint=2001:db8::1");
270 RecordTextReader
rtr(source
);
272 rtr
.xfrSvcParamKeyVals(v
);
273 BOOST_CHECK_EQUAL(v
.size(), 1U);
274 auto k
= v
.begin()->getKey();
275 BOOST_CHECK(k
== SvcParam::ipv6hint
);
276 auto val
= v
.begin()->getIPHints();
277 BOOST_CHECK_EQUAL(val
.size(), 1U);
278 BOOST_CHECK_EQUAL(val
.begin()->toString(), "2001:db8::1");
282 RecordTextWriter
rtw(target
);
283 rtw
.xfrSvcParamKeyVals(v
);
284 BOOST_CHECK_EQUAL(target
, source
);
287 source
= "ipv6hint=2001:db8::1,2001:db8::2,2001:db8::3";
288 RecordTextReader
rtr2(source
);
289 rtr2
.xfrSvcParamKeyVals(v
);
290 BOOST_CHECK_EQUAL(v
.size(), 1U);
291 k
= v
.begin()->getKey();
292 BOOST_CHECK(k
== SvcParam::ipv6hint
);
294 val
= v
.begin()->getIPHints();
295 BOOST_CHECK_EQUAL(val
.size(), 3U);
296 auto valit
= val
.begin();
297 BOOST_CHECK_EQUAL(valit
->toString(), "2001:db8::1");
299 BOOST_CHECK_EQUAL(valit
->toString(), "2001:db8::2");
301 BOOST_CHECK_EQUAL(valit
->toString(), "2001:db8::3");
305 RecordTextWriter
rtw2(target
);
306 rtw2
.xfrSvcParamKeyVals(v
);
307 BOOST_CHECK_EQUAL(target
, source
);
310 RecordTextReader
rtr3("ipv6hint=192.0.2.1");
311 BOOST_CHECK_THROW(rtr3
.xfrSvcParamKeyVals(v
), RecordTextException
);
314 RecordTextReader
rtr4("ipv6hint=192.0.2.1,2001:db8::1");
315 BOOST_CHECK_THROW(rtr4
.xfrSvcParamKeyVals(v
), RecordTextException
);
317 // Check if we can parse the generic format
319 RecordTextReader
rtr5("key6=\\032\\001\\013\\184\\000\\083\\000\\000\\000\\000\\000\\000\\000\\000\\000\\021");
320 rtr5
.xfrSvcParamKeyVals(v
);
321 BOOST_CHECK_EQUAL(v
.size(), 1U);
322 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().size(), 1U);
323 k
= v
.begin()->getKey();
324 BOOST_CHECK(k
== SvcParam::ipv6hint
);
325 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().begin()->toString(), "2001:db8:53::15");
328 source
= "key6=\\032\\001\\013\\184\\000\\083\\000\\000\\000\\000\\000\\000\\000\\000\\000\\021\\032\\001\\013\\184\\000\\083\\000\\000\\000\\000\\000\\000\\000\\000\\000\\022";
329 RecordTextReader
rtr6(source
);
330 rtr6
.xfrSvcParamKeyVals(v
);
331 BOOST_CHECK_EQUAL(v
.size(), 1U);
332 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().size(), 2U);
333 k
= v
.begin()->getKey();
334 BOOST_CHECK(k
== SvcParam::ipv6hint
);
335 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().begin()->toString(), "2001:db8:53::15");
336 BOOST_CHECK_EQUAL(v
.begin()->getIPHints().at(1).toString(), "2001:db8:53::16");
339 source
= "key6=\\040\\001\\015\\270\\000\\123\\000\\000\\000\\000\\000\\000\\000\\000\\000"; // wrong number of octets
340 RecordTextReader
rtr7(source
);
341 BOOST_CHECK_THROW(rtr7
.xfrSvcParamKeyVals(v
), RecordTextException
);
344 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_port
) {
345 string
source("port=53");
346 RecordTextReader
rtr(source
);
348 rtr
.xfrSvcParamKeyVals(v
);
349 BOOST_CHECK_EQUAL(v
.size(), 1U);
350 auto k
= v
.begin()->getKey();
351 BOOST_CHECK(k
== SvcParam::port
);
352 auto val
= v
.begin()->getPort();
353 BOOST_CHECK_EQUAL(val
, 53);
357 RecordTextWriter
rtw(target
);
358 rtw
.xfrSvcParamKeyVals(v
);
359 BOOST_CHECK_EQUAL(target
, source
);
362 RecordTextReader
rtr2("port=100000");
363 BOOST_CHECK_THROW(rtr2
.xfrSvcParamKeyVals(v
), RecordTextException
);
366 RecordTextReader
rtr3("port=foo");
367 BOOST_CHECK_THROW(rtr3
.xfrSvcParamKeyVals(v
), RecordTextException
);
370 RecordTextReader
rtr4("port=");
371 BOOST_CHECK_THROW(rtr4
.xfrSvcParamKeyVals(v
), RecordTextException
);
374 RecordTextReader
rtr5("port");
375 BOOST_CHECK_THROW(rtr5
.xfrSvcParamKeyVals(v
), RecordTextException
);
379 RecordTextReader
rtr6("key3");
380 BOOST_CHECK_THROW(rtr6
.xfrSvcParamKeyVals(v
), RecordTextException
);
383 RecordTextReader
rtr7("key3=\\000\\053");
384 rtr7
.xfrSvcParamKeyVals(v
);
385 BOOST_CHECK_EQUAL(v
.size(), 1U);
386 k
= v
.begin()->getKey();
387 BOOST_CHECK(k
== SvcParam::port
);
388 val
= v
.begin()->getPort();
389 BOOST_CHECK_EQUAL(val
, 53);
392 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_generic
) {
393 string
source("key666=foobar");
394 RecordTextReader
rtr(source
);
396 rtr
.xfrSvcParamKeyVals(v
);
397 BOOST_CHECK_EQUAL(v
.size(), 1U);
398 auto k
= v
.begin()->getKey();
399 BOOST_CHECK(k
== 666);
400 auto val
= v
.begin()->getValue();
401 BOOST_CHECK_EQUAL(val
, "foobar");
405 RecordTextWriter
rtw(target
);
406 rtw
.xfrSvcParamKeyVals(v
);
407 BOOST_CHECK_EQUAL(target
, "key666=\"foobar\"");
410 RecordTextReader
rtr2("key666=");
411 BOOST_CHECK_THROW(rtr2
.xfrSvcParamKeyVals(v
), RecordTextException
);
414 RecordTextReader
rtr3("key666");
415 BOOST_CHECK_THROW(rtr3
.xfrSvcParamKeyVals(v
), RecordTextException
);
418 source
= "key666=\"blablabla\"";
419 RecordTextReader
rtr4(source
);
420 rtr4
.xfrSvcParamKeyVals(v
);
421 BOOST_CHECK_EQUAL(v
.size(), 1U);
422 k
= v
.begin()->getKey();
423 BOOST_CHECK(k
== SvcParam::keyFromString("key666"));
424 val
= v
.begin()->getValue();
425 BOOST_CHECK_EQUAL(val
, "blablabla");
429 RecordTextWriter
rtw2(target
);
430 rtw2
.xfrSvcParamKeyVals(v
);
431 BOOST_CHECK_EQUAL(target
, source
);
434 source
= "key666=\"foo\\123 bar\"";
435 RecordTextReader
rtr5(source
);
436 rtr5
.xfrSvcParamKeyVals(v
);
437 BOOST_CHECK_EQUAL(v
.size(), 1U);
438 k
= v
.begin()->getKey();
439 BOOST_CHECK(k
== SvcParam::keyFromString("key666"));
440 val
= v
.begin()->getValue();
441 BOOST_CHECK_EQUAL(val
, "foo{ bar");
445 RecordTextWriter
rtw3(target
);
446 rtw3
.xfrSvcParamKeyVals(v
);
447 BOOST_CHECK_EQUAL("key666=\"foo{ bar\"", target
);
450 RecordTextReader
rtr6("key665= blabla");
451 BOOST_CHECK_THROW(rtr6
.xfrSvcParamKeyVals(v
), RecordTextException
);
454 RecordTextReader
rtr7("key665=bla bla");
455 BOOST_CHECK_THROW(rtr7
.xfrSvcParamKeyVals(v
), RecordTextException
);
458 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_multiple
) {
459 RecordTextReader
rtr("key666=foobar ech=\"dG90YWxseSBib2d1cyBlY2hjb25maWcgdmFsdWU=\" ipv6hint=2001:db8::1 alpn=h2,h3 mandatory=alpn ipv4hint=192.0.2.1,192.0.2.2"); // out of order, resulting set should be in-order
461 rtr
.xfrSvcParamKeyVals(v
);
462 BOOST_CHECK_EQUAL(v
.size(), 6U);
463 auto vit
= v
.begin();
466 for (size_t i
= 0; i
< v
.size(); i
++) {
468 BOOST_CHECK(vit
->getKey() == SvcParam::mandatory
);
471 BOOST_CHECK(vit
->getKey() == SvcParam::alpn
);
474 BOOST_CHECK(vit
->getKey() == SvcParam::ipv4hint
);
477 BOOST_CHECK(vit
->getKey() == SvcParam::ech
);
480 BOOST_CHECK(vit
->getKey() == SvcParam::ipv6hint
);
483 BOOST_CHECK(vit
->getKey() == SvcParam::keyFromString("key666"));
490 RecordTextWriter
rtw(target
);
491 rtw
.xfrSvcParamKeyVals(v
);
492 BOOST_CHECK_EQUAL(target
, "mandatory=alpn alpn=h2,h3 ipv4hint=192.0.2.1,192.0.2.2 ech=\"dG90YWxseSBib2d1cyBlY2hjb25maWcgdmFsdWU=\" ipv6hint=2001:db8::1 key666=\"foobar\"");
495 BOOST_AUTO_TEST_CASE(test_xfrSvcParamKeyVals_ech
) {
496 string
source("ech=\"dG90YWxseSBib2d1cyBlY2hjb25maWcgdmFsdWU=\"");
497 RecordTextReader
rtr(source
);
499 rtr
.xfrSvcParamKeyVals(v
);
500 BOOST_CHECK_EQUAL(v
.size(), 1U);
501 auto k
= v
.begin()->getKey();
502 BOOST_CHECK(k
== SvcParam::ech
);
503 auto val
= v
.begin()->getECH();
504 BOOST_CHECK_EQUAL(val
, "totally bogus echconfig value"); // decoded!
508 RecordTextWriter
rtw(target
);
509 rtw
.xfrSvcParamKeyVals(v
);
510 BOOST_CHECK_EQUAL(source
, target
);
514 source
= "key5=echconfig";
515 RecordTextReader
rtr2(source
);
516 rtr2
.xfrSvcParamKeyVals(v
);
517 BOOST_CHECK_EQUAL(v
.size(), 1U);
518 k
= v
.begin()->getKey();
519 BOOST_CHECK(k
== SvcParam::ech
);
520 val
= v
.begin()->getECH();
521 BOOST_CHECK_EQUAL(val
, "echconfig");
524 BOOST_AUTO_TEST_CASE(test_xfrNodeOrLocatorID
) {
525 string
source("0000:0000:0000:0001");
526 RecordTextReader
rtr(source
);
528 rtr
.xfrNodeOrLocatorID(v
);
529 BOOST_CHECK_EQUAL(v
.content
[0], 0);
530 BOOST_CHECK_EQUAL(v
.content
[1], 0);
531 BOOST_CHECK_EQUAL(v
.content
[2], 0);
532 BOOST_CHECK_EQUAL(v
.content
[3], 0);
533 BOOST_CHECK_EQUAL(v
.content
[4], 0);
534 BOOST_CHECK_EQUAL(v
.content
[5], 0);
535 BOOST_CHECK_EQUAL(v
.content
[6], 0);
536 BOOST_CHECK_EQUAL(v
.content
[7], 1);
539 RecordTextWriter
rtw(target
);
540 rtw
.xfrNodeOrLocatorID(v
);
541 BOOST_CHECK_EQUAL(source
, target
);
544 BOOST_AUTO_TEST_SUITE_END()