1#	$NetBSD: t_simplehook.sh,v 1.1 2021/09/30 02:00:20 yamaguchi Exp $
2#
3# Copyright (c) 2021 Internet Initiative Japan 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
28DEBUG=${DEBUG:-false}
29SOCK=unix://commsock
30HIJACKING="env LD_PRELOAD=/usr/lib/librumphijack.so \
31    RUMPHIJACK=path=/rump,socket=all:nolocal,sysctl=yes"
32
33atf_sysctl_rd()
34{
35	local sysctl_key=$1
36	local expected=$2
37
38	atf_check -s exit:0 -o match:"$expected" \
39	    rump.sysctl -n $sysctl_key
40}
41
42atf_sysctl_wr()
43{
44	local sysctl_key=$1
45	local value=$2
46
47	atf_check -s exit:0 -o ignore rump.sysctl -w $sysctl_key=$value
48}
49
50atf_sysctl_wait()
51{
52	local sysctl_key=$1
53	local expected=$2
54	local n=10
55	local i
56	local v
57
58	for i in $(seq $n); do
59		v=$(rump.sysctl -n $sysctl_key)
60		if [ x"$v" = x"$expected" ]; then
61			return
62		fi
63		sleep 0.5
64	done
65
66	atf_fail "Couldn't get the value for $n seconds."
67}
68
69atf_test_case simplehook_basic cleanup
70simplehook_basic_head()
71{
72
73	atf_set "descr" "tests for basically functions of simplehook"
74	atf_set "require.progs" "rump_server"
75}
76
77
78simplehook_basic_body()
79{
80	local key_hklist="kern.simplehook_tester.hook_list"
81	local key_hk0="kern.simplehook_tester.hook0"
82	local key_hk1="kern.simplehook_tester.hook1"
83
84	rump_server -lrumpkern_simplehook_tester $SOCK
85
86	export RUMP_SERVER=$SOCK
87
88	$DEBUG && rump.sysctl -e kern.simplehook_tester
89	atf_check -s exit:0 -o ignore rump.sysctl -e kern.simplehook_tester
90
91	# create and destroy
92	atf_sysctl_rd ${key_hklist}.created '0'
93	atf_sysctl_wr ${key_hklist}.created '1'
94	atf_sysctl_wr ${key_hklist}.created '0'
95	$DEBUG && rump.sysctl -e kern.simplehook_tester
96
97	# establish one hook
98	atf_sysctl_wr ${key_hklist}.created '1'
99	atf_sysctl_wr ${key_hk0}.established '1'
100	atf_sysctl_wr ${key_hk0}.count '0'
101	atf_sysctl_wr ${key_hklist}.dohooks '1'
102	atf_sysctl_wr ${key_hklist}.dohooks '0'
103	atf_sysctl_rd ${key_hk0}.count '1'
104	atf_sysctl_wr ${key_hk0}.established '0'
105	atf_sysctl_wr ${key_hklist}.created '0'
106
107	# establish two hooks
108	atf_sysctl_wr ${key_hklist}.created '1'
109	atf_sysctl_wr ${key_hk0}.established '1'
110	atf_sysctl_wr ${key_hk1}.established '1'
111	atf_sysctl_wr ${key_hk0}.count '0'
112	atf_sysctl_wr ${key_hk1}.count '0'
113
114	atf_sysctl_wr ${key_hklist}.dohooks '1'
115	atf_sysctl_wr ${key_hklist}.dohooks '0'
116	atf_sysctl_rd ${key_hk0}.count '1'
117	atf_sysctl_rd ${key_hk1}.count '1'
118
119	atf_sysctl_wr ${key_hk0}.established '0'
120	atf_sysctl_wr ${key_hk1}.established '0'
121	atf_sysctl_wr ${key_hklist}.created '0'
122}
123
124simplehook_basic_cleanup()
125{
126	export RUMP_SERVER=$SOCK
127
128	$DEBUG && rump.sysctl -e kern.simplehook_tester
129	$DEBUG && $HIJACKING dmesg
130	rump.halt
131}
132
133atf_test_case simplehook_disestablish cleanup
134simplehook_disestablish_head()
135{
136
137	atf_set "descr" "tests for disestablish of simplehook"
138	atf_set "require.progs" "rump_server"
139}
140
141simplehook_disestablish_body()
142{
143	local key_hklist="kern.simplehook_tester.hook_list"
144	local key_hk0="kern.simplehook_tester.hook0"
145	local key_hk1="kern.simplehook_tester.hook1"
146
147	rump_server -lrumpkern_simplehook_tester $SOCK
148
149	export RUMP_SERVER=$SOCK
150
151	$DEBUG && rump.sysctl -e kern.simplehook_tester
152	atf_check -s exit:0 -o ignore rump.sysctl -e kern.simplehook_tester
153
154	#
155	# disestablish on the running hook
156	#
157	atf_sysctl_wr ${key_hklist}.created '1'
158	atf_sysctl_wr ${key_hk0}.established '1'
159	atf_sysctl_wr ${key_hk0}.disestablish_in_hook '1'
160	atf_sysctl_wr ${key_hklist}.dohooks '1'
161	atf_sysctl_wr ${key_hklist}.dohooks '0'
162
163	# already disestablished
164	atf_sysctl_rd ${key_hk0}.established '0'
165	atf_sysctl_wr ${key_hk0}.disestablish_in_hook '0'
166
167	atf_sysctl_wr ${key_hklist}.created '0'
168
169	#
170	# disestablish called hook while doing other hook
171	#
172	atf_sysctl_wr ${key_hklist}.created '1'
173	atf_sysctl_wr ${key_hk0}.established '1'
174	atf_sysctl_wr ${key_hk1}.established '1'
175
176	atf_sysctl_wr ${key_hk0}.count '0'
177	atf_sysctl_wr ${key_hk1}.count '0'
178	atf_sysctl_wr ${key_hk0}.stopping '1'
179
180	# calls hook1 -> hook0
181	atf_sysctl_wr ${key_hklist}.dohooks '1'
182
183	# stop in hook0
184	atf_sysctl_wait ${key_hk0}.stopped '1'
185
186	atf_sysctl_rd ${key_hk1}.count '1'
187	atf_sysctl_wr ${key_hk1}.established '0'
188
189	# wakeup hook0
190	atf_sysctl_wr ${key_hk0}.stopping '0'
191	atf_sysctl_wr ${key_hklist}.dohooks '0'
192
193	atf_sysctl_wr ${key_hk0}.established '0'
194	atf_sysctl_wr ${key_hklist}.created '0'
195
196	#
197	# disestablish a hook in running hook list
198	#
199	atf_sysctl_wr ${key_hklist}.created '1'
200	atf_sysctl_wr ${key_hk0}.established '1'
201	atf_sysctl_wr ${key_hk1}.established '1'
202
203	atf_sysctl_wr ${key_hk0}.count '0'
204	atf_sysctl_wr ${key_hk1}.count '0'
205	atf_sysctl_wr ${key_hk1}.stopping '1'
206
207	# calls hook1 -> hook0
208	atf_sysctl_wr ${key_hklist}.dohooks '1'
209
210	# stop in hook1
211	atf_sysctl_wait ${key_hk1}.stopped '1'
212
213	atf_sysctl_wr ${key_hk0}.established '0'
214
215	# wakeup hook1
216	atf_sysctl_wr ${key_hk1}.stopping '0'
217	atf_sysctl_wr ${key_hklist}.dohooks '0'
218
219	# hook0 is not called
220	atf_sysctl_rd ${key_hk0}.count '0'
221
222	atf_sysctl_wr ${key_hk1}.established '0'
223	atf_sysctl_wr ${key_hklist}.created '0'
224
225	#
226	# disestablish the running hook
227	#
228	atf_sysctl_wr ${key_hklist}.created '1'
229	atf_sysctl_wr ${key_hk0}.established '1'
230	atf_sysctl_wr ${key_hk0}.stopping '1'
231
232	atf_sysctl_wr ${key_hklist}.dohooks '1'
233
234	atf_sysctl_wait ${key_hk0}.stopped '1'
235	atf_sysctl_wr ${key_hk0}.established '0'
236
237	atf_sysctl_wr ${key_hklist}.dohooks '0'
238	atf_sysctl_wr ${key_hklist}.created '0'
239}
240
241simplehook_disestablish_cleanup()
242{
243	export RUMP_SERVER=$SOCK
244
245	$DEBUG && rump.sysctl -e kern.simplehook_tester
246	$DEBUG && $HIJACKING dmesg
247	rump.halt
248}
249
250atf_test_case simplehook_nolock cleanup
251simplehook_nolock_head()
252{
253
254	atf_set "descr" "tests for hook that does not use lock in it"
255	atf_set "require.progs" "rump_server"
256}
257
258simplehook_nolock_body()
259{
260	local key_hklist="kern.simplehook_tester.hook_list"
261	local key_hk="kern.simplehook_tester.nbhook"
262
263	rump_server -lrumpkern_simplehook_tester $SOCK
264
265	export RUMP_SERVER=$SOCK
266	$DEBUG && rump.sysctl -e kern.simplehook_tester
267	atf_check -s exit:0 -o ignore rump.sysctl -e kern.simplehook_tester
268
269	atf_sysctl_wr ${key_hklist}.created '1'
270	atf_sysctl_wr ${key_hk}.established '1'
271
272	atf_sysctl_wr ${key_hklist}.dohooks '1'
273	atf_sysctl_wr ${key_hk}.established '0'
274	atf_sysctl_wr ${key_hklist}.dohooks '0'
275
276	atf_sysctl_wr ${key_hklist}.created '0'
277}
278
279simplehook_nolock_cleanup()
280{
281	export RUMP_SERVER=$SOCK
282
283	$DEBUG && rump.sysctl -e kern.simplehook_tester
284	$DEBUG && $HIJACKING dmesg
285	rump.halt
286}
287
288atf_init_test_cases()
289{
290
291	atf_add_test_case simplehook_basic
292	atf_add_test_case simplehook_disestablish
293	atf_add_test_case simplehook_nolock
294}
295