From: Ondřej Surý Date: Wed, 23 Jun 2021 13:29:22 +0000 (+0200) Subject: Add rbtdb setownercase/getownercase unit test X-Git-Tag: v9.17.16~18^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c7a11bd5b489576afbbf0050330a56589283b9c4;p=thirdparty%2Fbind9.git Add rbtdb setownercase/getownercase unit test This commit adds a unittest that tests private rdataset_getownercase() and rdataset_setownercase() methods from rbtdb.c. The test setups minimal mock dns_rbtdb_t and dns_rbtdbnode_t data structures. As the rbtdb methods are generally hidden behind layers and layers, we include the "rbtdb.c" directly from rbtdb_test.c, and thus we can use the private methods and data structures directly. This also opens up opportunity to add more unittest for the rbtdb private functions without going through all the layers. --- diff --git a/lib/dns/tests/Makefile.am b/lib/dns/tests/Makefile.am index 76e9b96b94b..006a2bf5efc 100644 --- a/lib/dns/tests/Makefile.am +++ b/lib/dns/tests/Makefile.am @@ -34,6 +34,7 @@ check_PROGRAMS = \ private_test \ rbt_serialize_test \ rbt_test \ + rbtdb_test \ rdata_test \ rdataset_test \ rdatasetstats_test \ diff --git a/lib/dns/tests/rbtdb_test.c b/lib/dns/tests/rbtdb_test.c new file mode 100644 index 00000000000..a92b4bd8af9 --- /dev/null +++ b/lib/dns/tests/rbtdb_test.c @@ -0,0 +1,237 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * 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. + */ + +#if HAVE_CMOCKA + +#include /* IWYU pragma: keep */ +#include +#include +#include +#include +#include +#include + +#define UNIT_TESTING +#include + +#include + +#include +#include +#include + +#include "dnstest.h" + +/* Include the main file */ + +#include "../rbtdb.c" + +static int +_setup(void **state) { + isc_result_t result; + + UNUSED(state); + + result = dns_test_begin(NULL, false); + assert_int_equal(result, ISC_R_SUCCESS); + + return (0); +} + +static int +_teardown(void **state) { + UNUSED(state); + + dns_test_end(); + + return (0); +} + +const char *ownercase_vectors[12][2] = { + { + "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz", + "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz", + }, + { + "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz", + "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ", + }, + { + "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ", + "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz", + }, + { + "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ", + "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz", + }, + { + "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVxXyYzZ", + "aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvxxyyzz", + }, + { + "WwW.ExAmPlE.OrG", + "wWw.eXaMpLe.oRg", + }, + { + "_SIP.tcp.example.org", + "_sip.TCP.example.org", + }, + { + "bind-USERS.lists.example.org", + "bind-users.lists.example.org", + }, + { + "a0123456789.example.org", + "A0123456789.example.org", + }, + { + "\\000.example.org", + "\\000.example.org", + }, + { + "wWw.\\000.isc.org", + "www.\\000.isc.org", + }, + { + "\255.example.org", + "\255.example.ORG", + } +}; + +static bool +ownercase_test_one(const char *str1, const char *str2) { + rbtdb_nodelock_t node_locks[1]; + dns_rbtdb_t rbtdb = { .node_locks = node_locks }; + dns_rbtnode_t rbtnode = { .locknum = 0 }; + rdatasetheader_t header = { 0 }; + unsigned char *raw = (unsigned char *)(&header) + sizeof(header); + dns_rdataset_t rdataset = { + .magic = DNS_RDATASET_MAGIC, + .private1 = &rbtdb, + .private2 = &rbtnode, + .private3 = raw, + .methods = &rdataset_methods, + }; + + isc_buffer_t b; + dns_fixedname_t fname1, fname2; + dns_name_t *name1, *name2; + + memset(node_locks, 0, sizeof(node_locks)); + /* Minimal initialization of the mock objects */ + NODE_INITLOCK(&rbtdb.node_locks[0].lock); + + name1 = dns_fixedname_initname(&fname1); + isc_buffer_constinit(&b, str1, strlen(str1)); + isc_buffer_add(&b, strlen(str1)); + dns_name_fromtext(name1, &b, dns_rootname, 0, NULL); + + name2 = dns_fixedname_initname(&fname2); + isc_buffer_constinit(&b, str2, strlen(str2)); + isc_buffer_add(&b, strlen(str2)); + dns_name_fromtext(name2, &b, dns_rootname, 0, NULL); + + /* Store the case from name1 */ + dns_rdataset_setownercase(&rdataset, name1); + + assert_true(CASESET(&header)); + + /* Retrieve the case to name2 */ + dns_rdataset_getownercase(&rdataset, name2); + + NODE_DESTROYLOCK(&rbtdb.node_locks[0].lock); + + return (dns_name_caseequal(name1, name2)); +} + +static void +ownercase_test(void **state) { + UNUSED(state); + + for (size_t n = 0; n < ARRAY_SIZE(ownercase_vectors); n++) { + assert_true(ownercase_test_one(ownercase_vectors[n][0], + ownercase_vectors[n][1])); + } + + assert_false(ownercase_test_one("W.example.org", "\\000.example.org")); + + /* Ö and ö in ISO Latin 1 */ + assert_false(ownercase_test_one("\\216", "\\246")); +} + +static void +setownercase_test(void **state) { + rbtdb_nodelock_t node_locks[1]; + dns_rbtdb_t rbtdb = { .node_locks = node_locks }; + dns_rbtnode_t rbtnode = { .locknum = 0 }; + rdatasetheader_t header = { 0 }; + unsigned char *raw = (unsigned char *)(&header) + sizeof(header); + dns_rdataset_t rdataset = { + .magic = DNS_RDATASET_MAGIC, + .private1 = &rbtdb, + .private2 = &rbtnode, + .private3 = raw, + .methods = &rdataset_methods, + }; + const char *str1 = + "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"; + + isc_buffer_t b; + dns_fixedname_t fname1, fname2; + dns_name_t *name1, *name2; + + UNUSED(state); + + /* Minimal initialization of the mock objects */ + memset(node_locks, 0, sizeof(node_locks)); + NODE_INITLOCK(&rbtdb.node_locks[0].lock); + + name1 = dns_fixedname_initname(&fname1); + isc_buffer_constinit(&b, str1, strlen(str1)); + isc_buffer_add(&b, strlen(str1)); + dns_name_fromtext(name1, &b, dns_rootname, 0, NULL); + + name2 = dns_fixedname_initname(&fname2); + isc_buffer_constinit(&b, str1, strlen(str1)); + isc_buffer_add(&b, strlen(str1)); + dns_name_fromtext(name2, &b, dns_rootname, 0, NULL); + + assert_false(CASESET(&header)); + + /* Retrieve the case to name2 */ + dns_rdataset_getownercase(&rdataset, name2); + + NODE_DESTROYLOCK(&rbtdb.node_locks[0].lock); + + assert_true(dns_name_caseequal(name1, name2)); +} + +int +main(void) { + const struct CMUnitTest tests[] = { + cmocka_unit_test(ownercase_test), + cmocka_unit_test(setownercase_test), + }; + + return (cmocka_run_group_tests(tests, _setup, _teardown)); +} + +#else /* HAVE_CMOCKA */ + +#include + +int +main(void) { + printf("1..0 # Skipped: cmocka not available\n"); + return (SKIPPED_TEST_EXIT_CODE); +} + +#endif /* if HAVE_CMOCKA */ diff --git a/util/copyrights b/util/copyrights index 19b533bfbaa..897149718a6 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1557,6 +1557,7 @@ ./lib/dns/tests/private_test.c C 2011,2012,2016,2018,2019,2020,2021 ./lib/dns/tests/rbt_serialize_test.c C 2014,2015,2016,2018,2019,2020,2021 ./lib/dns/tests/rbt_test.c C 2012,2013,2014,2015,2016,2017,2018,2019,2020,2021 +./lib/dns/tests/rbtdb_test.c C 2021 ./lib/dns/tests/rdata_test.c C 2012,2013,2015,2016,2017,2018,2019,2020,2021 ./lib/dns/tests/rdataset_test.c C 2012,2016,2018,2019,2020,2021 ./lib/dns/tests/rdatasetstats_test.c C 2012,2015,2016,2018,2019,2020,2021