1309466Sngie# $NetBSD: t_swsensor.sh,v 1.9 2015/04/23 23:23:28 pgoyette Exp $
2272343Sngie
3272343Sngieget_sensor_info() {
4272343Sngie	rump.envstat -x | \
5272343Sngie	sed -e "\;swsensor;,\;/array;p" -e "d"
6272343Sngie}
7272343Sngie
8272343Sngieget_sensor_key() {
9309466Sngie	local v
10309466Sngie	v=$(get_sensor_info | grep -A1 $1 | grep integer | \
11309466Sngie	    sed -e 's;<[/a-z]*>;;g')
12309466Sngie	if [ -z "$v" ] ; then
13309466Sngie		v="key_$1_not_found"
14309466Sngie	fi
15309466Sngie	echo $v
16272343Sngie}
17272343Sngie
18272343Sngieget_powerd_event_count() {
19272343Sngie	grep "not running" powerd.log | wc -l
20272343Sngie}
21272343Sngie
22272343Sngieget_rnd_bits_count() {
23272343Sngie	env RUMPHIJACK=blanket=/dev/random:/dev/urandom	\
24272343Sngie	    RUMP_SERVER=unix://t_swsensor_socket	\
25272343Sngie	    LD_PRELOAD=/usr/lib/librumphijack.so	  rndctl -l | \
26272343Sngie	grep "swsensor-sensor" | \
27272343Sngie	awk '{print $2}'
28272343Sngie}
29272343Sngie
30272343Sngiecheck_powerd_event() {
31272343Sngie	event=$(grep "not running" powerd.log | \
32272343Sngie		sed -e "$1p" -e "d" )
33272343Sngie	event=${event##*//}
34272343Sngie	script=${event%% *}
35272343Sngie	event=${event#* }
36272343Sngie	device=${event%% *}
37272343Sngie	event=${event#* }
38272343Sngie	state=${event%% *}
39272343Sngie	sensor=${event#* }
40272343Sngie	sensor=${sensor% *}
41272343Sngie
42272343Sngie	if [ "${script}" != "sensor_indicator" ] ; then
43272343Sngie		echo "Event uses wrong script: ${script}"
44272343Sngie	elif [ "${device}" != "swsensor" ] ; then
45272343Sngie		echo "Event uses wrong device: ${device}"
46272343Sngie	elif [ "${sensor}" != "sensor" ] ; then
47272343Sngie		echo "Event uses wrong sensor: ${sensor}"
48272343Sngie	elif [ "${state}" != "$2" ] ; then
49272343Sngie		echo "Event uses wrong state: ${state}"
50272343Sngie	fi
51272343Sngie}
52272343Sngie
53272343Sngie# Start the rump server, then load the swsensor module with the
54272343Sngie# requested properties
55272343Sngie
56272343Sngiestart_rump() {
57272343Sngie	rump_allserver -l rumpvfs -l rumpdev -l rumpdev_sysmon ${RUMP_SERVER}
58272343Sngie	if [ $( get_sensor_info | wc -l ) -ne 0 ] ; then
59272343Sngie		rump.modunload swsensor
60272343Sngie		rump.modload -f $1 swsensor
61272343Sngie	else
62272343Sngie		rump.modload $1 swsensor
63272343Sngie	fi
64272343Sngie	return $?
65272343Sngie}
66272343Sngie
67272343Sngiecommon_head() {
68272343Sngie	atf_set	descr		"$1"
69309466Sngie	atf_set	timeout		120
70272343Sngie	atf_set	require.progs	rump.powerd rump.envstat rump.modload	\
71272343Sngie				rump.halt   rump.sysctl  rump_server	\
72272343Sngie				sed         grep         awk		\
73272343Sngie				rndctl      expr
74272343Sngie}
75272343Sngie
76272343Sngiecommon_cleanup() {
77272343Sngie	rump.modunload swsensor
78272343Sngie	rump.halt
79272343Sngie}
80272343Sngie
81272343Sngiecreate_envsys_conf_files() {
82272343Sngie	cat << ENV0 > env0.conf
83272343Sngie	swsensor {
84272343Sngie		refresh-timeout = 2s;
85272343Sngie	}
86272343SngieENV0
87272343Sngie	cat << ENV1 > env1.conf
88272343Sngie	swsensor {
89272343Sngie		sensor0 { critical-min = $(( $1 - $2 )); }
90272343Sngie	}
91272343SngieENV1
92272343Sngie	cat << ENV2 > env2.conf
93272343Sngie	swsensor {
94272343Sngie		sensor0 { critical-min = $1; }
95272343Sngie	}
96272343SngieENV2
97272343Sngie}
98272343Sngie
99272343Sngie# Test body common to all sensors
100272343Sngie#	$1	sensor mode
101272343Sngie#	$2	initial sensor value
102272343Sngie#	$3	initial limit
103272343Sngie#	$4	amount to lower limit
104272343Sngie#	$5	difference from limit to trigger event
105272343Sngie#	$6	sensor flags, for FHAS_ENTROPY and FMONNOTSUPP
106272343Sngie
107272343Sngiecommon_body() {
108272343Sngie	# Start the rump-server process and load the module
109272343Sngie	modload_args="-i mode=$1 -i value=$2 -i limit=$3 ${6:+-i flags=$6}"
110272343Sngie	start_rump "$modload_args"
111272343Sngie
112272343Sngie	# create configuration files for updates
113272343Sngie	create_envsys_conf_files $3 $4
114272343Sngie
115272343Sngie	if [ $? -ne 0 ] ; then
116272343Sngie		atf_skip "Cannot set-up rump environment"
117272343Sngie	fi
118272343Sngie
119272343Sngie	# start powerd so we can detect sensor events
120272343Sngie	rump.powerd -n -d > powerd.log 2>&1 &
121272343Sngie	if [ -z "$(jobs)" ] ; then
122272343Sngie		skip_events=1
123272343Sngie		echo "Skipping event sub-tests - powerd did not start"
124272343Sngie	else
125272343Sngie		skip_events=0
126272343Sngie		expected_event=1
127272343Sngie	fi
128272343Sngie
129272343Sngie	# Step 0 - verify that sensor is registered
130272343Sngie	get_sensor_info | grep -q swsensor ||
131272343Sngie		atf_fail "0: Device swsensor not registered"
132272343Sngie
133272343Sngie	# Step 1 - update the refresh-timeout and verify
134272343Sngie	# (use $(( ... )) since the timeout is displayed in hex!)
135272343Sngie	rump.envstat -c env0.conf
136272343Sngie	if [ $(( $( get_sensor_key refresh-timeout ) )) -ne 2 ] ; then
137272343Sngie		atf_fail "1: Could not set refresh-timout to 2s"
138272343Sngie	fi
139272343Sngie
140272343Sngie	# Step 2 - verify that we can read sensor's value
141272343Sngie	if [ $1 -ne 0 -a $( get_sensor_key cur-value ) -ne $2 ] ; then
142272343Sngie		atf_fail "2: Value not available"
143272343Sngie	fi
144272343Sngie
145272343Sngie	# Step 3 - verify that changes in sensor value are seen
146272343Sngie	rump.sysctl -w hw.swsensor.cur_value=$(( $2 + 1 ))
147272343Sngie	if [ $( get_sensor_key cur-value ) -ne $(( $2 + 1 )) ] ; then
148272343Sngie		atf_fail "3: Value not updated"
149272343Sngie	fi
150272343Sngie
151272343Sngie	# Step 4 - if sensor provides hw limit, make sure we can read it
152272343Sngie	if [ $1 -ne 0 ] ; then
153272343Sngie		if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
154272343Sngie			atf_fail "4: Limit not set by device"
155272343Sngie		fi
156272343Sngie	fi
157272343Sngie
158272343Sngie	# Step 5 - if sensor provides hw limit, make sure it works
159272343Sngie	if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then
160272343Sngie		rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $5 ))
161272343Sngie		sleep 5
162272343Sngie		cnt=$(get_powerd_event_count)
163272343Sngie		if [ ${cnt} -lt ${expected_event} ] ; then
164272343Sngie			atf_fail "5: No event triggered"
165272343Sngie		elif [ ${cnt} -gt ${expected_event} ] ; then
166272343Sngie			atf_fail "5: Multiple events triggered"
167272343Sngie		fi
168272343Sngie		evt=$( check_powerd_event ${cnt} "critical-under")
169272343Sngie		if [ -n "${evt}" ] ; then
170272343Sngie			atf_fail "5: ${evt}"
171272343Sngie		fi
172272343Sngie		expected_event=$(( 1 + ${expected_event} ))
173272343Sngie	fi
174272343Sngie
175272343Sngie	# Step 6 - verify that we return to normal state
176272343Sngie	if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then
177272343Sngie		rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $5 ))
178272343Sngie		sleep 5
179272343Sngie		cnt=$(get_powerd_event_count)
180272343Sngie		if [ ${cnt} -lt ${expected_event} ] ; then
181272343Sngie			atf_fail "6: No event triggered"
182272343Sngie		elif [ ${cnt} -gt ${expected_event} ] ; then
183272343Sngie			atf_fail "6: Multiple events triggered"
184272343Sngie		fi
185272343Sngie		evt=$( check_powerd_event ${cnt} "normal")
186272343Sngie		if [ -n "${evt}" ] ; then
187272343Sngie			atf_fail "6: ${evt}"
188272343Sngie		fi
189272343Sngie		expected_event=$(( 1 + ${expected_event} ))
190272343Sngie	fi
191272343Sngie
192272343Sngie	# Step 7 - verify that we can set our own limit
193272343Sngie
194272343Sngie	# Steps 7 thru 12 are skipped if the sensor cannot be monitored
195272343Sngie	if [ $( expr \( 0$6 / 2048 \) % 2 ) -ne 1 ] ; then
196272343Sngie		rump.envstat -c env1.conf
197272343Sngie		if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then
198272343Sngie			atf_fail "7: Limit not set by envstat -c"
199272343Sngie		fi
200272343Sngie
201272343Sngie	# Step 8 - make sure user-set limit works
202272343Sngie		if [ ${skip_events} -eq 0 ] ; then
203272343Sngie			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 ))
204272343Sngie			sleep 5
205272343Sngie			cnt=$(get_powerd_event_count)
206272343Sngie			if [ ${cnt} -lt ${expected_event} ] ; then
207272343Sngie				atf_fail "8: No event triggered"
208272343Sngie			elif [ ${cnt} -gt ${expected_event} ] ; then
209272343Sngie				atf_fail "8: Multiple events triggered"
210272343Sngie			fi
211272343Sngie			evt=$( check_powerd_event ${cnt} "critical-under")
212272343Sngie			if [ -n "${evt}" ] ; then
213272343Sngie				atf_fail "8: ${evt}"
214272343Sngie			fi
215272343Sngie			expected_event=$(( 1 + ${expected_event} ))
216272343Sngie		fi
217272343Sngie
218272343Sngie	# Step 9 - verify that we return to normal state
219272343Sngie		if [ ${skip_events} -eq 0 ] ; then
220272343Sngie			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 + $5 ))
221272343Sngie			sleep 5
222272343Sngie			cnt=$(get_powerd_event_count)
223272343Sngie			if [ ${cnt} -lt ${expected_event} ] ; then
224272343Sngie				atf_fail "9: No event triggered"
225272343Sngie			elif [ ${cnt} -gt ${expected_event} ] ; then
226272343Sngie				atf_fail "9: Multiple events triggered"
227272343Sngie			fi
228272343Sngie			evt=$( check_powerd_event ${cnt} "normal")
229272343Sngie			if [ -n "${evt}" ] ; then
230272343Sngie				atf_fail "9: ${evt}"
231272343Sngie			fi
232272343Sngie			expected_event=$(( 1 + ${expected_event} ))
233272343Sngie		fi
234272343Sngie
235272343Sngie	# Step 10 - reset to defaults
236272343Sngie		rump.envstat -S
237272343Sngie		if [ $1 -eq 0 ] ; then
238272343Sngie			get_sensor_info | grep -q critical-min &&
239272343Sngie				atf_fail "10: Failed to clear a limit with envstat -S"
240272343Sngie		else
241272343Sngie			if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
242272343Sngie				atf_fail "10: Limit not reset to initial value"
243272343Sngie			fi
244272343Sngie		fi
245272343Sngie
246272343Sngie	# Step 11 - see if more events occur
247272343Sngie		if [ ${skip_events} -eq 0 ] ; then
248272343Sngie			rump.envstat -c env0.conf
249272343Sngie			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 ))
250272343Sngie			sleep 5
251272343Sngie			cnt=$(get_powerd_event_count)
252272343Sngie			if [ ${cnt} -ge ${expected_event} ] ; then
253272343Sngie				if [ $1 -ne 2 ] ; then
254272343Sngie					atf_fail "11b Event triggered after reset"
255272343Sngie				fi
256272343Sngie				evt=$( check_powerd_event ${cnt} "critical-under")
257272343Sngie				if [ -n "${evt}" ] ; then
258272343Sngie					atf_fail "11a: ${evt}"
259272343Sngie				fi
260272343Sngie			fi
261272343Sngie		fi
262272343Sngie
263272343Sngie	# Step 12 - make sure we can set new limits once more
264272343Sngie		rump.envstat -c env2.conf
265272343Sngie		if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
266272343Sngie			atf_fail "12a: Limit not reset to same value"
267272343Sngie		fi
268272343Sngie		rump.envstat -c env1.conf
269272343Sngie		if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then
270272343Sngie			atf_fail "12b: Limit not reset to new value"
271272343Sngie		fi
272272343Sngie	fi
273272343Sngie
274272343Sngie	# Step 13 - confirm registration (or lack thereof) with rndctl
275272343Sngie	rnd_bits=$( get_rnd_bits_count )
276272343Sngie	if [ $( expr \( 0$6 / 8192 \) % 2 ) -eq 1 ] ; then
277272343Sngie		if [ -z "$rnd_bits" ] ; then
278272343Sngie			atf_fail "13a: Not registered with rndctl"
279272343Sngie		fi
280272343Sngie	else
281272343Sngie		if [ -n "$rnd_bits" ] ; then
282272343Sngie			atf_fail "13b: Wrongly registered with rndctl"
283272343Sngie		fi
284272343Sngie	fi
285272343Sngie
286272343Sngie	# Steps 14 and 15 are only if sensor is providing entropy
287272343Sngie	if [ $( expr \( 0$6 / 8192 \) % 2 ) -ne 1 ] ; then
288272343Sngie		return
289272343Sngie	fi
290272343Sngie
291272343Sngie	# Step 14 - make sure entropy collected when device is being polled
292272343Sngie	rump.envstat -c env0.conf
293272343Sngie	rump.sysctl -w hw.swsensor.cur_value=$3
294272343Sngie	sleep 5
295272343Sngie	rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 ))
296272343Sngie	sleep 5
297272343Sngie	new_rnd_bits=$( get_rnd_bits_count )
298272343Sngie	if [ $new_rnd_bits -le $rnd_bits ] ; then
299272343Sngie		atf_expect_fail "PR kern/47661"
300272343Sngie		atf_fail "14a: entropy bits did not increase after polling"
301272343Sngie	fi
302272343Sngie	rnd_bits=$new_rnd_bits
303272343Sngie	sleep 5
304272343Sngie	new_rnd_bits=$( get_rnd_bits_count )
305272343Sngie	if [ $new_rnd_bits -gt $rnd_bits ] ; then
306272343Sngie		atf_expect_fail "PR kern/47661"
307272343Sngie		atf_fail "14b: entropy bits increased after poll with no value change"
308272343Sngie	fi
309272343Sngie
310272343Sngie	# Step 15 - make sure entropy collected when device is interrogated
311272343Sngie	# 
312272343Sngie	rump.envstat -c env0.conf
313272343Sngie	rump.sysctl -w hw.swsensor.cur_value=$3
314272343Sngie	get_sensor_key cur-value
315272343Sngie	rnd_bits=$( get_rnd_bits_count )
316272343Sngie	rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 ))
317272343Sngie	get_sensor_key cur-value
318272343Sngie	new_rnd_bits=$( get_rnd_bits_count )
319272343Sngie	if [ $new_rnd_bits -le $rnd_bits ] ; then
320272343Sngie		atf_expect_fail "PR kern/47661"
321272343Sngie		atf_fail "15a: entropy bits did not increase after interrogation"
322272343Sngie	fi
323272343Sngie	rnd_bits=$new_rnd_bits
324272343Sngie	get_sensor_key cur-value
325272343Sngie	new_rnd_bits=$( get_rnd_bits_count )
326272343Sngie	if [ $new_rnd_bits -gt $rnd_bits ] ; then
327272343Sngie		atf_expect_fail "PR kern/47661"
328272343Sngie		atf_fail "15b: entropy bits increased after interrogation with no value change"
329272343Sngie	fi
330272343Sngie}
331272343Sngie
332272343Sngieatf_test_case simple_sensor cleanup
333272343Sngiesimple_sensor_head() {
334272343Sngie	common_head "Test a simple sensor"
335272343Sngie}
336272343Sngie
337272343Sngiesimple_sensor_body() {
338272343Sngie	common_body 0 50 30 10 1
339272343Sngie}
340272343Sngie
341272343Sngiesimple_sensor_cleanup() {
342272343Sngie	common_cleanup
343272343Sngie}
344272343Sngie
345272343Sngieatf_test_case limit_sensor cleanup
346272343Sngielimit_sensor_head() {
347272343Sngie	common_head "Test a sensor with internal limit"
348272343Sngie}
349272343Sngie
350272343Sngielimit_sensor_body() {
351272343Sngie	common_body 1 45 25 8 2
352272343Sngie}
353272343Sngie
354272343Sngielimit_sensor_cleanup() {
355272343Sngie	common_cleanup
356272343Sngie}
357272343Sngie
358272343Sngieatf_test_case alarm_sensor cleanup
359272343Sngiealarm_sensor_head() {
360272343Sngie	common_head "Test a sensor with internal checking"
361272343Sngie}
362272343Sngie
363272343Sngiealarm_sensor_body() {
364272343Sngie	common_body 2 40 20 6 3
365272343Sngie}
366272343Sngie
367272343Sngiealarm_sensor_cleanup() {
368272343Sngie	common_cleanup
369272343Sngie}
370272343Sngie
371272343Sngieatf_test_case entropy_polled_sensor cleanup
372272343Sngieentropy_polled_sensor_head() {
373272343Sngie	common_head "Test a simple sensor that provides entropy"
374272343Sngie}
375272343Sngie
376272343Sngieentropy_polled_sensor_body() {
377272343Sngie	common_body 0 50 30 10 1 8192
378272343Sngie}
379272343Sngie
380272343Sngieentropy_polled_sensor_cleanup() {
381272343Sngie	common_cleanup
382272343Sngie}
383272343Sngie
384272343Sngieatf_test_case entropy_interrupt_sensor cleanup
385272343Sngieentropy_interrupt_sensor_head() {
386272343Sngie	common_head "Test a sensor that provides entropy without polling"
387272343Sngie}
388272343Sngie
389272343Sngieentropy_interrupt_sensor_body() {
390272343Sngie	common_body 0 50 30 10 1 10240
391272343Sngie}
392272343Sngie
393272343Sngieentropy_interrupt_sensor_cleanup() {
394272343Sngie	common_cleanup
395272343Sngie}
396272343Sngie
397272343Sngieatf_init_test_cases() {
398272343Sngie	RUMP_SERVER="unix://t_swsensor_socket" ; export RUMP_SERVER
399272343Sngie	atf_add_test_case simple_sensor
400272343Sngie	atf_add_test_case limit_sensor
401272343Sngie	atf_add_test_case alarm_sensor
402272343Sngie	atf_add_test_case entropy_polled_sensor
403272343Sngie	atf_add_test_case entropy_interrupt_sensor
404272343Sngie}
405