X-Git-Url: https://git.lttng.org/?a=blobdiff_plain;f=tests%2Futils%2Futils.sh;h=c9907fd6d37fe8e3cf0401791cc0c6cf90d83682;hb=9ff8f3ca6e45f1e083a7cb87605ce00b7b4e3008;hp=9df9a0bf0985fed35cdf2da8c9dc79cbbbef14b0;hpb=9f0e230a68c5715f28372aa3df9ad1cb13cf6b43;p=lttng-tools.git diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index 9df9a0bf0..c9907fd6d 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -1,17 +1,7 @@ -# Copyright (C) - 2012 David Goulet +# Copyright (C) 2012 David Goulet # -# This library is free software; you can redistribute it and/or modify it under -# the terms of the GNU Lesser General Public License as published by the Free -# Software Foundation; version 2.1 of the License. +# SPDX-License-Identifier: LGPL-2.1-only # -# This library 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 Lesser General Public License for more -# details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA SESSIOND_BIN="lttng-sessiond" SESSIOND_MATCH=".*lttng-sess.*" @@ -26,6 +16,11 @@ BABELTRACE_BIN="babeltrace" OUTPUT_DEST=/dev/null ERROR_OUTPUT_DEST=/dev/null +# To match 20201127-175802 +date_time_pattern="[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9][0-9]" +# The size of a long on this system +system_long_bit_size=$(getconf LONG_BIT) + # Minimal kernel version supported for session daemon tests KERNEL_MAJOR_VERSION=2 KERNEL_MINOR_VERSION=6 @@ -46,7 +41,7 @@ export LTTNG_SESSIOND_PATH="/bin/true" source $TESTDIR/utils/tap/tap.sh -if [ -z $LTTNG_TEST_TEARDOWN_TIMEOUT ]; then +if [ -z ${LTTNG_TEST_TEARDOWN_TIMEOUT+x} ]; then LTTNG_TEST_TEARDOWN_TIMEOUT=60 fi @@ -135,6 +130,38 @@ function randstring() echo } +# Helpers for get_possible_cpus. +function get_possible_cpus_count_from_sysfs_possible_mask() +{ + local max_possible_cpu_id=$(cut -d '-' -f 2 < /sys/devices/system/cpu/possible) + echo $((max_possible_cpu_id+1)) +} + +function get_max_cpus_count_from_sysfs_cpu_directories() +{ + local max_possible_cpu_id= \ + $(find /sys/devices/system/cpu/ -mindepth 1 -maxdepth 1 -regex ".+cpu[0-9]+" | \ + sed -e 's/cpu//g' | \ + awk -F '/' '{ if ($NF > N) N = $NF } END { print N }') + echo $((max_possible_cpu_id+1)) +} + +# Return the number of possible CPUs. +function get_possible_cpus_count() +{ + local possible_cpus_count=$(get_possible_cpus_count_from_sysfs_possible_mask) + + if [ $? -ne 0 ]; then + possible_cpus_count=$(get_max_cpus_count_from_sysfs_cpu_directories) + local configured_cpus_count=$(getconf _NPROCESSORS_CONF) + possible_cpus_count=$(($configured_cpus_count > $possible_cpus_count \ + ? $configured_cpus_count \ + : $possible_cpus_count)) + fi + + echo $possible_cpus_count +} + # Return the number of _configured_ CPUs. function conf_proc_count() { @@ -149,10 +176,33 @@ function conf_proc_count() # Bail out on failure function validate_lttng_modules_present () { + # Check for loadable modules. modprobe -n lttng-tracer 2>/dev/null - if [ $? -ne 0 ]; then - BAIL_OUT "LTTng modules not detected." + if [ $? -eq 0 ]; then + return 0 fi + + # Check for builtin modules. + ls /proc/lttng > /dev/null 2>&1 + if [ $? -eq 0 ]; then + return 0 + fi + + BAIL_OUT "LTTng modules not detected." +} + +# Run the lttng binary. +# +# The first two arguments are stdout and stderr redirect paths, respectively. +# The rest of the arguments are forwarded to the lttng binary +function _run_lttng_cmd +{ + local stdout_dest="$1" + local stderr_dest="$2" + shift 2 + + diag "$TESTDIR/../src/bin/lttng/$LTTNG_BIN $*" + $TESTDIR/../src/bin/lttng/$LTTNG_BIN "$@" 1> "$stdout_dest" 2> "$stderr_dest" } function enable_kernel_lttng_event @@ -331,9 +381,9 @@ function lttng_enable_kernel_channel() local expected_to_fail=$2 local sess_name=$3 local channel_name=$4 - local opt=$5 + local opts="${@:5}" - $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-channel -k $channel_name -s $sess_name $opt 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-channel -k $channel_name -s $sess_name $opts 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST ret=$? if [[ $expected_to_fail -eq "1" ]]; then test "$ret" -ne "0" @@ -665,7 +715,7 @@ function stop_lttng_sessiond_opt() if [ -n "$modules" ]; then diag "Unloading all LTTng modules" - modprobe -r "$modules" + modprobe --remove "$modules" fi fi fi @@ -946,9 +996,9 @@ function enable_ust_lttng_channel () local expected_to_fail=$2 local sess_name=$3 local channel_name=$4 - local opt=$5 + local opts="${@:5}" - $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-channel -u $channel_name -s $sess_name $opt 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-channel -u $channel_name -s $sess_name $opts 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST ret=$? if [[ $expected_to_fail -eq "1" ]]; then test "$ret" -ne "0" @@ -1107,37 +1157,80 @@ function enable_jul_lttng_event_loglevel() function enable_log4j_lttng_event() { - sess_name=$1 - event_name="$2" - channel_name=$3 + local sess_name=$1 + local event_name=$2 + local channel_name=$3 - if [ -z $channel_name ]; then - # default channel if none specified - chan="" - else - chan="-c $channel_name" + local chan_opt=() + + # default channel if none specified + if [ -n "$channel_name" ]; then + chan_opt=("-c" "$channel_name") fi - $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "$event_name" $chan -s $sess_name -l 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST - ok $? "Enable LOG4J event $event_name for session $sess_name" + _run_lttng_cmd "$OUTPUT_DEST" "$ERROR_OUTPUT_DEST" \ + enable-event "$event_name" "${chan_opt[@]}" -s "$sess_name" --log4j + ok $? "Enable LOG4J event '$event_name' for session '$sess_name'" +} + +function enable_log4j_lttng_event_filter() +{ + local sess_name=$1 + local event_name=$2 + local filter=$3 + + _run_lttng_cmd "$OUTPUT_DEST" "$ERROR_OUTPUT_DEST" \ + enable-event "$event_name" -s "$sess_name" --log4j --filter "$filter" + ok $? "Enable LOG4J event '$event_name' with filter '$filter' for session '$sess_name'" +} + +function enable_log4j_lttng_event_filter_loglevel_only() +{ + local sess_name=$1 + local event_name=$2 + local filter=$3 + local loglevel=$4 + + _run_lttng_cmd "$OUTPUT_DEST" "$ERROR_OUTPUT_DEST" \ + enable-event --loglevel-only "$loglevel" "$event_name" -s "$sess_name" -l --filter "$filter" + ok $? "Enable LOG4J event '$event_name' with filter '$filter' and loglevel-only '$loglevel' for session '$sess_name'" } function enable_log4j_lttng_event_loglevel() { local sess_name=$1 - local event_name="$2" + local event_name=$2 local loglevel=$3 local channel_name=$4 - if [ -z $channel_name ]; then - # default channel if none specified - chan="" - else - chan="-c $channel_name" + + # default channel if none specified + if [ -n "$channel_name" ]; then + chan_opt=("-c" "$channel_name") + fi + + _run_lttng_cmd "$OUTPUT_DEST" "$ERROR_OUTPUT_DEST" \ + enable-event --loglevel "$loglevel" "$event_name" "${chan_opt[@]}" -s "$sess_name" --log4j + ok $? "Enable LOG4J event '$event_name' for session '$sess_name' with loglevel '$loglevel'" +} + +function enable_log4j_lttng_event_loglevel_only() +{ + local sess_name=$1 + local event_name=$2 + local loglevel=$3 + local channel_name=$4 + + local chan_opt=() + + # default channel if none specified + if [ -n "$channel_name" ]; then + chan_opt=("-c" "$channel_name") fi - $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event --loglevel $loglevel "$event_name" $chan -s $sess_name -l 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST - ok $? "Enable LOG4J event $event_name for session $sess_name with loglevel $loglevel" + _run_lttng_cmd "$OUTPUT_DEST" "$ERROR_OUTPUT_DEST" \ + enable-event --loglevel-only "$loglevel" "$event_name" "${chan_opt[@]}" -s "$sess_name" --log4j + ok $? "Enable LOG4J event '$event_name' for session '$sess_name' with loglevel-only '$loglevel'" } function enable_python_lttng_event() @@ -1180,8 +1273,16 @@ function enable_ust_lttng_event_filter() local sess_name="$1" local event_name="$2" local filter="$3" + local channel_name=$4 + + 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 "$event_name" -s $sess_name -u --filter "$filter" 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event $chan "$event_name" -s $sess_name -u --filter "$filter" 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST ok $? "Enable event $event_name with filtering for session $sess_name" } @@ -1236,8 +1337,9 @@ function disable_log4j_lttng_event () local sess_name="$1" local event_name="$2" - $TESTDIR/../src/bin/lttng/$LTTNG_BIN disable-event "$event_name" -s $sess_name -l >/dev/null 2>&1 - ok $? "Disable LOG4J event $event_name for session $sess_name" + _run_lttng_cmd "$OUTPUT_DEST" "$ERROR_OUTPUT_DEST" \ + disable-event "$event_name" -s "$sess_name" --log4j + ok $? "Disable LOG4J event '$event_name' for session '$sess_name'" } function disable_python_lttng_event () @@ -1422,7 +1524,7 @@ function lttng_snapshot_record () local sess_name=$1 local trace_path=$2 - $TESTDIR/../src/bin/lttng/$LTTNG_BIN snapshot record -s $sess_name $trace_path 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + $TESTDIR/../src/bin/lttng/$LTTNG_BIN snapshot record -s "$sess_name" "$trace_path" 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST ok $? "Snapshot recorded" } @@ -1469,8 +1571,9 @@ function lttng_load_fail() function lttng_track() { - local expected_to_fail=$1 - local opts=$2 + local expected_to_fail="$1" + shift 1 + local opts="$@" $TESTDIR/../src/bin/lttng/$LTTNG_BIN track $opts >$OUTPUT_DEST ret=$? if [[ $expected_to_fail -eq "1" ]]; then @@ -1493,8 +1596,9 @@ function lttng_track_fail() function lttng_untrack() { - local expected_to_fail=$1 - local opts=$2 + local expected_to_fail="$1" + shift 1 + local opts="$@" $TESTDIR/../src/bin/lttng/$LTTNG_BIN untrack $opts >$OUTPUT_DEST ret=$? if [[ $expected_to_fail -eq "1" ]]; then @@ -1528,6 +1632,46 @@ function lttng_untrack_kernel_all_ok() ok $? "Lttng untrack all pid on the kernel domain" } +function lttng_track_ust_ok() +{ + lttng_track_ok -u "$@" +} + +function lttng_track_ust_fail() +{ + lttng_track_fail -u "$@" +} + +function lttng_track_kernel_ok() +{ + lttng_track_ok -k "$@" +} + +function lttng_track_kernel_fail() +{ + lttng_track_fail -k "$@" +} + +function lttng_untrack_ust_ok() +{ + lttng_untrack_ok -u "$@" +} + +function lttng_untrack_ust_fail() +{ + lttng_untrack_fail -u "$@" +} + +function lttng_untrack_kernel_ok() +{ + lttng_untrack_ok -k "$@" +} + +function lttng_untrack_kernel_fail() +{ + lttng_untrack_fail -k "$@" +} + function lttng_add_context_list() { $TESTDIR/../src/bin/lttng/$LTTNG_BIN add-context --list 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST @@ -1573,6 +1717,40 @@ function add_context_kernel_fail() add_context_lttng 1 -k "$@" } +function wait_live_trace_ready () +{ + local url=$1 + local zero_client_match=0 + + diag "Waiting for live trace at url: $url" + while [ $zero_client_match -eq 0 ]; do + zero_client_match=$($BABELTRACE_BIN -i lttng-live $url | grep "0 client(s) connected" | wc -l) + sleep 0.5 + done + pass "Waiting for live trace at url: $url" +} + +function wait_live_viewer_connect () +{ + local url=$1 + local one_client_match=0 + + diag "Waiting for live viewers on url: $url" + while [ $one_client_match -eq 0 ]; do + one_client_match=$($BABELTRACE_BIN -i lttng-live $url | grep "1 client(s) connected" | wc -l) + sleep 0.5 + done + pass "Waiting for live viewers on url: $url" +} + +function bail_out_if_no_babeltrace() +{ + which "$BABELTRACE_BIN" >/dev/null + if [ $? -ne 0 ]; then + LTTNG_BAIL_OUT "\"$BABELTRACE_BIN\" binary not found. Skipping tests" + fi +} + function validate_metadata_event () { local event_name=$1 @@ -1690,6 +1868,36 @@ function validate_trace_count ok $? "Read a total of $cnt events, expected $expected_count" } +function validate_trace_count_range_incl_min_excl_max +{ + local event_name=$1 + local trace_path=$2 + local expected_min=$3 + local expected_max=$4 + + which $BABELTRACE_BIN >/dev/null + if [ $? -ne 0 ]; then + skip 0 "Babeltrace binary not found. Skipping trace validation" + fi + + cnt=0 + OLDIFS=$IFS + IFS="," + for i in $event_name; do + traced=$($BABELTRACE_BIN $trace_path 2>/dev/null | grep $i | wc -l) + if [ "$traced" -ge $expected_min ]; then + pass "Validate trace for event $i, $traced events" + else + fail "Validate trace for event $i" + diag "Found $traced occurences of $i" + fi + cnt=$(($cnt + $traced)) + done + IFS=$OLDIFS + test $cnt -lt $expected_max + ok $? "Read a total of $cnt events, expected between [$expected_min, $expected_max[" +} + function trace_first_line { local trace_path=$1 @@ -1769,6 +1977,33 @@ function validate_trace_empty() return $ret } +function validate_directory_empty () +{ + local trace_path="$1" + + # Do not double quote `$trace_path` below as we want wildcards to be + # expanded. + files="$(ls -A $trace_path)" + ret=$? + if [ $ret -ne 0 ]; then + fail "Failed to list content of directory \"$trace_path\"" + return $ret + fi + + nb_files="$(echo -n "$files" | wc -l)" + ok $nb_files "Directory \"$trace_path\" is empty" +} + +function validate_trace_session_ust_empty() +{ + validate_directory_empty "$1"/ust +} + +function validate_trace_session_kernel_empty() +{ + validate_trace_empty "$1"/kernel +} + function regenerate_metadata () { local expected_to_fail=$1 @@ -1846,7 +2081,7 @@ function rotate_session_fail () function destructive_tests_enabled () { - if [ ${LTTNG_ENABLE_DESTRUCTIVE_TESTS} = "will-break-my-system" ]; then + if [ "$LTTNG_ENABLE_DESTRUCTIVE_TESTS" = "will-break-my-system" ]; then return 0 else return 1 @@ -1904,3 +2139,254 @@ function lttng_enable_rotation_size_fail () { lttng_enable_rotation_size 1 $@ } + +function lttng_clear_session () +{ + local expected_to_fail=$1 + local sess_name=$2 + + $TESTDIR/../src/bin/lttng/$LTTNG_BIN clear $sess_name 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + ret=$? + if [[ $expected_to_fail -eq "1" ]]; then + test "$ret" -ne "0" + ok $? "Expected fail on clear session $sess_name" + else + ok $ret "Clear session $sess_name" + fi +} + +function lttng_clear_session_ok () +{ + lttng_clear_session 0 $@ +} + +function lttng_clear_session_fail () +{ + lttng_clear_session 1 $@ +} + +function lttng_clear_all () +{ + $TESTDIR/../src/bin/lttng/$LTTNG_BIN clear --all 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + ok $? "Clear all lttng sessions" +} + +function validate_path_pattern () +{ + local message=$1 + local pattern=$2 + # Base path is only used in error case and is used to list the content + # of the base path. + local base_path=$3 + + + [ -f $pattern ] + ret=$? + ok $ret "$message" + + if [ "$ret" -ne "0" ]; then + diag "Path pattern expected: $pattern" + # List the tracepath for more info. We use find as a recursive + # directory lister. + diag "The base path content:" + find "$base_path" -print + fi +} + +function validate_trace_path_ust_uid () +{ + local trace_path=$1 + local session_name=$2 + local uid=$UID + local pattern="$trace_path/$session_name-$date_time_pattern/ust/uid/$uid/${system_long_bit_size}-bit/metadata" + + validate_path_pattern "UST per-uid trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_ust_uid_network () +{ + local trace_path=$1 + local session_name=$2 + local base_path=$3 + local uid=$UID + local hostname=$HOSTNAME + local pattern + local ret + + # If the session was given a network base path (e.g + # 127.0.0.1/my/custom/path on creation, there is no session name + # component to the path on the relayd side. Caller can simply not pass a + # session name for this scenario. + if [ -n "$session_name" ]; then + session_name="$session_name-$date_time_pattern" + if [ -n "$base_path" ]; then + fail "Session name and base path are mutually exclusive" + return + fi + fi + + pattern="$trace_path/$hostname/$base_path/$session_name/ust/uid/$uid/${system_long_bit_size}-bit/metadata" + + validate_path_pattern "UST per-uid network trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_ust_uid_snapshot_network () +{ + local trace_path=$1 + local session_name=$2 + local snapshot_name=$3 + local snapshot_number=$4 + local base_path=$5 + local hostname=$HOSTNAME + local uid=$UID + local pattern + local ret + + # If the session/output was given a network base path (e.g + # 127.0.0.1/my/custom/path on creation, there is no session name + # component to the path on the relayd side. Caller can simply not pass a + # session name for this scenario. + if [ -n "$session_name" ]; then + session_name="$session_name-$date_time_pattern" + if [ -n "$base_path" ]; then + fail "Session name and base path are mutually exclusive" + return + fi + fi + + pattern="$trace_path/$hostname/$base_path/$session_name/$snapshot_name-$date_time_pattern-$snapshot_number/ust/uid/$uid/${system_long_bit_size}-bit/metadata" + + validate_path_pattern "UST per-uid network snapshot trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_ust_uid_snapshot () +{ + local trace_path=$1 + local session_name=$2 + local snapshot_name=$3 + local snapshot_number=$4 + local base_path=$5 + local uid=$UID + local pattern + local ret + + # If the session/output was given a network base path (e.g + # 127.0.0.1/my/custom/path) on creation, there is no session name + # component to the path on the relayd side. Caller can simply not pass a + # session name for this scenario. + if [ -n "$session_name" ]; then + session_name="$session_name-$date_time_pattern" + if [ -n "$base_path" ]; then + fail "Session name and base path are mutually exclusive" + return + fi + fi + + pattern="$trace_path/$base_path/$session_name/$snapshot_name-$date_time_pattern-$snapshot_number/ust/uid/$uid/${system_long_bit_size}-bit/metadata" + + validate_path_pattern "UST per-uid snapshot trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_ust_pid () +{ + local trace_path=$1 + local session_name=$2 + local app_string=$3 + local pid=$4 + local pattern + local ret + + # If the session was given a trace path on creation, there is no session + # name component to the path. Caller can simply not pass a session name + # for this scenario. + if [ -n "$session_name" ]; then + session_name="$session_name-$date_time_pattern" + fi + + pattern="$trace_path/$session_name/ust/pid/$pid/$app_string-*-$date_time_pattern/metadata" + + validate_path_pattern "UST per-pid trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_kernel () +{ + local trace_path=$1 + local session_name=$2 + local pattern + + # If the session was given a trace path on creation, there is no session + # name component to the path. Caller can simply not pass a session name + # for this scenario. + if [ -n "$session_name" ]; then + session_name="$session_name-$date_time_pattern" + fi + + pattern="$trace_path/$session_name/kernel/metadata" + + validate_path_pattern "Kernel trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_kernel_network () +{ + local trace_path=$1 + local session_name=$2 + local hostname=$HOSTNAME + local pattern="$trace_path/$hostname/$session_name-$date_time_pattern/kernel/metadata" + + validate_path_pattern "Kernel network trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_kernel_snapshot () +{ + local trace_path=$1 + local session_name=$2 + local snapshot_name=$3 + local snapshot_number=$4 + local base_path=$5 + local pattern + local ret + + # If the session/output was given a network base path (e.g + # 127.0.0.1/my/custom/path on creation, there is no session name + # component to the path on the relayd side. Caller can simply not pass a + # session name for this scenario. + if [ -n "$session_name" ]; then + session_name="$session_name-$date_time_pattern" + if [ -n "$base_path" ]; then + fail "Session name and base path are mutually exclusive" + return + fi + fi + + pattern="$trace_path/$base_path/$session_name/$snapshot_name-$date_time_pattern-$snapshot_number/kernel/metadata" + + validate_path_pattern "Kernel snapshot trace path is valid" "$pattern" "$trace_path" +} + +function validate_trace_path_kernel_snapshot_network () +{ + local trace_path=$1 + local session_name=$2 + local snapshot_name=$3 + local snapshot_number=$4 + local base_path=$5 + local hostname=$HOSTNAME + local pattern + local ret + + # If the session/output was given a network base path (e.g + # 127.0.0.1/my/custom/path on creation, there is no session name + # component to the path on the relayd side. Caller can simply not pass a + # session name for this scenario. + if [ -n "$session_name" ]; then + session_name="$session_name-$date_time_pattern" + if [ -n "$base_path" ]; then + fail "Session name and base path are mutually exclusive" + return + fi + fi + + pattern="$trace_path/$hostname/$base_path/$session_name/$snapshot_name-$date_time_pattern-$snapshot_number/kernel/metadata" + + validate_path_pattern "Kernel network snapshot trace path is valid" "$pattern" "$trace_path" +}