Tests: Add test to cover live viewer hangs with an early inactive app
authorKienan Stewart <kstewart@efficios.com>
Fri, 15 Dec 2023 14:34:28 +0000 (09:34 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Thu, 24 Oct 2024 18:06:24 +0000 (14:06 -0400)
Refs: https://bugs.lttng.org/issues/1406

Change-Id: Iefe796d39ff39a04055acc5f95fc9440d5ee244a
Signed-off-by: Kienan Stewart <kstewart@efficios.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
tests/regression/Makefile.am
tests/regression/tools/live/Makefile.am
tests/regression/tools/live/test_early_inactive_app.py [new file with mode: 0755]

index 6537a33dd7b0651a420ece7a548d5463189ab85c..8afb7600ab995bed0886b7c55597322b3d3b34d4 100644 (file)
@@ -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 \
index a8042f67ddebf72e8b642fad0396497b3964f976..e2e7b7e17c1a8cec1d09e5439b98ededef8af332 100644 (file)
@@ -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 (executable)
index 0000000..925a1ab
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+#
+# SPDX-FileCopyrightText: 2024 Kienan Stewart <kstewart@efficios.com>
+# 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)
This page took 0.027314 seconds and 4 git commands to generate.