From: Alessio Podda Date: Mon, 24 Nov 2025 08:55:31 +0000 (+0100) Subject: Add vecheader unit tests X-Git-Tag: v9.21.17~42^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=852041457ec981bdb2248c83cfcdd8bfab6359c2;p=thirdparty%2Fbind9.git Add vecheader unit tests Adds unit tests for the new rdatavec, doing basic size and case checking. --- diff --git a/tests/dns/meson.build b/tests/dns/meson.build index 8d765013a8e..dcbf853c727 100644 --- a/tests/dns/meson.build +++ b/tests/dns/meson.build @@ -44,6 +44,7 @@ dns_tests = [ 'tsig', 'unreachcache', 'update', + 'vecheader', 'zonefile', 'zonemgr', 'zt', diff --git a/tests/dns/vecheader_test.c b/tests/dns/vecheader_test.c new file mode 100644 index 00000000000..4f7590f1987 --- /dev/null +++ b/tests/dns/vecheader_test.c @@ -0,0 +1,290 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +#include +#include /* IWYU pragma: keep */ +#include +#include +#include +#include +#include + +#define UNIT_TESTING +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* Helper function to create a vecheader directly */ +static isc_result_t +create_vecheader(isc_mem_t *mctx, dns_rdatatype_t type, dns_rdataclass_t rdclass, + dns_ttl_t ttl, const char *rdata_text, dns_vecheader_t **headerp) +{ + dns_rdataset_t rdataset; + dns_rdatalist_t *rdatalist; + dns_rdata_t *rdata; + unsigned char *data; + isc_region_t region; + isc_result_t result; + + /* Allocate temporary structures */ + data = isc_mem_get(mctx, 256); + rdatalist = isc_mem_get(mctx, sizeof(*rdatalist)); + rdata = isc_mem_get(mctx, sizeof(*rdata)); + + /* Initialize rdataset and rdatalist */ + dns_rdataset_init(&rdataset); + dns_rdatalist_init(rdatalist); + rdatalist->type = type; + rdatalist->rdclass = rdclass; + rdatalist->ttl = ttl; + + /* Create rdata */ + dns_rdata_init(rdata); + CHECK(dns_test_rdatafromstring(rdata, rdclass, type, data, + 256, rdata_text, false)); + + ISC_LIST_APPEND(rdatalist->rdata, rdata, link); + dns_rdatalist_tordataset(rdatalist, &rdataset); + + /* Convert to vecheader */ + CHECK(dns_rdatavec_fromrdataset(&rdataset, mctx, ®ion, 0)); + *headerp = (dns_vecheader_t *)region.base; + + /* Cleanup rdataset */ + dns_rdataset_disassociate(&rdataset); + +cleanup: + /* Cleanup temporary structures */ + isc_mem_put(mctx, rdata, sizeof(*rdata)); + isc_mem_put(mctx, rdatalist, sizeof(*rdatalist)); + isc_mem_put(mctx, data, 256); + + return result; +} + +/* Helper function to create an rdataset from a vecheader */ +static void +create_rdataset_from_vecheader(dns_vecheader_t *header, dns_rdataclass_t rdclass, + dns_rdatatype_t type, dns_rdataset_t *rdataset) +{ + dns_rdataset_init(rdataset); + rdataset->methods = &dns_rdatavec_rdatasetmethods; + rdataset->rdclass = rdclass; + rdataset->type = type; + rdataset->vec.header = header; +} + +/* Test merging two headers */ +ISC_RUN_TEST_IMPL(merge_headers) { + isc_mem_t *mctx = isc_g_mctx; + UNUSED(state); + dns_vecheader_t *header1 = NULL, *header2 = NULL, *merged_header = NULL; + unsigned int size1, size2, merged_size, expected_size; + unsigned int count1, count2, merged_count, expected_count; + isc_result_t result; + + /* Create vecheaders with A records */ + CHECK(create_vecheader(mctx, dns_rdatatype_a, dns_rdataclass_in, + 300, "192.168.1.1", &header1)); + + CHECK(create_vecheader(mctx, dns_rdatatype_a, dns_rdataclass_in, + 300, "192.168.1.2", &header2)); + + /* Get sizes and counts before merging */ + size1 = dns_rdatavec_size(header1); + size2 = dns_rdatavec_size(header2); + count1 = dns_rdatavec_count(header1); + count2 = dns_rdatavec_count(header2); + + /* Merge headers */ + CHECK(dns_rdatavec_merge(header1, header2, mctx, dns_rdataclass_in, + dns_rdatatype_a, 0, 0, &merged_header)); + assert_non_null(merged_header); + + /* Get merged size and count */ + merged_size = dns_rdatavec_size(merged_header); + merged_count = dns_rdatavec_count(merged_header); + + /* Test: merged size should be first_size + second_size - sizeof(header) - count_field_size */ + expected_size = size1 + size2 - sizeof(dns_vecheader_t) - 2; + assert_int_equal(merged_size, expected_size); + + /* Test: merged count should be first_count + second_count */ + expected_count = count1 + count2; + assert_int_equal(merged_count, expected_count); + +cleanup: + /* Cleanup */ + if (header1 != NULL) { + size1 = dns_rdatavec_size(header1); + isc_mem_put(mctx, header1, size1); + } + if (header2 != NULL) { + size2 = dns_rdatavec_size(header2); + isc_mem_put(mctx, header2, size2); + } + if (merged_header != NULL) { + merged_size = dns_rdatavec_size(merged_header); + isc_mem_put(mctx, merged_header, merged_size); + } +} + +/* Test case preservation during merge */ +ISC_RUN_TEST_IMPL(merge_case_preservation) { + isc_mem_t *mctx = isc_g_mctx; + UNUSED(state); + dns_vecheader_t *header1 = NULL, *header2 = NULL, *merged_header = NULL; + dns_fixedname_t fname1, fname2, fmerged_name; + dns_name_t *name1 = dns_fixedname_initname(&fname1); + dns_name_t *name2 = dns_fixedname_initname(&fname2); + dns_name_t *merged_name = dns_fixedname_initname(&fmerged_name); + unsigned int size1, size2, merged_size; + isc_result_t result; + + dns_test_namefromstring("Example.COM", &fname1); + dns_test_namefromstring("example.com", &fname2); + + /* Create vecheaders */ + CHECK(create_vecheader(mctx, dns_rdatatype_a, dns_rdataclass_in, + 300, "192.168.1.1", &header1)); + + CHECK(create_vecheader(mctx, dns_rdatatype_a, dns_rdataclass_in, + 300, "192.168.1.2", &header2)); + + /* Set case on first header */ + dns_vecheader_setownercase(header1, name1); + + /* Set case on second header */ + dns_vecheader_setownercase(header2, name2); + + /* Get sizes */ + size1 = dns_rdatavec_size(header1); + size2 = dns_rdatavec_size(header2); + + /* Merge headers */ + CHECK(dns_rdatavec_merge(header1, header2, mctx, dns_rdataclass_in, + dns_rdatatype_a, 0, 0, &merged_header)); + assert_non_null(merged_header); + + /* Test: case should be the same as the first header */ + /* Copy the name for testing */ + dns_name_copy(name1, merged_name); + + /* Create a test rdataset from merged header to test case */ + dns_rdataset_t test_rdataset; + create_rdataset_from_vecheader(merged_header, dns_rdataclass_in, + dns_rdatatype_a, &test_rdataset); + + /* Apply case from merged header */ + dns_rdataset_getownercase(&test_rdataset, merged_name); + + /* The case should match the original first name */ + assert_true(dns_name_caseequal(name1, merged_name)); + +cleanup: + /* Cleanup */ + if (header1 != NULL) { + size1 = dns_rdatavec_size(header1); + isc_mem_put(mctx, header1, size1); + } + if (header2 != NULL) { + size2 = dns_rdatavec_size(header2); + isc_mem_put(mctx, header2, size2); + } + if (merged_header != NULL) { + merged_size = dns_rdatavec_size(merged_header); + isc_mem_put(mctx, merged_header, merged_size); + } +} + +/* Test size consistency after setting case */ +ISC_RUN_TEST_IMPL(setcase_size_consistency) { + isc_mem_t *mctx = isc_g_mctx; + UNUSED(state); + dns_vecheader_t *header = NULL; + dns_fixedname_t fname, flower_fname, fretrieved_fname; + dns_name_t *name = dns_fixedname_initname(&fname); + dns_name_t *lower_name = dns_fixedname_initname(&flower_fname); + dns_name_t *retrieved_name = dns_fixedname_initname(&fretrieved_fname); + unsigned int original_size, cased_size; + dns_rdataset_t test_rdataset; + isc_result_t result; + + /* Initialize name */ + dns_test_namefromstring("Example.COM", &fname); + + /* Create vecheader */ + CHECK(create_vecheader(mctx, dns_rdatatype_a, dns_rdataclass_in, + 300, "192.168.1.1", &header)); + + /* Get original size */ + original_size = dns_rdatavec_size(header); + + /* Set case */ + dns_vecheader_setownercase(header, name); + + /* Get size after setting case */ + cased_size = dns_rdatavec_size(header); + + /* Test: size should be the same after setting case */ + assert_int_equal(cased_size, original_size); + + /* Create lowercase version of the original name */ + dns_test_namefromstring("example.com", &flower_fname); + + /* Copy lowercase name to retrieved_name for testing */ + dns_name_copy(lower_name, retrieved_name); + + /* Create a test rdataset from cased header */ + create_rdataset_from_vecheader(header, dns_rdataclass_in, + dns_rdatatype_a, &test_rdataset); + + /* Apply case from cased header to retrieved_name */ + dns_rdataset_getownercase(&test_rdataset, retrieved_name); + + /* Test: retrieved case should match the original mixed case */ + assert_true(dns_name_caseequal(name, retrieved_name)); + +cleanup: + /* Cleanup */ + if (header != NULL) { + cased_size = dns_rdatavec_size(header); + isc_mem_put(mctx, header, cased_size); + } +} + +ISC_TEST_LIST_START +ISC_TEST_ENTRY_CUSTOM(merge_headers, setup_mctx, teardown_mctx) +ISC_TEST_ENTRY_CUSTOM(merge_case_preservation, setup_mctx, teardown_mctx) +ISC_TEST_ENTRY_CUSTOM(setcase_size_consistency, setup_mctx, teardown_mctx) +ISC_TEST_LIST_END + +ISC_TEST_MAIN