1#!/bin/bash
2# daemon operations
3# SPDX-License-Identifier: GPL-2.0
4
5check_line_first()
6{
7	local line=$1
8	local name=$2
9	local base=$3
10	local output=$4
11	local lock=$5
12	local up=$6
13
14	local line_name
15	line_name=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $2 }'`
16	local line_base
17	line_base=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $3 }'`
18	local line_output
19	line_output=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $4 }'`
20	local line_lock
21	line_lock=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $5 }'`
22	local line_up
23	line_up=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $6 }'`
24
25	if [ "${name}" != "${line_name}" ]; then
26		echo "FAILED: wrong name"
27		error=1
28	fi
29
30	if [ "${base}" != "${line_base}" ]; then
31		echo "FAILED: wrong base"
32		error=1
33	fi
34
35	if [ "${output}" != "${line_output}" ]; then
36		echo "FAILED: wrong output"
37		error=1
38	fi
39
40	if [ "${lock}" != "${line_lock}" ]; then
41		echo "FAILED: wrong lock"
42		error=1
43	fi
44
45	if [ "${up}" != "${line_up}" ]; then
46		echo "FAILED: wrong up"
47		error=1
48	fi
49}
50
51check_line_other()
52{
53	local line=$1
54	local name=$2
55	local run=$3
56	local base=$4
57	local output=$5
58	local control=$6
59	local ack=$7
60	local up=$8
61
62	local line_name
63	line_name=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $2 }'`
64	local line_run
65	line_run=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $3 }'`
66	local line_base
67	line_base=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $4 }'`
68	local line_output
69	line_output=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $5 }'`
70	local line_control
71	line_control=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $6 }'`
72	local line_ack
73	line_ack=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $7 }'`
74	local line_up
75	line_up=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $8 }'`
76
77	if [ "${name}" != "${line_name}" ]; then
78		echo "FAILED: wrong name"
79		error=1
80	fi
81
82	if [ "${run}" != "${line_run}" ]; then
83		echo "FAILED: wrong run"
84		error=1
85	fi
86
87	if [ "${base}" != "${line_base}" ]; then
88		echo "FAILED: wrong base"
89		error=1
90	fi
91
92	if [ "${output}" != "${line_output}" ]; then
93		echo "FAILED: wrong output"
94		error=1
95	fi
96
97	if [ "${control}" != "${line_control}" ]; then
98		echo "FAILED: wrong control"
99		error=1
100	fi
101
102	if [ "${ack}" != "${line_ack}" ]; then
103		echo "FAILED: wrong ack"
104		error=1
105	fi
106
107	if [ "${up}" != "${line_up}" ]; then
108		echo "FAILED: wrong up"
109		error=1
110	fi
111}
112
113daemon_exit()
114{
115	local config=$1
116
117	local line
118	line=`perf daemon --config ${config} -x: | head -1`
119	local pid
120	pid=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $1 }'`
121
122	# Reset trap handler.
123	trap - SIGINT SIGTERM
124
125	# stop daemon
126	perf daemon stop --config ${config}
127
128	# ... and wait for the pid to go away
129	tail --pid=${pid} -f /dev/null
130}
131
132daemon_start()
133{
134	local config=$1
135	local session=$2
136
137	perf daemon start --config ${config}
138
139	# Clean up daemon if interrupted.
140	trap 'echo "FAILED: Signal caught"; daemon_exit "${config}"; exit 1' SIGINT SIGTERM
141
142	# wait for the session to ping
143	local state="FAIL"
144	local retries=0
145	while [ "${state}" != "OK" ]; do
146		state=`perf daemon ping --config ${config} --session ${session} | awk '{ print $1 }'`
147		sleep 0.05
148		retries=$((${retries} +1))
149		if [ ${retries} -ge 600 ]; then
150			echo "FAILED: Timeout waiting for daemon to ping"
151			daemon_exit ${config}
152			exit 1
153		fi
154	done
155}
156
157test_list()
158{
159	echo "test daemon list"
160
161	local config
162	config=$(mktemp /tmp/perf.daemon.config.XXX)
163	local base
164	base=$(mktemp -d /tmp/perf.daemon.base.XXX)
165
166	cat <<EOF > ${config}
167[daemon]
168base=BASE
169
170[session-size]
171run = -e cpu-clock -m 1 sleep 10
172
173[session-time]
174run = -e task-clock -m 1 sleep 10
175EOF
176
177	sed -i -e "s|BASE|${base}|" ${config}
178
179	# start daemon
180	daemon_start ${config} size
181
182	# check first line
183	# pid:daemon:base:base/output:base/lock
184	local line
185	line=`perf daemon --config ${config} -x: | head -1`
186	check_line_first ${line} daemon ${base} ${base}/output ${base}/lock "0"
187
188	# check 1st session
189	# pid:size:-e cpu-clock:base/size:base/size/output:base/size/control:base/size/ack:0
190	local line
191	line=`perf daemon --config ${config} -x: | head -2 | tail -1`
192	check_line_other "${line}" size "-e cpu-clock -m 1 sleep 10" ${base}/session-size \
193			 ${base}/session-size/output ${base}/session-size/control \
194			 ${base}/session-size/ack "0"
195
196	# check 2nd session
197	# pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
198	local line
199	line=`perf daemon --config ${config} -x: | head -3 | tail -1`
200	check_line_other "${line}" time "-e task-clock -m 1 sleep 10" ${base}/session-time \
201			 ${base}/session-time/output ${base}/session-time/control \
202			 ${base}/session-time/ack "0"
203
204	# stop daemon
205	daemon_exit ${config}
206
207	rm -rf ${base}
208	rm -f ${config}
209}
210
211test_reconfig()
212{
213	echo "test daemon reconfig"
214
215	local config
216	config=$(mktemp /tmp/perf.daemon.config.XXX)
217	local base
218	base=$(mktemp -d /tmp/perf.daemon.base.XXX)
219
220	# prepare config
221	cat <<EOF > ${config}
222[daemon]
223base=BASE
224
225[session-size]
226run = -e cpu-clock -m 1 sleep 10
227
228[session-time]
229run = -e task-clock -m 1 sleep 10
230EOF
231
232	sed -i -e "s|BASE|${base}|" ${config}
233
234	# start daemon
235	daemon_start ${config} size
236
237	# check 2nd session
238	# pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
239	local line
240	line=`perf daemon --config ${config} -x: | head -3 | tail -1`
241	check_line_other "${line}" time "-e task-clock -m 1 sleep 10" ${base}/session-time \
242			 ${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0"
243	local pid
244	pid=`echo "${line}" | awk 'BEGIN { FS = ":" } ; { print $1 }'`
245
246	# prepare new config
247	local config_new=${config}.new
248	cat <<EOF > ${config_new}
249[daemon]
250base=BASE
251
252[session-size]
253run = -e cpu-clock -m 1 sleep 10
254
255[session-time]
256run = -e cpu-clock -m 1 sleep 10
257EOF
258
259	# TEST 1 - change config
260
261	sed -i -e "s|BASE|${base}|" ${config_new}
262	cp ${config_new} ${config}
263
264	# wait for old session to finish
265	tail --pid=${pid} -f /dev/null
266
267	# wait for new one to start
268	local state="FAIL"
269	while [ "${state}" != "OK" ]; do
270		state=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'`
271	done
272
273	# check reconfigured 2nd session
274	# pid:time:-e task-clock:base/time:base/time/output:base/time/control:base/time/ack:0
275	local line
276	line=`perf daemon --config ${config} -x: | head -3 | tail -1`
277	check_line_other "${line}" time "-e cpu-clock -m 1 sleep 10" ${base}/session-time \
278			 ${base}/session-time/output ${base}/session-time/control ${base}/session-time/ack "0"
279
280	# TEST 2 - empty config
281
282	local config_empty=${config}.empty
283	cat <<EOF > ${config_empty}
284[daemon]
285base=BASE
286EOF
287
288	# change config
289	sed -i -e "s|BASE|${base}|" ${config_empty}
290	cp ${config_empty} ${config}
291
292	# wait for sessions to finish
293	local state="OK"
294	while [ "${state}" != "FAIL" ]; do
295		state=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'`
296	done
297
298	local state="OK"
299	while [ "${state}" != "FAIL" ]; do
300		state=`perf daemon ping --config ${config} --session size | awk '{ print $1 }'`
301	done
302
303	local one
304	one=`perf daemon --config ${config} -x: | wc -l`
305
306	if [ ${one} -ne "1" ]; then
307		echo "FAILED: wrong list output"
308		error=1
309	fi
310
311	# TEST 3 - config again
312
313	cp ${config_new} ${config}
314
315	# wait for size to start
316	local state="FAIL"
317	while [ "${state}" != "OK" ]; do
318		state=`perf daemon ping --config ${config} --session size | awk '{ print $1 }'`
319	done
320
321	# wait for time to start
322	local state="FAIL"
323	while [ "${state}" != "OK" ]; do
324		state=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'`
325	done
326
327	# stop daemon
328	daemon_exit ${config}
329
330	rm -rf ${base}
331	rm -f ${config}
332	rm -f ${config_new}
333	rm -f ${config_empty}
334}
335
336test_stop()
337{
338	echo "test daemon stop"
339
340	local config
341	config=$(mktemp /tmp/perf.daemon.config.XXX)
342	local base
343	base=$(mktemp -d /tmp/perf.daemon.base.XXX)
344
345	# prepare config
346	cat <<EOF > ${config}
347[daemon]
348base=BASE
349
350[session-size]
351run = -e cpu-clock -m 1 sleep 10
352
353[session-time]
354run = -e task-clock -m 1 sleep 10
355EOF
356
357	sed -i -e "s|BASE|${base}|" ${config}
358
359	# start daemon
360	daemon_start ${config} size
361
362	local pid_size
363	pid_size=`perf daemon --config ${config} -x: | head -2 | tail -1 |
364		  awk 'BEGIN { FS = ":" } ; { print $1 }'`
365	local pid_time
366	pid_time=`perf daemon --config ${config} -x: | head -3 | tail -1 |
367		  awk 'BEGIN { FS = ":" } ; { print $1 }'`
368
369	# check that sessions are running
370	if [ ! -d "/proc/${pid_size}" ]; then
371		echo "FAILED: session size not up"
372	fi
373
374	if [ ! -d "/proc/${pid_time}" ]; then
375		echo "FAILED: session time not up"
376	fi
377
378	# stop daemon
379	daemon_exit ${config}
380
381	# check that sessions are gone
382	if [ -d "/proc/${pid_size}" ]; then
383		echo "FAILED: session size still up"
384	fi
385
386	if [ -d "/proc/${pid_time}" ]; then
387		echo "FAILED: session time still up"
388	fi
389
390	rm -rf ${base}
391	rm -f ${config}
392}
393
394test_signal()
395{
396	echo "test daemon signal"
397
398	local config
399	config=$(mktemp /tmp/perf.daemon.config.XXX)
400	local base
401	base=$(mktemp -d /tmp/perf.daemon.base.XXX)
402
403	# prepare config
404	cat <<EOF > ${config}
405[daemon]
406base=BASE
407
408[session-test]
409run = -e cpu-clock --switch-output -m 1 sleep 10
410EOF
411
412	sed -i -e "s|BASE|${base}|" ${config}
413
414	# start daemon
415	daemon_start ${config} test
416
417	# send 2 signals
418	perf daemon signal --config ${config} --session test
419	perf daemon signal --config ${config}
420
421	# stop daemon
422	daemon_exit ${config}
423
424	# count is 2 perf.data for signals and 1 for perf record finished
425	count=`ls ${base}/session-test/*perf.data* | wc -l`
426	if [ ${count} -ne 3 ]; then
427		error=1
428		echo "FAILED: perf data no generated"
429	fi
430
431	rm -rf ${base}
432	rm -f ${config}
433}
434
435test_ping()
436{
437	echo "test daemon ping"
438
439	local config
440	config=$(mktemp /tmp/perf.daemon.config.XXX)
441	local base
442	base=$(mktemp -d /tmp/perf.daemon.base.XXX)
443
444	# prepare config
445	cat <<EOF > ${config}
446[daemon]
447base=BASE
448
449[session-size]
450run = -e cpu-clock -m 1 sleep 10
451
452[session-time]
453run = -e task-clock -m 1 sleep 10
454EOF
455
456	sed -i -e "s|BASE|${base}|" ${config}
457
458	# start daemon
459	daemon_start ${config} size
460
461	size=`perf daemon ping --config ${config} --session size | awk '{ print $1 }'`
462	type=`perf daemon ping --config ${config} --session time | awk '{ print $1 }'`
463
464	if [ ${size} != "OK" ] || [ ${type} != "OK" ]; then
465		error=1
466		echo "FAILED: daemon ping failed"
467	fi
468
469	# stop daemon
470	daemon_exit ${config}
471
472	rm -rf ${base}
473	rm -f ${config}
474}
475
476test_lock()
477{
478	echo "test daemon lock"
479
480	local config
481	config=$(mktemp /tmp/perf.daemon.config.XXX)
482	local base
483	base=$(mktemp -d /tmp/perf.daemon.base.XXX)
484
485	# prepare config
486	cat <<EOF > ${config}
487[daemon]
488base=BASE
489
490[session-size]
491run = -e cpu-clock -m 1 sleep 10
492EOF
493
494	sed -i -e "s|BASE|${base}|" ${config}
495
496	# start daemon
497	daemon_start ${config} size
498
499	# start second daemon over the same config/base
500	failed=`perf daemon start --config ${config} 2>&1 | awk '{ print $1 }'`
501
502	# check that we failed properly
503	if [ ${failed} != "failed:" ]; then
504		error=1
505		echo "FAILED: daemon lock failed"
506	fi
507
508	# stop daemon
509	daemon_exit ${config}
510
511	rm -rf ${base}
512	rm -f ${config}
513}
514
515error=0
516
517test_list
518test_reconfig
519test_stop
520test_signal
521test_ping
522test_lock
523
524exit ${error}
525