From 8cfcd41c7fac2e14d8f8527238d928bd4ec732fb Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 23 Sep 2014 21:19:07 -0400 Subject: [PATCH] Implement tests for kernel syscall tracing feature Signed-off-by: Mathieu Desnoyers --- tests/regression/kernel/Makefile.am | 2 +- tests/regression/kernel/test_syscall | 451 +++++++++++++++++++++++++++ tests/root_regression | 1 + tests/utils/utils.sh | 139 +++++++++ 4 files changed, 592 insertions(+), 1 deletion(-) create mode 100755 tests/regression/kernel/test_syscall diff --git a/tests/regression/kernel/Makefile.am b/tests/regression/kernel/Makefile.am index a3afbf8dd..36ff6eeac 100644 --- a/tests/regression/kernel/Makefile.am +++ b/tests/regression/kernel/Makefile.am @@ -1,4 +1,4 @@ -EXTRA_DIST = test_event_basic test_all_events +EXTRA_DIST = test_event_basic test_all_events test_syscall all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/regression/kernel/test_syscall b/tests/regression/kernel/test_syscall new file mode 100755 index 000000000..5e6b7467b --- /dev/null +++ b/tests/regression/kernel/test_syscall @@ -0,0 +1,451 @@ +#!/bin/bash +# +# Copyright (C) - 2013 Christian Babeux +# Copyright (C) - 2014 Mathieu Desnoyers +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License, version 2 only, as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# this program; if not, write to the Free Software Foundation, Inc., 51 +# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +TEST_DESC="Kernel tracer - System calls" + +CURDIR=$(dirname $0)/ +TESTDIR=$CURDIR/../.. +NUM_TESTS=124 + +# test command issues at least open and close system calls +TESTCMD="cat /proc/cpuinfo > /dev/null" + +source $TESTDIR/utils/utils.sh + +function test_syscall_single() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_single" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_syscall_ok $SESSION_NAME "open" + + start_lttng_tracing + eval ${TESTCMD} + stop_lttng_tracing + + # ensure each is there. + validate_trace_exp "-e syscall_entry_open -e compat_syscall_entry_open" $TRACE_PATH + validate_trace_exp "-e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + + # ensure trace only contains those. + validate_trace_only_exp "-e syscall_entry_open -e compat_syscall_entry_open -e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_two() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_two" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_syscall_ok $SESSION_NAME "open" + lttng_enable_kernel_syscall_ok $SESSION_NAME "close" + + start_lttng_tracing + eval ${TESTCMD} + stop_lttng_tracing + + # ensure each is there. + validate_trace_exp "-e syscall_entry_open -e compat_syscall_entry_open" $TRACE_PATH + validate_trace_exp "-e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + validate_trace_exp "-e syscall_entry_close -e compat_syscall_entry_close" $TRACE_PATH + validate_trace_exp "-e syscall_exit_close -e compat_syscall_exit_close" $TRACE_PATH + + # ensure trace only contains those. + validate_trace_only_exp "-e syscall_entry_open -e compat_syscall_entry_open -e syscall_exit_open -e compat_syscall_exit_open -e syscall_entry_close -e compat_syscall_entry_close -e syscall_exit_close -e compat_syscall_exit_close" $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_all() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_all" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable all syscalls + lttng_enable_kernel_syscall_ok $SESSION_NAME + + start_lttng_tracing + eval ${TESTCMD} + stop_lttng_tracing + + # ensure at least open and close are there. + validate_trace_exp "-e syscall_entry_open -e compat_syscall_entry_open" $TRACE_PATH + validate_trace_exp "-e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + validate_trace_exp "-e syscall_entry_close -e compat_syscall_entry_close" $TRACE_PATH + validate_trace_exp "-e syscall_exit_close -e compat_syscall_exit_close" $TRACE_PATH + # trace may contain other syscalls. + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_all_disable_one() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_all_disable_one" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable all syscalls + lttng_enable_kernel_syscall_ok $SESSION_NAME + # disable open system call + lttng_disable_kernel_syscall_ok $SESSION_NAME "open" + + start_lttng_tracing + eval ${TESTCMD} + stop_lttng_tracing + + # ensure "open" syscall is not there. + validate_trace_only_exp "-v -e syscall_entry_open -e compat_syscall_entry_open -e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + + # ensure "close" syscall is there. + validate_trace_exp "-e syscall_entry_close -e compat_syscall_entry_close" $TRACE_PATH + validate_trace_exp "-e syscall_exit_close -e compat_syscall_exit_close" $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_all_disable_two() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_all_disable_two" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable all syscalls + lttng_enable_kernel_syscall_ok $SESSION_NAME + # disable open system call + lttng_disable_kernel_syscall_ok $SESSION_NAME "open" + lttng_disable_kernel_syscall_ok $SESSION_NAME "close" + + start_lttng_tracing + # generates open, close, execve (at least) + eval ${TESTCMD} + stop_lttng_tracing + + # ensure "open" and "close" syscalls are not there. + validate_trace_only_exp "-v -e syscall_entry_open -e compat_syscall_entry_open -e syscall_exit_open -e compat_syscall_exit_open -e syscall_entry_close -e compat_syscall_entry_close -e syscall_exit_close -e compat_syscall_exit_close" $TRACE_PATH + + # ensure "execve" syscall is there. + validate_trace_exp "-e syscall_entry_execve -e compat_syscall_entry_execve" $TRACE_PATH + validate_trace_exp "-e syscall_exit_execve -e compat_syscall_exit_execve" $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_enable_all_disable_all() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_all_disable_all" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable all system calls + lttng_enable_kernel_syscall_ok $SESSION_NAME + # disable all system calls + lttng_disable_kernel_syscall_ok $SESSION_NAME + + start_lttng_tracing + # generates open, close, execve (at least) + eval ${TESTCMD} + stop_lttng_tracing + + # ensure nothing has been traced. + validate_trace_empty $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_enable_all_disable_all_enable_all() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_all_disable_all_enable_all" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable all system calls + lttng_enable_kernel_syscall_ok $SESSION_NAME + # disable all system calls + lttng_disable_kernel_syscall_ok $SESSION_NAME + # enable all system calls + lttng_enable_kernel_syscall_ok $SESSION_NAME + + start_lttng_tracing + # generates open, close, execve (at least) + eval ${TESTCMD} + stop_lttng_tracing + + # ensure at least open and close are there. + validate_trace_exp "-e syscall_entry_open -e compat_syscall_entry_open" $TRACE_PATH + validate_trace_exp "-e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + validate_trace_exp "-e syscall_entry_close -e compat_syscall_entry_close" $TRACE_PATH + validate_trace_exp "-e syscall_exit_close -e compat_syscall_exit_close" $TRACE_PATH + # trace may contain other syscalls. + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_enable_all_disable_all_twice() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_all_disable_all_twice" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable all system calls + lttng_enable_kernel_syscall_ok $SESSION_NAME + # disable all system calls + lttng_disable_kernel_syscall_ok $SESSION_NAME + # enable all system calls + lttng_enable_kernel_syscall_ok $SESSION_NAME + # disable all system calls + lttng_disable_kernel_syscall_ok $SESSION_NAME + + start_lttng_tracing + # generates open, close, execve (at least) + eval ${TESTCMD} + stop_lttng_tracing + + # ensure nothing has been traced. + validate_trace_empty $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_enable_one_disable_one() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_one_disable_one" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable open system call + lttng_enable_kernel_syscall_ok $SESSION_NAME "open" + # disable open system call + lttng_disable_kernel_syscall_ok $SESSION_NAME "open" + + start_lttng_tracing + # generates open, close, execve (at least) + eval ${TESTCMD} + stop_lttng_tracing + + # ensure nothing has been traced. + validate_trace_empty $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_enable_two_disable_two() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_two_disable_two" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable open and close system calls + lttng_enable_kernel_syscall_ok $SESSION_NAME "open" + lttng_enable_kernel_syscall_ok $SESSION_NAME "close" + # disable open and close system calls + lttng_disable_kernel_syscall_ok $SESSION_NAME "open" + lttng_disable_kernel_syscall_ok $SESSION_NAME "close" + + start_lttng_tracing + # generates open, close, execve (at least) + eval ${TESTCMD} + stop_lttng_tracing + + # ensure nothing has been traced. + validate_trace_empty $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_enable_two_disable_one() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_two_disable_one" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + # enable open and close system calls + lttng_enable_kernel_syscall_ok $SESSION_NAME "open" + lttng_enable_kernel_syscall_ok $SESSION_NAME "close" + # disable close system call + lttng_disable_kernel_syscall_ok $SESSION_NAME "close" + + start_lttng_tracing + # generates open, close, execve (at least) + eval ${TESTCMD} + stop_lttng_tracing + + # ensure open is there. + validate_trace_exp "-e syscall_entry_open -e compat_syscall_entry_open" $TRACE_PATH + validate_trace_exp "-e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + + # ensure trace only contains those. + validate_trace_only_exp "-e syscall_entry_open -e compat_syscall_entry_open -e syscall_exit_open -e compat_syscall_exit_open" $TRACE_PATH + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_disable_twice() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_disable_twice" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_syscall_ok $SESSION_NAME "open" + # First disable will succeed + lttng_disable_kernel_syscall_ok $SESSION_NAME "open" + # Second disable will fail + lttng_disable_kernel_syscall_fail $SESSION_NAME "open" + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_disable_all_twice() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_disable_all_twice" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_syscall_ok $SESSION_NAME + # First disable will succeed + lttng_disable_kernel_syscall_ok $SESSION_NAME + # Second disable will fail + lttng_disable_kernel_syscall_fail $SESSION_NAME + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + + +function test_syscall_enable_unknown() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_unknown" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_syscall_fail $SESSION_NAME "thissyscallcannotexist" + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_enable_all_enable_one() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_all_enable_one" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_syscall_ok $SESSION_NAME + # Enabling an event already enabled fails. + lttng_enable_kernel_syscall_fail $SESSION_NAME "open" + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +function test_syscall_disable_all_disable_one() +{ + TRACE_PATH=$(mktemp -d) + SESSION_NAME="kernel_syscall_enable_all_enable_one" + + create_lttng_session $SESSION_NAME $TRACE_PATH + + lttng_enable_kernel_syscall_ok $SESSION_NAME + lttng_disable_kernel_syscall_ok $SESSION_NAME + # Disabling an event already disabled fails. + lttng_disable_kernel_syscall_fail $SESSION_NAME "open" + + destroy_lttng_session $SESSION_NAME + + rm -rf $TRACE_PATH +} + +# MUST set TESTDIR before calling those functions +plan_tests $NUM_TESTS + +print_test_banner "$TEST_DESC" + +if [ "$(id -u)" == "0" ]; then + isroot=1 +else + isroot=0 +fi + +skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS || +{ + start_lttng_sessiond + + test_syscall_single + test_syscall_two + test_syscall_all + test_syscall_all_disable_one + test_syscall_all_disable_two + test_syscall_enable_all_disable_all + test_syscall_enable_all_disable_all_enable_all + test_syscall_enable_all_disable_all_twice + test_syscall_enable_one_disable_one + test_syscall_enable_two_disable_two + test_syscall_enable_two_disable_one + test_syscall_disable_twice + test_syscall_disable_all_twice + test_syscall_enable_unknown + test_syscall_enable_all_enable_one + test_syscall_disable_all_disable_one + + stop_lttng_sessiond +} diff --git a/tests/root_regression b/tests/root_regression index f585cddd1..559870f10 100644 --- a/tests/root_regression +++ b/tests/root_regression @@ -1,5 +1,6 @@ regression/kernel/test_all_events regression/kernel/test_event_basic +regression/kernel/test_syscall regression/tools/live/test_kernel regression/tools/live/test_lttng_kernel regression/tools/streaming/test_high_throughput_limits diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index 117f72f1f..2647769f2 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -102,6 +102,85 @@ function lttng_enable_kernel_event ok $? "Enable kernel event $event_name for session $sess_name" } +function lttng_enable_kernel_syscall() +{ + local expected_to_fail=$1 + local sess_name=$2 + local syscall_name=$3 + local channel_name=$4 + + if [ -z $syscall_name ]; then + # Enable all event if no syscall name specified + syscall_name="-a" + fi + + if [ -z $channel_name ]; then + # default channel if none specified + chan="" + else + chan="-c $channel_name" + fi + + $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event --syscall "$syscall_name" $chan -s $sess_name -k >$OUTPUT_DEST + ret=$? + if [[ $expected_to_fail -eq "1" ]]; then + test $ret -ne "0" + ok $? "Enable kernel syscall $syscall_name for session $sess_name on channel $channel_name fail as expected" + else + ok $ret "Enable kernel syscall $syscall_name for session $sess_name on channel $channel_name" + fi +} + +function lttng_enable_kernel_syscall_ok() +{ + lttng_enable_kernel_syscall 0 ${*} +} + +function lttng_enable_kernel_syscall_fail() +{ + lttng_enable_kernel_syscall 1 ${*} +} + +function lttng_disable_kernel_syscall() +{ + local expected_to_fail=$1 + local sess_name=$2 + local syscall_name=$3 + local channel_name=$4 + + if [ -z $syscall_name ]; then + # Enable all event if no syscall name specified + syscall_name="-a" + fi + + if [ -z $channel_name ]; then + # default channel if none specified + chan="" + else + chan="-c $channel_name" + fi + + $TESTDIR/../src/bin/lttng/$LTTNG_BIN disable-event --syscall "$syscall_name" $chan -s $sess_name -k >$OUTPUT_DEST + + ret=$? + if [[ $expected_to_fail -eq "1" ]]; then + test $ret -ne "0" + ok $? "Disable kernel syscall $syscall_name for session $sess_name on channel $channel_name fail as expected" + else + ok $ret "Disable kernel syscall $syscall_name for session $sess_name on channel $channel_name" + fi +} + +function lttng_disable_kernel_syscall_ok() +{ + lttng_disable_kernel_syscall 0 ${*} +} + +function lttng_disable_kernel_syscall_fail() +{ + lttng_disable_kernel_syscall 1 ${*} +} + function start_lttng_relayd { local opt=$1 @@ -628,3 +707,63 @@ function validate_trace IFS=$OLDIFS return $ret } + +function validate_trace_exp() +{ + local event_exp=$1 + local trace_path=$2 + + which $BABELTRACE_BIN >/dev/null + skip $? -ne 0 "Babeltrace binary not found. Skipping trace validation" + + traced=$($BABELTRACE_BIN $trace_path 2>/dev/null | grep ${event_exp} | wc -l) + if [ "$traced" -ne 0 ]; then + pass "Validate trace for expression '${event_exp}', $traced events" + else + fail "Validate trace for expression '${event_exp}'" + diag "Found $traced occurences of '${event_exp}'" + fi + ret=$? + return $ret +} + +function validate_trace_only_exp() +{ + local event_exp=$1 + local trace_path=$2 + + which $BABELTRACE_BIN >/dev/null + skip $? -ne 0 "Babeltrace binary not found. Skipping trace matches" + + local count=$($BABELTRACE_BIN $trace_path | grep ${event_exp} | wc -l) + local total=$($BABELTRACE_BIN $trace_path | wc -l) + + if [ "$count" -ne 0 ] && [ "$total" -eq "$count" ]; then + pass "Trace match with $total for expression '${event_exp}" + else + fail "Trace match" + diag "$total syscall event(s) found, only syscalls matching expression '${event_exp}' ($count occurrences) are expected" + fi + ret=$? + return $ret +} + +function validate_trace_empty() +{ + local trace_path=$1 + + which $BABELTRACE_BIN >/dev/null + if [ $? -ne 0 ]; then + skip 0 "Babeltrace binary not found. Skipping trace validation" + fi + + traced=$($BABELTRACE_BIN $trace_path 2>/dev/null | wc -l) + if [ "$traced" -eq 0 ]; then + pass "Validate empty trace" + else + fail "Validate empty trace" + diag "Found $traced events in trace" + fi + ret=$? + return $ret +} -- 2.34.1