Tests: python: use quoted annotations to support python <= 3.6
[lttng-tools.git] / tests / regression / tools / context / test_ust.py
CommitLineData
ef945e4d
JG
1#!/usr/bin/env python3
2#
3# Copyright (C) 2022 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4#
5# SPDX-License-Identifier: GPL-2.0-only
6
7from cgi import test
8import pathlib
9import sys
10import os
11from typing import Any, Callable, Type
12
13"""
14Test the addition of various user space contexts.
15
16This test successively sets up a session with a certain context enabled, traces
17a 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.
20
21The vpid, vuid, vgid and java application contexts are validated by this test.
22"""
23
24# Import in-tree test utils
25test_utils_import_path = pathlib.Path(__file__).absolute().parents[3] / "utils"
26sys.path.append(str(test_utils_import_path))
27
28import lttngtest
29import bt2
30
31
ce8470c9
MJ
32def context_trace_field_name(context_type):
33 # type: (Type[lttngtest.ContextType]) -> str
ef945e4d
JG
34 if isinstance(context_type, lttngtest.VpidContextType):
35 return "vpid"
36 elif isinstance(context_type, lttngtest.VuidContextType):
37 return "vuid"
38 elif isinstance(context_type, lttngtest.VgidContextType):
39 return "vgid"
40 elif isinstance(context_type, lttngtest.JavaApplicationContextType):
41 # Depends on the trace format and will need to be adapted for CTF 2.
42 return "_app_{retriever}_{name}".format(
43 retriever=context_type.retriever_name, name=context_type.field_name
44 )
45 else:
46 raise NotImplementedError
47
48
49def trace_stream_class_has_context_field_in_event_context(
ce8470c9
MJ
50 trace_location, context_field_name
51):
52 # type: (pathlib.Path, str) -> bool
ef945e4d
JG
53 iterator = bt2.TraceCollectionMessageIterator(str(trace_location))
54
55 # A bt2 message sequence is guaranteed to begin with a StreamBeginningMessage.
56 # Since we only have one channel (one stream class) and one trace, it is
57 # safe to use it to determine if the stream class contains the expected
58 # context field.
59 stream_begin_msg = next(iterator)
60
61 trace_class = stream_begin_msg.stream.trace.cls
62 # Ensure the trace class has only one stream class.
63 assert len(trace_class)
64
65 stream_class_id = next(iter(trace_class))
66 stream_class = trace_class[stream_class_id]
67 event_common_context_field_class = stream_class.event_common_context_field_class
68
69 return context_field_name in event_common_context_field_class
70
71
ce8470c9
MJ
72def trace_events_have_context_value(trace_location, context_field_name, value):
73 # type: (pathlib.Path, str, Any) -> bool
ef945e4d
JG
74 for msg in bt2.TraceCollectionMessageIterator(str(trace_location)):
75 if type(msg) is not bt2._EventMessageConst:
76 continue
77
78 if msg.event.common_context_field[context_field_name] != value:
79 print(msg.event.common_context_field[context_field_name])
80 return False
81 return True
82
83
ce8470c9
MJ
84def test_static_context(tap, test_env, context_type, context_value_retriever):
85 # type: (lttngtest.TapGenerator, lttngtest._Environment, lttngtest.ContextType, Callable[[lttngtest.WaitTraceTestApplication], Any]) -> None
ef945e4d
JG
86 tap.diagnostic(
87 "Test presence and expected value of context `{context_name}`".format(
88 context_name=type(context_type).__name__
89 )
90 )
91
92 session_output_location = lttngtest.LocalSessionOutputLocation(
93 test_env.create_temporary_directory("trace")
94 )
95
63c98ca6 96 client = lttngtest.LTTngClient(test_env, log=tap.diagnostic)
ef945e4d
JG
97
98 with tap.case("Create a session") as test_case:
99 session = client.create_session(output=session_output_location)
100 tap.diagnostic("Created session `{session_name}`".format(session_name=session.name))
101
102 with tap.case(
103 "Add a channel to session `{session_name}`".format(session_name=session.name)
104 ) as test_case:
105 channel = session.add_channel(lttngtest.TracingDomain.User)
106 tap.diagnostic("Created channel `{channel_name}`".format(channel_name=channel.name))
107
108 with tap.case(
109 "Add {context_type} context to channel `{channel_name}`".format(
110 context_type=type(context_type).__name__, channel_name=channel.name
111 )
112 ) as test_case:
113 channel.add_context(context_type)
114
115 test_app = test_env.launch_wait_trace_test_application(50)
116
117 # Only track the test application
118 session.user_vpid_process_attribute_tracker.track(test_app.vpid)
119 expected_context_value = context_value_retriever(test_app)
120
121 # Enable all user space events, the default for a user tracepoint event rule.
122 channel.add_recording_rule(lttngtest.UserTracepointEventRule())
123
124 session.start()
125 test_app.trace()
126 test_app.wait_for_exit()
127 session.stop()
128 session.destroy()
129
130 tap.test(
131 trace_stream_class_has_context_field_in_event_context(
132 session_output_location.path, context_trace_field_name(context_type)
133 ),
134 "Stream class contains field `{context_field_name}`".format(
135 context_field_name=context_trace_field_name(context_type)
136 ),
137 )
138
139 tap.test(
140 trace_events_have_context_value(
141 session_output_location.path,
142 context_trace_field_name(context_type),
143 expected_context_value,
144 ),
145 "Trace's events contain the expected `{context_field_name}` value `{expected_context_value}`".format(
146 context_field_name=context_trace_field_name(context_type),
147 expected_context_value=expected_context_value,
148 ),
149 )
150
151
152tap = lttngtest.TapGenerator(20)
153tap.diagnostic("Test user space context tracing")
154
155with lttngtest.test_environment(with_sessiond=True, log=tap.diagnostic) as test_env:
156 test_static_context(
157 tap, test_env, lttngtest.VpidContextType(), lambda test_app: test_app.vpid
158 )
159 test_static_context(
160 tap, test_env, lttngtest.VuidContextType(), lambda test_app: os.getuid()
161 )
162 test_static_context(
163 tap, test_env, lttngtest.VgidContextType(), lambda test_app: os.getgid()
164 )
165 test_static_context(
166 tap,
167 test_env,
168 lttngtest.JavaApplicationContextType("mayo", "ketchup"),
169 lambda test_app: {},
170 )
171
172sys.exit(0 if tap.is_successful else 1)
This page took 0.0307 seconds and 4 git commands to generate.