1# $NetBSD: t_config.sh,v 1.12 2024/04/28 07:27:42 rillig Exp $ 2# 3# Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 19# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25# POSSIBILITY OF SUCH DAMAGE. 26# 27 28srcdir=.. 29merge_backslash() 30{ 31 sed ' 32: again 33/\\$/ { 34 N 35 s/\\\n// 36 t again 37} 38' "$1" 39} 40run_and_check_prep() 41{ 42 local name="${1}"; shift 43 44 mkdir -p compile 45 srcdir="$(atf_get_srcdir)" 46 if [ ! -d "${srcdir}/support" ]; then 47 srcdir="$(dirname "${srcdir}")" 48 if [ ! -d "${srcdir}/support" ]; then 49 atf_fail "bad source directory ${srcdir}" 50 exit 1 51 fi 52 fi 53 supportdir="${srcdir}/support" 54 55 local config_str 56 eval config_str=\$${name}_config_str 57 if [ -n "$config_str" ]; then 58 config="d_${name}" 59 printf "$config_str" >"${config}" 60 else 61 config="${srcdir}/d_${name}" 62 fi 63} 64 65run_and_check_pass() 66{ 67 local name="${1}"; shift 68 69 run_and_check_prep "${name}" 70 71 atf_check -o ignore -s exit:0 \ 72 config -s "${supportdir}" -b "compile/${name}" "${config}" 73} 74 75run_and_check_warn() 76{ 77 local name="${1}"; shift 78 79 run_and_check_prep "${name}" 80 81 local stderr 82 eval stderr=\$${name}_stderr 83 atf_check -o ignore -e "${stderr}" -s exit:0 \ 84 config -s "${supportdir}" -b "compile/${name}" "${config}" 85} 86 87run_and_check_fail() 88{ 89 local name="${1}"; shift 90 91 run_and_check_prep "${name}" 92 93 atf_check -o ignore -e ignore -s ne:0 \ 94 config -s "${supportdir}" -b "compile/${name}" "${config}" 95} 96 97test_output() 98{ 99 local name="${1}"; shift 100 local res=1 101 102 run_and_check_prep "${name}" 103 104 config -s "${supportdir}" -b compile/"${name}" "${config}" >/dev/null && 105 cd compile/"${name}" && 106 check_${name} && 107 cd $OLDPWD && 108 res=0 109 110 atf_check test $res -eq 0 111} 112 113# Defines a test case for config(1). 114test_case() 115{ 116 local name="${1}"; shift 117 local type="${1}"; shift 118 local descr="${*}" 119 120 atf_test_case "${name}" 121 eval "${name}_head() { \ 122 atf_set descr \"${descr}\"; \ 123 atf_set require.progs \"config\"; \ 124 }" 125 eval "${name}_body() { \ 126 run_and_check_${type} '${name}'; \ 127 }" 128} 129 130test_case shadow_instance pass "Checks correct handling of shadowed instances" 131test_case loop pass "Checks correct handling of loops" 132test_case loop2 pass "Checks correct handling of devices that can be their" \ 133 "own parents" 134test_case pseudo_parent pass "Checks correct handling of children of pseudo" \ 135 "devices (PR/32329)" 136test_case postponed_orphan fail "Checks that config catches adding an" \ 137 "instance of a child of a negated instance as error" 138test_case no_pseudo fail "Checks that config catches omitted 'pseudo-device'" \ 139 "as error (PR/34111)" 140test_case deffs_redef fail "Checks that config doesn't allow a deffs to use" \ 141 "the same name as a previous defflag/defparam" 142 143# Selecting an undefined option. 144undefined_opt_config_str=" 145include \"${srcdir}/d_min\" 146options UNDEFINED 147" 148test_case undefined_opt pass \ 149 "Checks that config allows a selection for an undefined options" 150 151# Negating an undefined option. 152no_undefined_opt_config_str=" 153include \"${srcdir}/d_min\" 154no options UNDEFINED 155" 156no_undefined_opt_stderr='match:UNDEFINED' 157test_case no_undefined_opt warn \ 158 "Checks that config allows a negation for an undefined options" 159 160# Attribute selection 161test_case select pass "Attribute selection" 162select_config_str=" 163include \"${srcdir}/d_min\" 164select c 165" 166check_select() 167{ 168 local f=Makefile 169 170 grep -q '^ a\.c ' $f && 171 grep -q '^ b\.c ' $f && 172 grep -q '^ c\.c ' $f && 173 : 174} 175select_body() { 176 test_output select 177} 178 179# Attribute negation 180test_case no_select pass "Attribute negation" 181no_select_config_str=" 182include \"${srcdir}/d_min\" 183select c 184no select a 185" 186check_no_select() 187{ 188 local f=Makefile 189 190 : >tmp 191 grep -q '^a\.o:' $f >>tmp 192 grep -q '^b\.o:' $f >>tmp 193 grep -q '^c\.o:' $f >>tmp 194 195 [ ! -s tmp ] && 196 : 197} 198no_select_body() { 199 test_output no_select 200} 201 202# Device instance 203test_case devi pass "Device instance" 204devi_config_str=" 205include \"${srcdir}/d_min\" 206d0 at root 207" 208check_devi() 209{ 210 local f=ioconf.c 211 212 sed -ne '/^struct cfdriver \* const cfdriver_list_initial\[\]/,/^};/p' $f >tmp.cfdriver 213 sed -ne '/^struct cfdata cfdata\[\]/,/^};/p' $f >tmp.cfdata 214 215 grep -q '^CFDRIVER_DECL(d, ' $f && 216 grep -q '&d_cd,' tmp.cfdriver && 217 grep -q '^extern struct cfattach d_ca;$' $f && 218 grep -q '^static const struct cfiattrdata \* const d_attrs\[\]' $f && 219 grep -q '^static const struct cfiattrdata icf_iattrdata' $f && 220 grep -q '{ "d",' tmp.cfdata && 221 : 222} 223devi_body() { 224 test_output devi 225} 226 227# Check minimal kernel config(1) output 228test_case min pass "Minimal config" 229check_min_files() 230{ 231 test -e Makefile && 232 test -e config_file.h && 233 test -e config_time.src && 234 test -e ioconf.c && 235 test -e ioconf.h && 236 test -e locators.h && 237 test -e swapregress.c && 238 test -h machine && 239 test -h regress && 240 : 241} 242check_min_makefile() 243{ 244 local f=Makefile 245 246 grep -q '^%' $f >tmp.template 247 248 grep -q '^MACHINE=regress$' $f && 249 (merge_backslash $f | grep -q '^IDENT=[ ]*-DMAXUSERS="4"') && 250 [ ! -s tmp.template ] && 251 : 252} 253check_min() 254{ 255 check_min_files && 256 check_min_makefile && 257 : 258} 259min_body() { 260 test_output min 261} 262 263# Check ifdef supper 264test_case ifdef pass "ifdef config" 265check_ifdef_files() 266{ 267 test -e Makefile && 268 test -e config_file.h && 269 test -e config_time.src && 270 test -e ioconf.c && 271 test -e ioconf.h && 272 test -e locators.h && 273 test -e swapregress.c && 274 test -h machine && 275 test -h regress && 276 : 277} 278 279check_ifdef_makefile() 280{ 281 local f=Makefile 282 local e='-DOK1_1 -DOK2_1 -DOK2_2 -DOK3_1 -DOK3_2 -DOK3_3 -DOK3_4 -DOK3_5 -DOK4_1 -DMAXUSERS="4"' 283 local r 284 r=$(make -f Makefile -V IDENT) 285 if [ "$r" != "$e" ]; then 286 echo "Expected: '$e'" 287 echo "Result: '$r'" 288 return 1 289 fi 290} 291 292check_ifdef() 293{ 294 check_ifdef_files && 295 check_ifdef_makefile && 296 : 297} 298ifdef_body() { 299 test_output ifdef 300} 301 302atf_init_test_cases() 303{ 304 atf_add_test_case shadow_instance 305 atf_add_test_case loop 306 atf_add_test_case loop2 307 atf_add_test_case pseudo_parent 308 atf_add_test_case postponed_orphan 309 atf_add_test_case no_pseudo 310 atf_add_test_case deffs_redef 311 atf_add_test_case undefined_opt 312 atf_add_test_case no_undefined_opt 313 atf_add_test_case select 314 atf_add_test_case no_select 315 atf_add_test_case devi 316 atf_add_test_case min 317 atf_add_test_case ifdef 318} 319