30e48ff1306f8b8f32b47ad3d625b5c341bec97e
3 # Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 # Copyright (C) 2023 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6 # SPDX-License-Identifier: GPL-2.0-only
12 from typing
import Any
, Callable
, Type
15 Test instrumentation coverage of C/C++ constructors and destructors by LTTng-UST
18 This test successively sets up a session, traces a test application, and then
19 reads the resulting trace to determine if all the expected events are present.
22 # Import in-tree test utils
23 test_utils_import_path
= pathlib
.Path(__file__
).absolute().parents
[3] / "utils"
24 sys
.path
.append(str(test_utils_import_path
))
30 {"name": "tp_so:constructor_c_provider_shared_library", "msg": None, "count": 0},
31 {"name": "tp_a:constructor_c_provider_static_archive", "msg": None, "count": 0},
33 "name": "tp_so:constructor_cplusplus_provider_shared_library",
34 "msg": "global - shared library define and provider",
38 "name": "tp_a:constructor_cplusplus_provider_static_archive",
39 "msg": "global - static archive define and provider",
42 {"name": "tp:constructor_c_across_units_before_define", "msg": None, "count": 0},
44 "name": "tp:constructor_cplusplus",
45 "msg": "global - across units before define",
48 {"name": "tp:constructor_c_same_unit_before_define", "msg": None, "count": 0},
49 {"name": "tp:constructor_c_same_unit_after_define", "msg": None, "count": 0},
51 "name": "tp:constructor_cplusplus",
52 "msg": "global - same unit before define",
56 "name": "tp:constructor_cplusplus",
57 "msg": "global - same unit after define",
60 {"name": "tp:constructor_c_across_units_after_define", "msg": None, "count": 0},
62 "name": "tp:constructor_cplusplus",
63 "msg": "global - across units after define",
66 {"name": "tp:constructor_c_same_unit_before_provider", "msg": None, "count": 0},
67 {"name": "tp:constructor_c_same_unit_after_provider", "msg": None, "count": 0},
69 "name": "tp:constructor_cplusplus",
70 "msg": "global - same unit before provider",
74 "name": "tp:constructor_cplusplus",
75 "msg": "global - same unit after provider",
78 {"name": "tp:constructor_c_across_units_after_provider", "msg": None, "count": 0},
80 "name": "tp:constructor_cplusplus",
81 "msg": "global - across units after provider",
84 {"name": "tp:constructor_cplusplus", "msg": "main() local", "count": 0},
86 "name": "tp_so:constructor_cplusplus_provider_shared_library",
87 "msg": "main() local - shared library define and provider",
91 "name": "tp_a:constructor_cplusplus_provider_static_archive",
92 "msg": "main() local - static archive define and provider",
95 {"name": "tp:main", "msg": None, "count": 0},
97 "name": "tp_a:destructor_cplusplus_provider_static_archive",
98 "msg": "main() local - static archive define and provider",
102 "name": "tp_so:destructor_cplusplus_provider_shared_library",
103 "msg": "main() local - shared library define and provider",
106 {"name": "tp:destructor_cplusplus", "msg": "main() local", "count": 0},
108 "name": "tp:destructor_cplusplus",
109 "msg": "global - across units after provider",
113 "name": "tp:destructor_cplusplus",
114 "msg": "global - same unit after provider",
118 "name": "tp:destructor_cplusplus",
119 "msg": "global - same unit before provider",
123 "name": "tp:destructor_cplusplus",
124 "msg": "global - across units after define",
128 "name": "tp:destructor_cplusplus",
129 "msg": "global - same unit after define",
133 "name": "tp:destructor_cplusplus",
134 "msg": "global - same unit before define",
138 "name": "tp:destructor_cplusplus",
139 "msg": "global - across units before define",
143 "name": "tp_a:destructor_cplusplus_provider_static_archive",
144 "msg": "global - static archive define and provider",
148 "name": "tp_so:destructor_cplusplus_provider_shared_library",
149 "msg": "global - shared library define and provider",
152 {"name": "tp:destructor_c_across_units_after_provider", "msg": None, "count": 0},
153 {"name": "tp:destructor_c_same_unit_after_provider", "msg": None, "count": 0},
154 {"name": "tp:destructor_c_same_unit_before_provider", "msg": None, "count": 0},
155 {"name": "tp:destructor_c_across_units_after_define", "msg": None, "count": 0},
156 {"name": "tp:destructor_c_same_unit_after_define", "msg": None, "count": 0},
157 {"name": "tp:destructor_c_same_unit_before_define", "msg": None, "count": 0},
158 {"name": "tp:destructor_c_across_units_before_define", "msg": None, "count": 0},
159 {"name": "tp_a:destructor_c_provider_static_archive", "msg": None, "count": 0},
160 {"name": "tp_so:destructor_c_provider_shared_library", "msg": None, "count": 0},
163 num_tests
= 7 + len(expected_events
)
166 def capture_trace(tap
, test_env
):
167 # type: (lttngtest.TapGenerator, lttngtest._Environment) -> lttngtest.LocalSessionOutputLocation
169 "Capture trace from application with instrumented C/C++ constructors/destructors"
172 session_output_location
= lttngtest
.LocalSessionOutputLocation(
173 test_env
.create_temporary_directory("trace")
176 client
= lttngtest
.LTTngClient(test_env
, log
=tap
.diagnostic
)
178 with tap
.case("Create a session") as test_case
:
179 session
= client
.create_session(output
=session_output_location
)
180 tap
.diagnostic("Created session `{session_name}`".format(session_name
=session
.name
))
183 "Add a channel to session `{session_name}`".format(session_name
=session
.name
)
185 channel
= session
.add_channel(lttngtest
.TracingDomain
.User
)
186 tap
.diagnostic("Created channel `{channel_name}`".format(channel_name
=channel
.name
))
188 # Enable all user space events, the default for a user tracepoint event rule.
189 channel
.add_recording_rule(lttngtest
.UserTracepointEventRule("tp*"))
192 "Start session `{session_name}`".format(session_name
=session
.name
)
196 test_app
= test_env
.launch_trace_test_constructor_application()
197 with tap
.case("Run test app".format(session_name
=session
.name
)) as test_case
:
198 test_app
.wait_for_exit()
201 "Stop session `{session_name}`".format(session_name
=session
.name
)
206 "Destroy session `{session_name}`".format(session_name
=session
.name
)
210 return session_output_location
213 def validate_trace(trace_location
, tap
):
214 # type: (pathlib.Path, lttngtest.TapGenerator)
215 unknown_event_count
= 0
217 for msg
in bt2
.TraceCollectionMessageIterator(str(trace_location
)):
218 if type(msg
) is not bt2
._EventMessageConst
:
222 for event
in expected_events
:
223 if event
["name"] == msg
.event
.name
and event
["msg"] is None:
225 event
["count"] = event
["count"] + 1
228 event
["name"] == msg
.event
.name
229 and event
["msg"] is not None
230 and event
["msg"] == msg
.event
["msg"]
233 event
["count"] = event
["count"] + 1
237 unknown_event_count
= unknown_event_count
+ 1
239 if "msg" in msg
.event
:
240 printmsg
= msg
.event
["msg"]
242 'Unexpected event name="{}" msg="{}" encountered'.format(
243 msg
.event
.name
, str(printmsg
)
247 for event
in expected_events
:
250 'Found expected event name="{}" msg="{}"'.format(
251 event
["name"], str(event
["msg"])
255 tap
.test(unknown_event_count
== 0, "Found no unexpected events")
258 tap
= lttngtest
.TapGenerator(num_tests
)
259 tap
.diagnostic("Test user space constructor/destructor instrumentation coverage")
261 with lttngtest
.test_environment(with_sessiond
=True, log
=tap
.diagnostic
) as test_env
:
262 outputlocation
= capture_trace(tap
, test_env
)
263 validate_trace(outputlocation
.path
, tap
)
265 sys
.exit(0 if tap
.is_successful
else 1)
This page took 0.03532 seconds and 3 git commands to generate.