3 # SPDX-FileCopyrightText: 2024 Kienan Stewart <kstewart@efficios.com>
4 # SPDX-License-Identifer: GPL-2.0-only
12 from typing
import Any
, Callable
, Type
14 # Import in-tree test utils
15 test_utils_import_path
= pathlib
.Path(__file__
).absolute().parents
[3] / "utils"
16 sys
.path
.append(str(test_utils_import_path
))
21 # Determine if LTTNG_UST_ALLOCATE_COMPOUND_LITERAL_ON_HEAP is set. This will
22 # affect if certain events may or may not be expected when compiling with
24 # @see https://github.com/lttng/lttng-ust/blob/47fa3e4ed7ab43e034dc61fc1480f919f4ee51d0/include/lttng/ust-compiler.h#L51
26 compound_literal_on_heap
= False
27 process
= subprocess
.Popen(
30 str(test_utils_import_path
),
32 "gen-ust-events-constructor",
38 if process
.returncode
== 0:
39 compound_literal_on_heap
= True
41 expected_events_common_cpp
= [
43 "name": "tp:constructor_cplusplus",
44 "msg": "global - across units before define",
46 "may_fail": compound_literal_on_heap
,
49 "name": "tp:constructor_cplusplus",
50 "msg": "global - same unit before define",
52 "may_fail": compound_literal_on_heap
,
55 "name": "tp:constructor_cplusplus",
56 "msg": "global - same unit after define",
58 "may_fail": compound_literal_on_heap
,
61 "name": "tp:constructor_cplusplus",
62 "msg": "global - across units after define",
64 "may_fail": compound_literal_on_heap
,
67 "name": "tp:constructor_cplusplus",
68 "msg": "global - same unit before provider",
70 "may_fail": compound_literal_on_heap
,
73 "name": "tp:constructor_cplusplus",
74 "msg": "global - same unit after provider",
78 "name": "tp:constructor_cplusplus",
79 "msg": "global - across units after provider",
82 {"name": "tp:constructor_cplusplus", "msg": "main() local", "count": 0},
83 {"name": "tp:destructor_cplusplus", "msg": "main() local", "count": 0},
85 "name": "tp:destructor_cplusplus",
86 "msg": "global - across units after provider",
90 "name": "tp:destructor_cplusplus",
91 "msg": "global - same unit after provider",
95 "name": "tp:destructor_cplusplus",
96 "msg": "global - same unit before provider",
98 "may_fail": compound_literal_on_heap
,
101 "name": "tp:destructor_cplusplus",
102 "msg": "global - across units after define",
104 "may_fail": compound_literal_on_heap
,
107 "name": "tp:destructor_cplusplus",
108 "msg": "global - same unit after define",
110 "may_fail": compound_literal_on_heap
,
113 "name": "tp:destructor_cplusplus",
114 "msg": "global - same unit before define",
116 "may_fail": compound_literal_on_heap
,
119 "name": "tp:destructor_cplusplus",
120 "msg": "global - across units before define",
122 "may_fail": compound_literal_on_heap
,
126 expected_events_common
= [
128 "name": "tp:constructor_c_across_units_before_define",
131 "may_fail": compound_literal_on_heap
,
134 "name": "tp:constructor_c_same_unit_before_define",
137 "may_fail": compound_literal_on_heap
,
140 "name": "tp:constructor_c_same_unit_after_define",
143 "may_fail": compound_literal_on_heap
,
146 "name": "tp:constructor_c_across_units_after_define",
149 "may_fail": compound_literal_on_heap
,
152 "name": "tp:constructor_c_same_unit_before_provider",
155 "may_fail": compound_literal_on_heap
,
158 "name": "tp:constructor_c_same_unit_after_provider",
161 "may_fail": compound_literal_on_heap
,
163 {"name": "tp:constructor_c_across_units_after_provider", "msg": None, "count": 0},
164 {"name": "tp:main", "msg": None, "count": 0},
166 "name": "tp:destructor_c_across_units_after_provider",
169 "may_fail": compound_literal_on_heap
,
172 "name": "tp:destructor_c_same_unit_after_provider",
175 "may_fail": compound_literal_on_heap
,
178 "name": "tp:destructor_c_same_unit_before_provider",
181 "may_fail": compound_literal_on_heap
,
184 "name": "tp:destructor_c_across_units_after_define",
187 "may_fail": compound_literal_on_heap
,
190 "name": "tp:destructor_c_same_unit_after_define",
193 "may_fail": compound_literal_on_heap
,
196 "name": "tp:destructor_c_same_unit_before_define",
199 "may_fail": compound_literal_on_heap
,
202 "name": "tp:destructor_c_across_units_before_define",
205 "may_fail": compound_literal_on_heap
,
209 expected_events_tp_so_cpp
= [
211 "name": "tp_so:constructor_cplusplus_provider_shared_library",
212 "msg": "global - shared library define and provider",
216 "name": "tp_so:constructor_cplusplus_provider_shared_library",
217 "msg": "main() local - shared library define and provider",
221 "name": "tp_so:destructor_cplusplus_provider_shared_library",
222 "msg": "main() local - shared library define and provider",
226 "name": "tp_so:destructor_cplusplus_provider_shared_library",
227 "msg": "global - shared library define and provider",
232 expected_events_tp_so
= [
233 {"name": "tp_so_c:constructor_c_provider_shared_library", "msg": None, "count": 0},
234 {"name": "tp_so_c:destructor_c_provider_shared_library", "msg": None, "count": 0},
237 expected_events_tp_a_cpp
= [
239 "name": "tp_a:constructor_cplusplus_provider_static_archive",
240 "msg": "global - static archive define and provider",
242 "may_fail": compound_literal_on_heap
,
245 "name": "tp_a:constructor_cplusplus_provider_static_archive",
246 "msg": "main() local - static archive define and provider",
250 "name": "tp_a:destructor_cplusplus_provider_static_archive",
251 "msg": "main() local - static archive define and provider",
255 "name": "tp_a:destructor_cplusplus_provider_static_archive",
256 "msg": "global - static archive define and provider",
258 "may_fail": compound_literal_on_heap
,
262 expected_events_tp_a
= [
263 {"name": "tp_a_c:constructor_c_provider_static_archive", "msg": None, "count": 0},
264 {"name": "tp_a_c:destructor_c_provider_static_archive", "msg": None, "count": 0},
268 def capture_trace(tap
, test_env
, application
, description
):
269 # type: (lttngtest.TapGenerator, lttngtest._Environment) -> lttngtest.LocalSessionOutputLocation
270 tap
.diagnostic(description
)
272 session_output_location
= lttngtest
.LocalSessionOutputLocation(
273 test_env
.create_temporary_directory("trace")
276 client
= lttngtest
.LTTngClient(test_env
, log
=tap
.diagnostic
)
278 with tap
.case("Create a session") as test_case
:
279 session
= client
.create_session(output
=session_output_location
)
280 tap
.diagnostic("Created session `{session_name}`".format(session_name
=session
.name
))
283 "Add a channel to session `{session_name}`".format(session_name
=session
.name
)
285 channel
= session
.add_channel(lttngtest
.TracingDomain
.User
)
286 tap
.diagnostic("Created channel `{channel_name}`".format(channel_name
=channel
.name
))
288 # Enable all user space events, the default for a user tracepoint event rule.
289 channel
.add_recording_rule(lttngtest
.UserTracepointEventRule("tp*"))
292 "Start session `{session_name}`".format(session_name
=session
.name
)
296 test_app
= test_env
.launch_test_application(application
)
298 "Run test app '{}'".format(application
, session_name
=session
.name
)
300 test_app
.wait_for_exit()
303 "Stop session `{session_name}`".format(session_name
=session
.name
)
308 "Destroy session `{session_name}`".format(session_name
=session
.name
)
312 return session_output_location
315 def validate_trace(trace_location
, tap
, expected_events
):
316 # type: (pathlib.Path, lttngtest.TapGenerator)
317 unknown_event_count
= 0
319 for msg
in bt2
.TraceCollectionMessageIterator(str(trace_location
)):
320 if type(msg
) is not bt2
._EventMessageConst
:
324 for event
in expected_events
:
325 if event
["name"] == msg
.event
.name
and event
["msg"] is None:
327 event
["count"] = event
["count"] + 1
330 event
["name"] == msg
.event
.name
331 and event
["msg"] is not None
332 and event
["msg"] == msg
.event
["msg"]
335 event
["count"] = event
["count"] + 1
339 unknown_event_count
= unknown_event_count
+ 1
341 if "msg" in msg
.event
:
342 printmsg
= msg
.event
["msg"]
344 'Unexpected event name="{}" msg="{}" encountered'.format(
345 msg
.event
.name
, str(printmsg
)
349 for event
in expected_events
:
350 may_fail
= "may_fail" in event
.keys() and event
["may_fail"]
354 'Found expected event name="{}" msg="{}"'.format(
355 event
["name"], str(event
["msg"])
359 tap
.skip("Event '{}' may or may not be recorded".format(event
["name"]))
361 tap
.test(unknown_event_count
== 0, "Found no unexpected events")