1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * SPDX-License-Identifier: MPL-2.0
5 *
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9 *
10 * See the COPYRIGHT file distributed with this work for additional
11 * information regarding copyright ownership.
12 */
13
14 #if HAVE_CMOCKA
15
16 #include <inttypes.h>
17 #include <sched.h> /* IWYU pragma: keep */
18 #include <setjmp.h>
19 #include <stdarg.h>
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <unistd.h>
25
26 #define UNIT_TESTING
27 #include <cmocka.h>
28
29 #include <isc/buffer.h>
30 #include <isc/commandline.h>
31 #include <isc/mem.h>
32 #include <isc/os.h>
33 #include <isc/print.h>
34 #include <isc/thread.h>
35 #include <isc/util.h>
36
37 #include <dns/compress.h>
38 #include <dns/fixedname.h>
39 #include <dns/name.h>
40
41 #include "dnstest.h"
42
43 /* Set to true (or use -v option) for verbose output */
44 static bool verbose = false;
45
46 static int
_setup(void ** state)47 _setup(void **state) {
48 isc_result_t result;
49
50 UNUSED(state);
51
52 result = dns_test_begin(NULL, false);
53 assert_int_equal(result, ISC_R_SUCCESS);
54
55 return (0);
56 }
57
58 static int
_teardown(void ** state)59 _teardown(void **state) {
60 UNUSED(state);
61
62 dns_test_end();
63
64 return (0);
65 }
66
67 /* dns_name_fullcompare test */
68 static void
fullcompare_test(void ** state)69 fullcompare_test(void **state) {
70 dns_fixedname_t fixed1;
71 dns_fixedname_t fixed2;
72 dns_name_t *name1;
73 dns_name_t *name2;
74 dns_namereln_t relation;
75 int i;
76 isc_result_t result;
77 struct {
78 const char *name1;
79 const char *name2;
80 dns_namereln_t relation;
81 int order;
82 unsigned int nlabels;
83 } data[] = {
84 /* relative */
85 { "", "", dns_namereln_equal, 0, 0 },
86 { "foo", "", dns_namereln_subdomain, 1, 0 },
87 { "", "foo", dns_namereln_contains, -1, 0 },
88 { "foo", "bar", dns_namereln_none, 4, 0 },
89 { "bar", "foo", dns_namereln_none, -4, 0 },
90 { "bar.foo", "foo", dns_namereln_subdomain, 1, 1 },
91 { "foo", "bar.foo", dns_namereln_contains, -1, 1 },
92 { "baz.bar.foo", "bar.foo", dns_namereln_subdomain, 1, 2 },
93 { "bar.foo", "baz.bar.foo", dns_namereln_contains, -1, 2 },
94 { "foo.example", "bar.example", dns_namereln_commonancestor, 4,
95 1 },
96
97 /* absolute */
98 { ".", ".", dns_namereln_equal, 0, 1 },
99 { "foo.", "bar.", dns_namereln_commonancestor, 4, 1 },
100 { "bar.", "foo.", dns_namereln_commonancestor, -4, 1 },
101 { "foo.example.", "bar.example.", dns_namereln_commonancestor,
102 4, 2 },
103 { "bar.foo.", "foo.", dns_namereln_subdomain, 1, 2 },
104 { "foo.", "bar.foo.", dns_namereln_contains, -1, 2 },
105 { "baz.bar.foo.", "bar.foo.", dns_namereln_subdomain, 1, 3 },
106 { "bar.foo.", "baz.bar.foo.", dns_namereln_contains, -1, 3 },
107 { NULL, NULL, dns_namereln_none, 0, 0 }
108 };
109
110 UNUSED(state);
111
112 name1 = dns_fixedname_initname(&fixed1);
113 name2 = dns_fixedname_initname(&fixed2);
114 for (i = 0; data[i].name1 != NULL; i++) {
115 int order = 3000;
116 unsigned int nlabels = 3000;
117
118 if (data[i].name1[0] == 0) {
119 dns_fixedname_init(&fixed1);
120 } else {
121 result = dns_name_fromstring2(name1, data[i].name1,
122 NULL, 0, NULL);
123 assert_int_equal(result, ISC_R_SUCCESS);
124 }
125 if (data[i].name2[0] == 0) {
126 dns_fixedname_init(&fixed2);
127 } else {
128 result = dns_name_fromstring2(name2, data[i].name2,
129 NULL, 0, NULL);
130 assert_int_equal(result, ISC_R_SUCCESS);
131 }
132 relation = dns_name_fullcompare(name1, name1, &order, &nlabels);
133 assert_int_equal(relation, dns_namereln_equal);
134 assert_int_equal(order, 0);
135 assert_int_equal(nlabels, name1->labels);
136
137 /* Some random initializer */
138 order = 3001;
139 nlabels = 3001;
140
141 relation = dns_name_fullcompare(name1, name2, &order, &nlabels);
142 assert_int_equal(relation, data[i].relation);
143 assert_int_equal(order, data[i].order);
144 assert_int_equal(nlabels, data[i].nlabels);
145 }
146 }
147
148 static void
compress_test(dns_name_t * name1,dns_name_t * name2,dns_name_t * name3,unsigned char * expected,unsigned int length,dns_compress_t * cctx,dns_decompress_t * dctx)149 compress_test(dns_name_t *name1, dns_name_t *name2, dns_name_t *name3,
150 unsigned char *expected, unsigned int length,
151 dns_compress_t *cctx, dns_decompress_t *dctx) {
152 isc_buffer_t source;
153 isc_buffer_t target;
154 dns_name_t name;
155 unsigned char buf1[1024];
156 unsigned char buf2[1024];
157
158 isc_buffer_init(&source, buf1, sizeof(buf1));
159 isc_buffer_init(&target, buf2, sizeof(buf2));
160
161 assert_int_equal(dns_name_towire(name1, cctx, &source), ISC_R_SUCCESS);
162
163 assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS);
164 assert_int_equal(dns_name_towire(name2, cctx, &source), ISC_R_SUCCESS);
165 assert_int_equal(dns_name_towire(name3, cctx, &source), ISC_R_SUCCESS);
166
167 isc_buffer_setactive(&source, source.used);
168
169 dns_name_init(&name, NULL);
170 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
171 ISC_R_SUCCESS);
172 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
173 ISC_R_SUCCESS);
174 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
175 ISC_R_SUCCESS);
176 RUNTIME_CHECK(dns_name_fromwire(&name, &source, dctx, 0, &target) ==
177 ISC_R_SUCCESS);
178 dns_decompress_invalidate(dctx);
179
180 assert_int_equal(target.used, length);
181 assert_true(memcmp(target.base, expected, target.used) == 0);
182 }
183
184 /* name compression test */
185 static void
compression_test(void ** state)186 compression_test(void **state) {
187 unsigned int allowed;
188 dns_compress_t cctx;
189 dns_decompress_t dctx;
190 dns_name_t name1;
191 dns_name_t name2;
192 dns_name_t name3;
193 isc_region_t r;
194 unsigned char plain1[] = "\003yyy\003foo";
195 unsigned char plain2[] = "\003bar\003yyy\003foo";
196 unsigned char plain3[] = "\003xxx\003bar\003foo";
197 unsigned char plain[] = "\003yyy\003foo\0\003bar\003yyy\003foo\0\003"
198 "bar\003yyy\003foo\0\003xxx\003bar\003foo";
199
200 UNUSED(state);
201
202 dns_name_init(&name1, NULL);
203 r.base = plain1;
204 r.length = sizeof(plain1);
205 dns_name_fromregion(&name1, &r);
206
207 dns_name_init(&name2, NULL);
208 r.base = plain2;
209 r.length = sizeof(plain2);
210 dns_name_fromregion(&name2, &r);
211
212 dns_name_init(&name3, NULL);
213 r.base = plain3;
214 r.length = sizeof(plain3);
215 dns_name_fromregion(&name3, &r);
216
217 /* Test 1: NONE */
218 allowed = DNS_COMPRESS_NONE;
219 assert_int_equal(dns_compress_init(&cctx, -1, dt_mctx), ISC_R_SUCCESS);
220 dns_compress_setmethods(&cctx, allowed);
221 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
222 dns_decompress_setmethods(&dctx, allowed);
223
224 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
225 &dctx);
226
227 dns_compress_rollback(&cctx, 0);
228 dns_compress_invalidate(&cctx);
229
230 /* Test2: GLOBAL14 */
231 allowed = DNS_COMPRESS_GLOBAL14;
232 assert_int_equal(dns_compress_init(&cctx, -1, dt_mctx), ISC_R_SUCCESS);
233 dns_compress_setmethods(&cctx, allowed);
234 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
235 dns_decompress_setmethods(&dctx, allowed);
236
237 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
238 &dctx);
239
240 dns_compress_rollback(&cctx, 0);
241 dns_compress_invalidate(&cctx);
242
243 /* Test3: ALL */
244 allowed = DNS_COMPRESS_ALL;
245 assert_int_equal(dns_compress_init(&cctx, -1, dt_mctx), ISC_R_SUCCESS);
246 dns_compress_setmethods(&cctx, allowed);
247 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
248 dns_decompress_setmethods(&dctx, allowed);
249
250 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
251 &dctx);
252
253 dns_compress_rollback(&cctx, 0);
254 dns_compress_invalidate(&cctx);
255
256 /* Test4: NONE disabled */
257 allowed = DNS_COMPRESS_NONE;
258 assert_int_equal(dns_compress_init(&cctx, -1, dt_mctx), ISC_R_SUCCESS);
259 dns_compress_setmethods(&cctx, allowed);
260 dns_compress_disable(&cctx);
261 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
262 dns_decompress_setmethods(&dctx, allowed);
263
264 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
265 &dctx);
266
267 dns_compress_rollback(&cctx, 0);
268 dns_compress_invalidate(&cctx);
269
270 /* Test5: GLOBAL14 disabled */
271 allowed = DNS_COMPRESS_GLOBAL14;
272 assert_int_equal(dns_compress_init(&cctx, -1, dt_mctx), ISC_R_SUCCESS);
273 dns_compress_setmethods(&cctx, allowed);
274 dns_compress_disable(&cctx);
275 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
276 dns_decompress_setmethods(&dctx, allowed);
277
278 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
279 &dctx);
280
281 dns_compress_rollback(&cctx, 0);
282 dns_compress_invalidate(&cctx);
283
284 /* Test6: ALL disabled */
285 allowed = DNS_COMPRESS_ALL;
286 assert_int_equal(dns_compress_init(&cctx, -1, dt_mctx), ISC_R_SUCCESS);
287 dns_compress_setmethods(&cctx, allowed);
288 dns_compress_disable(&cctx);
289 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
290 dns_decompress_setmethods(&dctx, allowed);
291
292 compress_test(&name1, &name2, &name3, plain, sizeof(plain), &cctx,
293 &dctx);
294
295 dns_compress_rollback(&cctx, 0);
296 dns_compress_invalidate(&cctx);
297 }
298
299 /* is trust-anchor-telemetry test */
300 static void
istat_test(void ** state)301 istat_test(void **state) {
302 dns_fixedname_t fixed;
303 dns_name_t *name;
304 isc_result_t result;
305 size_t i;
306 struct {
307 const char *name;
308 bool istat;
309 } data[] = { { ".", false },
310 { "_ta-", false },
311 { "_ta-1234", true },
312 { "_TA-1234", true },
313 { "+TA-1234", false },
314 { "_fa-1234", false },
315 { "_td-1234", false },
316 { "_ta_1234", false },
317 { "_ta-g234", false },
318 { "_ta-1h34", false },
319 { "_ta-12i4", false },
320 { "_ta-123j", false },
321 { "_ta-1234-abcf", true },
322 { "_ta-1234-abcf-ED89", true },
323 { "_ta-12345-abcf-ED89", false },
324 { "_ta-.example", false },
325 { "_ta-1234.example", true },
326 { "_ta-1234-abcf.example", true },
327 { "_ta-1234-abcf-ED89.example", true },
328 { "_ta-12345-abcf-ED89.example", false },
329 { "_ta-1234-abcfe-ED89.example", false },
330 { "_ta-1234-abcf-EcD89.example", false } };
331
332 UNUSED(state);
333
334 name = dns_fixedname_initname(&fixed);
335
336 for (i = 0; i < (sizeof(data) / sizeof(data[0])); i++) {
337 result = dns_name_fromstring(name, data[i].name, 0, NULL);
338 assert_int_equal(result, ISC_R_SUCCESS);
339 assert_int_equal(dns_name_istat(name), data[i].istat);
340 }
341 }
342
343 /* dns_nane_init */
344 static void
init_test(void ** state)345 init_test(void **state) {
346 dns_name_t name;
347 unsigned char offsets[1];
348
349 UNUSED(state);
350
351 dns_name_init(&name, offsets);
352
353 assert_null(name.ndata);
354 assert_int_equal(name.length, 0);
355 assert_int_equal(name.labels, 0);
356 assert_int_equal(name.attributes, 0);
357 assert_ptr_equal(name.offsets, offsets);
358 assert_null(name.buffer);
359 }
360
361 /* dns_nane_invalidate */
362 static void
invalidate_test(void ** state)363 invalidate_test(void **state) {
364 dns_name_t name;
365 unsigned char offsets[1];
366
367 UNUSED(state);
368
369 dns_name_init(&name, offsets);
370 dns_name_invalidate(&name);
371
372 assert_null(name.ndata);
373 assert_int_equal(name.length, 0);
374 assert_int_equal(name.labels, 0);
375 assert_int_equal(name.attributes, 0);
376 assert_null(name.offsets);
377 assert_null(name.buffer);
378 }
379
380 /* dns_nane_setbuffer/hasbuffer */
381 static void
buffer_test(void ** state)382 buffer_test(void **state) {
383 dns_name_t name;
384 unsigned char buf[BUFSIZ];
385 isc_buffer_t b;
386
387 UNUSED(state);
388
389 isc_buffer_init(&b, buf, BUFSIZ);
390 dns_name_init(&name, NULL);
391 dns_name_setbuffer(&name, &b);
392 assert_ptr_equal(name.buffer, &b);
393 assert_true(dns_name_hasbuffer(&name));
394 }
395
396 /* dns_nane_isabsolute */
397 static void
isabsolute_test(void ** state)398 isabsolute_test(void **state) {
399 struct {
400 const char *namestr;
401 bool expect;
402 } testcases[] = { { "x", false },
403 { "a.b.c.d.", true },
404 { "x.z", false } };
405 unsigned int i;
406
407 UNUSED(state);
408
409 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
410 isc_result_t result;
411 dns_name_t name;
412 unsigned char data[BUFSIZ];
413 isc_buffer_t b, nb;
414 size_t len;
415
416 len = strlen(testcases[i].namestr);
417 isc_buffer_constinit(&b, testcases[i].namestr, len);
418 isc_buffer_add(&b, len);
419
420 dns_name_init(&name, NULL);
421 isc_buffer_init(&nb, data, BUFSIZ);
422 dns_name_setbuffer(&name, &nb);
423 result = dns_name_fromtext(&name, &b, NULL, 0, NULL);
424 assert_int_equal(result, ISC_R_SUCCESS);
425
426 assert_int_equal(dns_name_isabsolute(&name),
427 testcases[i].expect);
428 }
429 }
430
431 /* dns_nane_hash */
432 static void
hash_test(void ** state)433 hash_test(void **state) {
434 struct {
435 const char *name1;
436 const char *name2;
437 bool expect;
438 bool expecti;
439 } testcases[] = {
440 { "a.b.c.d", "A.B.C.D", true, false },
441 { "a.b.c.d.", "A.B.C.D.", true, false },
442 { "a.b.c.d", "a.b.c.d", true, true },
443 { "A.B.C.D.", "A.B.C.D.", true, false },
444 { "x.y.z.w", "a.b.c.d", false, false },
445 { "x.y.z.w.", "a.b.c.d.", false, false },
446 };
447 unsigned int i;
448
449 UNUSED(state);
450
451 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
452 isc_result_t result;
453 dns_fixedname_t f1, f2;
454 dns_name_t *n1, *n2;
455 unsigned int h1, h2;
456
457 n1 = dns_fixedname_initname(&f1);
458 n2 = dns_fixedname_initname(&f2);
459
460 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
461 NULL);
462 assert_int_equal(result, ISC_R_SUCCESS);
463 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
464 NULL);
465 assert_int_equal(result, ISC_R_SUCCESS);
466
467 /* Check case-insensitive hashing first */
468 h1 = dns_name_hash(n1, false);
469 h2 = dns_name_hash(n2, false);
470
471 if (verbose) {
472 print_message("# %s hashes to %u, "
473 "%s to %u, case insensitive\n",
474 testcases[i].name1, h1,
475 testcases[i].name2, h2);
476 }
477
478 assert_int_equal((h1 == h2), testcases[i].expect);
479
480 /* Now case-sensitive */
481 h1 = dns_name_hash(n1, false);
482 h2 = dns_name_hash(n2, false);
483
484 if (verbose) {
485 print_message("# %s hashes to %u, "
486 "%s to %u, case sensitive\n",
487 testcases[i].name1, h1,
488 testcases[i].name2, h2);
489 }
490
491 assert_int_equal((h1 == h2), testcases[i].expect);
492 }
493 }
494
495 /* dns_nane_issubdomain */
496 static void
issubdomain_test(void ** state)497 issubdomain_test(void **state) {
498 struct {
499 const char *name1;
500 const char *name2;
501 bool expect;
502 } testcases[] = {
503 { "c.d", "a.b.c.d", false }, { "c.d.", "a.b.c.d.", false },
504 { "b.c.d", "c.d", true }, { "a.b.c.d.", "c.d.", true },
505 { "a.b.c", "a.b.c", true }, { "a.b.c.", "a.b.c.", true },
506 { "x.y.z", "a.b.c", false }
507 };
508 unsigned int i;
509
510 UNUSED(state);
511
512 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
513 isc_result_t result;
514 dns_fixedname_t f1, f2;
515 dns_name_t *n1, *n2;
516
517 n1 = dns_fixedname_initname(&f1);
518 n2 = dns_fixedname_initname(&f2);
519
520 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
521 NULL);
522 assert_int_equal(result, ISC_R_SUCCESS);
523 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
524 NULL);
525 assert_int_equal(result, ISC_R_SUCCESS);
526
527 if (verbose) {
528 print_message("# check: %s %s a subdomain of %s\n",
529 testcases[i].name1,
530 testcases[i].expect ? "is" : "is not",
531 testcases[i].name2);
532 }
533
534 assert_int_equal(dns_name_issubdomain(n1, n2),
535 testcases[i].expect);
536 }
537 }
538
539 /* dns_nane_countlabels */
540 static void
countlabels_test(void ** state)541 countlabels_test(void **state) {
542 struct {
543 const char *namestr;
544 unsigned int expect;
545 } testcases[] = {
546 { "c.d", 2 }, { "c.d.", 3 }, { "a.b.c.d.", 5 },
547 { "a.b.c.d", 4 }, { "a.b.c", 3 }, { ".", 1 },
548 };
549 unsigned int i;
550
551 UNUSED(state);
552
553 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
554 isc_result_t result;
555 dns_fixedname_t fname;
556 dns_name_t *name;
557
558 name = dns_fixedname_initname(&fname);
559
560 result = dns_name_fromstring2(name, testcases[i].namestr, NULL,
561 0, NULL);
562 assert_int_equal(result, ISC_R_SUCCESS);
563
564 if (verbose) {
565 print_message("# %s: expect %u labels\n",
566 testcases[i].namestr,
567 testcases[i].expect);
568 }
569
570 assert_int_equal(dns_name_countlabels(name),
571 testcases[i].expect);
572 }
573 }
574
575 /* dns_nane_getlabel */
576 static void
getlabel_test(void ** state)577 getlabel_test(void **state) {
578 struct {
579 const char *name1;
580 unsigned int pos1;
581 const char *name2;
582 unsigned int pos2;
583 } testcases[] = {
584 { "c.d", 1, "a.b.c.d", 3 },
585 { "a.b.c.d", 3, "c.d", 1 },
586 { "a.b.c.", 3, "A.B.C.", 3 },
587 };
588 unsigned int i;
589
590 UNUSED(state);
591
592 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
593 isc_result_t result;
594 dns_fixedname_t f1, f2;
595 dns_name_t *n1, *n2;
596 dns_label_t l1, l2;
597 unsigned int j;
598
599 n1 = dns_fixedname_initname(&f1);
600 n2 = dns_fixedname_initname(&f2);
601
602 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
603 NULL);
604 assert_int_equal(result, ISC_R_SUCCESS);
605 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
606 NULL);
607 assert_int_equal(result, ISC_R_SUCCESS);
608
609 dns_name_getlabel(n1, testcases[i].pos1, &l1);
610 dns_name_getlabel(n2, testcases[i].pos2, &l2);
611 assert_int_equal(l1.length, l2.length);
612
613 for (j = 0; j < l1.length; j++) {
614 assert_int_equal(l1.base[j], l2.base[j]);
615 }
616 }
617 }
618
619 /* dns_nane_getlabelsequence */
620 static void
getlabelsequence_test(void ** state)621 getlabelsequence_test(void **state) {
622 struct {
623 const char *name1;
624 unsigned int pos1;
625 const char *name2;
626 unsigned int pos2;
627 unsigned int range;
628 } testcases[] = {
629 { "c.d", 1, "a.b.c.d", 3, 1 },
630 { "a.b.c.d.e", 2, "c.d", 0, 2 },
631 { "a.b.c", 0, "a.b.c", 0, 3 },
632 };
633 unsigned int i;
634
635 UNUSED(state);
636
637 for (i = 0; i < (sizeof(testcases) / sizeof(testcases[0])); i++) {
638 isc_result_t result;
639 dns_name_t t1, t2;
640 dns_fixedname_t f1, f2;
641 dns_name_t *n1, *n2;
642
643 /* target names */
644 dns_name_init(&t1, NULL);
645 dns_name_init(&t2, NULL);
646
647 /* source names */
648 n1 = dns_fixedname_initname(&f1);
649 n2 = dns_fixedname_initname(&f2);
650
651 result = dns_name_fromstring2(n1, testcases[i].name1, NULL, 0,
652 NULL);
653 assert_int_equal(result, ISC_R_SUCCESS);
654 result = dns_name_fromstring2(n2, testcases[i].name2, NULL, 0,
655 NULL);
656 assert_int_equal(result, ISC_R_SUCCESS);
657
658 dns_name_getlabelsequence(n1, testcases[i].pos1,
659 testcases[i].range, &t1);
660 dns_name_getlabelsequence(n2, testcases[i].pos2,
661 testcases[i].range, &t2);
662
663 assert_true(dns_name_equal(&t1, &t2));
664 }
665 }
666
667 #ifdef DNS_BENCHMARK_TESTS
668
669 /*
670 * XXXMUKS: Don't delete this code. It is useful in benchmarking the
671 * name parser, but we don't require it as part of the unit test runs.
672 */
673
674 /* Benchmark dns_name_fromwire() implementation */
675
676 static void *
fromwire_thread(void * arg)677 fromwire_thread(void *arg) {
678 unsigned int maxval = 32000000;
679 uint8_t data[] = { 3, 'w', 'w', 'w', 7, 'e', 'x',
680 'a', 'm', 'p', 'l', 'e', 7, 'i',
681 'n', 'v', 'a', 'l', 'i', 'd', 0 };
682 unsigned char output_data[DNS_NAME_MAXWIRE];
683 isc_buffer_t source, target;
684 unsigned int i;
685 dns_decompress_t dctx;
686
687 UNUSED(arg);
688
689 dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_STRICT);
690 dns_decompress_setmethods(&dctx, DNS_COMPRESS_NONE);
691
692 isc_buffer_init(&source, data, sizeof(data));
693 isc_buffer_add(&source, sizeof(data));
694 isc_buffer_init(&target, output_data, sizeof(output_data));
695
696 /* Parse 32 million names in each thread */
697 for (i = 0; i < maxval; i++) {
698 dns_name_t name;
699
700 isc_buffer_clear(&source);
701 isc_buffer_clear(&target);
702 isc_buffer_add(&source, sizeof(data));
703 isc_buffer_setactive(&source, sizeof(data));
704
705 dns_name_init(&name, NULL);
706 (void)dns_name_fromwire(&name, &source, &dctx, 0, &target);
707 }
708
709 return (NULL);
710 }
711
712 static void
benchmark_test(void ** state)713 benchmark_test(void **state) {
714 isc_result_t result;
715 unsigned int i;
716 isc_time_t ts1, ts2;
717 double t;
718 unsigned int nthreads;
719 isc_thread_t threads[32];
720
721 UNUSED(state);
722
723 debug_mem_record = false;
724
725 result = isc_time_now(&ts1);
726 assert_int_equal(result, ISC_R_SUCCESS);
727
728 nthreads = ISC_MIN(isc_os_ncpus(), 32);
729 nthreads = ISC_MAX(nthreads, 1);
730 for (i = 0; i < nthreads; i++) {
731 isc_thread_create(fromwire_thread, NULL, &threads[i]);
732 }
733
734 for (i = 0; i < nthreads; i++) {
735 isc_thread_join(threads[i], NULL);
736 }
737
738 result = isc_time_now(&ts2);
739 assert_int_equal(result, ISC_R_SUCCESS);
740
741 t = isc_time_microdiff(&ts2, &ts1);
742
743 printf("%u dns_name_fromwire() calls, %f seconds, %f calls/second\n",
744 nthreads * 32000000, t / 1000000.0,
745 (nthreads * 32000000) / (t / 1000000.0));
746 }
747
748 #endif /* DNS_BENCHMARK_TESTS */
749
750 int
main(int argc,char ** argv)751 main(int argc, char **argv) {
752 const struct CMUnitTest tests[] = {
753 cmocka_unit_test(fullcompare_test),
754 cmocka_unit_test_setup_teardown(compression_test, _setup,
755 _teardown),
756 cmocka_unit_test(istat_test),
757 cmocka_unit_test(init_test),
758 cmocka_unit_test(invalidate_test),
759 cmocka_unit_test(buffer_test),
760 cmocka_unit_test(isabsolute_test),
761 cmocka_unit_test(hash_test),
762 cmocka_unit_test(issubdomain_test),
763 cmocka_unit_test(countlabels_test),
764 cmocka_unit_test(getlabel_test),
765 cmocka_unit_test(getlabelsequence_test),
766 #ifdef DNS_BENCHMARK_TESTS
767 cmocka_unit_test_setup_teardown(benchmark_test, _setup,
768 _teardown),
769 #endif /* DNS_BENCHMARK_TESTS */
770 };
771 int c;
772
773 while ((c = isc_commandline_parse(argc, argv, "v")) != -1) {
774 switch (c) {
775 case 'v':
776 verbose = true;
777 break;
778 default:
779 break;
780 }
781 }
782
783 return (cmocka_run_group_tests(tests, NULL, NULL));
784 }
785
786 #else /* HAVE_CMOCKA */
787
788 #include <stdio.h>
789
790 int
main(void)791 main(void) {
792 printf("1..0 # Skipped: cmocka not available\n");
793 return (SKIPPED_TEST_EXIT_CODE);
794 }
795
796 #endif /* if HAVE_CMOCKA */
797