X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=tests%2Fregression%2Fust%2Fust-constructor%2Ftest_ust_constructor.py;h=130d0657da35a988148142d8a7071601629b26aa;hb=21b65d7fb06219571f42159b3667454c3104a8b7;hp=ea6a125d08b8d4d94045ffe4dc23c7bb44071dd5;hpb=d2455527078ecb1963372d67323a32e9be02cda2;p=lttng-tools.git diff --git a/tests/regression/ust/ust-constructor/test_ust_constructor.py b/tests/regression/ust/ust-constructor/test_ust_constructor.py index ea6a125d0..130d0657d 100755 --- a/tests/regression/ust/ust-constructor/test_ust_constructor.py +++ b/tests/regression/ust/ust-constructor/test_ust_constructor.py @@ -5,10 +5,11 @@ # # SPDX-License-Identifier: GPL-2.0-only -from cgi import test +import copy import pathlib import sys import os +import subprocess from typing import Any, Callable, Type """ @@ -26,85 +27,68 @@ sys.path.append(str(test_utils_import_path)) import lttngtest import bt2 -num_tests = 3 +# Determine if LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP is set. This will +# affect if certain events may or may not be expected when compiling with +# C++. +# @see https://github.com/lttng/lttng-ust/blob/47fa3e4ed7ab43e034dc61fc1480f919f4ee51d0/include/lttng/ust-compiler.h#L51 +# +compound_literal_on_heap = False +process = subprocess.Popen( + [ + os.path.join( + str(test_utils_import_path), + "testapp", + "gen-ust-events-constructor", + "uses_heap", + ) + ] +) +process.wait() +if process.returncode == 0: + compound_literal_on_heap = True -expected_events = [ - {"name": "tp_so:constructor_c_provider_shared_library", "msg": None, "count": 0}, - {"name": "tp_a:constructor_c_provider_static_archive", "msg": None, "count": 0}, - { - "name": "tp_so:constructor_cplusplus_provider_shared_library", - "msg": "global - shared library define and provider", - "count": 0, - }, - { - "name": "tp_a:constructor_cplusplus_provider_static_archive", - "msg": "global - static archive define and provider", - "count": 0, - }, - {"name": "tp:constructor_c_across_units_before_define", "msg": None, "count": 0}, +expected_events_common_cpp = [ { "name": "tp:constructor_cplusplus", "msg": "global - across units before define", "count": 0, + "may_fail": compound_literal_on_heap, }, - {"name": "tp:constructor_c_same_unit_before_define", "msg": None, "count": 0}, - {"name": "tp:constructor_c_same_unit_after_define", "msg": None, "count": 0}, { "name": "tp:constructor_cplusplus", "msg": "global - same unit before define", "count": 0, + "may_fail": compound_literal_on_heap, }, { "name": "tp:constructor_cplusplus", "msg": "global - same unit after define", "count": 0, + "may_fail": compound_literal_on_heap, }, - {"name": "tp:constructor_c_across_units_after_define", "msg": None, "count": 0}, { "name": "tp:constructor_cplusplus", "msg": "global - across units after define", "count": 0, + "may_fail": compound_literal_on_heap, }, - {"name": "tp:constructor_c_same_unit_before_provider", "msg": None, "count": 0}, - {"name": "tp:constructor_c_same_unit_after_provider", "msg": None, "count": 0}, { "name": "tp:constructor_cplusplus", "msg": "global - same unit before provider", "count": 0, + "may_fail": compound_literal_on_heap, }, { "name": "tp:constructor_cplusplus", "msg": "global - same unit after provider", "count": 0, }, - {"name": "tp:constructor_c_across_units_after_provider", "msg": None, "count": 0}, { "name": "tp:constructor_cplusplus", "msg": "global - across units after provider", "count": 0, }, {"name": "tp:constructor_cplusplus", "msg": "main() local", "count": 0}, - { - "name": "tp_so:constructor_cplusplus_provider_shared_library", - "msg": "main() local - shared library define and provider", - "count": 0, - }, - { - "name": "tp_a:constructor_cplusplus_provider_static_archive", - "msg": "main() local - static archive define and provider", - "count": 0, - }, - {"name": "tp:main", "msg": None, "count": 0}, - { - "name": "tp_a:destructor_cplusplus_provider_static_archive", - "msg": "main() local - static archive define and provider", - "count": 0, - }, - { - "name": "tp_so:destructor_cplusplus_provider_shared_library", - "msg": "main() local - shared library define and provider", - "count": 0, - }, {"name": "tp:destructor_cplusplus", "msg": "main() local", "count": 0}, { "name": "tp:destructor_cplusplus", @@ -120,30 +104,131 @@ expected_events = [ "name": "tp:destructor_cplusplus", "msg": "global - same unit before provider", "count": 0, + "may_fail": compound_literal_on_heap, }, { "name": "tp:destructor_cplusplus", "msg": "global - across units after define", "count": 0, + "may_fail": compound_literal_on_heap, }, { "name": "tp:destructor_cplusplus", "msg": "global - same unit after define", "count": 0, + "may_fail": compound_literal_on_heap, }, { "name": "tp:destructor_cplusplus", "msg": "global - same unit before define", "count": 0, + "may_fail": compound_literal_on_heap, }, { "name": "tp:destructor_cplusplus", "msg": "global - across units before define", "count": 0, + "may_fail": compound_literal_on_heap, }, +] + +expected_events_common = [ { - "name": "tp_a:destructor_cplusplus_provider_static_archive", - "msg": "global - static archive define and provider", + "name": "tp:constructor_c_across_units_before_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:constructor_c_same_unit_before_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:constructor_c_same_unit_after_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:constructor_c_across_units_after_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:constructor_c_same_unit_before_provider", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:constructor_c_same_unit_after_provider", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + {"name": "tp:constructor_c_across_units_after_provider", "msg": None, "count": 0}, + {"name": "tp:main", "msg": None, "count": 0}, + { + "name": "tp:destructor_c_across_units_after_provider", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:destructor_c_same_unit_after_provider", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:destructor_c_same_unit_before_provider", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:destructor_c_across_units_after_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:destructor_c_same_unit_after_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:destructor_c_same_unit_before_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp:destructor_c_across_units_before_define", + "msg": None, + "count": 0, + "may_fail": compound_literal_on_heap, + }, +] + +expected_events_tp_so_cpp = [ + { + "name": "tp_so:constructor_cplusplus_provider_shared_library", + "msg": "global - shared library define and provider", + "count": 0, + }, + { + "name": "tp_so:constructor_cplusplus_provider_shared_library", + "msg": "main() local - shared library define and provider", + "count": 0, + }, + { + "name": "tp_so:destructor_cplusplus_provider_shared_library", + "msg": "main() local - shared library define and provider", "count": 0, }, { @@ -151,29 +236,53 @@ expected_events = [ "msg": "global - shared library define and provider", "count": 0, }, - {"name": "tp:destructor_c_across_units_after_provider", "msg": None, "count": 0}, - {"name": "tp:destructor_c_same_unit_after_provider", "msg": None, "count": 0}, - {"name": "tp:destructor_c_same_unit_before_provider", "msg": None, "count": 0}, - {"name": "tp:destructor_c_across_units_after_define", "msg": None, "count": 0}, - {"name": "tp:destructor_c_same_unit_after_define", "msg": None, "count": 0}, - {"name": "tp:destructor_c_same_unit_before_define", "msg": None, "count": 0}, - {"name": "tp:destructor_c_across_units_before_define", "msg": None, "count": 0}, - {"name": "tp_a:destructor_c_provider_static_archive", "msg": None, "count": 0}, - {"name": "tp_so:destructor_c_provider_shared_library", "msg": None, "count": 0}, +] + +expected_events_tp_so = [ + {"name": "tp_so_c:constructor_c_provider_shared_library", "msg": None, "count": 0}, + {"name": "tp_so_c:destructor_c_provider_shared_library", "msg": None, "count": 0}, +] + +expected_events_tp_a_cpp = [ + { + "name": "tp_a:constructor_cplusplus_provider_static_archive", + "msg": "global - static archive define and provider", + "count": 0, + "may_fail": compound_literal_on_heap, + }, + { + "name": "tp_a:constructor_cplusplus_provider_static_archive", + "msg": "main() local - static archive define and provider", + "count": 0, + }, + { + "name": "tp_a:destructor_cplusplus_provider_static_archive", + "msg": "main() local - static archive define and provider", + "count": 0, + }, + { + "name": "tp_a:destructor_cplusplus_provider_static_archive", + "msg": "global - static archive define and provider", + "count": 0, + "may_fail": compound_literal_on_heap, + }, +] + +expected_events_tp_a = [ + {"name": "tp_a_c:constructor_c_provider_static_archive", "msg": None, "count": 0}, + {"name": "tp_a_c:destructor_c_provider_static_archive", "msg": None, "count": 0}, ] -def capture_trace(tap, test_env): +def capture_trace(tap, test_env, application, description): # type: (lttngtest.TapGenerator, lttngtest._Environment) -> lttngtest.LocalSessionOutputLocation - tap.diagnostic( - "Capture trace from application with instrumented C/C++ constructors/destructors" - ) + tap.diagnostic(description) session_output_location = lttngtest.LocalSessionOutputLocation( test_env.create_temporary_directory("trace") ) - client: lttngtest.Controller = lttngtest.LTTngClient(test_env, log=tap.diagnostic) + client = lttngtest.LTTngClient(test_env, log=tap.diagnostic) with tap.case("Create a session") as test_case: session = client.create_session(output=session_output_location) @@ -188,17 +297,32 @@ def capture_trace(tap, test_env): # Enable all user space events, the default for a user tracepoint event rule. channel.add_recording_rule(lttngtest.UserTracepointEventRule("tp*")) - session.start() - test_app = test_env.launch_trace_test_constructor_application() - test_app.wait_for_exit() - session.stop() - session.destroy() + with tap.case( + "Start session `{session_name}`".format(session_name=session.name) + ) as test_case: + session.start() + + test_app = test_env.launch_test_application(application) + with tap.case( + "Run test app '{}'".format(application, session_name=session.name) + ) as test_case: + test_app.wait_for_exit() + + with tap.case( + "Stop session `{session_name}`".format(session_name=session.name) + ) as test_case: + session.stop() + + with tap.case( + "Destroy session `{session_name}`".format(session_name=session.name) + ) as test_case: + session.destroy() + return session_output_location -def validate_trace(trace_location, tap) -> bool: - # type: (pathlib.Path, lttngtest.TapGenerator) -> bool - success = True +def validate_trace(trace_location, tap, expected_events): + # type: (pathlib.Path, lttngtest.TapGenerator) unknown_event_count = 0 for msg in bt2.TraceCollectionMessageIterator(str(trace_location)): @@ -219,6 +343,7 @@ def validate_trace(trace_location, tap) -> bool: found = True event["count"] = event["count"] + 1 break + if found == False: unknown_event_count = unknown_event_count + 1 printmsg = None @@ -231,22 +356,83 @@ def validate_trace(trace_location, tap) -> bool: ) for event in expected_events: - if event["count"] != 1: - success = False - tap.diagnostic("Expected event {} not found".format(event["name"])) - if unknown_event_count != 0: - success = False - return success - - -tap = lttngtest.TapGenerator(num_tests) -tap.diagnostic("Test user space constructor/destructor instrumentation coverage") - -with lttngtest.test_environment(with_sessiond=True, log=tap.diagnostic) as test_env: - outputlocation = capture_trace(tap, test_env) - tap.test( - validate_trace(outputlocation.path, tap), - "Validate that trace constains expected events", - ) + may_fail = "may_fail" in event.keys() and event["may_fail"] + if not may_fail: + tap.test( + event["count"] == 1, + '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 tap.is_successful else 1) +sys.exit(0 if success else 1)