From mboxrd@z Thu Jan 1 00:00:00 1970 From: Joerg Vehlow Date: Mon, 15 Mar 2021 10:28:44 +0100 Subject: [LTP] [PATCH 2/2] pec: Fix multiple event test In-Reply-To: <20210315092844.991073-1-lkml@jv-coder.de> References: <20210315092844.991073-1-lkml@jv-coder.de> Message-ID: <20210315092844.991073-2-lkml@jv-coder.de> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: ltp@lists.linux.it From: Joerg Vehlow The test case for NUM_EVENTS != 1 was not correct at all. Now the test looks for each event recorded by the generator in the correct order in the listener's log. Additionally the test is parameterized, to the the number of generated events and the default is now set to 10. Signed-off-by: Joerg Vehlow --- testcases/kernel/connectors/pec/cn_pec.sh | 98 ++++++++++++++++--- .../kernel/connectors/pec/event_generator.c | 54 +++++----- 2 files changed, 113 insertions(+), 39 deletions(-) diff --git a/testcases/kernel/connectors/pec/cn_pec.sh b/testcases/kernel/connectors/pec/cn_pec.sh index 98abd50fc..b46ce533f 100755 --- a/testcases/kernel/connectors/pec/cn_pec.sh +++ b/testcases/kernel/connectors/pec/cn_pec.sh @@ -9,16 +9,48 @@ # 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" -NUM_EVENTS=1 - . tst_test.sh +num_events=10 + +usage() +{ + cat << EOF +usage: $0 [-n ] + +OPTIONS +-n The number of evetns to generate per test (default 10) +EOF +} + +parse_args() +{ + case $1 in + n) num_events=$2;; + esac +} + +free_fd() +{ + # Find a free file handle + local found + for fd in $(seq 200); do + rco="$(true 2>/dev/null >&${fd}; echo $?)" + rci="$(true 2>/dev/null <&${fd}; echo $?)" + [[ "${rco}${rci}" = "11" ]] && found=${fd} && break + done + echo $found +} + setup() { if ! grep -q cn_proc /proc/net/connector; then @@ -32,35 +64,75 @@ setup() test() { local event=$2 + + tst_res TINFO "Testing $2 event (nevents=$num_events)" + pec_listener >lis_$event.log 2>lis_$event.err & - pid=$! + lis_pid=$! # Wait for pec_listener to start listening tst_sleep 100ms # Run with absolute path, so the generator can exec itself generator="$(command -v event_generator)" - "$generator" -n $NUM_EVENTS -e $event >gen_$event.log 2>gen_$event.err + "$generator" -n $num_events -e $event >gen_$event.log 2>gen_$event.err gen_rc=$? - # Sleep until pec_listener has seen and handled all of the generated events - tst_sleep 100ms - kill -s SIGINT $pid 2> /dev/null - wait $pid + kill -s SIGINT $lis_pid 2> /dev/null + wait $lis_pid lis_rc=$? if [ $gen_rc -ne 0 -o ! -s gen_$event.log ]; then - tst_brk TBROK "failed to generate process events" + 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 - expected_events="$(cat gen_$event.log)" - if grep -q "$expected_events" lis_$event.log; then - tst_res TPASS "$event detected by listener" + # 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}pw_uid; ltp_gid = ent->pw_gid; - signal(SIGCHLD, SIG_IGN); - /* special processing for gen_exec, see comments above gen_exec() */ if (gen_event == gen_exec) { exec_argv = argv; @@ -224,8 +208,26 @@ int main(int argc, char **argv) } /* other events */ - for (i = 0; i < nr_event; i++) - gen_event(); + for (i = 0; i < nr_event; i++) { + pid_t pid; + int status; + + pid = SAFE_FORK(); + if (pid == 0) { + gen_event(); + exit(0); + } else { + if (pid != SAFE_WAITPID(pid, &status, 0)) { + fprintf(stderr, + "Child process did not terminate as expected\n"); + return 1; + } + if (WEXITSTATUS(status) != 0) { + fprintf(stderr, "Child process did not terminate with 0\n"); + return 1; + } + } + } return 0; } -- 2.25.1