android13/external/ltp/testcases/kernel/connectors/pec/cn_pec.sh

142 lines
3.3 KiB
Bash
Executable File

#!/bin/sh
# SPDX-License-Identifier: GPL-2.0-or-later
# Copyright (c) 2008 FUJITSU LIMITED
# Copyright (c) 2021 Joerg Vehlow <joerg.vehlow@aox-tech.de>
# Copyright (c) 2021 Petr Vorel <pvorel@suse.cz>
#
# Author: Li Zefan <lizf@cn.fujitsu.com>
#
# Process event connector is a netlink connector that reports process events
# to userspace. It sends events such as fork, exec, id change and exit.
TST_OPTS="n:"
TST_SETUP=setup
TST_TESTFUNC=test
TST_PARSE_ARGS=parse_args
TST_USAGE=usage
TST_NEEDS_ROOT=1
TST_NEEDS_TMPDIR=1
TST_TEST_DATA="fork exec exit uid gid"
. tst_test.sh
num_events=10
usage()
{
cat << EOF
usage: $0 [-n <nevents>]
OPTIONS
-n The number of evetns to generate per test (default 10)
EOF
}
parse_args()
{
case $1 in
n) num_events=$2;;
esac
}
# Find a free file handle
free_fd()
{
local fd
for fd in $(seq 200); do
# Sapwn a new sh, because redirecting to a non existing file handle
# will trigger a syntax error.
sh -c ": 2>/dev/null >&$fd || : 2>/dev/null <&$fd" 2>/dev/null
if [ $? -ne 0 ]; then
echo $fd
return
fi
done
}
setup()
{
if ! grep -q cn_proc /proc/net/connector; then
tst_brk TCONF "Process Event Connector is not supported or kernel < 2.6.26"
fi
tst_res TINFO "Test process events connector"
}
test()
{
local event=$2
local expected_events lis_rc pid fd_act failed act_nevents exp act
tst_res TINFO "Testing $2 event (nevents=$num_events)"
pec_listener >lis_$event.log 2>lis_$event.err &
pid=$!
# wait for pec_listener to start listening
tst_sleep 100ms
ROD event_generator -n $num_events -e $event \>gen_$event.log 2\>gen_$event.err
kill -s INT $pid 2> /dev/null
wait $pid
lis_rc=$?
if [ ! -s gen_$event.log ]; then
tst_brk TBROK "failed to generate process events: $(cat gen_$event.err)"
fi
if [ $lis_rc -ne 0 ]; then
tst_brk TBROK "failed to execute the listener: $(cat lis_$event.err)"
fi
# The listener writes the same messages as the generator, but it can
# also see more events (e.g. for testing exit, a fork is generated).
# So: The events generated by the generator have to be in the same order
# as the events printed by the listener, but my interleaved with other
# messages. To correctly compare them, we have to open both logs
# and iterate over both of them at the same time, skipping messages
# in the listener log, that are not of interest.
# Because some messages may be multiple times in the listener log,
# we have to open it only once!
# This however does not check, if the listener sees more messages,
# than expected.
fd_act=$(free_fd)
[ -z "$fd_act" ] && tst_brk TBROK "No free filehandle found"
eval "exec ${fd_act}<lis_$event.log"
failed=0
act_nevents=0
while read -r exp; do
local found=0
act_nevents=$((act_nevents + 1))
while read -r act; do
if [ "$exp" = "$act" ]; then
found=1
break
fi
done <&${fd_act}
if [ $found -ne 1 ]; then
failed=1
tst_res TFAIL "Event was not detected by the event listener: $exp"
break
fi
done <gen_$event.log
eval "exec ${fd_act}<&-"
if [ $failed -eq 0 ]; then
if [ $act_nevents -ne $num_events ]; then
tst_res TBROK "Expected $num_events, but $act_nevents generated"
else
tst_res TPASS "All events detected"
fi
else
# TFAIL message is already printed in the loop above
cat lis_$event.log
fi
}
tst_run