Commit | Line | Data |
---|---|---|
32d2d479 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 | ||
cd03c43c | 19 | import uuid |
9cf643d1 | 20 | import unittest |
9cbe0c59 | 21 | import utils |
f377a958 | 22 | from utils import get_default_trace_class |
9cbe0c59 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 | |
ab778b5c | 27 | from bt2 import utils as bt2_utils |
9cf643d1 PP |
28 | |
29 | ||
30 | class TraceTestCase(unittest.TestCase): | |
31 | def setUp(self): | |
f377a958 | 32 | self._tc = get_default_trace_class() |
9cf643d1 PP |
33 | |
34 | def test_create_default(self): | |
f377a958 | 35 | trace = self._tc() |
cd03c43c PP |
36 | self.assertIsNone(trace.name) |
37 | self.assertIsNone(trace.uuid) | |
3f1a6e26 | 38 | self.assertEqual(len(trace.environment), 0) |
b2df5780 | 39 | self.assertEqual(len(trace.user_attributes), 0) |
9cf643d1 | 40 | |
f377a958 | 41 | def test_create_invalid_name(self): |
9cf643d1 | 42 | with self.assertRaises(TypeError): |
f377a958 | 43 | self._tc(name=17) |
9cf643d1 | 44 | |
b2df5780 PP |
45 | def test_create_user_attributes(self): |
46 | trace = self._tc(user_attributes={'salut': 23}) | |
47 | self.assertEqual(trace.user_attributes, {'salut': 23}) | |
9cbe0c59 | 48 | self.assertIs(type(trace.user_attributes), bt2_value.MapValue) |
b2df5780 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 | ||
a7f0580d | 58 | def test_attr_trace_class(self): |
cd03c43c | 59 | trace = self._tc() |
a7f0580d | 60 | self.assertEqual(trace.cls.addr, self._tc.addr) |
9cbe0c59 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) | |
a7f0580d | 66 | |
cd03c43c 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): | |
3f1a6e26 | 76 | trace = self._tc(environment={'hello': 'you', 'foo': -5}) |
9cbe0c59 FD |
77 | self.assertIs(type(trace.environment), bt2_trace._TraceEnvironment) |
78 | self.assertIs(type(trace.environment['foo']), bt2_value.SignedIntegerValue) | |
3f1a6e26 PP |
79 | self.assertEqual(trace.environment['hello'], 'you') |
80 | self.assertEqual(trace.environment['foo'], -5) | |
cd03c43c | 81 | |
9cbe0c59 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 | ||
2e30cfd1 | 94 | def test_const_env_iter(self): |
9cbe0c59 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 | ||
cd03c43c | 104 | def test_env_get_non_existent(self): |
3f1a6e26 | 105 | trace = self._tc(environment={'hello': 'you', 'foo': -5}) |
cd03c43c PP |
106 | |
107 | with self.assertRaises(KeyError): | |
3f1a6e26 | 108 | trace.environment['lel'] |
cd03c43c | 109 | |
f377a958 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 | |
f377a958 SM |
115 | trace.create_stream(sc) |
116 | self.assertEqual(len(trace), 1) | |
9cf643d1 | 117 | |
f377a958 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 | |
f377a958 | 125 | return trace |
9cf643d1 PP |
126 | |
127 | def test_iter(self): | |
f377a958 SM |
128 | trace = self._create_trace_with_some_streams() |
129 | stream_ids = set(trace) | |
130 | self.assertEqual(stream_ids, {12, 15, 17}) | |
9cf643d1 | 131 | |
f377a958 SM |
132 | def test_getitem(self): |
133 | trace = self._create_trace_with_some_streams() | |
f377a958 | 134 | self.assertEqual(trace[12].id, 12) |
9cbe0c59 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 | |
f377a958 SM |
141 | def test_getitem_invalid_key(self): |
142 | trace = self._create_trace_with_some_streams() | |
9cf643d1 | 143 | with self.assertRaises(KeyError): |
f377a958 | 144 | trace[18] |
9cf643d1 | 145 | |
f377a958 SM |
146 | def test_destruction_listener(self): |
147 | def on_trace_class_destruction(trace_class): | |
ab778b5c SM |
148 | nonlocal num_trace_class_destroyed_calls |
149 | num_trace_class_destroyed_calls += 1 | |
f6a5e476 | 150 | |
f377a958 | 151 | def on_trace_destruction(trace): |
ab778b5c SM |
152 | nonlocal num_trace_destroyed_calls |
153 | num_trace_destroyed_calls += 1 | |
f6a5e476 | 154 | |
ab778b5c SM |
155 | num_trace_class_destroyed_calls = 0 |
156 | num_trace_destroyed_calls = 0 | |
f6a5e476 | 157 | |
f377a958 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) | |
f6a5e476 | 162 | |
f377a958 | 163 | trace_class.add_destruction_listener(on_trace_class_destruction) |
ab778b5c SM |
164 | td_handle1 = trace.add_destruction_listener(on_trace_destruction) |
165 | td_handle2 = trace.add_destruction_listener(on_trace_destruction) | |
f6a5e476 | 166 | |
ab778b5c SM |
167 | self.assertIs(type(td_handle1), bt2_utils._ListenerHandle) |
168 | ||
169 | trace.remove_destruction_listener(td_handle2) | |
170 | ||
ab778b5c SM |
171 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
172 | self.assertEqual(num_trace_destroyed_calls, 0) | |
9cf643d1 | 173 | |
f377a958 | 174 | del trace |
9cf643d1 | 175 | |
ab778b5c SM |
176 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
177 | self.assertEqual(num_trace_destroyed_calls, 0) | |
9cf643d1 | 178 | |
f377a958 | 179 | del stream |
9cf643d1 | 180 | |
ab778b5c SM |
181 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
182 | self.assertEqual(num_trace_destroyed_calls, 1) | |
9cf643d1 | 183 | |
f377a958 | 184 | del trace_class |
9cf643d1 | 185 | |
ab778b5c SM |
186 | self.assertEqual(num_trace_class_destroyed_calls, 0) |
187 | self.assertEqual(num_trace_destroyed_calls, 1) | |
9cf643d1 | 188 | |
f377a958 | 189 | del stream_class |
9cf643d1 | 190 | |
ab778b5c SM |
191 | self.assertEqual(num_trace_class_destroyed_calls, 1) |
192 | self.assertEqual(num_trace_destroyed_calls, 1) | |
193 | ||
194 | def test_remove_destruction_listener_wrong_type(self): | |
195 | trace_class = get_default_trace_class() | |
196 | trace = trace_class() | |
197 | ||
198 | with self.assertRaisesRegex( | |
199 | TypeError, r"'int' is not a '<class 'bt2.utils._ListenerHandle'>' object" | |
200 | ): | |
201 | trace.remove_destruction_listener(123) | |
202 | ||
203 | def test_remove_destruction_listener_wrong_object(self): | |
204 | def on_trace_destruction(trace): | |
205 | pass | |
206 | ||
207 | trace_class_1 = get_default_trace_class() | |
208 | trace1 = trace_class_1() | |
209 | trace_class_2 = get_default_trace_class() | |
210 | trace2 = trace_class_2() | |
211 | ||
212 | handle1 = trace1.add_destruction_listener(on_trace_destruction) | |
213 | ||
214 | with self.assertRaisesRegex( | |
215 | ValueError, | |
216 | r'This trace destruction listener does not match the trace object\.', | |
217 | ): | |
218 | trace2.remove_destruction_listener(handle1) | |
219 | ||
220 | def test_remove_destruction_listener_twice(self): | |
221 | def on_trace_destruction(trace_class): | |
222 | pass | |
223 | ||
224 | trace_class = get_default_trace_class() | |
225 | trace = trace_class() | |
226 | handle = trace.add_destruction_listener(on_trace_destruction) | |
227 | ||
228 | trace.remove_destruction_listener(handle) | |
229 | ||
230 | with self.assertRaisesRegex( | |
231 | ValueError, r'This trace destruction listener was already removed\.' | |
232 | ): | |
233 | trace.remove_destruction_listener(handle) | |
3db06b1d | 234 | |
b6932b96 SM |
235 | def test_raise_in_destruction_listener(self): |
236 | def on_trace_destruction(trace): | |
237 | raise ValueError('it hurts') | |
238 | ||
239 | trace_class = get_default_trace_class() | |
240 | trace = trace_class() | |
241 | trace.add_destruction_listener(on_trace_destruction) | |
242 | ||
243 | del trace | |
244 | ||
3db06b1d SM |
245 | |
246 | if __name__ == '__main__': | |
247 | unittest.main() |