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