Commit | Line | Data |
---|---|---|
0235b0db | 1 | # SPDX-License-Identifier: GPL-2.0-only |
d2d857a8 MJ |
2 | # |
3 | # Copyright (C) 2019 EfficiOS Inc. | |
4 | # | |
d2d857a8 | 5 | |
335a2da5 | 6 | import uuid |
9cf643d1 | 7 | import unittest |
5995b304 | 8 | |
f0a42b33 | 9 | import utils |
f0a42b33 | 10 | from bt2 import trace as bt2_trace |
1114a7d5 | 11 | from bt2 import utils as bt2_utils |
5995b304 SM |
12 | from bt2 import value as bt2_value |
13 | from bt2 import stream as bt2_stream | |
14 | from bt2 import trace_class as bt2_trace_class | |
15 | from utils import get_default_trace_class | |
9cf643d1 PP |
16 | |
17 | ||
18 | class TraceTestCase(unittest.TestCase): | |
19 | def setUp(self): | |
8c2367b8 | 20 | self._tc = get_default_trace_class() |
9cf643d1 PP |
21 | |
22 | def test_create_default(self): | |
8c2367b8 | 23 | trace = self._tc() |
335a2da5 PP |
24 | self.assertIsNone(trace.name) |
25 | self.assertIsNone(trace.uuid) | |
b7bc733b | 26 | self.assertEqual(len(trace.environment), 0) |
5783664e | 27 | self.assertEqual(len(trace.user_attributes), 0) |
9cf643d1 | 28 | |
8c2367b8 | 29 | def test_create_invalid_name(self): |
9cf643d1 | 30 | with self.assertRaises(TypeError): |
8c2367b8 | 31 | self._tc(name=17) |
9cf643d1 | 32 | |
5783664e | 33 | def test_create_user_attributes(self): |
f5567ea8 FD |
34 | trace = self._tc(user_attributes={"salut": 23}) |
35 | self.assertEqual(trace.user_attributes, {"salut": 23}) | |
f0a42b33 | 36 | self.assertIs(type(trace.user_attributes), bt2_value.MapValue) |
5783664e PP |
37 | |
38 | def test_create_invalid_user_attributes(self): | |
39 | with self.assertRaises(TypeError): | |
40 | self._tc(user_attributes=object()) | |
41 | ||
42 | def test_create_invalid_user_attributes_value_type(self): | |
43 | with self.assertRaises(TypeError): | |
44 | self._tc(user_attributes=23) | |
45 | ||
05abc762 | 46 | def test_attr_trace_class(self): |
335a2da5 | 47 | trace = self._tc() |
05abc762 | 48 | self.assertEqual(trace.cls.addr, self._tc.addr) |
f0a42b33 FD |
49 | self.assertIs(type(trace.cls), bt2_trace_class._TraceClass) |
50 | ||
51 | def test_const_attr_trace_class(self): | |
52 | trace = utils.get_const_stream_beginning_message().stream.trace | |
53 | self.assertIs(type(trace.cls), bt2_trace_class._TraceClassConst) | |
05abc762 | 54 | |
335a2da5 | 55 | def test_attr_name(self): |
f5567ea8 FD |
56 | trace = self._tc(name="mein trace") |
57 | self.assertEqual(trace.name, "mein trace") | |
335a2da5 PP |
58 | |
59 | def test_attr_uuid(self): | |
f5567ea8 FD |
60 | trace = self._tc(uuid=uuid.UUID("da7d6b6f-3108-4706-89bd-ab554732611b")) |
61 | self.assertEqual(trace.uuid, uuid.UUID("da7d6b6f-3108-4706-89bd-ab554732611b")) | |
335a2da5 PP |
62 | |
63 | def test_env_get(self): | |
f5567ea8 | 64 | trace = self._tc(environment={"hello": "you", "foo": -5}) |
f0a42b33 | 65 | self.assertIs(type(trace.environment), bt2_trace._TraceEnvironment) |
f5567ea8 FD |
66 | self.assertIs(type(trace.environment["foo"]), bt2_value.SignedIntegerValue) |
67 | self.assertEqual(trace.environment["hello"], "you") | |
68 | self.assertEqual(trace.environment["foo"], -5) | |
335a2da5 | 69 | |
f0a42b33 | 70 | def test_env_iter(self): |
f5567ea8 | 71 | trace = self._tc(environment={"hello": "you", "foo": -5}) |
f0a42b33 | 72 | values = set(trace.environment) |
f5567ea8 | 73 | self.assertEqual(values, {"hello", "foo"}) |
f0a42b33 FD |
74 | |
75 | def test_const_env_get(self): | |
76 | trace = utils.get_const_stream_beginning_message().stream.trace | |
77 | self.assertIs(type(trace.environment), bt2_trace._TraceEnvironmentConst) | |
78 | self.assertIs( | |
f5567ea8 | 79 | type(trace.environment["patate"]), bt2_value._SignedIntegerValueConst |
f0a42b33 FD |
80 | ) |
81 | ||
af4e2957 | 82 | def test_const_env_iter(self): |
f0a42b33 FD |
83 | trace = utils.get_const_stream_beginning_message().stream.trace |
84 | values = set(trace.environment) | |
f5567ea8 | 85 | self.assertEqual(values, {"patate"}) |
f0a42b33 FD |
86 | |
87 | def test_const_env_set(self): | |
88 | trace = utils.get_const_stream_beginning_message().stream.trace | |
89 | with self.assertRaises(TypeError): | |
f5567ea8 | 90 | trace.environment["patate"] = 33 |
f0a42b33 | 91 | |
335a2da5 | 92 | def test_env_get_non_existent(self): |
f5567ea8 | 93 | trace = self._tc(environment={"hello": "you", "foo": -5}) |
335a2da5 PP |
94 | |
95 | with self.assertRaises(KeyError): | |
f5567ea8 | 96 | trace.environment["lel"] |
335a2da5 | 97 | |
8c2367b8 SM |
98 | def test_len(self): |
99 | trace = self._tc() | |
100 | sc = self._tc.create_stream_class() | |
101 | self.assertEqual(len(trace), 0) | |
9cf643d1 | 102 | |
8c2367b8 SM |
103 | trace.create_stream(sc) |
104 | self.assertEqual(len(trace), 1) | |
9cf643d1 | 105 | |
8c2367b8 SM |
106 | def _create_trace_with_some_streams(self): |
107 | sc = self._tc.create_stream_class(assigns_automatic_stream_id=False) | |
108 | trace = self._tc() | |
109 | trace.create_stream(sc, id=12) | |
110 | trace.create_stream(sc, id=15) | |
111 | trace.create_stream(sc, id=17) | |
9cf643d1 | 112 | |
8c2367b8 | 113 | return trace |
9cf643d1 PP |
114 | |
115 | def test_iter(self): | |
8c2367b8 SM |
116 | trace = self._create_trace_with_some_streams() |
117 | stream_ids = set(trace) | |
118 | self.assertEqual(stream_ids, {12, 15, 17}) | |
9cf643d1 | 119 | |
8c2367b8 SM |
120 | def test_getitem(self): |
121 | trace = self._create_trace_with_some_streams() | |
8c2367b8 | 122 | self.assertEqual(trace[12].id, 12) |
f0a42b33 FD |
123 | self.assertIs(type(trace[12]), bt2_stream._Stream) |
124 | ||
125 | def test_const_getitem(self): | |
126 | trace = utils.get_const_stream_beginning_message().stream.trace | |
127 | self.assertIs(type(trace[0]), bt2_stream._StreamConst) | |
9cf643d1 | 128 | |
8c2367b8 SM |
129 | def test_getitem_invalid_key(self): |
130 | trace = self._create_trace_with_some_streams() | |
9cf643d1 | 131 | with self.assertRaises(KeyError): |
8c2367b8 | 132 | trace[18] |
9cf643d1 | 133 | |
8c2367b8 SM |
134 | def test_destruction_listener(self): |
135 | def on_trace_class_destruction(trace_class): | |
1114a7d5 SM |
136 | nonlocal num_trace_class_destroyed_calls |
137 | num_trace_class_destroyed_calls += 1 | |
811644b8 | 138 | |
8c2367b8 | 139 | def on_trace_destruction(trace): |
1114a7d5 SM |
140 | nonlocal num_trace_destroyed_calls |
141 | num_trace_destroyed_calls += 1 | |
811644b8 | 142 | |
1114a7d5 SM |
143 | num_trace_class_destroyed_calls = 0 |
144 | num_trace_destroyed_calls = 0 | |
811644b8 | 145 | |
8c2367b8 SM |
146 | trace_class = get_default_trace_class() |
147 | stream_class = trace_class.create_stream_class() | |
148 | trace = trace_class() | |
149 | stream = trace.create_stream(stream_class) | |
811644b8 | 150 | |
8c2367b8 | 151 | trace_class.add_destruction_listener(on_trace_class_destruction) |
1114a7d5 SM |
152 | td_handle1 = trace.add_destruction_listener(on_trace_destruction) |
153 | td_handle2 = trace.add_destruction_listener(on_trace_destruction) | |
811644b8 | 154 | |
1114a7d5 SM |
155 | self.assertIs(type(td_handle1), bt2_utils._ListenerHandle) |
156 | ||
157 | trace.remove_destruction_listener(td_handle2) | |
158 | ||
1114a7d5 SM |
159 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
160 | self.assertEqual(num_trace_destroyed_calls, 0) | |
9cf643d1 | 161 | |
8c2367b8 | 162 | del trace |
9cf643d1 | 163 | |
1114a7d5 SM |
164 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
165 | self.assertEqual(num_trace_destroyed_calls, 0) | |
9cf643d1 | 166 | |
8c2367b8 | 167 | del stream |
9cf643d1 | 168 | |
1114a7d5 SM |
169 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
170 | self.assertEqual(num_trace_destroyed_calls, 1) | |
9cf643d1 | 171 | |
8c2367b8 | 172 | del trace_class |
9cf643d1 | 173 | |
1114a7d5 SM |
174 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
175 | self.assertEqual(num_trace_destroyed_calls, 1) | |
9cf643d1 | 176 | |
8c2367b8 | 177 | del stream_class |
9cf643d1 | 178 | |
1114a7d5 SM |
179 | self.assertEqual(num_trace_class_destroyed_calls, 1) |
180 | self.assertEqual(num_trace_destroyed_calls, 1) | |
181 | ||
182 | def test_remove_destruction_listener_wrong_type(self): | |
183 | trace_class = get_default_trace_class() | |
184 | trace = trace_class() | |
185 | ||
186 | with self.assertRaisesRegex( | |
187 | TypeError, r"'int' is not a '<class 'bt2.utils._ListenerHandle'>' object" | |
188 | ): | |
189 | trace.remove_destruction_listener(123) | |
190 | ||
191 | def test_remove_destruction_listener_wrong_object(self): | |
192 | def on_trace_destruction(trace): | |
193 | pass | |
194 | ||
195 | trace_class_1 = get_default_trace_class() | |
196 | trace1 = trace_class_1() | |
197 | trace_class_2 = get_default_trace_class() | |
198 | trace2 = trace_class_2() | |
199 | ||
200 | handle1 = trace1.add_destruction_listener(on_trace_destruction) | |
201 | ||
202 | with self.assertRaisesRegex( | |
203 | ValueError, | |
f5567ea8 | 204 | r"This trace destruction listener does not match the trace object\.", |
1114a7d5 SM |
205 | ): |
206 | trace2.remove_destruction_listener(handle1) | |
207 | ||
208 | def test_remove_destruction_listener_twice(self): | |
209 | def on_trace_destruction(trace_class): | |
210 | pass | |
211 | ||
212 | trace_class = get_default_trace_class() | |
213 | trace = trace_class() | |
214 | handle = trace.add_destruction_listener(on_trace_destruction) | |
215 | ||
216 | trace.remove_destruction_listener(handle) | |
217 | ||
218 | with self.assertRaisesRegex( | |
f5567ea8 | 219 | ValueError, r"This trace destruction listener was already removed\." |
1114a7d5 SM |
220 | ): |
221 | trace.remove_destruction_listener(handle) | |
d14ddbba | 222 | |
64961f8b SM |
223 | def test_raise_in_destruction_listener(self): |
224 | def on_trace_destruction(trace): | |
f5567ea8 | 225 | raise ValueError("it hurts") |
64961f8b SM |
226 | |
227 | trace_class = get_default_trace_class() | |
228 | trace = trace_class() | |
229 | trace.add_destruction_listener(on_trace_destruction) | |
230 | ||
231 | del trace | |
232 | ||
d14ddbba | 233 | |
f5567ea8 | 234 | if __name__ == "__main__": |
d14ddbba | 235 | unittest.main() |