summaryrefslogtreecommitdiffstats
path: root/contrib/netbsd-tests/dev/sysmon/t_swsensor.sh
blob: 5b54431fad857587c64ea56794708ffae66b339e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
# $NetBSD: t_swsensor.sh,v 1.7 2013/04/14 16:07:46 martin Exp $

get_sensor_info() {
	rump.envstat -x | \
	sed -e "\;swsensor;,\;/array;p" -e "d"
}

get_sensor_key() {
	get_sensor_info | grep -A1 $1 | grep integer | sed -e 's;<[/a-z]*>;;g'
}

get_powerd_event_count() {
	grep "not running" powerd.log | wc -l
}

get_rnd_bits_count() {
	env RUMPHIJACK=blanket=/dev/random:/dev/urandom	\
	    RUMP_SERVER=unix://t_swsensor_socket	\
	    LD_PRELOAD=/usr/lib/librumphijack.so	  rndctl -l | \
	grep "swsensor-sensor" | \
	awk '{print $2}'
}

check_powerd_event() {
	event=$(grep "not running" powerd.log | \
		sed -e "$1p" -e "d" )
	event=${event##*//}
	script=${event%% *}
	event=${event#* }
	device=${event%% *}
	event=${event#* }
	state=${event%% *}
	sensor=${event#* }
	sensor=${sensor% *}

	if [ "${script}" != "sensor_indicator" ] ; then
		echo "Event uses wrong script: ${script}"
	elif [ "${device}" != "swsensor" ] ; then
		echo "Event uses wrong device: ${device}"
	elif [ "${sensor}" != "sensor" ] ; then
		echo "Event uses wrong sensor: ${sensor}"
	elif [ "${state}" != "$2" ] ; then
		echo "Event uses wrong state: ${state}"
	fi
}

# Start the rump server, then load the swsensor module with the
# requested properties

start_rump() {
	rump_allserver -l rumpvfs -l rumpdev -l rumpdev_sysmon ${RUMP_SERVER}
	if [ $( get_sensor_info | wc -l ) -ne 0 ] ; then
		rump.modunload swsensor
		rump.modload -f $1 swsensor
	else
		rump.modload $1 swsensor
	fi
	return $?
}

common_head() {
	atf_set	descr		"$1"
	atf_set	timeout		60
	atf_set	require.progs	rump.powerd rump.envstat rump.modload	\
				rump.halt   rump.sysctl  rump_server	\
				sed         grep         awk		\
				rndctl      expr
}

common_cleanup() {
	rump.modunload swsensor
	rump.halt
}

create_envsys_conf_files() {
	cat << ENV0 > env0.conf
	swsensor {
		refresh-timeout = 2s;
	}
ENV0
	cat << ENV1 > env1.conf
	swsensor {
		sensor0 { critical-min = $(( $1 - $2 )); }
	}
ENV1
	cat << ENV2 > env2.conf
	swsensor {
		sensor0 { critical-min = $1; }
	}
ENV2
}

# Test body common to all sensors
#	$1	sensor mode
#	$2	initial sensor value
#	$3	initial limit
#	$4	amount to lower limit
#	$5	difference from limit to trigger event
#	$6	sensor flags, for FHAS_ENTROPY and FMONNOTSUPP

common_body() {
	# Start the rump-server process and load the module
	modload_args="-i mode=$1 -i value=$2 -i limit=$3 ${6:+-i flags=$6}"
	start_rump "$modload_args"

	# create configuration files for updates
	create_envsys_conf_files $3 $4

	if [ $? -ne 0 ] ; then
		atf_skip "Cannot set-up rump environment"
	fi

	# start powerd so we can detect sensor events
	rump.powerd -n -d > powerd.log 2>&1 &
	if [ -z "$(jobs)" ] ; then
		skip_events=1
		echo "Skipping event sub-tests - powerd did not start"
	else
		skip_events=0
		expected_event=1
	fi

	# Step 0 - verify that sensor is registered
	get_sensor_info | grep -q swsensor ||
		atf_fail "0: Device swsensor not registered"

	# Step 1 - update the refresh-timeout and verify
	# (use $(( ... )) since the timeout is displayed in hex!)
	rump.envstat -c env0.conf
	if [ $(( $( get_sensor_key refresh-timeout ) )) -ne 2 ] ; then
		atf_fail "1: Could not set refresh-timout to 2s"
	fi

	# Step 2 - verify that we can read sensor's value
	if [ $1 -ne 0 -a $( get_sensor_key cur-value ) -ne $2 ] ; then
		atf_fail "2: Value not available"
	fi

	# Step 3 - verify that changes in sensor value are seen
	rump.sysctl -w hw.swsensor.cur_value=$(( $2 + 1 ))
	if [ $( get_sensor_key cur-value ) -ne $(( $2 + 1 )) ] ; then
		atf_fail "3: Value not updated"
	fi

	# Step 4 - if sensor provides hw limit, make sure we can read it
	if [ $1 -ne 0 ] ; then
		if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
			atf_fail "4: Limit not set by device"
		fi
	fi

	# Step 5 - if sensor provides hw limit, make sure it works
	if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then
		rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $5 ))
		sleep 5
		cnt=$(get_powerd_event_count)
		if [ ${cnt} -lt ${expected_event} ] ; then
			atf_fail "5: No event triggered"
		elif [ ${cnt} -gt ${expected_event} ] ; then
			atf_fail "5: Multiple events triggered"
		fi
		evt=$( check_powerd_event ${cnt} "critical-under")
		if [ -n "${evt}" ] ; then
			atf_fail "5: ${evt}"
		fi
		expected_event=$(( 1 + ${expected_event} ))
	fi

	# Step 6 - verify that we return to normal state
	if [ $1 -ne 0 -a ${skip_events} -eq 0 ] ; then
		rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $5 ))
		sleep 5
		cnt=$(get_powerd_event_count)
		if [ ${cnt} -lt ${expected_event} ] ; then
			atf_fail "6: No event triggered"
		elif [ ${cnt} -gt ${expected_event} ] ; then
			atf_fail "6: Multiple events triggered"
		fi
		evt=$( check_powerd_event ${cnt} "normal")
		if [ -n "${evt}" ] ; then
			atf_fail "6: ${evt}"
		fi
		expected_event=$(( 1 + ${expected_event} ))
	fi

	# Step 7 - verify that we can set our own limit

	# Steps 7 thru 12 are skipped if the sensor cannot be monitored
	if [ $( expr \( 0$6 / 2048 \) % 2 ) -ne 1 ] ; then
		rump.envstat -c env1.conf
		if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then
			atf_fail "7: Limit not set by envstat -c"
		fi

	# Step 8 - make sure user-set limit works
		if [ ${skip_events} -eq 0 ] ; then
			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 ))
			sleep 5
			cnt=$(get_powerd_event_count)
			if [ ${cnt} -lt ${expected_event} ] ; then
				atf_fail "8: No event triggered"
			elif [ ${cnt} -gt ${expected_event} ] ; then
				atf_fail "8: Multiple events triggered"
			fi
			evt=$( check_powerd_event ${cnt} "critical-under")
			if [ -n "${evt}" ] ; then
				atf_fail "8: ${evt}"
			fi
			expected_event=$(( 1 + ${expected_event} ))
		fi

	# Step 9 - verify that we return to normal state
		if [ ${skip_events} -eq 0 ] ; then
			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 + $5 ))
			sleep 5
			cnt=$(get_powerd_event_count)
			if [ ${cnt} -lt ${expected_event} ] ; then
				atf_fail "9: No event triggered"
			elif [ ${cnt} -gt ${expected_event} ] ; then
				atf_fail "9: Multiple events triggered"
			fi
			evt=$( check_powerd_event ${cnt} "normal")
			if [ -n "${evt}" ] ; then
				atf_fail "9: ${evt}"
			fi
			expected_event=$(( 1 + ${expected_event} ))
		fi

	# Step 10 - reset to defaults
		rump.envstat -S
		if [ $1 -eq 0 ] ; then
			get_sensor_info | grep -q critical-min &&
				atf_fail "10: Failed to clear a limit with envstat -S"
		else
			if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
				atf_fail "10: Limit not reset to initial value"
			fi
		fi

	# Step 11 - see if more events occur
		if [ ${skip_events} -eq 0 ] ; then
			rump.envstat -c env0.conf
			rump.sysctl -w hw.swsensor.cur_value=$(( $3 - $4 - $5 ))
			sleep 5
			cnt=$(get_powerd_event_count)
			if [ ${cnt} -ge ${expected_event} ] ; then
				if [ $1 -ne 2 ] ; then
					atf_fail "11b Event triggered after reset"
				fi
				evt=$( check_powerd_event ${cnt} "critical-under")
				if [ -n "${evt}" ] ; then
					atf_fail "11a: ${evt}"
				fi
			fi
		fi

	# Step 12 - make sure we can set new limits once more
		rump.envstat -c env2.conf
		if [ $( get_sensor_key critical-min ) -ne $3 ] ; then
			atf_fail "12a: Limit not reset to same value"
		fi
		rump.envstat -c env1.conf
		if [ $( get_sensor_key critical-min ) -ne $(( $3 - $4 )) ] ; then
			atf_fail "12b: Limit not reset to new value"
		fi
	fi

	# Step 13 - confirm registration (or lack thereof) with rndctl
	rnd_bits=$( get_rnd_bits_count )
	if [ $( expr \( 0$6 / 8192 \) % 2 ) -eq 1 ] ; then
		if [ -z "$rnd_bits" ] ; then
			atf_fail "13a: Not registered with rndctl"
		fi
	else
		if [ -n "$rnd_bits" ] ; then
			atf_fail "13b: Wrongly registered with rndctl"
		fi
	fi

	# Steps 14 and 15 are only if sensor is providing entropy
	if [ $( expr \( 0$6 / 8192 \) % 2 ) -ne 1 ] ; then
		return
	fi

	# Step 14 - make sure entropy collected when device is being polled
	rump.envstat -c env0.conf
	rump.sysctl -w hw.swsensor.cur_value=$3
	sleep 5
	rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 ))
	sleep 5
	new_rnd_bits=$( get_rnd_bits_count )
	if [ $new_rnd_bits -le $rnd_bits ] ; then
		atf_expect_fail "PR kern/47661"
		atf_fail "14a: entropy bits did not increase after polling"
	fi
	rnd_bits=$new_rnd_bits
	sleep 5
	new_rnd_bits=$( get_rnd_bits_count )
	if [ $new_rnd_bits -gt $rnd_bits ] ; then
		atf_expect_fail "PR kern/47661"
		atf_fail "14b: entropy bits increased after poll with no value change"
	fi

	# Step 15 - make sure entropy collected when device is interrogated
	# 
	rump.envstat -c env0.conf
	rump.sysctl -w hw.swsensor.cur_value=$3
	get_sensor_key cur-value
	rnd_bits=$( get_rnd_bits_count )
	rump.sysctl -w hw.swsensor.cur_value=$(( $3 + $4 ))
	get_sensor_key cur-value
	new_rnd_bits=$( get_rnd_bits_count )
	if [ $new_rnd_bits -le $rnd_bits ] ; then
		atf_expect_fail "PR kern/47661"
		atf_fail "15a: entropy bits did not increase after interrogation"
	fi
	rnd_bits=$new_rnd_bits
	get_sensor_key cur-value
	new_rnd_bits=$( get_rnd_bits_count )
	if [ $new_rnd_bits -gt $rnd_bits ] ; then
		atf_expect_fail "PR kern/47661"
		atf_fail "15b: entropy bits increased after interrogation with no value change"
	fi
}

