1# $NetBSD: t_config.sh,v 1.8 2016/08/27 12:08:14 christos 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 eq: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 eq: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 ommited '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
263atf_init_test_cases()
264{
265	atf_add_test_case shadow_instance
266	atf_add_test_case loop
267	atf_add_test_case loop2
268	atf_add_test_case pseudo_parent
269	atf_add_test_case postponed_orphan
270	atf_add_test_case no_pseudo
271	atf_add_test_case deffs_redef
272	atf_add_test_case undefined_opt
273	atf_add_test_case no_undefined_opt
274	atf_add_test_case select
275	atf_add_test_case no_select
276	atf_add_test_case devi
277	atf_add_test_case min
278}
279