t_swsensor.sh revision 313498
1# $NetBSD: t_swsensor.sh,v 1.9 2015/04/23 23:23:28 pgoyette Exp $
2
3get_sensor_info() {
4	rump.envstat -x | \
5	sed -e "\;swsensor;,\;/array;p" -e "d"
6}
7
8get_sensor_key() {
9	local v
10	v=$(get_sensor_info | grep -A1 $1 | grep integer | \
11	    sed -e 's;<[/a-z]*>;;g')
12	if [ -z "$v" ] ; then
13		v="key_$1_not_found"
14	fi
15	echo $v
16}
17
18get_powerd_event_count() {
19	grep "not running" powerd.log | wc -l
20}
21
22get_rnd_bits_count() {
23	env RUMPHIJACK=blanket=/dev/random:/dev/urandom	\
24	    RUMP_SERVER=unix://t_swsensor_socket	\
25	    LD_PRELOAD=/usr/lib/librumphijack.so	  rndctl -l | \
26	grep "swsensor-sensor" | \
27	awk '{print $2}'
28}
29
30check_powerd_event() {
31	event=$(grep "not running" powerd.log | \
32		sed -e "$1p" -e "d" )
33	event=${event##*//}
34	script=${event%% *}
35	event=${event#* }
36	device=${event%% *}
37	event=${event#* }
38	state=${event%% *}
39	sensor=${event#* }
40	sensor=${sensor% *}
41
42	if [ "${script}" != "sensor_indicator" ] ; then
43		echo "Event uses wrong script: ${script}"
44	elif [ "${device}" != "swsensor" ] ; then
45		echo "Event uses wrong device: ${device}"
46	elif [ "${sensor}" != "sensor" ] ; then
47		echo "Event uses wrong sensor: ${sensor}"
48	elif [ "${state}" != "$2" ] ; then
49		echo "Event uses wrong state: ${state}"
50	fi
51}
52
53# Start the rump server, then load the swsensor module with the
54# requested properties
55
56start_rump() {
57	rump_allserver -l rumpvfs -l rumpdev -l rumpdev_sysmon ${RUMP_SERVER}
58	if [ $( get_sensor_info | wc -l ) -ne 0 ] ; then
59		rump.modunload swsensor
60		rump.modload -f $1 swsensor
61	else
62		rump.modload $1 swsensor
63	fi
64	return $?
65}
66
67common_head() {
68	atf_set	descr		"$1"
69	atf_set	timeout		120
70	atf_set	require.progs	rump.powerd rump.envstat rump.modload	\
71				rump.halt   rump.sysctl  rump_server	\
72				sed         grep         awk		\
73				rndctl      expr
74}
75
76common_cleanup() {
77	rump.modunload swsensor
78	rump.halt
79}
80
81create_envsys_conf_files() {
82	cat << ENV0 > env0.conf
83	swsensor {
84		refresh-timeout = 2s;
85	}
86ENV0
87	cat << ENV1 > env1.conf
88	swsensor {
89		sensor0 { critical-min = $(( $1 - $2 )); }
90	}
91ENV1
92	cat << ENV2 > env2.conf
93	swsensor {
94		sensor0 { critical-min = $1; }
95	}
96ENV2
97}
98
99# Test body common to all sensors
100#	$1	sensor mode
101#	$2	initial sensor value
102#	$3	initial limit
103#	$4	amount to lower limit
104#	$5	difference from limit to trigger event
105#	$6	sensor flags, for FHAS_ENTROPY and FMONNOTSUPP
106
107common_body() {
108	# Start the rump-server process and load the module
109	modload_args="-i mode=$1 -i value=$2 -i limit=$3 ${6:+-i flags=$6}"
110	start_rump "$modload_args"
111
112	# create configuration files for updates
113	create_envsys_conf_files $3 $4
114
115	if [ $? -ne 0 ] ; then
116		atf_skip "Cannot set-up rump environment"
117	fi
118
119	# start powerd so we can detect sensor events
120	rump.powerd -n -d > powerd.log 2>&1 &
121	if [ -z "$(jobs)" ] ; then
122		skip_events=1
123		echo "Skipping event sub-tests - powerd did not start"
124	else
125		skip_events=0
126		expected_event=1
127	fi
128
129	# Step 0 - verify that sensor is registered
130	get_sensor_info | grep -q swsensor ||
131		atf_fail "0: Device swsensor not registered"
132
133	# Step 1 - update the refresh-timeout and verify
134	# (use $(( ... )) since the timeout is displayed in hex!)
135	rump.envstat -c env0.conf
136	if [ $(( $( get_sensor_key refresh-timeout ) )) -ne 2 ] ; then
137		atf_fail "1: Could not set refresh-timout to 2s"
138	fi
139
140	# Step 2 - verify that we can read sensor's value
141	if [ $1 -ne 0 -a $( get_sensor_key cur-value ) -ne $2 ] ; then
142		atf_fail "2: Value not available"
143	fi
144
145	# Step 3 - verify that changes in sensor value are seen
146	rump.sysctl -w hw.swsensor.cur_value=$(( $2 + 1 ))
147	if [ $( get_sensor_key cur-value ) -ne $(( $2 + 1 )) ] ; then
148		atf_fail "3: Value not updated"
149	fi
150
151	# Step 4 - if sensor provides hw limit, make sure we can read it
152	if [ $1 -ne 0 ] ; then
153		if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
154			atf_fail "4: Limit not set by device"
155		fi
156	fi
157
158	# Step 5 - if sensor provides hw limit, make sure it works
159	if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then
160		rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $5 ))
161		sleep 5
162		cnt=$(get_powerd_event_count)
163		if [ ${cnt} -lt ${expected_event} ] ; then
164			atf_fail "5: No event triggered"
165		elif [ ${cnt} -gt ${expected_event} ] ; then
166			atf_fail "5: Multiple events triggered"
167		fi
168		evt=$( check_powerd_event ${cnt} "critical-under")
169		if [ -n "${evt}" ] ; then
170			atf_fail "5: ${evt}"
171		fi
172		expected_event=$(( 1 + ${expected_event} ))
173	fi
174
175	# Step 6 - verify that we return to normal state
176	if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then
177		rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $5 ))
178		sleep 5
179		cnt=$(get_powerd_event_count)
180		if [ ${cnt} -lt ${expected_event} ] ; then
181			atf_fail "6: No event triggered"
182		elif [ ${cnt} -gt ${expected_event} ] ; then
183			atf_fail "6: Multiple events triggered"
184		fi
185		evt=$( check_powerd_event ${cnt} "normal")
186		if [ -n "${evt}" ] ; then
187			atf_fail "6: ${evt}"
188		fi
189		expected_event=$(( 1 + ${expected_event} ))
190	fi
191
192	# Step 7 - verify that we can set our own limit
193
194	# Steps 7 thru 12 are skipped if the sensor cannot be monitored
195	if [ $( expr \( 0$6 / 2048 \) % 2 ) -ne 1 ] ; then
196		rump.envstat -c env1.conf
197		if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then
198			atf_fail "7: Limit not set by envstat -c"
199		fi
200
201	# Step 8 - make sure user-set limit works
202		if [ ${skip_events} -eq 0 ] ; then
203			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 ))
204			sleep 5
205			cnt=$(get_powerd_event_count)
206			if [ ${cnt} -lt ${expected_event} ] ; then
207				atf_fail "8: No event triggered"
208			elif [ ${cnt} -gt ${expected_event} ] ; then
209				atf_fail "8: Multiple events triggered"
210			fi
211			evt=$( check_powerd_event ${cnt} "critical-under")
212			if [ -n "${evt}" ] ; then
213				atf_fail "8: ${evt}"
214			fi
215			expected_event=$(( 1 + ${expected_event} ))
216		fi
217
218	# Step 9 - verify that we return to normal state
219		if [ ${skip_events} -eq 0 ] ; then
220			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 + $5 ))
221			sleep 5
222			cnt=$(get_powerd_event_count)
223			if [ ${cnt} -lt ${expected_event} ] ; then
224				atf_fail "9: No event triggered"
225			elif [ ${cnt} -gt ${expected_event} ] ; then
226				atf_fail "9: Multiple events triggered"
227			fi
228			evt=$( check_powerd_event ${cnt} "normal")
229			if [ -n "${evt}" ] ; then
230				atf_fail "9: ${evt}"
231			fi
232			expected_event=$(( 1 + ${expected_event} ))
233		fi
234
235	# Step 10 - reset to defaults
236		rump.envstat -S
237		if [ $1 -eq 0 ] ; then
238			get_sensor_info | grep -q critical-min &&
239				atf_fail "10: Failed to clear a limit with envstat -S"
240		else
241			if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
242				atf_fail "10: Limit not reset to initial value"
243			fi
244		fi
245
246	# Step 11 - see if more events occur
247		if [ ${skip_events} -eq 0 ] ; then
248			rump.envstat -c env0.conf
249			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 ))
250			sleep 5
251			cnt=$(get_powerd_event_count)
252			if [ ${cnt} -ge ${expected_event} ] ; then
253				if [ $1 -ne 2 ] ; then
254					atf_fail "11b Event triggered after reset"
255				fi
256				evt=$( check_powerd_event ${cnt} "critical-under")
257				if [ -n "${evt}" ] ; then
258					atf_fail "11a: ${evt}"
259				fi
260			fi
261		fi
262
263	# Step 12 - make sure we can set new limits once more
264		rump.envstat -c env2.conf
265		if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
266			atf_fail "12a: Limit not reset to same value"
267		fi
268		rump.envstat -c env1.conf
269		if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then
270			atf_fail "12b: Limit not reset to new value"
271		fi
272	fi
273
274	# Step 13 - confirm registration (or lack thereof) with rndctl
275	rnd_bits=$( get_rnd_bits_count )
276	if [ $( expr \( 0$6 / 8192 \) % 2 ) -eq 1 ] ; then
277		if [ -z "$rnd_bits" ] ; then
278			atf_fail "13a: Not registered with rndctl"
279		fi
280	else
281		if [ -n "$rnd_bits" ] ; then
282			atf_fail "13b: Wrongly registered with rndctl"
283		fi
284	fi
285
286	# Steps 14 and 15 are only if sensor is providing entropy
287	if [ $( expr \( 0$6 / 8192 \) % 2 ) -ne 1 ] ; then
288		return
289	fi
290
291	# Step 14 - make sure entropy collected when device is being polled
292	rump.envstat -c env0.conf
293	rump.sysctl -w hw.swsensor.cur_value=$3
294	sleep 5
295	rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 ))
296	sleep 5
297	new_rnd_bits=$( get_rnd_bits_count )
298	if [ $new_rnd_bits -le $rnd_bits ] ; then
299		atf_expect_fail "PR kern/47661"
300		atf_fail "14a: entropy bits did not increase after polling"
301	fi
302	rnd_bits=$new_rnd_bits
303	sleep 5
304	new_rnd_bits=$( get_rnd_bits_count )
305	if [ $new_rnd_bits -gt $rnd_bits ] ; then
306		atf_expect_fail "PR kern/47661"
307		atf_fail "14b: entropy bits increased after poll with no value change"
308	fi
309
310	# Step 15 - make sure entropy collected when device is interrogated
311	# 
312	rump.envstat -c env0.conf
313	rump.sysctl -w hw.swsensor.cur_value=$3
314	get_sensor_key cur-value
315	rnd_bits=$( get_rnd_bits_count )
316	rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 ))
317	get_sensor_key cur-value
318	new_rnd_bits=$( get_rnd_bits_count )
319	if [ $new_rnd_bits -le $rnd_bits ] ; then
320		atf_expect_fail "PR kern/47661"
321		atf_fail "15a: entropy bits did not increase after interrogation"
322	fi
323	rnd_bits=$new_rnd_bits
324	get_sensor_key cur-value
325	new_rnd_bits=$( get_rnd_bits_count )
326	if [ $new_rnd_bits -gt $rnd_bits ] ; then
327		atf_expect_fail "PR kern/47661"
328		atf_fail "15b: entropy bits increased after interrogation with no value change"
329	fi
330}
331
332atf_test_case simple_sensor cleanup
333simple_sensor_head() {
334	common_head "Test a simple sensor"
335}
336
337simple_sensor_body() {
338	common_body 0 50 30 10 1
339}
340
341simple_sensor_cleanup() {
342	common_cleanup
343}
344
345atf_test_case limit_sensor cleanup
346limit_sensor_head() {
347	common_head "Test a sensor with internal limit"
348}
349
350limit_sensor_body() {
351	common_body 1 45 25 8 2
352}
353
354limit_sensor_cleanup() {
355	common_cleanup
356}
357
358atf_test_case alarm_sensor cleanup
359alarm_sensor_head() {
360	common_head "Test a sensor with internal checking"
361}
362
363alarm_sensor_body() {
364	common_body 2 40 20 6 3
365}
366
367alarm_sensor_cleanup() {
368	common_cleanup
369}
370
371atf_test_case entropy_polled_sensor cleanup
372entropy_polled_sensor_head() {
373	common_head "Test a simple sensor that provides entropy"
374}
375
376entropy_polled_sensor_body() {
377	common_body 0 50 30 10 1 8192
378}
379
380entropy_polled_sensor_cleanup() {
381	common_cleanup
382}
383
384atf_test_case entropy_interrupt_sensor cleanup
385entropy_interrupt_sensor_head() {
386	common_head "Test a sensor that provides entropy without polling"
387}
388
389entropy_interrupt_sensor_body() {
390	common_body 0 50 30 10 1 10240
391}
392
393entropy_interrupt_sensor_cleanup() {
394	common_cleanup
395}
396
397atf_init_test_cases() {
398	RUMP_SERVER="unix://t_swsensor_socket" ; export RUMP_SERVER
399	atf_add_test_case simple_sensor
400	atf_add_test_case limit_sensor
401	atf_add_test_case alarm_sensor
402	atf_add_test_case entropy_polled_sensor
403	atf_add_test_case entropy_interrupt_sensor
404}
405