Home | History | Annotate | Line # | Download | only in dns
      1 /*	$NetBSD: resconf_test.c,v 1.2 2025/05/21 14:48:06 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 #include <inttypes.h>
     17 #include <sched.h> /* IWYU pragma: keep */
     18 #include <setjmp.h>
     19 #include <stdarg.h>
     20 #include <stddef.h>
     21 #include <stdio.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/mem.h>
     30 #include <isc/util.h>
     31 
     32 #include <irs/resconf.h>
     33 
     34 #include <tests/isc.h>
     35 
     36 static isc_result_t
     37 check_nameserver(irs_resconf_t *resconf, const char *expected) {
     38 	char buf[ISC_SOCKADDR_FORMATSIZE];
     39 	isc_sockaddrlist_t *servers = irs_resconf_getnameservers(resconf);
     40 	isc_sockaddr_t *entry = ISC_LIST_HEAD(*servers);
     41 	assert_true(entry != NULL);
     42 	isc_sockaddr_format(entry, buf, sizeof(buf));
     43 	assert_string_equal(buf, expected);
     44 	return ISC_R_SUCCESS;
     45 }
     46 
     47 static isc_result_t
     48 check_ns4(irs_resconf_t *resconf) {
     49 	return check_nameserver(resconf, "10.0.0.1#53");
     50 }
     51 
     52 static isc_result_t
     53 check_ns6(irs_resconf_t *resconf) {
     54 	return check_nameserver(resconf, "2001:db8::1#53");
     55 }
     56 
     57 static isc_result_t
     58 check_scoped(irs_resconf_t *resconf) {
     59 	return check_nameserver(resconf, "fe80::1%1#53");
     60 }
     61 
     62 static isc_result_t
     63 check_number(unsigned int n, unsigned int expected) {
     64 	return (n == expected) ? ISC_R_SUCCESS : ISC_R_BADNUMBER;
     65 }
     66 
     67 static isc_result_t
     68 check_attempts(irs_resconf_t *resconf) {
     69 	return check_number(irs_resconf_getattempts(resconf), 4);
     70 }
     71 
     72 static isc_result_t
     73 check_timeout(irs_resconf_t *resconf) {
     74 	return check_number(irs_resconf_gettimeout(resconf), 1);
     75 }
     76 
     77 static isc_result_t
     78 check_ndots(irs_resconf_t *resconf) {
     79 	return check_number(irs_resconf_getndots(resconf), 2);
     80 }
     81 
     82 static isc_result_t
     83 search_example(irs_resconf_t *resconf) {
     84 	irs_resconf_search_t *entry;
     85 	irs_resconf_searchlist_t *list;
     86 	list = irs_resconf_getsearchlist(resconf);
     87 	if (list == NULL) {
     88 		return ISC_R_NOTFOUND;
     89 	}
     90 	entry = ISC_LIST_HEAD(*list);
     91 	assert_true(entry != NULL && entry->domain != NULL);
     92 	assert_string_equal(entry->domain, "example.com");
     93 
     94 	entry = ISC_LIST_TAIL(*list);
     95 	assert_true(entry != NULL && entry->domain != NULL);
     96 	assert_string_equal(entry->domain, "example.net");
     97 	return ISC_R_SUCCESS;
     98 }
     99 
    100 static isc_result_t
    101 check_options(irs_resconf_t *resconf) {
    102 	if (irs_resconf_getattempts(resconf) != 3) {
    103 		return ISC_R_BADNUMBER; /* default value only */
    104 	}
    105 
    106 	if (irs_resconf_getndots(resconf) != 2) {
    107 		return ISC_R_BADNUMBER;
    108 	}
    109 
    110 	if (irs_resconf_gettimeout(resconf) != 1) {
    111 		return ISC_R_BADNUMBER;
    112 	}
    113 
    114 	return ISC_R_SUCCESS;
    115 }
    116 
    117 /* test irs_resconf_load() */
    118 ISC_RUN_TEST_IMPL(irs_resconf_load) {
    119 	isc_result_t result;
    120 	irs_resconf_t *resconf = NULL;
    121 	unsigned int i;
    122 	struct {
    123 		const char *file;
    124 		isc_result_t loadres;
    125 		isc_result_t (*check)(irs_resconf_t *resconf);
    126 		isc_result_t checkres;
    127 	} tests[] = { { "testdata/resconf/domain.conf", ISC_R_SUCCESS, NULL,
    128 			ISC_R_SUCCESS },
    129 		      { "testdata/resconf/nameserver-v4.conf", ISC_R_SUCCESS,
    130 			check_ns4, ISC_R_SUCCESS },
    131 		      { "testdata/resconf/nameserver-v6.conf", ISC_R_SUCCESS,
    132 			check_ns6, ISC_R_SUCCESS },
    133 		      { "testdata/resconf/nameserver-v6-scoped.conf",
    134 			ISC_R_SUCCESS, check_scoped, ISC_R_SUCCESS },
    135 		      { "testdata/resconf/options-attempts.conf", ISC_R_SUCCESS,
    136 			check_attempts, ISC_R_SUCCESS },
    137 		      { "testdata/resconf/options-debug.conf", ISC_R_SUCCESS,
    138 			NULL, ISC_R_SUCCESS },
    139 		      { "testdata/resconf/options-ndots.conf", ISC_R_SUCCESS,
    140 			check_ndots, ISC_R_SUCCESS },
    141 		      { "testdata/resconf/options-timeout.conf", ISC_R_SUCCESS,
    142 			check_timeout, ISC_R_SUCCESS },
    143 		      { "testdata/resconf/options-unknown.conf", ISC_R_SUCCESS,
    144 			NULL, ISC_R_SUCCESS },
    145 		      { "testdata/resconf/options.conf", ISC_R_SUCCESS,
    146 			check_options, ISC_R_SUCCESS },
    147 		      { "testdata/resconf/options-bad-ndots.conf", ISC_R_RANGE,
    148 			NULL, ISC_R_SUCCESS },
    149 		      { "testdata/resconf/options-empty.conf",
    150 			ISC_R_UNEXPECTEDEND, NULL, ISC_R_SUCCESS },
    151 		      { "testdata/resconf/port.conf", ISC_R_SUCCESS, NULL,
    152 			ISC_R_SUCCESS },
    153 		      { "testdata/resconf/resolv.conf", ISC_R_SUCCESS, NULL,
    154 			ISC_R_SUCCESS },
    155 		      { "testdata/resconf/search.conf", ISC_R_SUCCESS,
    156 			search_example, ISC_R_SUCCESS },
    157 		      { "testdata/resconf/sortlist-v4.conf", ISC_R_SUCCESS,
    158 			NULL, ISC_R_SUCCESS },
    159 		      { "testdata/resconf/timeout.conf", ISC_R_SUCCESS, NULL,
    160 			ISC_R_SUCCESS },
    161 		      { "testdata/resconf/unknown-with-value.conf",
    162 			ISC_R_SUCCESS, NULL, ISC_R_SUCCESS },
    163 		      { "testdata/resconf/unknown-without-value.conf",
    164 			ISC_R_SUCCESS, NULL, ISC_R_SUCCESS },
    165 		      { "testdata/resconf/unknown+search.conf", ISC_R_SUCCESS,
    166 			search_example, ISC_R_SUCCESS } };
    167 
    168 	UNUSED(state);
    169 
    170 	assert_return_code(chdir(TESTS_DIR), 0);
    171 
    172 	for (i = 0; i < sizeof(tests) / sizeof(tests[1]); i++) {
    173 		if (debug) {
    174 			fprintf(stderr, "# testing '%s'\n", tests[i].file);
    175 		}
    176 		result = irs_resconf_load(mctx, tests[i].file, &resconf);
    177 		if (result != tests[i].loadres) {
    178 			fail_msg("# unexpected result %s loading %s",
    179 				 isc_result_totext(result), tests[i].file);
    180 		}
    181 
    182 		if (result == ISC_R_SUCCESS && resconf == NULL) {
    183 			fail_msg("# NULL on success loading %s", tests[i].file);
    184 		} else if (result != ISC_R_SUCCESS && resconf != NULL) {
    185 			fail_msg("# non-NULL on failure loading %s",
    186 				 tests[i].file);
    187 		}
    188 
    189 		if (resconf != NULL && tests[i].check != NULL) {
    190 			result = (tests[i].check)(resconf);
    191 			if (result != tests[i].checkres) {
    192 				fail_msg("# unexpected result %s loading %s",
    193 					 isc_result_totext(result),
    194 					 tests[i].file);
    195 			}
    196 		}
    197 		if (resconf != NULL) {
    198 			irs_resconf_destroy(&resconf);
    199 		}
    200 	}
    201 }
    202 
    203 ISC_TEST_LIST_START
    204 ISC_TEST_ENTRY(irs_resconf_load)
    205 ISC_TEST_LIST_END
    206 
    207 ISC_TEST_MAIN
    208