| 1 | #!/bin/bash |
| 2 | # |
| 3 | # Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com> |
| 4 | # |
| 5 | # This program is free software; you can redistribute it and/or |
| 6 | # modify it under the terms of the GNU General Public License |
| 7 | # as published by the Free Software Foundation; only version 2 |
| 8 | # of the License. |
| 9 | # |
| 10 | # This program is distributed in the hope that it will be useful, |
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | # GNU General Public License for more details. |
| 14 | # |
| 15 | # You should have received a copy of the GNU General Public License |
| 16 | # along with this program; if not, write to the Free Software |
| 17 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 18 | |
| 19 | # This test validates that a `src.ctf.fs` component successfully reads |
| 20 | # specific CTF traces and creates the expected messages. |
| 21 | # |
| 22 | # Such CTF traces to open either exist (in `tests/ctf-traces/succeed`) |
| 23 | # or are generated by this test using local trace generators. |
| 24 | |
| 25 | SH_TAP=1 |
| 26 | |
| 27 | if [ "x${BT_TESTS_SRCDIR:-}" != "x" ]; then |
| 28 | UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh" |
| 29 | else |
| 30 | UTILSSH="$(dirname "$0")/../../utils/utils.sh" |
| 31 | fi |
| 32 | |
| 33 | # shellcheck source=../../utils/utils.sh |
| 34 | source "$UTILSSH" |
| 35 | |
| 36 | function cleanup () |
| 37 | { |
| 38 | # Disable trap for SIGTERM since the following kill to the |
| 39 | # pidgroup will be SIGTERM. Otherwise it loops. |
| 40 | # The '-' before the pid number ($$) indicates 'kill' to signal the |
| 41 | # whole process group. |
| 42 | trap - SIGTERM && kill -- -$$ |
| 43 | } |
| 44 | |
| 45 | # Ensure that background child jobs are killed on SIGINT/SIGTERM |
| 46 | trap cleanup SIGINT SIGTERM |
| 47 | |
| 48 | this_dir_relative="plugins/src.ctf.lttng-live" |
| 49 | test_data_dir="$BT_TESTS_DATADIR/$this_dir_relative" |
| 50 | trace_dir="$BT_CTF_TRACES_PATH/succeed" |
| 51 | |
| 52 | lttng_live_server() { |
| 53 | local port_file="$1" |
| 54 | local pid_file="$2" |
| 55 | local retcode_file="$3" |
| 56 | local server_args="$4" |
| 57 | local server_script="$test_data_dir/lttng_live_server.py" |
| 58 | |
| 59 | # start server |
| 60 | echo "$server_args" | xargs "$BT_TESTS_PYTHON_BIN" "$server_script" --port-file "$port_file" & |
| 61 | |
| 62 | # write PID to file |
| 63 | echo $! > "$pid_file" |
| 64 | |
| 65 | # wait for server to exit |
| 66 | wait |
| 67 | |
| 68 | # write return code to file |
| 69 | echo $? > "$retcode_file" |
| 70 | } |
| 71 | |
| 72 | kill_lttng_live_server() { |
| 73 | local pid_file="$1" |
| 74 | |
| 75 | if [ ! -s "$pid_file" ]; then |
| 76 | return |
| 77 | fi |
| 78 | |
| 79 | kill -9 "$(cat "$pid_file")" |
| 80 | } |
| 81 | |
| 82 | get_cli_output_with_lttng_live_server() { |
| 83 | local cli_args_template="$1" |
| 84 | local server_args="$2" |
| 85 | local cli_stdout_file="$3" |
| 86 | local cli_stderr_file="$4" |
| 87 | local port_file="$5" |
| 88 | |
| 89 | local i |
| 90 | local ret |
| 91 | local port |
| 92 | local cli_args |
| 93 | local server_pid_file |
| 94 | local server_retcode_file |
| 95 | |
| 96 | server_pid_file="$(mktemp -t test_live_server_pid.XXXXXX)" |
| 97 | server_retcode_file="$(mktemp -t test_live_server_ret.XXXXX)" |
| 98 | |
| 99 | diag "Starting LTTng live server mockup" |
| 100 | |
| 101 | # This starts the server, which eventually writes its listening |
| 102 | # port number to the `$port_file` file. The lttng_live_server() |
| 103 | # function itself writes the server's PID to the |
| 104 | # `$server_pid_file` file. When the server exits, |
| 105 | # lttng_live_server() writes its return code to the |
| 106 | # `$server_retcode_file` file. |
| 107 | lttng_live_server "$port_file" "$server_pid_file" \ |
| 108 | "$server_retcode_file" "$server_args" & |
| 109 | |
| 110 | # Get port number |
| 111 | i=0 |
| 112 | while [ ! -s "$port_file" ]; do |
| 113 | sleep .1 |
| 114 | |
| 115 | # Timeout of 30 seconds |
| 116 | if [ "$i" -eq "300" ]; then |
| 117 | # too long, kill it |
| 118 | kill_lttng_live_server "$server_pid_file" |
| 119 | wait |
| 120 | rm -f "$server_pid_file" |
| 121 | rm -f "$server_retcode_file" |
| 122 | return 1 |
| 123 | fi |
| 124 | |
| 125 | i=$((i + 1)) |
| 126 | done |
| 127 | |
| 128 | port=$(<"$port_file") |
| 129 | |
| 130 | diag "LTTng live port is $port" |
| 131 | |
| 132 | cli_args=${cli_args_template//@PORT@/$port} |
| 133 | |
| 134 | diag "Running CLI: 'babeltrace2 $cli_args'" |
| 135 | if ! "$BT_TESTS_BT2_BIN" $cli_args 1>"$cli_stdout_file" 2>"$cli_stderr_file"; then |
| 136 | # CLI failed: cancel everything else |
| 137 | kill_lttng_live_server "$server_pid_file" |
| 138 | wait |
| 139 | rm -f "$server_pid_file" |
| 140 | rm -f "$server_retcode_file" |
| 141 | return 1 |
| 142 | fi |
| 143 | |
| 144 | # get server's return code |
| 145 | i=0 |
| 146 | while [ ! -s "$server_retcode_file" ]; do |
| 147 | sleep .1 |
| 148 | |
| 149 | # Timeout of 30 seconds |
| 150 | if [ "$i" -eq "300" ]; then |
| 151 | # too long, kill it |
| 152 | kill_lttng_live_server "$server_pid_file" |
| 153 | wait |
| 154 | rm -f "$server_pid_file" |
| 155 | rm -f "$server_retcode_file" |
| 156 | return 1 |
| 157 | fi |
| 158 | |
| 159 | i=$((i + 1)) |
| 160 | done |
| 161 | |
| 162 | wait |
| 163 | |
| 164 | ret=$(<"$server_retcode_file") |
| 165 | |
| 166 | rm -f "$server_pid_file" |
| 167 | rm -f "$server_retcode_file" |
| 168 | return "$ret" |
| 169 | } |
| 170 | |
| 171 | run_test() { |
| 172 | local test_text="$1" |
| 173 | local cli_args_template="$2" |
| 174 | local server_args="$3" |
| 175 | local expected_stdout="$4" |
| 176 | local expected_stderr="$5" |
| 177 | |
| 178 | local cli_stderr |
| 179 | local cli_stdout |
| 180 | local port_file |
| 181 | local port |
| 182 | |
| 183 | cli_stderr="$(mktemp -t test_live_stderr.XXXXXX)" |
| 184 | cli_stdout="$(mktemp -t test_live_stdout.XXXXXX)" |
| 185 | port_file="$(mktemp -t test_live_server_port.XXXXXX)" |
| 186 | |
| 187 | get_cli_output_with_lttng_live_server "$cli_args_template" "$server_args" "$cli_stdout" "$cli_stderr" "$port_file" |
| 188 | port=$(<"$port_file") |
| 189 | |
| 190 | bt_diff "$expected_stdout" "$cli_stdout" |
| 191 | ok $? "$test_text - stdout" |
| 192 | bt_diff "$expected_stderr" "$cli_stderr" |
| 193 | ok $? "$test_text - stderr" |
| 194 | |
| 195 | rm -f "$cli_stderr" |
| 196 | rm -f "$cli_stdout" |
| 197 | rm -f "$port_file" |
| 198 | } |
| 199 | |
| 200 | test_list_sessions() { |
| 201 | # Test the basic listing of sessions. |
| 202 | # Ensure that a multi-domain trace is seen as a single session. |
| 203 | # run_test() is not used here because the port is needed to craft the |
| 204 | # expected output. |
| 205 | |
| 206 | local port |
| 207 | local port_file |
| 208 | local tmp_stdout_expected |
| 209 | local template_expected |
| 210 | |
| 211 | local test_text="CLI prints the expected session list" |
| 212 | local cli_args_template="-i lttng-live net://localhost:@PORT@" |
| 213 | local server_args="'multi-domains,0,hostname,1,0,${trace_dir}/multi-domains/ust/' 'multi-domains,1,hostname,1,0,${trace_dir}/multi-domains/kernel/' 'trace-with-index,2,hostname,1,0,${trace_dir}/trace-with-index/' " |
| 214 | |
| 215 | template_expected=$(<"$test_data_dir/cli-list-sessions.expect") |
| 216 | cli_stderr="$(mktemp -t test_live_list_sessions_stderr.XXXXXX)" |
| 217 | cli_stdout="$(mktemp -t test_live_list_sessions_stdout.XXXXXX)" |
| 218 | empty_file="$(mktemp -t test_live_list_sessions_empty.XXXXXX)" |
| 219 | port_file="$(mktemp -t test_live_list_sessions_server_port.XXXXXX)" |
| 220 | tmp_stdout_expected="$(mktemp -t test_live_list_sessions_stdout_expected.XXXXXX)" |
| 221 | |
| 222 | get_cli_output_with_lttng_live_server "$cli_args_template" "$server_args" "$cli_stdout" "$cli_stderr" "$port_file" |
| 223 | port=$(<"$port_file") |
| 224 | |
| 225 | # Craft the expected output. This is necessary since the port number |
| 226 | # (random) of a "relayd" is present in the output. |
| 227 | template_expected=${template_expected//@PORT@/$port} |
| 228 | |
| 229 | echo "$template_expected" > "$tmp_stdout_expected" |
| 230 | |
| 231 | bt_diff "$tmp_stdout_expected" "$cli_stdout" |
| 232 | ok $? "$test_text - stdout" |
| 233 | bt_diff "$empty_file" "$cli_stderr" |
| 234 | ok $? "$test_text - stderr" |
| 235 | |
| 236 | rm -f "$cli_stderr" |
| 237 | rm -f "$cli_stdout" |
| 238 | rm -f "$empty_file" |
| 239 | rm -f "$port_file" |
| 240 | rm -f "$tmp_stdout_expected" |
| 241 | } |
| 242 | |
| 243 | test_base() { |
| 244 | # Attach and consume data from a multi packets ust session with no |
| 245 | # discarded events. |
| 246 | local test_text="CLI attach and fetch from single-domains session - no discarded events" |
| 247 | local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/trace-with-index -c sink.text.details" |
| 248 | local server_args="'trace-with-index,0,hostname,1,0,${trace_dir}/trace-with-index/'" |
| 249 | local expected_stdout="${test_data_dir}/cli-base.expect" |
| 250 | local expected_stderr |
| 251 | |
| 252 | # Empty file for stderr expected |
| 253 | expected_stderr="$(mktemp -t test_live_base_stderr_expected.XXXXXX)" |
| 254 | |
| 255 | run_test "$test_text" "$cli_args_template" "$server_args" "$expected_stdout" "$expected_stderr" |
| 256 | |
| 257 | rm -f "$expected_stderr" |
| 258 | } |
| 259 | |
| 260 | test_multi_domains() { |
| 261 | # Attach and consume data from a multi-domains session with discarded |
| 262 | # events. |
| 263 | local test_text="CLI attach and fetch from multi-domains session - discarded events" |
| 264 | local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/multi-domains -c sink.text.details" |
| 265 | local server_args="'multi-domains,0,hostname,1,0,${trace_dir}/multi-domains/kernel/,${trace_dir}/multi-domains/ust/'" |
| 266 | local expected_stdout="${test_data_dir}/cli-multi-domains.expect" |
| 267 | local expected_stderr |
| 268 | |
| 269 | # Empty file for stderr expected |
| 270 | expected_stderr="$(mktemp -t test_live_multi_domains_stderr_expected.XXXXXX)" |
| 271 | |
| 272 | run_test "$test_text" "$cli_args_template" "$server_args" "$expected_stdout" "$expected_stderr" |
| 273 | |
| 274 | rm -f "$expected_stderr" |
| 275 | } |
| 276 | |
| 277 | test_rate_limited() { |
| 278 | # Attach and consume data from a multi packets ust session with no |
| 279 | # discarded events. Enforce a server side limit on the stream data |
| 280 | # requests size. Ensure that babeltrace respect the returned size and that |
| 281 | # many requests per packet works as expected. |
| 282 | # The packet size of the test trace is 4k. Limit requests to 1k. |
| 283 | local test_text="CLI many requests per packet" |
| 284 | local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/trace-with-index -c sink.text.details" |
| 285 | local server_args="--max-query-data-response-size 1024 'trace-with-index,0,hostname,1,0,${trace_dir}/trace-with-index/'" |
| 286 | local expected_stdout="${test_data_dir}/cli-base.expect" |
| 287 | local expected_stderr |
| 288 | |
| 289 | # Empty file for stderr expected |
| 290 | expected_stderr="$(mktemp -t test_live_rate_limited_stderr_expected.XXXXXX)" |
| 291 | |
| 292 | run_test "$test_text" "$cli_args_template" "$server_args" "$expected_stdout" "$expected_stderr" |
| 293 | |
| 294 | rm -f "$expected_stderr" |
| 295 | } |
| 296 | |
| 297 | test_compare_to_ctf_fs() { |
| 298 | # Compare the details text sink or ctf.fs and ctf.lttng-live to ensure |
| 299 | # that the trace is parsed the same way. |
| 300 | # Do the same with the session swapped on the relayd side. This validate |
| 301 | # that ordering is consistent between live and ctf fs. |
| 302 | local test_text="CLI src.ctf.fs vs src.ctf.lttng-live" |
| 303 | local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/multi-domains -c sink.text.details --params with-trace-name=false,with-stream-name=false" |
| 304 | local server_args="'multi-domains,0,hostname,1,0,${trace_dir}/multi-domains/kernel/' 'multi-domains,1,hostname,1,0,${trace_dir}/multi-domains/ust/'" |
| 305 | local server_args_inverse="'multi-domains,0,hostname,1,0,${trace_dir}/multi-domains/ust/' 'multi-domains,1,hostname,1,0,${trace_dir}/multi-domains/kernel/'" |
| 306 | local expected_stdout |
| 307 | local expected_stderr |
| 308 | |
| 309 | expected_stdout="$(mktemp -t test_live_compare_stdout_expected.XXXXXX)" |
| 310 | expected_stderr="$(mktemp -t test_live_compare_stderr_expected.XXXXXX)" |
| 311 | |
| 312 | bt_cli "$expected_stdout" "$expected_stderr" "${trace_dir}/multi-domains" -c sink.text.details --params "with-trace-name=false,with-stream-name=false" |
| 313 | run_test "$test_text" "$cli_args_template" "$server_args" "$expected_stdout" "$expected_stderr" |
| 314 | diag "Inverse session order from lttng-relayd" |
| 315 | run_test "$test_text" "$cli_args_template" "$server_args_inverse" "$expected_stdout" "$expected_stderr" |
| 316 | |
| 317 | rm -f "$expected_stdout" |
| 318 | rm -f "$expected_stderr" |
| 319 | } |
| 320 | |
| 321 | plan_tests 12 |
| 322 | |
| 323 | test_list_sessions |
| 324 | test_base |
| 325 | test_multi_domains |
| 326 | test_rate_limited |
| 327 | test_compare_to_ctf_fs |