From: Kienan Stewart Date: Fri, 15 Dec 2023 14:34:28 +0000 (-0500) Subject: Tests: Add test to cover live viewer hangs with an early inactive app X-Git-Url: https://git.lttng.org./?a=commitdiff_plain;h=b7ccf4cc56d37bfc4546c256b81dbf0806b720ae;p=lttng-tools.git Tests: Add test to cover live viewer hangs with an early inactive app Refs: https://bugs.lttng.org/issues/1406 Change-Id: Iefe796d39ff39a04055acc5f95fc9440d5ee244a Signed-off-by: Kienan Stewart Signed-off-by: Jérémie Galarneau --- diff --git a/tests/regression/Makefile.am b/tests/regression/Makefile.am index 6537a33dd..8afb7600a 100644 --- a/tests/regression/Makefile.am +++ b/tests/regression/Makefile.am @@ -14,6 +14,7 @@ TESTS = tools/base-path/test_ust \ tools/streaming/test_kernel \ tools/streaming/test_ust \ tools/health/test_thread_ok \ + tools/live/test_early_inactive_app.py \ tools/live/test_kernel \ tools/live/test_lttng_kernel \ tools/live/test_miss_short_lived_app.py \ diff --git a/tests/regression/tools/live/Makefile.am b/tests/regression/tools/live/Makefile.am index a8042f67d..e2e7b7e17 100644 --- a/tests/regression/tools/live/Makefile.am +++ b/tests/regression/tools/live/Makefile.am @@ -9,7 +9,8 @@ noinst_PROGRAMS = live_test EXTRA_DIST = test_kernel test_lttng_kernel test_per_application_leaks.py if HAVE_LIBLTTNG_UST_CTL -EXTRA_DIST += test_lttng_ust \ +EXTRA_DIST += test_early_inactive_app.py \ + test_lttng_ust \ test_miss_short_lived_app.py \ test_ust \ test_ust_tracefile_count diff --git a/tests/regression/tools/live/test_early_inactive_app.py b/tests/regression/tools/live/test_early_inactive_app.py new file mode 100755 index 000000000..925a1ab01 --- /dev/null +++ b/tests/regression/tools/live/test_early_inactive_app.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 +# +# SPDX-FileCopyrightText: 2024 Kienan Stewart +# SPDX-LicenseIdentifier: LGPL-2.1-only +# + +""" +Test that live doesn't hang when a traced UST application started before the +session if the application doesn't produce any further events. +""" + +import os +import pathlib +import subprocess +import sys +import time + +test_utils_import_path = pathlib.Path(__file__).absolute().parents[3] / "utils" +sys.path.append(str(test_utils_import_path)) + +import lttngtest + + +def test_early_ust_app(tap, test_env, buffer_sharing_policy): + tap.diagnostic( + "test_early_inactive_app with buffer sharing policy {}".format( + buffer_sharing_policy + ) + ) + + uid = None + user = None + if buffer_sharing_policy == lttngtest.lttngctl.BufferSharingPolicy.PerUID: + if os.getuid() != 0 or not test_env.allows_destructive(): + tap.skip( + "Need to run PerUID test as root and have `LTTNG_ENABLE_DESTRUCTIVE_TESTS` set properly to create a dummy user", + 2, + ) + return + (uid, user) = test_env.create_dummy_user() + + # Run early app + early_app = test_env.launch_wait_trace_test_application( + 10, + wait_before_exit=True, + run_as=user, + ) + early_app.trace() + early_app.wait_for_tracing_done() + + client = lttngtest.LTTngClient(test_env, log=tap.diagnostic) + output = lttngtest.NetworkSessionOutputLocation( + "net://localhost:{}:{}/".format( + test_env.lttng_relayd_control_port, test_env.lttng_relayd_data_port + ) + ) + + session = client.create_session(output=output, live=True) + channel = session.add_channel( + lttngtest.lttngctl.TracingDomain.User, + buffer_sharing_policy=buffer_sharing_policy, + ) + channel.add_recording_rule(lttngtest.lttngctl.UserTracepointEventRule("tp:tptest")) + session.start() + + # Connect live viewer + viewer = test_env.launch_live_viewer(session.name) + viewer.wait_until_connected() + + # Run second test app + late_app = test_env.launch_wait_trace_test_application( + 10, wait_before_exit=True, run_as=user + ) + late_app.trace() + late_app.wait_for_tracing_done() + + # Wait for the viewer to receive at least the expected number of events. + # If the session is stopped and destroyed immediately, there is a small + # window where new streams with per-PID buffers may not be sent to the + # live client. + while len(viewer.messages) < 10: + viewer.wait() + time.sleep(0.1) + + session.stop() + session.destroy() + + # The viewer should be disconnected then the session is destroyed + viewer.wait_until_disconnected() + tap.test( + not viewer.is_connected(), + "Live viewer exited gracefully", + ) + tap.test( + len(viewer.messages) == 10, + "Live viewer got {} / 10 expected events".format(len(viewer.messages)), + ) + + early_app.touch_exit_file() + early_app.wait_for_exit() + late_app.touch_exit_file() + late_app.wait_for_exit() + + +tap = lttngtest.TapGenerator(4) +for buffer_sharing_policy in [ + lttngtest.lttngctl.BufferSharingPolicy.PerUID, + lttngtest.lttngctl.BufferSharingPolicy.PerPID, +]: + with lttngtest.test_environment( + log=tap.diagnostic, with_relayd=True, with_sessiond=True + ) as test_env: + test_early_ust_app(tap, test_env, buffer_sharing_policy) + +sys.exit(0 if tap.is_successful else 1)