f4d9cedf04b86cab779d1f2bb997931843596914
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
))
29 # Determine if LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP is set. This will
30 # affect if certain events may or may not be expected when compiling with
32 # @see https://github.com/lttng/lttng-ust/blob/47fa3e4ed7ab43e034dc61fc1480f919f4ee51d0/include/lttng/ust-compiler.h#L51
34 compound_literal_on_heap
= False
35 process
= subprocess
.Popen(
38 str(test_utils_import_path
),
40 "gen-ust-events-constructor",
46 if process
.returncode
== 0:
47 compound_literal_on_heap
= True
50 {"name": "tp_so:constructor_c_provider_shared_library", "msg": None, "count": 0},
52 "name": "tp_a:constructor_c_provider_static_archive",
55 "may_fail": compound_literal_on_heap
,
58 "name": "tp_so:constructor_cplusplus_provider_shared_library",
59 "msg": "global - shared library define and provider",
63 "name": "tp_a:constructor_cplusplus_provider_static_archive",
64 "msg": "global - static archive define and provider",
66 "may_fail": compound_literal_on_heap
,
69 "name": "tp:constructor_c_across_units_before_define",
72 "may_fail": compound_literal_on_heap
,
75 "name": "tp:constructor_cplusplus",
76 "msg": "global - across units before define",
78 "may_fail": compound_literal_on_heap
,
81 "name": "tp:constructor_c_same_unit_before_define",
84 "may_fail": compound_literal_on_heap
,
87 "name": "tp:constructor_c_same_unit_after_define",
90 "may_fail": compound_literal_on_heap
,
93 "name": "tp:constructor_cplusplus",
94 "msg": "global - same unit before define",
96 "may_fail": compound_literal_on_heap
,
99 "name": "tp:constructor_cplusplus",
100 "msg": "global - same unit after define",
102 "may_fail": compound_literal_on_heap
,
105 "name": "tp:constructor_c_across_units_after_define",
108 "may_fail": compound_literal_on_heap
,
111 "name": "tp:constructor_cplusplus",
112 "msg": "global - across units after define",
114 "may_fail": compound_literal_on_heap
,
117 "name": "tp:constructor_c_same_unit_before_provider",
120 "may_fail": compound_literal_on_heap
,
123 "name": "tp:constructor_c_same_unit_after_provider",
126 "may_fail": compound_literal_on_heap
,
129 "name": "tp:constructor_cplusplus",
130 "msg": "global - same unit before provider",
132 "may_fail": compound_literal_on_heap
,
135 "name": "tp:constructor_cplusplus",
136 "msg": "global - same unit after provider",
139 {"name": "tp:constructor_c_across_units_after_provider", "msg": None, "count": 0},
141 "name": "tp:constructor_cplusplus",
142 "msg": "global - across units after provider",
145 {"name": "tp:constructor_cplusplus", "msg": "main() local", "count": 0},
147 "name": "tp_so:constructor_cplusplus_provider_shared_library",
148 "msg": "main() local - shared library define and provider",
152 "name": "tp_a:constructor_cplusplus_provider_static_archive",
153 "msg": "main() local - static archive define and provider",
156 {"name": "tp:main", "msg": None, "count": 0},
158 "name": "tp_a:destructor_cplusplus_provider_static_archive",
159 "msg": "main() local - static archive define and provider",
163 "name": "tp_so:destructor_cplusplus_provider_shared_library",
164 "msg": "main() local - shared library define and provider",
167 {"name": "tp:destructor_cplusplus", "msg": "main() local", "count": 0},
169 "name": "tp:destructor_cplusplus",
170 "msg": "global - across units after provider",
174 "name": "tp:destructor_cplusplus",
175 "msg": "global - same unit after provider",
179 "name": "tp:destructor_cplusplus",
180 "msg": "global - same unit before provider",
182 "may_fail": compound_literal_on_heap
,
185 "name": "tp:destructor_cplusplus",
186 "msg": "global - across units after define",
188 "may_fail": compound_literal_on_heap
,
191 "name": "tp:destructor_cplusplus",
192 "msg": "global - same unit after define",
194 "may_fail": compound_literal_on_heap
,
197 "name": "tp:destructor_cplusplus",
198 "msg": "global - same unit before define",
200 "may_fail": compound_literal_on_heap
,
203 "name": "tp:destructor_cplusplus",
204 "msg": "global - across units before define",
206 "may_fail": compound_literal_on_heap
,
209 "name": "tp_a:destructor_cplusplus_provider_static_archive",
210 "msg": "global - static archive define and provider",
212 "may_fail": compound_literal_on_heap
,
215 "name": "tp_so:destructor_cplusplus_provider_shared_library",
216 "msg": "global - shared library define and provider",
220 "name": "tp:destructor_c_across_units_after_provider",
223 "may_fail": compound_literal_on_heap
,
226 "name": "tp:destructor_c_same_unit_after_provider",
229 "may_fail": compound_literal_on_heap
,
232 "name": "tp:destructor_c_same_unit_before_provider",
235 "may_fail": compound_literal_on_heap
,
238 "name": "tp:destructor_c_across_units_after_define",
241 "may_fail": compound_literal_on_heap
,
244 "name": "tp:destructor_c_same_unit_after_define",
247 "may_fail": compound_literal_on_heap
,
250 "name": "tp:destructor_c_same_unit_before_define",
253 "may_fail": compound_literal_on_heap
,
256 "name": "tp:destructor_c_across_units_before_define",
259 "may_fail": compound_literal_on_heap
,
262 "name": "tp_a:destructor_c_provider_static_archive",
265 "may_fail": compound_literal_on_heap
,
267 {"name": "tp_so:destructor_c_provider_shared_library", "msg": None, "count": 0},
270 num_tests
= 7 + len(expected_events
)
273 def capture_trace(tap
, test_env
):
274 # type: (lttngtest.TapGenerator, lttngtest._Environment) -> lttngtest.LocalSessionOutputLocation
276 "Capture trace from application with instrumented C/C++ constructors/destructors"
279 session_output_location
= lttngtest
.LocalSessionOutputLocation(
280 test_env
.create_temporary_directory("trace")
283 client
= lttngtest
.LTTngClient(test_env
, log
=tap
.diagnostic
)
285 with tap
.case("Create a session") as test_case
:
286 session
= client
.create_session(output
=session_output_location
)
287 tap
.diagnostic("Created session `{session_name}`".format(session_name
=session
.name
))
290 "Add a channel to session `{session_name}`".format(session_name
=session
.name
)
292 channel
= session
.add_channel(lttngtest
.TracingDomain
.User
)
293 tap
.diagnostic("Created channel `{channel_name}`".format(channel_name
=channel
.name
))
295 # Enable all user space events, the default for a user tracepoint event rule.
296 channel
.add_recording_rule(lttngtest
.UserTracepointEventRule("tp*"))
299 "Start session `{session_name}`".format(session_name
=session
.name
)
303 test_app
= test_env
.launch_trace_test_constructor_application()
304 with tap
.case("Run test app".format(session_name
=session
.name
)) as test_case
:
305 test_app
.wait_for_exit()
308 "Stop session `{session_name}`".format(session_name
=session
.name
)
313 "Destroy session `{session_name}`".format(session_name
=session
.name
)
317 return session_output_location
320 def validate_trace(trace_location
, tap
):
321 # type: (pathlib.Path, lttngtest.TapGenerator)
322 unknown_event_count
= 0
324 for msg
in bt2
.TraceCollectionMessageIterator(str(trace_location
)):
325 if type(msg
) is not bt2
._EventMessageConst
:
329 for event
in expected_events
:
330 if event
["name"] == msg
.event
.name
and event
["msg"] is None:
332 event
["count"] = event
["count"] + 1
335 event
["name"] == msg
.event
.name
336 and event
["msg"] is not None
337 and event
["msg"] == msg
.event
["msg"]
340 event
["count"] = event
["count"] + 1
344 unknown_event_count
= unknown_event_count
+ 1
346 if "msg" in msg
.event
:
347 printmsg
= msg
.event
["msg"]
349 'Unexpected event name="{}" msg="{}" encountered'.format(
350 msg
.event
.name
, str(printmsg
)
354 for event
in expected_events
:
355 may_fail
= "may_fail" in event
.keys() and event
["may_fail"]
359 'Found expected event name="{}" msg="{}"'.format(
360 event
["name"], str(event
["msg"])
364 tap
.skip("Event '{}' may or may not be recorded".format(event
["name"]))
366 tap
.test(unknown_event_count
== 0, "Found no unexpected events")
369 tap
= lttngtest
.TapGenerator(num_tests
)
370 tap
.diagnostic("Test user space constructor/destructor instrumentation coverage")
372 with lttngtest
.test_environment(with_sessiond
=True, log
=tap
.diagnostic
) as test_env
:
373 outputlocation
= capture_trace(tap
, test_env
)
374 validate_trace(outputlocation
.path
, tap
)
376 sys
.exit(0 if tap
.is_successful
else 1)
This page took 0.061799 seconds and 3 git commands to generate.