]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add rbtdb setownercase/getownercase unit test
authorOndřej Surý <ondrej@sury.org>
Wed, 23 Jun 2021 13:29:22 +0000 (15:29 +0200)
committerOndřej Surý <ondrej@sury.org>
Wed, 23 Jun 2021 14:38:46 +0000 (16:38 +0200)
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.

lib/dns/tests/Makefile.am
lib/dns/tests/rbtdb_test.c [new file with mode: 0644]
util/copyrights

index 76e9b96b94b66f32ae2c4c2ac4bdeb95e801c115..006a2bf5efc6cdb846e9cd88d685a43b6d115421 100644 (file)
@@ -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 (file)
index 0000000..a92b4bd
--- /dev/null
@@ -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 <sched.h> /* IWYU pragma: keep */
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define UNIT_TESTING
+#include <cmocka.h>
+
+#include <isc/util.h>
+
+#include <dns/rbt.h>
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+
+#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 <stdio.h>
+
+int
+main(void) {
+       printf("1..0 # Skipped: cmocka not available\n");
+       return (SKIPPED_TEST_EXIT_CODE);
+}
+
+#endif /* if HAVE_CMOCKA */
index 19b533bfbaa398bd2f7b98f886bb635c6b14bacc..897149718a68a0e18422b1a9ea8a301a997c147a 100644 (file)
 ./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