atf_test_case simple_sensor cleanup
simple_sensor_head() {
	common_head "Test a simple sensor"
}

simple_sensor_body() {
	common_body 0 50 30 10 1
}

simple_sensor_cleanup() {
	common_cleanup
}

atf_test_case limit_sensor cleanup
limit_sensor_head() {
	common_head "Test a sensor with internal limit"
}

limit_sensor_body() {
	common_body 1 45 25 8 2
}

limit_sensor_cleanup() {
	common_cleanup
}

atf_test_case alarm_sensor cleanup
alarm_sensor_head() {
	common_head "Test a sensor with internal checking"
}

alarm_sensor_body() {
	common_body 2 40 20 6 3
}

alarm_sensor_cleanup() {
	common_cleanup
}

atf_test_case entropy_polled_sensor cleanup
entropy_polled_sensor_head() {
	common_head "Test a simple sensor that provides entropy"
}

entropy_polled_sensor_body() {
	common_body 0 50 30 10 1 8192
}

entropy_polled_sensor_cleanup() {
	common_cleanup
}

atf_test_case entropy_interrupt_sensor cleanup
entropy_interrupt_sensor_head() {
	common_head "Test a sensor that provides entropy without polling"
}

entropy_interrupt_sensor_body() {
	common_body 0 50 30 10 1 10240
}

entropy_interrupt_sensor_cleanup() {
	common_cleanup
}

atf_init_test_cases() {
	RUMP_SERVER="unix://t_swsensor_socket" ; export RUMP_SERVER
	atf_add_test_case simple_sensor
	atf_add_test_case limit_sensor
	atf_add_test_case alarm_sensor
	atf_add_test_case entropy_polled_sensor
	atf_add_test_case entropy_interrupt_sensor
}
OpenPOWER on IntegriCloud