From f506900f904887310c26a441ea86352fc27242c2 Mon Sep 17 00:00:00 2001 From: Kienan Stewart Date: Thu, 7 Mar 2024 15:20:17 -0500 Subject: [PATCH] tests: Split test_ust_constructor into several tests MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Observed issue ============== TAP parsers fail when parsing a single executable that contains several plans. Eg., ``` ok 44 - Found no unexpected events PASS: ust/ust-constructor/test_ust_constructor.py 44 - Found no unexpected events 1..44 ERROR: ust/ust-constructor/test_ust_constructor.py - multiple test plans ok 1 - Create a session ERROR: ust/ust-constructor/test_ust_constructor.py 1 - Create a session # UNPLANNED ``` and ``` 14:03:23 org.tap4j.parser.ParserException: Error parsing TAP Stream: Duplicated TAP Plan found. 14:03:23 at org.tap4j.parser.Tap13Parser.parseTapStream(Tap13Parser.java:257) 14:03:23 at org.tap4j.parser.Tap13Parser.parseFile(Tap13Parser.java:231) 14:03:23 at org.tap4j.plugin.TapParser.parse(TapParser.java:172) 14:03:23 at org.tap4j.plugin.TapPublisher.loadResults(TapPublisher.java:475) 14:03:23 at org.tap4j.plugin.TapPublisher.performImpl(TapPublisher.java:352) 14:03:23 at org.tap4j.plugin.TapPublisher.perform(TapPublisher.java:312) 14:03:23 at jenkins.tasks.SimpleBuildStep.perform(SimpleBuildStep.java:123) 14:03:23 at hudson.tasks.BuildStepCompatibilityLayer.perform(BuildStepCompatibilityLayer.java:80) 14:03:23 at hudson.tasks.BuildStepMonitor$1.perform(BuildStepMonitor.java:20) 14:03:23 at hudson.model.AbstractBuild$AbstractBuildExecution.perform(AbstractBuild.java:818) 14:03:23 at hudson.model.AbstractBuild$AbstractBuildExecution.performAllBuildSteps(AbstractBuild.java:767) 14:03:23 at hudson.model.Build$BuildExecution.post2(Build.java:179) 14:03:23 at hudson.model.AbstractBuild$AbstractBuildExecution.post(AbstractBuild.java:711) 14:03:23 at hudson.model.Run.execute(Run.java:1918) 14:03:23 at hudson.matrix.MatrixRun.run(MatrixRun.java:153) 14:03:23 at hudson.model.ResourceController.execute(ResourceController.java:101) 14:03:23 at hudson.model.Executor.run(Executor.java:442) 14:03:23 Caused by: org.tap4j.parser.ParserException: Duplicated TAP Plan found. 14:03:23 at org.tap4j.parser.Tap13Parser.parseLine(Tap13Parser.java:354) 14:03:23 at org.tap4j.parser.Tap13Parser.parseTapStream(Tap13Parser.java:252) 14:03:23 ... 16 more ``` Cause ===== 09a872ef0b4e1432329aa42fecc61f50e9baa367 introduced multiple plans in to test_ust_constructor Solution ======== Split the script into several smaller test scripts sharing a common import for data and the bulk of execution. Known drawbacks =============== None. Signed-off-by: Kienan Stewart Signed-off-by: Jérémie Galarneau Change-Id: I81649d714afe0e325996b730d5c72cfd5b28d1f8 --- tests/regression/Makefile.am | 5 +- .../ust/ust-constructor/Makefile.am | 16 +++- .../ust/ust-constructor/__init__.py | 4 + .../test_ust_constructor_c_dynamic.py | 55 ++++++++++++ .../test_ust_constructor_c_static.py | 53 ++++++++++++ .../test_ust_constructor_cpp_dynamic.py | 58 +++++++++++++ .../test_ust_constructor_cpp_static.py | 58 +++++++++++++ ...nstructor.py => ust_constructor_common.py} | 83 +------------------ 8 files changed, 249 insertions(+), 83 deletions(-) create mode 100644 tests/regression/ust/ust-constructor/__init__.py create mode 100755 tests/regression/ust/ust-constructor/test_ust_constructor_c_dynamic.py create mode 100755 tests/regression/ust/ust-constructor/test_ust_constructor_c_static.py create mode 100755 tests/regression/ust/ust-constructor/test_ust_constructor_cpp_dynamic.py create mode 100755 tests/regression/ust/ust-constructor/test_ust_constructor_cpp_static.py rename tests/regression/ust/ust-constructor/{test_ust_constructor.py => ust_constructor_common.py} (77%) mode change 100755 => 100644 diff --git a/tests/regression/Makefile.am b/tests/regression/Makefile.am index 05cfbc54c..ca3fb2d52 100644 --- a/tests/regression/Makefile.am +++ b/tests/regression/Makefile.am @@ -91,7 +91,10 @@ TESTS += ust/before-after/test_before_after \ ust/blocking/test_blocking \ ust/multi-lib/test_multi_lib \ ust/rotation-destroy-flush/test_rotation_destroy_flush \ - ust/ust-constructor/test_ust_constructor.py \ + ust/ust-constructor/test_ust_constructor_c_dynamic.py \ + ust/ust-constructor/test_ust_constructor_c_static.py \ + ust/ust-constructor/test_ust_constructor_cpp_dynamic.py \ + ust/ust-constructor/test_ust_constructor_cpp_static.py \ tools/metadata/test_ust \ tools/relayd-grouping/test_ust \ tools/trigger/rate-policy/test_ust_rate_policy diff --git a/tests/regression/ust/ust-constructor/Makefile.am b/tests/regression/ust/ust-constructor/Makefile.am index 4201fdfe8..89267d38d 100644 --- a/tests/regression/ust/ust-constructor/Makefile.am +++ b/tests/regression/ust/ust-constructor/Makefile.am @@ -1,7 +1,19 @@ # SPDX-License-Identifier: GPL-2.0-only -noinst_SCRIPTS = test_ust_constructor.py -EXTRA_DIST = test_ust_constructor.py +noinst_SCRIPTS = __init__.py \ + test_ust_constructor_c_dynamic.py \ + test_ust_constructor_c_static.py \ + test_ust_constructor_cpp_dynamic.py \ + test_ust_constructor_cpp_static.py \ + ust_constructor_common.py + +EXTRA_DIST = __init__.py \ + test_ust_constructor_c_dynamic.py \ + test_ust_constructor_c_static.py \ + test_ust_constructor_cpp_dynamic.py \ + test_ust_constructor_cpp_static.py \ + ust_constructor_common.py + all-local: @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ diff --git a/tests/regression/ust/ust-constructor/__init__.py b/tests/regression/ust/ust-constructor/__init__.py new file mode 100644 index 000000000..5acd59f54 --- /dev/null +++ b/tests/regression/ust/ust-constructor/__init__.py @@ -0,0 +1,4 @@ +#!/usr/bin/env python3 +# +# SPDX-FileCopyrightText: Kienan Stewart +# SPDX-License-Identifier: GPL-2.0-only diff --git a/tests/regression/ust/ust-constructor/test_ust_constructor_c_dynamic.py b/tests/regression/ust/ust-constructor/test_ust_constructor_c_dynamic.py new file mode 100755 index 000000000..93ef4c14c --- /dev/null +++ b/tests/regression/ust/ust-constructor/test_ust_constructor_c_dynamic.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python3 +# +# SPDX-FileCopyrightText: Kienan Stewart +# SPDX-License-Identifier: GPL-2.0-only +# + +""" +Test instrumentation coverage of C constructors and destructors by LTTng-UST +tracepoints with a dynamic object. + +This test successively sets up a session, traces a test application, and then +reads the resulting trace to determine if all the expected events are present. +""" + +import copy +import pathlib +import sys + +# Import in-tree test utils +test_utils_import_path = pathlib.Path(__file__).absolute().parents[3] / "utils" +sys.path.append(str(test_utils_import_path)) + +import lttngtest +import ust_constructor_common as ust + +test = { + "description": "Test user space constructor/destructor instrumentation coverage (C w/ dynamic object)", + "application": "gen-ust-events-constructor/gen-ust-events-c-constructor-so", + "expected_events": copy.deepcopy( + ust.expected_events_common + ust.expected_events_tp_so + ), + # This application is not be built when `NO_SHARED` is set in the + # configuration options. + "skip_if_application_not_present": True, +} + +tap = lttngtest.TapGenerator(7 + len(test["expected_events"])) +with lttngtest.test_environment(with_sessiond=True, log=tap.diagnostic) as test_env: + try: + outputlocation = ust.capture_trace( + tap, test_env, test["application"], test["description"] + ) + except FileNotFoundError as fne: + tap.diagnostic(fne) + if test["skip_if_application_not_present"]: + tap.skip( + "Test application '{}' not found".format(test["application"]), + tap.remaining_test_cases, + ) + sys.exit(0) + # Warning: validate_trace mutates test['expected_events'] + ust.validate_trace(outputlocation.path, tap, test["expected_events"]) + + +sys.exit(0 if tap.is_successful else 1) diff --git a/tests/regression/ust/ust-constructor/test_ust_constructor_c_static.py b/tests/regression/ust/ust-constructor/test_ust_constructor_c_static.py new file mode 100755 index 000000000..4fb509a1f --- /dev/null +++ b/tests/regression/ust/ust-constructor/test_ust_constructor_c_static.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python3 +# +# SPDX-FileCopyrightText: Kienan Stewart +# SPDX-License-Identifier: GPL-2.0-only +# + +""" +Test instrumentation coverage of C constructors and destructors by LTTng-UST +tracepoints with a static archive. + +This test successively sets up a session, traces a test application, and then +reads the resulting trace to determine if all the expected events are present. +""" + +import copy +import pathlib +import sys + +# Import in-tree test utils +test_utils_import_path = pathlib.Path(__file__).absolute().parents[3] / "utils" +sys.path.append(str(test_utils_import_path)) + +import lttngtest +import ust_constructor_common as ust + +test = { + "description": "Test user space constructor/destructor instrumentation coverage (C w/ static archive)", + "application": "gen-ust-events-constructor/gen-ust-events-c-constructor-a", + "expected_events": copy.deepcopy( + ust.expected_events_common + ust.expected_events_tp_a + ), + "skip_if_application_not_present": False, +} + +tap = lttngtest.TapGenerator(7 + len(test["expected_events"])) +with lttngtest.test_environment(with_sessiond=True, log=tap.diagnostic) as test_env: + try: + outputlocation = ust.capture_trace( + tap, test_env, test["application"], test["description"] + ) + except FileNotFoundError as fne: + tap.diagnostic(fne) + if test["skip_if_application_not_present"]: + tap.skip( + "Test application '{}' not found".format(test["application"]), + tap.remaining_test_cases, + ) + sys.exit(0) + # Warning: validate_trace mutates test['expected_events'] + ust.validate_trace(outputlocation.path, tap, test["expected_events"]) + + +sys.exit(0 if tap.is_successful else 1) diff --git a/tests/regression/ust/ust-constructor/test_ust_constructor_cpp_dynamic.py b/tests/regression/ust/ust-constructor/test_ust_constructor_cpp_dynamic.py new file mode 100755 index 000000000..cc7988ac1 --- /dev/null +++ b/tests/regression/ust/ust-constructor/test_ust_constructor_cpp_dynamic.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# +# SPDX-FileCopyrightText: Kienan Stewart +# SPDX-License-Identifier: GPL-2.0-only +# + +""" +Test instrumentation coverage of C++ constructors and destructors by LTTng-UST +tracepoints with a dynamic object. + +This test successively sets up a session, traces a test application, and then +reads the resulting trace to determine if all the expected events are present. +""" + +import copy +import pathlib +import sys + +# Import in-tree test utils +test_utils_import_path = pathlib.Path(__file__).absolute().parents[3] / "utils" +sys.path.append(str(test_utils_import_path)) + +import lttngtest +import ust_constructor_common as ust + +test = { + "description": "Test user space constructor/destructor instrumentation coverage (C++ w/ dynamic object", + "application": "gen-ust-events-constructor/gen-ust-events-constructor-so", + "expected_events": copy.deepcopy( + ust.expected_events_common + + ust.expected_events_common_cpp + + ust.expected_events_tp_so + + ust.expected_events_tp_so_cpp + ), + # This application is not be built when `NO_SHARED` is set in the + # configuration options. + "skip_if_application_not_present": True, +} + +tap = lttngtest.TapGenerator(7 + len(test["expected_events"])) +with lttngtest.test_environment(with_sessiond=True, log=tap.diagnostic) as test_env: + try: + outputlocation = ust.capture_trace( + tap, test_env, test["application"], test["description"] + ) + except FileNotFoundError as fne: + tap.diagnostic(fne) + if test["skip_if_application_not_present"]: + tap.skip( + "Test application '{}' not found".format(test["application"]), + tap.remaining_test_cases, + ) + sys.exit(0) + # Warning: validate_trace mutates test['expected_events'] + ust.validate_trace(outputlocation.path, tap, test["expected_events"]) + + +sys.exit(0 if tap.is_successful else 1) diff --git a/tests/regression/ust/ust-constructor/test_ust_constructor_cpp_static.py b/tests/regression/ust/ust-constructor/test_ust_constructor_cpp_static.py new file mode 100755 index 000000000..db1570df4 --- /dev/null +++ b/tests/regression/ust/ust-constructor/test_ust_constructor_cpp_static.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2022 Jérémie Galarneau +# Copyright (C) 2023 Mathieu Desnoyers +# +# SPDX-License-Identifier: GPL-2.0-only + + +""" +Test instrumentation coverage of C++ constructors and destructors by LTTng-UST +tracepoints with a static archive. + +This test successively sets up a session, traces a test application, and then +reads the resulting trace to determine if all the expected events are present. +""" + +import copy +import pathlib +import sys + +# Import in-tree test utils +test_utils_import_path = pathlib.Path(__file__).absolute().parents[3] / "utils" +sys.path.append(str(test_utils_import_path)) + +import lttngtest +import ust_constructor_common as ust + +test = { + "description": "Test user space constructor/destructor instrumentation coverage (C++ w/ static archive)", + "application": "gen-ust-events-constructor/gen-ust-events-constructor-a", + "expected_events": copy.deepcopy( + ust.expected_events_common + + ust.expected_events_common_cpp + + ust.expected_events_tp_a + + ust.expected_events_tp_a_cpp + ), + "skip_if_application_not_present": False, +} + +tap = lttngtest.TapGenerator(7 + len(test["expected_events"])) +with lttngtest.test_environment(with_sessiond=True, log=tap.diagnostic) as test_env: + try: + outputlocation = ust.capture_trace( + tap, test_env, test["application"], test["description"] + ) + except FileNotFoundError as fne: + tap.diagnostic(fne) + if test["skip_if_application_not_present"]: + tap.skip( + "Test application '{}' not found".format(test["application"]), + tap.remaining_test_cases, + ) + sys.exit(0) + # Warning: validate_trace mutates test['expected_events'] + ust.validate_trace(outputlocation.path, tap, test["expected_events"]) + + +sys.exit(0 if tap.is_successful else 1) diff --git a/tests/regression/ust/ust-constructor/test_ust_constructor.py b/tests/regression/ust/ust-constructor/ust_constructor_common.py old mode 100755 new mode 100644 similarity index 77% rename from tests/regression/ust/ust-constructor/test_ust_constructor.py rename to tests/regression/ust/ust-constructor/ust_constructor_common.py index 130d0657d..0ea724810 --- a/tests/regression/ust/ust-constructor/test_ust_constructor.py +++ b/tests/regression/ust/ust-constructor/ust_constructor_common.py @@ -1,9 +1,8 @@ #!/usr/bin/env python3 # -# Copyright (C) 2022 Jérémie Galarneau -# Copyright (C) 2023 Mathieu Desnoyers +# SPDX-FileCopyrightText: 2024 Kienan Stewart +# SPDX-License-Identifer: GPL-2.0-only # -# SPDX-License-Identifier: GPL-2.0-only import copy import pathlib @@ -12,14 +11,6 @@ import os import subprocess from typing import Any, Callable, Type -""" -Test instrumentation coverage of C/C++ constructors and destructors by LTTng-UST -tracepoints. - -This test successively sets up a session, traces a test application, and then -reads the resulting trace to determine if all the expected events are present. -""" - # Import in-tree test utils test_utils_import_path = pathlib.Path(__file__).absolute().parents[3] / "utils" sys.path.append(str(test_utils_import_path)) @@ -363,76 +354,8 @@ def validate_trace(trace_location, tap, expected_events): 'Found expected event name="{}" msg="{}"'.format( event["name"], str(event["msg"]) ), - ), + ) else: tap.skip("Event '{}' may or may not be recorded".format(event["name"])) tap.test(unknown_event_count == 0, "Found no unexpected events") - - -success = True -tests = [ - { - "description": "Test user space constructor/destructor instrumentation coverage (C++ w/ static archive)", - "application": "gen-ust-events-constructor/gen-ust-events-constructor-a", - "expected_events": copy.deepcopy( - expected_events_common - + expected_events_common_cpp - + expected_events_tp_a - + expected_events_tp_a_cpp - ), - "skip_if_application_not_present": False, - }, - { - "description": "Test user space constructor/destructor instrumentation coverage (C++ w/ dynamic object", - "application": "gen-ust-events-constructor/gen-ust-events-constructor-so", - "expected_events": copy.deepcopy( - expected_events_common - + expected_events_common_cpp - + expected_events_tp_so - + expected_events_tp_so_cpp - ), - # This application is not be built when `NO_SHARED` is set in the - # configuration options. - "skip_if_application_not_present": True, - }, - { - "description": "Test user space constructor/destructor instrumentation coverage (C w/ static archive)", - "application": "gen-ust-events-constructor/gen-ust-events-c-constructor-a", - "expected_events": copy.deepcopy(expected_events_common + expected_events_tp_a), - "skip_if_application_not_present": False, - }, - { - "description": "Test user space constructor/destructor instrumentation coverage (C w/ dynamic object", - "application": "gen-ust-events-constructor/gen-ust-events-c-constructor-so", - "expected_events": copy.deepcopy( - expected_events_common + expected_events_tp_so - ), - # This application is not be built when `NO_SHARED` is set in the - # configuration options. - "skip_if_application_not_present": True, - }, -] - -success = True -for test in tests: - tap = lttngtest.TapGenerator(7 + len(test["expected_events"])) - with lttngtest.test_environment(with_sessiond=True, log=tap.diagnostic) as test_env: - try: - outputlocation = capture_trace( - tap, test_env, test["application"], test["description"] - ) - except FileNotFoundError as fne: - tap.diagnostic(fne) - if test["skip_if_application_not_present"]: - tap.skip( - "Test application '{}' not found".format(test["application"]), - tap.remaining_test_cases, - ) - break - # Warning: validate_trace mutates test['expected_events'] - validate_trace(outputlocation.path, tap, test["expected_events"]) - success = success and tap.is_successful - - -sys.exit(0 if success else 1) -- 2.34.1