5446fb3ec08ef1636c39cdd371e064fc13abbc3f
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
13 from typing
import Any
, Callable
, Type
16 Test instrumentation coverage of C/C++ constructors and destructors by LTTng-UST
19 This test successively sets up a session, traces a test application, and then
20 reads the resulting trace to determine if all the expected events are present.
23 # Import in-tree test utils
24 test_utils_import_path
= pathlib
.Path(__file__
).absolute().parents
[3] / "utils"
25 sys
.path
.append(str(test_utils_import_path
))
30 # Determine if LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP is set. This will
31 # affect if certain events may or may not be expected when compiling with
33 # @see https://github.com/lttng/lttng-ust/blob/47fa3e4ed7ab43e034dc61fc1480f919f4ee51d0/include/lttng/ust-compiler.h#L51
35 compound_literal_on_heap
= False
36 process
= subprocess
.Popen(
39 str(test_utils_import_path
),
41 "gen-ust-events-constructor",
47 if process
.returncode
== 0:
48 compound_literal_on_heap
= True
50 expected_events_common
= [
52 "name": "tp:constructor_c_across_units_before_define",
55 "may_fail": compound_literal_on_heap
,
58 "name": "tp:constructor_cplusplus",
59 "msg": "global - across units before define",
61 "may_fail": compound_literal_on_heap
,
64 "name": "tp:constructor_c_same_unit_before_define",
67 "may_fail": compound_literal_on_heap
,
70 "name": "tp:constructor_c_same_unit_after_define",
73 "may_fail": compound_literal_on_heap
,
76 "name": "tp:constructor_cplusplus",
77 "msg": "global - same unit before define",
79 "may_fail": compound_literal_on_heap
,
82 "name": "tp:constructor_cplusplus",
83 "msg": "global - same unit after define",
85 "may_fail": compound_literal_on_heap
,
88 "name": "tp:constructor_c_across_units_after_define",
91 "may_fail": compound_literal_on_heap
,
94 "name": "tp:constructor_cplusplus",
95 "msg": "global - across units after define",
97 "may_fail": compound_literal_on_heap
,
100 "name": "tp:constructor_c_same_unit_before_provider",
103 "may_fail": compound_literal_on_heap
,
106 "name": "tp:constructor_c_same_unit_after_provider",
109 "may_fail": compound_literal_on_heap
,
112 "name": "tp:constructor_cplusplus",
113 "msg": "global - same unit before provider",
115 "may_fail": compound_literal_on_heap
,
118 "name": "tp:constructor_cplusplus",
119 "msg": "global - same unit after provider",
122 {"name": "tp:constructor_c_across_units_after_provider", "msg": None, "count": 0},
124 "name": "tp:constructor_cplusplus",
125 "msg": "global - across units after provider",
128 {"name": "tp:constructor_cplusplus", "msg": "main() local", "count": 0},
129 {"name": "tp:destructor_cplusplus", "msg": "main() local", "count": 0},
130 {"name": "tp:main", "msg": None, "count": 0},
132 "name": "tp:destructor_cplusplus",
133 "msg": "global - across units after provider",
137 "name": "tp:destructor_cplusplus",
138 "msg": "global - same unit after provider",
142 "name": "tp:destructor_cplusplus",
143 "msg": "global - same unit before provider",
145 "may_fail": compound_literal_on_heap
,
148 "name": "tp:destructor_cplusplus",
149 "msg": "global - across units after define",
151 "may_fail": compound_literal_on_heap
,
154 "name": "tp:destructor_cplusplus",
155 "msg": "global - same unit after define",
157 "may_fail": compound_literal_on_heap
,
160 "name": "tp:destructor_cplusplus",
161 "msg": "global - same unit before define",
163 "may_fail": compound_literal_on_heap
,
166 "name": "tp:destructor_cplusplus",
167 "msg": "global - across units before define",
169 "may_fail": compound_literal_on_heap
,
172 "name": "tp:destructor_c_across_units_after_provider",
175 "may_fail": compound_literal_on_heap
,
178 "name": "tp:destructor_c_same_unit_after_provider",
181 "may_fail": compound_literal_on_heap
,
184 "name": "tp:destructor_c_same_unit_before_provider",
187 "may_fail": compound_literal_on_heap
,
190 "name": "tp:destructor_c_across_units_after_define",
193 "may_fail": compound_literal_on_heap
,
196 "name": "tp:destructor_c_same_unit_after_define",
199 "may_fail": compound_literal_on_heap
,
202 "name": "tp:destructor_c_same_unit_before_define",
205 "may_fail": compound_literal_on_heap
,
208 "name": "tp:destructor_c_across_units_before_define",
211 "may_fail": compound_literal_on_heap
,
214 expected_events_tp_so
= [
215 {"name": "tp_so_c:constructor_c_provider_shared_library", "msg": None, "count": 0},
217 "name": "tp_so:constructor_cplusplus_provider_shared_library",
218 "msg": "global - shared library define and provider",
222 "name": "tp_so:constructor_cplusplus_provider_shared_library",
223 "msg": "main() local - shared library define and provider",
227 "name": "tp_so:destructor_cplusplus_provider_shared_library",
228 "msg": "main() local - shared library define and provider",
232 "name": "tp_so:destructor_cplusplus_provider_shared_library",
233 "msg": "global - shared library define and provider",
236 {"name": "tp_so_c:destructor_c_provider_shared_library", "msg": None, "count": 0},
238 expected_events_tp_a
= [
239 {"name": "tp_a_c:constructor_c_provider_static_archive", "msg": None, "count": 0},
241 "name": "tp_a:constructor_cplusplus_provider_static_archive",
242 "msg": "global - static archive define and provider",
244 "may_fail": compound_literal_on_heap
,
247 "name": "tp_a:constructor_cplusplus_provider_static_archive",
248 "msg": "main() local - static archive define and provider",
252 "name": "tp_a:destructor_cplusplus_provider_static_archive",
253 "msg": "main() local - static archive define and provider",
257 "name": "tp_a:destructor_cplusplus_provider_static_archive",
258 "msg": "global - static archive define and provider",
260 "may_fail": compound_literal_on_heap
,
262 {"name": "tp_a_c:destructor_c_provider_static_archive", "msg": None, "count": 0},
266 def capture_trace(tap
, test_env
, application
, description
):
267 # type: (lttngtest.TapGenerator, lttngtest._Environment) -> lttngtest.LocalSessionOutputLocation
268 tap
.diagnostic(description
)
270 session_output_location
= lttngtest
.LocalSessionOutputLocation(
271 test_env
.create_temporary_directory("trace")
274 client
= lttngtest
.LTTngClient(test_env
, log
=tap
.diagnostic
)
276 with tap
.case("Create a session") as test_case
:
277 session
= client
.create_session(output
=session_output_location
)
278 tap
.diagnostic("Created session `{session_name}`".format(session_name
=session
.name
))
281 "Add a channel to session `{session_name}`".format(session_name
=session
.name
)
283 channel
= session
.add_channel(lttngtest
.TracingDomain
.User
)
284 tap
.diagnostic("Created channel `{channel_name}`".format(channel_name
=channel
.name
))
286 # Enable all user space events, the default for a user tracepoint event rule.
287 channel
.add_recording_rule(lttngtest
.UserTracepointEventRule("tp*"))
290 "Start session `{session_name}`".format(session_name
=session
.name
)
294 test_app
= test_env
.launch_test_application(application
)
296 "Run test app '{}'".format(application
, session_name
=session
.name
)
298 test_app
.wait_for_exit()
301 "Stop session `{session_name}`".format(session_name
=session
.name
)
306 "Destroy session `{session_name}`".format(session_name
=session
.name
)
310 return session_output_location
313 def validate_trace(trace_location
, tap
, expected_events
):
314 # type: (pathlib.Path, lttngtest.TapGenerator)
315 unknown_event_count
= 0
317 for msg
in bt2
.TraceCollectionMessageIterator(str(trace_location
)):
318 if type(msg
) is not bt2
._EventMessageConst
:
322 for event
in expected_events
:
323 if event
["name"] == msg
.event
.name
and event
["msg"] is None:
325 event
["count"] = event
["count"] + 1
328 event
["name"] == msg
.event
.name
329 and event
["msg"] is not None
330 and event
["msg"] == msg
.event
["msg"]
333 event
["count"] = event
["count"] + 1
337 unknown_event_count
= unknown_event_count
+ 1
339 if "msg" in msg
.event
:
340 printmsg
= msg
.event
["msg"]
342 'Unexpected event name="{}" msg="{}" encountered'.format(
343 msg
.event
.name
, str(printmsg
)
347 for event
in expected_events
:
348 may_fail
= "may_fail" in event
.keys() and event
["may_fail"]
352 'Found expected event name="{}" msg="{}"'.format(
353 event
["name"], str(event
["msg"])
357 tap
.skip("Event '{}' may or may not be recorded".format(event
["name"]))
359 tap
.test(unknown_event_count
== 0, "Found no unexpected events")
365 "description": "Test user space constructor/destructor instrumentation coverage (C++ w/ static archive)",
366 "application": "gen-ust-events-constructor/gen-ust-events-constructor-a",
367 "expected_events": copy
.deepcopy(expected_events_common
+ expected_events_tp_a
),
368 "skip_if_application_not_present": False,
371 "description": "Test user space constructor/destructor instrumentation coverage (C++ w/ dynamic object",
372 "application": "gen-ust-events-constructor/gen-ust-events-constructor-so",
373 "expected_events": copy
.deepcopy(
374 expected_events_common
+ expected_events_tp_so
376 # This application is not be built when `NO_SHARED` is set in the
377 # configuration options.
378 "skip_if_application_not_present": True,
384 tap
= lttngtest
.TapGenerator(7 + len(test
["expected_events"]))
385 with lttngtest
.test_environment(with_sessiond
=True, log
=tap
.diagnostic
) as test_env
:
387 outputlocation
= capture_trace(
388 tap
, test_env
, test
["application"], test
["description"]
390 except FileNotFoundError
as fne
:
392 if test
["skip_if_application_not_present"]:
394 "Test application '{}' not found".format(test
["application"]),
395 tap
.remaining_test_cases
,
398 # Warning: validate_trace mutates test['expected_events']
399 validate_trace(outputlocation
.path
, tap
, test
["expected_events"])
400 success
= success
and tap
.is_successful
403 sys
.exit(0 if success
else 1)
This page took 0.038216 seconds and 4 git commands to generate.