3 # Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
5 # SPDX-License-Identifier: GPL-2.0-only
11 from typing
import Any
, Callable
, Type
14 Test the addition of various user space contexts.
16 This test successively sets up a session with a certain context enabled, traces
17 a test application, and then reads the resulting trace to determine if:
18 - the context field is present in the trace
19 - the context field has the expected value.
21 The vpid, vuid, vgid and java application contexts are validated by this test.
24 # Import in-tree test utils
25 test_utils_import_path
= pathlib
.Path(__file__
).absolute().parents
[3] / "utils"
26 sys
.path
.append(str(test_utils_import_path
))
32 def context_trace_field_name(context_type
: Type
[lttngtest
.ContextType
]) -> str:
33 if isinstance(context_type
, lttngtest
.VpidContextType
):
35 elif isinstance(context_type
, lttngtest
.VuidContextType
):
37 elif isinstance(context_type
, lttngtest
.VgidContextType
):
39 elif isinstance(context_type
, lttngtest
.JavaApplicationContextType
):
40 # Depends on the trace format and will need to be adapted for CTF 2.
41 return "_app_{retriever}_{name}".format(
42 retriever
=context_type
.retriever_name
, name
=context_type
.field_name
45 raise NotImplementedError
48 def trace_stream_class_has_context_field_in_event_context(
49 trace_location
: pathlib
.Path
, context_field_name
: str
51 iterator
= bt2
.TraceCollectionMessageIterator(str(trace_location
))
53 # A bt2 message sequence is guaranteed to begin with a StreamBeginningMessage.
54 # Since we only have one channel (one stream class) and one trace, it is
55 # safe to use it to determine if the stream class contains the expected
57 stream_begin_msg
= next(iterator
)
59 trace_class
= stream_begin_msg
.stream
.trace
.cls
60 # Ensure the trace class has only one stream class.
61 assert len(trace_class
)
63 stream_class_id
= next(iter(trace_class
))
64 stream_class
= trace_class
[stream_class_id
]
65 event_common_context_field_class
= stream_class
.event_common_context_field_class
67 return context_field_name
in event_common_context_field_class
70 def trace_events_have_context_value(
71 trace_location
: pathlib
.Path
, context_field_name
: str, value
: Any
73 for msg
in bt2
.TraceCollectionMessageIterator(str(trace_location
)):
74 if type(msg
) is not bt2
._EventMessageConst
:
77 if msg
.event
.common_context_field
[context_field_name
] != value
:
78 print(msg
.event
.common_context_field
[context_field_name
])
83 def test_static_context(
84 tap
: lttngtest
.TapGenerator
,
85 test_env
: lttngtest
._Environment
,
86 context_type
: lttngtest
.ContextType
,
87 context_value_retriever
: Callable
[[lttngtest
.WaitTraceTestApplication
], Any
],
90 "Test presence and expected value of context `{context_name}`".format(
91 context_name
=type(context_type
).__name
__
95 session_output_location
= lttngtest
.LocalSessionOutputLocation(
96 test_env
.create_temporary_directory("trace")
99 client
: lttngtest
.Controller
= lttngtest
.LTTngClient(test_env
, log
=tap
.diagnostic
)
101 with tap
.case("Create a session") as test_case
:
102 session
= client
.create_session(output
=session_output_location
)
103 tap
.diagnostic("Created session `{session_name}`".format(session_name
=session
.name
))
106 "Add a channel to session `{session_name}`".format(session_name
=session
.name
)
108 channel
= session
.add_channel(lttngtest
.TracingDomain
.User
)
109 tap
.diagnostic("Created channel `{channel_name}`".format(channel_name
=channel
.name
))
112 "Add {context_type} context to channel `{channel_name}`".format(
113 context_type
=type(context_type
).__name
__, channel_name
=channel
.name
116 channel
.add_context(context_type
)
118 test_app
= test_env
.launch_wait_trace_test_application(50)
120 # Only track the test application
121 session
.user_vpid_process_attribute_tracker
.track(test_app
.vpid
)
122 expected_context_value
= context_value_retriever(test_app
)
124 # Enable all user space events, the default for a user tracepoint event rule.
125 channel
.add_recording_rule(lttngtest
.UserTracepointEventRule())
129 test_app
.wait_for_exit()
134 trace_stream_class_has_context_field_in_event_context(
135 session_output_location
.path
, context_trace_field_name(context_type
)
137 "Stream class contains field `{context_field_name}`".format(
138 context_field_name
=context_trace_field_name(context_type
)
143 trace_events_have_context_value(
144 session_output_location
.path
,
145 context_trace_field_name(context_type
),
146 expected_context_value
,
148 "Trace's events contain the expected `{context_field_name}` value `{expected_context_value}`".format(
149 context_field_name
=context_trace_field_name(context_type
),
150 expected_context_value
=expected_context_value
,
155 tap
= lttngtest
.TapGenerator(20)
156 tap
.diagnostic("Test user space context tracing")
158 with lttngtest
.test_environment(with_sessiond
=True, log
=tap
.diagnostic
) as test_env
:
160 tap
, test_env
, lttngtest
.VpidContextType(), lambda test_app
: test_app
.vpid
163 tap
, test_env
, lttngtest
.VuidContextType(), lambda test_app
: os
.getuid()
166 tap
, test_env
, lttngtest
.VgidContextType(), lambda test_app
: os
.getgid()
171 lttngtest
.JavaApplicationContextType("mayo", "ketchup"),
175 sys
.exit(0 if tap
.is_successful
else 1)