X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=tests%2Futils%2Futils.sh;h=48a60fe9b0f403c1ff22bbf0a889704ce27863b0;hb=f03ea3f43450abb1a1ea704044e1e8c78cfc0b4c;hp=8e76ce4976413ec2e50e6eac9e971cf72b7818d5;hpb=b6d14cf333b2b06b4a42d97382c6d5dc3f371a3d;p=lttng-tools.git diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index 8e76ce497..48a60fe9b 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -15,6 +15,19 @@ LTTNG_BIN="lttng" BABELTRACE_BIN="babeltrace" OUTPUT_DEST=/dev/null ERROR_OUTPUT_DEST=/dev/null +MI_XSD_MAJOR_VERSION=4 +MI_XSD_MINOR_VERSION=1 +MI_XSD_PATH="$TESTDIR/../src/common/mi-lttng-${MI_XSD_MAJOR_VERSION}.${MI_XSD_MINOR_VERSION}.xsd" +MI_VALIDATE="$TESTDIR/utils/xml-utils/validate_xml ${MI_XSD_PATH}" + +XML_PRETTY="$TESTDIR/utils/xml-utils/pretty_xml" +XML_EXTRACT="$TESTDIR/utils/xml-utils/extract_xml" +XML_NODE_CHECK="${XML_EXTRACT} -e" + +# 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 @@ -40,25 +53,60 @@ if [ -z ${LTTNG_TEST_TEARDOWN_TIMEOUT+x} ]; then LTTNG_TEST_TEARDOWN_TIMEOUT=60 fi -function full_cleanup () +# Enable job monitor mode. +# Here we are mostly interested in the following from the monitor mode: +# All processes run in a separate process group. +# This allows us to ensure that all subprocesses from all background tasks are +# cleaned up correctly using signal to process group id. +set -m + +kill_background_jobs () +{ + local pids + pids=$(jobs -p) + + if [ -z "$pids" ]; then + # Empty + return 0 + fi + + while read -r pid; + do + # Use negative number to send the signal to the process group. + # This ensure that any subprocesses receive the signal. + # /dev/null is used since there is an acceptable race between + # the moments the pids are listed and the moment we send a + # signal. + kill -SIGTERM -- "-$pid" 2>/dev/null + done <<< "$pids" +} + +function cleanup () { # Try to kill daemons gracefully - stop_lttng_relayd_notap SIGTERM $LTTNG_TEST_TEARDOWN_TIMEOUT - stop_lttng_sessiond_notap SIGTERM $LTTNG_TEST_TEARDOWN_TIMEOUT + stop_lttng_relayd_cleanup SIGTERM $LTTNG_TEST_TEARDOWN_TIMEOUT + stop_lttng_sessiond_cleanup SIGTERM $LTTNG_TEST_TEARDOWN_TIMEOUT # If daemons are still present, forcibly kill them - stop_lttng_relayd_notap SIGKILL $LTTNG_TEST_TEARDOWN_TIMEOUT - stop_lttng_sessiond_notap SIGKILL $LTTNG_TEST_TEARDOWN_TIMEOUT - stop_lttng_consumerd_notap SIGKILL $LTTNG_TEST_TEARDOWN_TIMEOUT - - # Disable trap for SIGTERM since the following kill to the - # pidgroup will be SIGTERM. Otherwise it loops. - # The '-' before the pid number ($$) indicates 'kill' to signal the - # whole process group. - trap - SIGTERM && kill -- -$$ + stop_lttng_relayd_cleanup SIGKILL $LTTNG_TEST_TEARDOWN_TIMEOUT + stop_lttng_sessiond_cleanup SIGKILL $LTTNG_TEST_TEARDOWN_TIMEOUT + stop_lttng_consumerd_cleanup SIGKILL $LTTNG_TEST_TEARDOWN_TIMEOUT + + kill_background_jobs +} + +function full_cleanup () +{ + cleanup exit 1 } +function LTTNG_BAIL_OUT () +{ + cleanup + BAIL_OUT "$@" +} + function null_pipes () { exec 0>/dev/null @@ -161,6 +209,105 @@ function randstring() echo } +# Return a space-separated string of online CPU IDs, based on +# /sys/devices/system/cpu/online, or from 0 to nproc - 1 otherwise. +function get_online_cpus() +{ + local cpus=() + local range_re + if [ -f /sys/devices/system/cpu/online ]; then + range_re='([0-9]+)-([0-9]+)' + while read -r range ; do + if [[ "${range}" =~ ${range_re} ]] ; then + mapfile -t -O "${#cpus[*]}" cpus <<< $(seq "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}") + else + cpus+=("${range}") + fi + done < <(tr ',' $'\n' < /sys/devices/system/cpu/online) + else + read -r -a cpus <<< $(seq 0 $(( $(conf_proc_count) - 1 )) ) + fi + echo "${cpus[*]}" +} + +# Helpers for get_possible_cpus. +function get_possible_cpus_count_from_sysfs_possible_mask() +{ + local max_possible_cpu_id + + # The Awk script extracts the highest CPU id from the possible CPU + # mask. Assuming a numerical order, a field separator '-' and a record + # separator ','. The last value parsed is the highest id. + if [ -f /sys/devices/system/cpu/possible ]; then + max_possible_cpu_id=$(awk -F '-' 'BEGIN { RS = ","} { last = $NF } END { printf("%d\n", last) }' \ + /sys/devices/system/cpu/possible) + echo "$((max_possible_cpu_id+1))" + else + echo "0" + fi +} + +# This is a fallback if the possible CPU mask is not available. This will not +# take into account unplugged CPUs. +function get_max_cpus_count_from_sysfs_cpu_directories() +{ + local max_possible_cpu_id=0 + local current_cpu_id + + for i in /sys/devices/system/cpu/cpu[0-9]*; do + current_cpu_id="${i#/sys/devices/system/cpu/cpu}" + if [ "$current_cpu_id" -gt "$max_possible_cpu_id" ]; then + max_possible_cpu_id="$current_cpu_id" + fi + done + + echo "$((max_possible_cpu_id+1))" +} + +# Return the number of possible CPUs. +function get_possible_cpus_count() +{ + local possible_cpus_count + possible_cpus_count=$(get_possible_cpus_count_from_sysfs_possible_mask) + + if [ "$possible_cpus_count" -eq "0" ]; then + local configured_cpus_count + configured_cpus_count=$(getconf _NPROCESSORS_CONF) + possible_cpus_count=$(get_max_cpus_count_from_sysfs_cpu_directories) + possible_cpus_count=$((configured_cpus_count > possible_cpus_count \ + ? configured_cpus_count \ + : possible_cpus_count)) + fi + + echo "$possible_cpus_count" +} + +# Return the list of exposed CPU. +# +# NOTE! Use it like so: +# +# IFS=" " read -r -a VARIABLE <<< "$(get_exposed_cpus_list)" +function get_exposed_cpus_list() +{ + local list=() + + for i in /sys/devices/system/cpu/cpu[0-9]*; do + list+=("${i#/sys/devices/system/cpu/cpu}") + done + + echo "${list[@]}" +} + +# Return any available CPU found. Do not make assumption about the returned +# value, e.g. that it could be 0. +function get_any_available_cpu() +{ + for cpu in $(get_online_cpus); do + echo "${cpu}" + break; + done +} + # Return the number of _configured_ CPUs. function conf_proc_count() { @@ -187,7 +334,21 @@ function validate_lttng_modules_present () return 0 fi - BAIL_OUT "LTTng modules not detected." + LTTNG_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 @@ -462,7 +623,7 @@ function start_lttng_relayd_opt() if [ -z $(lttng_pgrep "$RELAYD_MATCH") ]; then # shellcheck disable=SC2086 $DIR/../src/bin/lttng-relayd/$RELAYD_BIN $process_mode $opt 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST - #$DIR/../src/bin/lttng-relayd/$RELAYD_BIN $opt -vvv >>/tmp/relayd.log 2>&1 & + #$DIR/../src/bin/lttng-relayd/$RELAYD_BIN $process_mode $opt -vvv >>/tmp/relayd.log 2>&1 & if [ $? -eq 1 ]; then if [ $withtap -eq "1" ]; then fail "Start lttng-relayd (process mode: $process_mode opt: $opt)" @@ -491,27 +652,32 @@ function start_lttng_relayd_notap() function stop_lttng_relayd_opt() { local withtap=$1 - local signal=$2 + local is_cleanup=$2 + local signal=$3 + local timeout_s=$4 + local dtimeleft_s= + local retval=0 + local pids if [ -z "$signal" ]; then signal="SIGTERM" fi - local timeout_s=$3 - local dtimeleft_s= # Multiply time by 2 to simplify integer arithmetic if [ -n "$timeout_s" ]; then dtimeleft_s=$((timeout_s * 2)) fi - local retval=0 - local pids= pids=$(lttng_pgrep "$RELAYD_MATCH") if [ -z "$pids" ]; then - if [ "$withtap" -eq "1" ]; then - pass "No relay daemon to kill" + if [ "$is_cleanup" -eq 1 ]; then + : + elif [ "$withtap" -eq "1" ]; then + fail "No relay daemon to kill" + else + LTTNG_BAIL_OUT "No relay daemon to kill" fi return 0 fi @@ -550,12 +716,17 @@ function stop_lttng_relayd_opt() function stop_lttng_relayd() { - stop_lttng_relayd_opt 1 "$@" + stop_lttng_relayd_opt 1 0 "$@" } function stop_lttng_relayd_notap() { - stop_lttng_relayd_opt 0 "$@" + stop_lttng_relayd_opt 0 0 "$@" +} + +function stop_lttng_relayd_cleanup() +{ + stop_lttng_relayd_opt 0 1 "$@" } #First arg: show tap output @@ -565,6 +736,9 @@ function start_lttng_sessiond_opt() local withtap=$1 local load_path=$2 + # The rest of the arguments will be passed directly to lttng-sessiond. + shift 2 + local env_vars="" local consumerd="" @@ -599,7 +773,7 @@ function start_lttng_sessiond_opt() if ! validate_kernel_version; then fail "Start session daemon" - BAIL_OUT "*** Kernel too old for session daemon tests ***" + LTTNG_BAIL_OUT "*** Kernel too old for session daemon tests ***" fi : "${LTTNG_SESSION_CONFIG_XSD_PATH="${DIR}/../src/common/config/"}" @@ -609,10 +783,10 @@ function start_lttng_sessiond_opt() # Have a load path ? if [ -n "$load_path" ]; then # shellcheck disable=SC2086 - env $env_vars --load "$load_path" --background "$consumerd" + env $env_vars --load "$load_path" --background "$consumerd" "$@" else # shellcheck disable=SC2086 - env $env_vars --background "$consumerd" + env $env_vars --background "$consumerd" "$@" fi #$DIR/../src/bin/lttng-sessiond/$SESSIOND_BIN --background --consumerd32-path="$DIR/../src/bin/lttng-consumerd/lttng-consumerd" --consumerd64-path="$DIR/../src/bin/lttng-consumerd/lttng-consumerd" --verbose-consumer >>/tmp/sessiond.log 2>&1 status=$? @@ -635,15 +809,18 @@ function start_lttng_sessiond_notap() function stop_lttng_sessiond_opt() { local withtap=$1 - local signal=$2 + local is_cleanup=$2 + local signal=$3 + local timeout_s=$4 + local dtimeleft_s= + local retval=0 + local runas_pids + local pids if [ -z "$signal" ]; then signal=SIGTERM fi - local timeout_s=$3 - local dtimeleft_s= - # Multiply time by 2 to simplify integer arithmetic if [ -n "$timeout_s" ]; then dtimeleft_s=$((timeout_s * 2)) @@ -654,12 +831,7 @@ function stop_lttng_sessiond_opt() return 0 fi - local retval=0 - - local runas_pids= runas_pids=$(lttng_pgrep "$RUNAS_MATCH") - - local pids= pids=$(lttng_pgrep "$SESSIOND_MATCH") if [ -n "$runas_pids" ]; then @@ -667,10 +839,12 @@ function stop_lttng_sessiond_opt() fi if [ -z "$pids" ]; then - if [ "$withtap" -eq "1" ]; then + if [ "$is_cleanup" -eq 1 ]; then + : + elif [ "$withtap" -eq "1" ]; then fail "No session daemon to kill" else - BAIL_OUT "No session daemon to kill" + LTTNG_BAIL_OUT "No session daemon to kill" fi return 0 fi @@ -734,44 +908,50 @@ function stop_lttng_sessiond_opt() function stop_lttng_sessiond() { - stop_lttng_sessiond_opt 1 "$@" + stop_lttng_sessiond_opt 1 0 "$@" } function stop_lttng_sessiond_notap() { - stop_lttng_sessiond_opt 0 "$@" + stop_lttng_sessiond_opt 0 0 "$@" +} + +function stop_lttng_sessiond_cleanup() +{ + stop_lttng_sessiond_opt 0 1 "$@" } function sigstop_lttng_sessiond_opt() { local withtap=$1 local signal=SIGSTOP + local pids if [ -n "$TEST_NO_SESSIOND" ] && [ "$TEST_NO_SESSIOND" == "1" ]; then # Env variable requested no session daemon return fi - PID_SESSIOND="$(lttng_pgrep "${SESSIOND_MATCH}") $(lttng_pgrep "$RUNAS_MATCH")" + pids="$(lttng_pgrep "${SESSIOND_MATCH}") $(lttng_pgrep "$RUNAS_MATCH")" if [ "$withtap" -eq "1" ]; then - diag "Sending SIGSTOP to lt-$SESSIOND_BIN and $SESSIOND_BIN pids: $(echo "$PID_SESSIOND" | tr '\n' ' ')" + diag "Sending SIGSTOP to lt-$SESSIOND_BIN and $SESSIOND_BIN pids: $(echo "$pids" | tr '\n' ' ')" fi # shellcheck disable=SC2086 - if ! kill -s $signal $PID_SESSIOND 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST; then + if ! kill -s $signal $pids 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST; then if [ "$withtap" -eq "1" ]; then fail "Sending SIGSTOP to session daemon" fi else out=1 while [ $out -ne 0 ]; do - pid="$(lttng_pgrep "$SESSIOND_MATCH")" + pids="$(lttng_pgrep "$SESSIOND_MATCH")" # Wait until state becomes stopped for session # daemon(s). out=0 - for sessiond_pid in $pid; do + for sessiond_pid in $pids; do state="$(ps -p "$sessiond_pid" -o state= )" if [[ -n "$state" && "$state" != "T" ]]; then out=1 @@ -798,35 +978,39 @@ function sigstop_lttng_sessiond_notap() function stop_lttng_consumerd_opt() { local withtap=$1 - local signal=$2 + local is_cleanup=$2 + local signal=$3 + local timeout_s=$4 + local dtimeleft_s= + local retval=0 + local pids if [ -z "$signal" ]; then signal=SIGTERM fi - local timeout_s=$3 - local dtimeleft_s= - # Multiply time by 2 to simplify integer arithmetic if [ -n "$timeout_s" ]; then dtimeleft_s=$((timeout_s * 2)) fi - local retval=0 - - PID_CONSUMERD="$(lttng_pgrep "$CONSUMERD_MATCH")" + pids="$(lttng_pgrep "$CONSUMERD_MATCH")" - if [ -z "$PID_CONSUMERD" ]; then - if [ "$withtap" -eq "1" ]; then - pass "No consumer daemon to kill" + if [ -z "$pids" ]; then + if [ "$is_cleanup" -eq 1 ]; then + : + elif [ "$withtap" -eq "1" ]; then + fail "No consumerd daemon to kill" + else + LTTNG_BAIL_OUT "No consumerd daemon to kill" fi return 0 fi - diag "Killing (signal $signal) $CONSUMERD_BIN pids: $(echo "$PID_CONSUMERD" | tr '\n' ' ')" + diag "Killing (signal $signal) $CONSUMERD_BIN pids: $(echo "$pids" | tr '\n' ' ')" # shellcheck disable=SC2086 - if ! kill -s $signal $PID_CONSUMERD 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST; then + if ! kill -s $signal $pids 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST; then retval=1 if [ "$withtap" -eq "1" ]; then fail "Kill consumer daemon" @@ -834,12 +1018,12 @@ function stop_lttng_consumerd_opt() else out=1 while [ $out -ne 0 ]; do - pid="$(lttng_pgrep "$CONSUMERD_MATCH")" + pids="$(lttng_pgrep "$CONSUMERD_MATCH")" # If consumerds are still present check their status. # A zombie status qualifies the consumerd as *killed* out=0 - for consumer_pid in $pid; do + for consumer_pid in $pids; do state="$(ps -p "$consumer_pid" -o state= )" if [[ -n "$state" && "$state" != "Z" ]]; then out=1 @@ -868,25 +1052,31 @@ function stop_lttng_consumerd_opt() function stop_lttng_consumerd() { - stop_lttng_consumerd_opt 1 "$@" + stop_lttng_consumerd_opt 1 0 "$@" } function stop_lttng_consumerd_notap() { - stop_lttng_consumerd_opt 0 "$@" + stop_lttng_consumerd_opt 0 0 "$@" +} + +function stop_lttng_consumerd_cleanup() +{ + stop_lttng_consumerd_opt 0 1 "$@" } function sigstop_lttng_consumerd_opt() { local withtap=$1 local signal=SIGSTOP + local pids - PID_CONSUMERD="$(lttng_pgrep "$CONSUMERD_MATCH")" + pids="$(lttng_pgrep "$CONSUMERD_MATCH")" - diag "Sending SIGSTOP to $CONSUMERD_BIN pids: $(echo "$PID_CONSUMERD" | tr '\n' ' ')" + diag "Sending SIGSTOP to $CONSUMERD_BIN pids: $(echo "$pids" | tr '\n' ' ')" # shellcheck disable=SC2086 - kill -s $signal $PID_CONSUMERD 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + kill -s $signal $pids 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST retval=$? if [ $retval -eq 1 ]; then @@ -897,12 +1087,12 @@ function sigstop_lttng_consumerd_opt() else out=1 while [ $out -ne 0 ]; do - pid="$(lttng_pgrep "$CONSUMERD_MATCH")" + pids="$(lttng_pgrep "$CONSUMERD_MATCH")" # Wait until state becomes stopped for all # consumers. out=0 - for consumer_pid in $pid; do + for consumer_pid in $pids; do state="$(ps -p "$consumer_pid" -o state= )" if [[ -n "$state" && "$state" != "T" ]]; then out=1 @@ -929,9 +1119,25 @@ function sigstop_lttng_consumerd_notap() function list_lttng_with_opts () { + local ret + local withtap=$1 + shift local opts=$1 $TESTDIR/../src/bin/lttng/$LTTNG_BIN list $opts 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST - ok $? "Lttng-tool list command with option $opts" + ret=$? + if [ $withtap -eq "1" ]; then + ok $ret "Lttng-tool list command with option $opts" + fi +} + +function list_lttng_ok () +{ + list_lttng_with_opts 1 "$@" +} + +function list_lttng_notap () +{ + list_lttng_with_opts 0 "$@" } function create_lttng_session_no_output () @@ -1166,37 +1372,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() @@ -1257,8 +1506,13 @@ function enable_ust_lttng_event_loglevel() local sess_name="$1" local event_name="$2" local loglevel="$3" + local channel_name="$4" + local chan=() + if [ -n "${channel_name}" ] ; then + chan=('-c' "${channel_name}") + fi - $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "$event_name" -s $sess_name -u --loglevel $loglevel 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "${chan[@]}" "$event_name" -s $sess_name -u --loglevel $loglevel 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST ok $? "Enable event $event_name with loglevel $loglevel" } @@ -1267,8 +1521,13 @@ function enable_ust_lttng_event_loglevel_only() local sess_name="$1" local event_name="$2" local loglevel="$3" + local channel_name="$4" + local chan=() + if [ -n "${channel_name}" ] ; then + chan=('-c' "${channel_name}") + fi - $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "$event_name" -s $sess_name -u --loglevel-only $loglevel 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST + $TESTDIR/../src/bin/lttng/$LTTNG_BIN enable-event "${chan[@]}" "$event_name" -s $sess_name -u --loglevel-only $loglevel 1> $OUTPUT_DEST 2> $ERROR_OUTPUT_DEST ok $? "Enable event $event_name with loglevel-only $loglevel" } @@ -1303,8 +1562,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 () @@ -1487,8 +1747,9 @@ function lttng_snapshot_del_output_fail () 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" } @@ -1707,13 +1968,21 @@ function wait_live_viewer_connect () 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 local nr_event_id=$2 local trace_path=$3 - local metadata_file=$(find $trace_path | grep metadata) + local metadata_file=$(find $trace_path -name "metadata") local metadata_path=$(dirname $metadata_file) which $BABELTRACE_BIN >/dev/null @@ -1787,7 +2056,7 @@ function validate_trace pass "Validate trace for event $i, $traced events" else fail "Validate trace for event $i" - diag "Found $traced occurences of $i" + diag "Found $traced occurrences of $i" fi done ret=$? @@ -1815,7 +2084,7 @@ function validate_trace_count pass "Validate trace for event $i, $traced events" else fail "Validate trace for event $i" - diag "Found $traced occurences of $i" + diag "Found $traced occurrences of $i" fi cnt=$(($cnt + $traced)) done @@ -1845,7 +2114,7 @@ function validate_trace_count_range_incl_min_excl_max pass "Validate trace for event $i, $traced events" else fail "Validate trace for event $i" - diag "Found $traced occurences of $i" + diag "Found $traced occurrences of $i" fi cnt=$(($cnt + $traced)) done @@ -1879,7 +2148,7 @@ function validate_trace_exp() pass "Validate trace for expression '${event_exp}', $traced events" else fail "Validate trace for expression '${event_exp}'" - diag "Found $traced occurences of '${event_exp}'" + diag "Found $traced occurrences of '${event_exp}'" fi ret=$? return $ret @@ -2037,7 +2306,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 @@ -2126,3 +2395,331 @@ 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 lttng_add_trigger() +{ + local expected_to_fail="$1" + local trigger_name="$2" + shift 2 + local args=("$@") + + diag "$TESTDIR/../src/bin/lttng/$LTTNG_BIN add-trigger --name $trigger_name ${args[*]}" + $TESTDIR/../src/bin/lttng/$LTTNG_BIN add-trigger --name "$trigger_name" "${args[@]}" 1> /dev/null 2> /dev/null + ret=$? + if [[ $expected_to_fail -eq "1" ]]; then + test "$ret" -ne "0" + ok $? "Add trigger $trigger_name failed as expected" + else + ok $ret "Add trigger $trigger_name" + fi +} + +function lttng_remove_trigger() +{ + local expected_to_fail="$1" + local trigger_name="$2" + shift 2 + + diag "$TESTDIR/../src/bin/lttng/$LTTNG_BIN remove-trigger $trigger_name $*" + "$TESTDIR/../src/bin/lttng/$LTTNG_BIN" remove-trigger "$trigger_name" "$@" 1> /dev/null 2> /dev/null + ret=$? + if [[ $expected_to_fail -eq "1" ]]; then + test "$ret" -ne "0" + ok $? "Remove trigger $trigger_name failed as expected" + else + ok $ret "Remove trigger $trigger_name" + fi +} + +function lttng_add_trigger_ok() +{ + lttng_add_trigger 0 "$@" +} + +function lttng_add_trigger_fail() +{ + lttng_add_trigger 1 "$@" +} + +function lttng_remove_trigger_ok() +{ + lttng_remove_trigger 0 "$@" +} + +function list_triggers_matches_ok () +{ + local tmp_stdout=$(mktemp --tmpdir -t "tmp.${FUNCNAME[0]}_stdout.XXXXXX") + local tmp_stderr=$(mktemp --tmpdir -t "tmp.${FUNCNAME[0]}_stderr.XXXXXX") + + local test_name="$1" + local expected_stdout_file="$2" + + diag "$TESTDIR/../src/bin/lttng/$LTTNG_BIN list-triggers" + + "$TESTDIR/../src/bin/lttng/$LTTNG_BIN" list-triggers > "${tmp_stdout}" 2> "${tmp_stderr}" + ok $? "${test_name}: exit code is 0" + + diff -u "${expected_stdout_file}" "${tmp_stdout}" + ok $? "${test_name}: expected stdout" + + diff -u /dev/null "${tmp_stderr}" + ok $? "${test_name}: expected stderr" + + rm -f "${tmp_stdout}" + rm -f "${tmp_stderr}" +} + +function list_triggers_matches_mi_ok () +{ + local tmp_stdout + local tmp_stdout_raw + local tmp_stderr + + local test_name="$1" + local expected_stdout_file="$2" + + tmp_stdout_raw=$(mktemp --tmpdir -t "tmp.${FUNCNAME[0]}_stdout.XXXXXX") + tmp_stdout=$(mktemp --tmpdir -t "tmp.${FUNCNAME[0]}_stdout.XXXXXX") + tmp_stderr=$(mktemp --tmpdir -t "tmp.${FUNCNAME[0]}_stderr.XXXXXX") + + diag "$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi xml list-triggers" + + "$TESTDIR/../src/bin/lttng/$LTTNG_BIN" --mi=xml list-triggers > "${tmp_stdout_raw}" 2> "${tmp_stderr}" + ok $? "${test_name}: exit code is 0" + + # Pretty-fy xml before further test. + $XML_PRETTY < "${tmp_stdout_raw}" > "${tmp_stdout}" + + $MI_VALIDATE "${tmp_stdout}" + ok $? "list-trigger mi is valid" + + diff -u "${expected_stdout_file}" "${tmp_stdout}" + ok $? "${test_name}: expected stdout" + + diff -u /dev/null "${tmp_stderr}" + ok $? "${test_name}: expected stderr" + + rm -f "${tmp_stdout}" + rm -f "${tmp_stdout_raw}" + rm -f "${tmp_stderr}" +} + +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" +}