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
))
32 {"name": "tp_so:constructor_c_provider_shared_library", "msg": None, "count": 0},
33 {"name": "tp_a:constructor_c_provider_static_archive", "msg": None, "count": 0},
35 "name": "tp_so:constructor_cplusplus_provider_shared_library",
36 "msg": "global - shared library define and provider",
40 "name": "tp_a:constructor_cplusplus_provider_static_archive",
41 "msg": "global - static archive define and provider",
44 {"name": "tp:constructor_c_across_units_before_define", "msg": None, "count": 0},
46 "name": "tp:constructor_cplusplus",
47 "msg": "global - across units before define",
50 {"name": "tp:constructor_c_same_unit_before_define", "msg": None, "count": 0},
51 {"name": "tp:constructor_c_same_unit_after_define", "msg": None, "count": 0},
53 "name": "tp:constructor_cplusplus",
54 "msg": "global - same unit before define",
58 "name": "tp:constructor_cplusplus",
59 "msg": "global - same unit after define",
62 {"name": "tp:constructor_c_across_units_after_define", "msg": None, "count": 0},
64 "name": "tp:constructor_cplusplus",
65 "msg": "global - across units after define",
68 {"name": "tp:constructor_c_same_unit_before_provider", "msg": None, "count": 0},
69 {"name": "tp:constructor_c_same_unit_after_provider", "msg": None, "count": 0},
71 "name": "tp:constructor_cplusplus",
72 "msg": "global - same unit before provider",
76 "name": "tp:constructor_cplusplus",
77 "msg": "global - same unit after provider",
80 {"name": "tp:constructor_c_across_units_after_provider", "msg": None, "count": 0},
82 "name": "tp:constructor_cplusplus",
83 "msg": "global - across units after provider",
86 {"name": "tp:constructor_cplusplus", "msg": "main() local", "count": 0},
88 "name": "tp_so:constructor_cplusplus_provider_shared_library",
89 "msg": "main() local - shared library define and provider",
93 "name": "tp_a:constructor_cplusplus_provider_static_archive",
94 "msg": "main() local - static archive define and provider",
97 {"name": "tp:main", "msg": None, "count": 0},
99 "name": "tp_a:destructor_cplusplus_provider_static_archive",
100 "msg": "main() local - static archive define and provider",
104 "name": "tp_so:destructor_cplusplus_provider_shared_library",
105 "msg": "main() local - shared library define and provider",
108 {"name": "tp:destructor_cplusplus", "msg": "main() local", "count": 0},
110 "name": "tp:destructor_cplusplus",
111 "msg": "global - across units after provider",
115 "name": "tp:destructor_cplusplus",
116 "msg": "global - same unit after provider",
120 "name": "tp:destructor_cplusplus",
121 "msg": "global - same unit before provider",
125 "name": "tp:destructor_cplusplus",
126 "msg": "global - across units after define",
130 "name": "tp:destructor_cplusplus",
131 "msg": "global - same unit after define",
135 "name": "tp:destructor_cplusplus",
136 "msg": "global - same unit before define",
140 "name": "tp:destructor_cplusplus",
141 "msg": "global - across units before define",
145 "name": "tp_a:destructor_cplusplus_provider_static_archive",
146 "msg": "global - static archive define and provider",
150 "name": "tp_so:destructor_cplusplus_provider_shared_library",
151 "msg": "global - shared library define and provider",
154 {"name": "tp:destructor_c_across_units_after_provider", "msg": None, "count": 0},
155 {"name": "tp:destructor_c_same_unit_after_provider", "msg": None, "count": 0},
156 {"name": "tp:destructor_c_same_unit_before_provider", "msg": None, "count": 0},
157 {"name": "tp:destructor_c_across_units_after_define", "msg": None, "count": 0},
158 {"name": "tp:destructor_c_same_unit_after_define", "msg": None, "count": 0},
159 {"name": "tp:destructor_c_same_unit_before_define", "msg": None, "count": 0},
160 {"name": "tp:destructor_c_across_units_before_define", "msg": None, "count": 0},
161 {"name": "tp_a:destructor_c_provider_static_archive", "msg": None, "count": 0},
162 {"name": "tp_so:destructor_c_provider_shared_library", "msg": None, "count": 0},
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 test_app
= test_env
.launch_trace_test_constructor_application()
193 test_app
.wait_for_exit()
196 return session_output_location
199 def validate_trace(trace_location
, tap
):
200 # type: (pathlib.Path, lttngtest.TapGenerator) -> bool
202 unknown_event_count
= 0
204 for msg
in bt2
.TraceCollectionMessageIterator(str(trace_location
)):
205 if type(msg
) is not bt2
._EventMessageConst
:
209 for event
in expected_events
:
210 if event
["name"] == msg
.event
.name
and event
["msg"] is None:
212 event
["count"] = event
["count"] + 1
215 event
["name"] == msg
.event
.name
216 and event
["msg"] is not None
217 and event
["msg"] == msg
.event
["msg"]
220 event
["count"] = event
["count"] + 1
223 unknown_event_count
= unknown_event_count
+ 1
225 if "msg" in msg
.event
:
226 printmsg
= msg
.event
["msg"]
228 'Unexpected event name="{}" msg="{}" encountered'.format(
229 msg
.event
.name
, str(printmsg
)
233 for event
in expected_events
:
234 if event
["count"] != 1:
236 tap
.diagnostic("Expected event {} not found".format(event
["name"]))
237 if unknown_event_count
!= 0:
242 tap
= lttngtest
.TapGenerator(num_tests
)
243 tap
.diagnostic("Test user space constructor/destructor instrumentation coverage")
245 with lttngtest
.test_environment(with_sessiond
=True, log
=tap
.diagnostic
) as test_env
:
246 outputlocation
= capture_trace(tap
, test_env
)
248 validate_trace(outputlocation
.path
, tap
),
249 "Validate that trace constains expected events",
252 sys
.exit(0 if tap
.is_successful
else 1)
This page took 0.040037 seconds and 4 git commands to generate.