1 /* $NetBSD: plugin_test.c,v 1.3 2025/01/26 16:25:51 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 <limits.h> 18 #include <sched.h> /* IWYU pragma: keep */ 19 #include <setjmp.h> 20 #include <stdarg.h> 21 #include <stdbool.h> 22 #include <stddef.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #define UNIT_TESTING 27 #include <cmocka.h> 28 29 #include <isc/attributes.h> 30 #include <isc/dir.h> 31 #include <isc/mem.h> 32 #include <isc/result.h> 33 #include <isc/types.h> 34 #include <isc/util.h> 35 36 #include <ns/hooks.h> 37 38 #include <tests/ns.h> 39 40 /*% 41 * Structure containing parameters for run_full_path_test(). 42 */ 43 typedef struct { 44 const ns_test_id_t id; /* libns test identifier */ 45 const char *input; /* source string - plugin name or path 46 * */ 47 size_t output_size; /* size of target char array to 48 * allocate */ 49 isc_result_t result; /* expected return value */ 50 const char *output; /* expected output string */ 51 } ns_plugin_expandpath_test_params_t; 52 53 /*% 54 * Perform a single ns_plugin_expandpath() check using given parameters. 55 */ 56 static void 57 run_full_path_test(const ns_plugin_expandpath_test_params_t *test, 58 void **state) { 59 char **target = (char **)state; 60 isc_result_t result; 61 62 REQUIRE(test != NULL); 63 REQUIRE(test->id.description != NULL); 64 REQUIRE(test->input != NULL); 65 REQUIRE(test->result != ISC_R_SUCCESS || test->output != NULL); 66 67 /* 68 * Prepare a target buffer of given size. Store it in 'state' so that 69 * it can get cleaned up by _teardown() if the test fails. 70 */ 71 *target = isc_mem_allocate(mctx, test->output_size); 72 73 /* 74 * Call ns_plugin_expandpath(). 75 */ 76 result = ns_plugin_expandpath(test->input, *target, test->output_size); 77 78 /* 79 * Check return value. 80 */ 81 if (result != test->result) { 82 fail_msg("# test \"%s\" on line %d: " 83 "expected result %d (%s), got %d (%s)", 84 test->id.description, test->id.lineno, test->result, 85 isc_result_totext(test->result), result, 86 isc_result_totext(result)); 87 } 88 89 /* 90 * Check output string if return value indicates success. 91 */ 92 if (result == ISC_R_SUCCESS && strcmp(*target, test->output) != 0) { 93 fail_msg("# test \"%s\" on line %d: " 94 "expected output \"%s\", got \"%s\"", 95 test->id.description, test->id.lineno, test->output, 96 *target); 97 } 98 99 isc_mem_free(mctx, *target); 100 } 101 102 /* test ns_plugin_expandpath() */ 103 ISC_RUN_TEST_IMPL(ns_plugin_expandpath) { 104 size_t i; 105 106 const ns_plugin_expandpath_test_params_t tests[] = { 107 { 108 NS_TEST_ID("correct use with an absolute path"), 109 .input = "/usr/lib/named/foo.so", 110 .output_size = PATH_MAX, 111 .result = ISC_R_SUCCESS, 112 .output = "/usr/lib/named/foo.so", 113 }, 114 { 115 NS_TEST_ID("correct use with a relative path"), 116 .input = "../../foo.so", 117 .output_size = PATH_MAX, 118 .result = ISC_R_SUCCESS, 119 .output = "../../foo.so", 120 }, 121 { 122 NS_TEST_ID("correct use with a filename"), 123 .input = "foo.so", 124 .output_size = PATH_MAX, 125 .result = ISC_R_SUCCESS, 126 .output = NAMED_PLUGINDIR "/foo.so", 127 }, 128 { 129 NS_TEST_ID("no space at all in target buffer"), 130 .input = "/usr/lib/named/foo.so", 131 .output_size = 0, 132 .result = ISC_R_NOSPACE, 133 }, 134 { 135 NS_TEST_ID("target buffer too small to fit input"), 136 .input = "/usr/lib/named/foo.so", 137 .output_size = 1, 138 .result = ISC_R_NOSPACE, 139 }, 140 { 141 NS_TEST_ID("target buffer too small to fit NULL byte"), 142 .input = "/foo.so", 143 .output_size = 7, 144 .result = ISC_R_NOSPACE, 145 }, 146 { 147 NS_TEST_ID("target buffer too small to fit full path"), 148 .input = "foo.so", 149 .output_size = 7, 150 .result = ISC_R_NOSPACE, 151 }, 152 }; 153 154 for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { 155 run_full_path_test(&tests[i], state); 156 } 157 } 158 159 ISC_TEST_LIST_START 160 ISC_TEST_ENTRY(ns_plugin_expandpath) 161 ISC_TEST_LIST_END 162 163 ISC_TEST_MAIN 164