Fix: bt2: pass _TraceClassConst to destruction listeners
[babeltrace.git] / tests / bindings / python / bt2 / test_trace_class.py
CommitLineData
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
0bee8ea9 19import unittest
9cbe0c59
FD
20from utils import (
21 run_in_component_init,
22 get_default_trace_class,
23 get_const_stream_beginning_message,
24)
25from bt2 import stream_class as bt2_stream_class
26from bt2 import trace_class as bt2_trace_class
ab778b5c 27from bt2 import utils as bt2_utils
0bee8ea9
SM
28
29
30class TraceClassTestCase(unittest.TestCase):
b2df5780
PP
31 def assertRaisesInComponentInit(self, expected_exc_type, user_code):
32 def f(comp_self):
33 try:
34 user_code(comp_self)
35 except Exception as exc:
36 return type(exc)
37
38 exc_type = run_in_component_init(f)
39 self.assertIsNotNone(exc_type)
40 self.assertEqual(exc_type, expected_exc_type)
41
0bee8ea9
SM
42 def test_create_default(self):
43 def f(comp_self):
44 return comp_self._create_trace_class()
45
46 tc = run_in_component_init(f)
47
48 self.assertEqual(len(tc), 0)
9cbe0c59 49 self.assertIs(type(tc), bt2_trace_class._TraceClass)
0bee8ea9 50 self.assertTrue(tc.assigns_automatic_stream_class_id)
b2df5780
PP
51 self.assertEqual(len(tc.user_attributes), 0)
52
53 def test_create_user_attributes(self):
54 def f(comp_self):
55 return comp_self._create_trace_class(user_attributes={'salut': 23})
56
57 tc = run_in_component_init(f)
58 self.assertEqual(tc.user_attributes, {'salut': 23})
59
60 def test_create_invalid_user_attributes(self):
61 def f(comp_self):
62 return comp_self._create_trace_class(user_attributes=object())
63
64 self.assertRaisesInComponentInit(TypeError, f)
65
66 def test_create_invalid_user_attributes_value_type(self):
67 def f(comp_self):
68 return comp_self._create_trace_class(user_attributes=23)
69
70 self.assertRaisesInComponentInit(TypeError, f)
0bee8ea9 71
350e94d3
SM
72 def test_create_invalid_automatic_stream_class_id_type(self):
73 def f(comp_self):
74 return comp_self._create_trace_class(
75 assigns_automatic_stream_class_id='perchaude'
76 )
77
78 self.assertRaisesInComponentInit(TypeError, f)
79
0bee8ea9
SM
80 def test_automatic_stream_class_id(self):
81 def f(comp_self):
82 return comp_self._create_trace_class(assigns_automatic_stream_class_id=True)
83
84 tc = run_in_component_init(f)
85 self.assertTrue(tc.assigns_automatic_stream_class_id)
86
87 # This should not throw.
88 sc1 = tc.create_stream_class()
89 sc2 = tc.create_stream_class()
90
9cbe0c59
FD
91 self.assertIs(type(sc1), bt2_stream_class._StreamClass)
92 self.assertIs(type(sc2), bt2_stream_class._StreamClass)
0bee8ea9
SM
93 self.assertNotEqual(sc1.id, sc2.id)
94
95 def test_automatic_stream_class_id_raises(self):
96 def f(comp_self):
97 return comp_self._create_trace_class(assigns_automatic_stream_class_id=True)
98
99 tc = run_in_component_init(f)
100 self.assertTrue(tc.assigns_automatic_stream_class_id)
101
116779e3 102 with self.assertRaises(ValueError):
36153ada 103 tc.create_stream_class(23)
0bee8ea9
SM
104
105 def test_no_assigns_automatic_stream_class_id(self):
106 def f(comp_self):
61d96b89
FD
107 return comp_self._create_trace_class(
108 assigns_automatic_stream_class_id=False
109 )
0bee8ea9
SM
110
111 tc = run_in_component_init(f)
112 self.assertFalse(tc.assigns_automatic_stream_class_id)
113
114 sc = tc.create_stream_class(id=28)
115 self.assertEqual(sc.id, 28)
116
117 def test_no_assigns_automatic_stream_class_id_raises(self):
118 def f(comp_self):
61d96b89
FD
119 return comp_self._create_trace_class(
120 assigns_automatic_stream_class_id=False
121 )
0bee8ea9
SM
122
123 tc = run_in_component_init(f)
124 self.assertFalse(tc.assigns_automatic_stream_class_id)
125
126 # In this mode, it is required to pass an explicit id.
116779e3 127 with self.assertRaises(ValueError):
0bee8ea9
SM
128 tc.create_stream_class()
129
0bee8ea9
SM
130 @staticmethod
131 def _create_trace_class_with_some_stream_classes():
132 def f(comp_self):
61d96b89
FD
133 return comp_self._create_trace_class(
134 assigns_automatic_stream_class_id=False
135 )
0bee8ea9
SM
136
137 tc = run_in_component_init(f)
138 sc1 = tc.create_stream_class(id=12)
139 sc2 = tc.create_stream_class(id=54)
140 sc3 = tc.create_stream_class(id=2018)
141 return tc, sc1, sc2, sc3
142
143 def test_getitem(self):
144 tc, _, _, sc3 = self._create_trace_class_with_some_stream_classes()
9cbe0c59 145 self.assertIs(type(tc[2018]), bt2_stream_class._StreamClass)
0bee8ea9
SM
146 self.assertEqual(tc[2018].addr, sc3.addr)
147
9cbe0c59
FD
148 def test_const_getitem(self):
149 const_tc = get_const_stream_beginning_message().stream.trace.cls
150 self.assertIs(type(const_tc[0]), bt2_stream_class._StreamClassConst)
151
0bee8ea9
SM
152 def test_getitem_wrong_key_type(self):
153 tc, _, _, _ = self._create_trace_class_with_some_stream_classes()
154 with self.assertRaises(TypeError):
155 tc['hello']
156
157 def test_getitem_wrong_key(self):
158 tc, _, _, _ = self._create_trace_class_with_some_stream_classes()
159 with self.assertRaises(KeyError):
160 tc[4]
161
162 def test_len(self):
163 tc = get_default_trace_class()
164 self.assertEqual(len(tc), 0)
165 tc.create_stream_class()
166 self.assertEqual(len(tc), 1)
167
168 def test_iter(self):
169 tc, sc1, sc2, sc3 = self._create_trace_class_with_some_stream_classes()
170
171 for sc_id, stream_class in tc.items():
0bee8ea9 172 if sc_id == 12:
9cbe0c59 173 self.assertIs(type(stream_class), bt2_stream_class._StreamClass)
0bee8ea9
SM
174 self.assertEqual(stream_class.addr, sc1.addr)
175 elif sc_id == 54:
176 self.assertEqual(stream_class.addr, sc2.addr)
177 elif sc_id == 2018:
178 self.assertEqual(stream_class.addr, sc3.addr)
179
9cbe0c59
FD
180 def test_const_iter(self):
181 const_tc = get_const_stream_beginning_message().stream.trace.cls
182 const_sc = list(const_tc.values())[0]
183 self.assertIs(type(const_sc), bt2_stream_class._StreamClassConst)
184
0bee8ea9
SM
185 def test_destruction_listener(self):
186 def on_trace_class_destruction(trace_class):
eead7a76
SM
187 nonlocal type_of_passed_trace_class
188 type_of_passed_trace_class = type(trace_class)
189
ab778b5c
SM
190 nonlocal num_destruct_calls
191 num_destruct_calls += 1
0bee8ea9 192
eead7a76 193 type_of_passed_trace_class = None
ab778b5c 194 num_destruct_calls = 0
0bee8ea9
SM
195
196 trace_class = get_default_trace_class()
0bee8ea9 197
ab778b5c
SM
198 handle1 = trace_class.add_destruction_listener(on_trace_class_destruction)
199 self.assertIs(type(handle1), bt2_utils._ListenerHandle)
200
201 handle2 = trace_class.add_destruction_listener(on_trace_class_destruction)
202
203 trace_class.remove_destruction_listener(handle2)
204
ab778b5c 205 self.assertEqual(num_destruct_calls, 0)
0bee8ea9
SM
206
207 del trace_class
208
ab778b5c 209 self.assertEqual(num_destruct_calls, 1)
eead7a76 210 self.assertIs(type_of_passed_trace_class, bt2_trace_class._TraceClassConst)
ab778b5c
SM
211
212 def test_remove_destruction_listener_wrong_type(self):
213 trace_class = get_default_trace_class()
214
215 with self.assertRaisesRegex(
216 TypeError, r"'int' is not a '<class 'bt2.utils._ListenerHandle'>' object"
217 ):
218 trace_class.remove_destruction_listener(123)
219
220 def test_remove_destruction_listener_wrong_object(self):
221 def on_trace_class_destruction(trace_class):
222 pass
223
224 trace_class_1 = get_default_trace_class()
225 trace_class_2 = get_default_trace_class()
226
227 handle1 = trace_class_1.add_destruction_listener(on_trace_class_destruction)
228
229 with self.assertRaisesRegex(
230 ValueError,
7a16abe7 231 r'This trace class destruction listener does not match the trace class object\.',
ab778b5c
SM
232 ):
233 trace_class_2.remove_destruction_listener(handle1)
234
235 def test_remove_destruction_listener_twice(self):
236 def on_trace_class_destruction(trace_class):
237 pass
238
239 trace_class = get_default_trace_class()
240 handle = trace_class.add_destruction_listener(on_trace_class_destruction)
241
242 trace_class.remove_destruction_listener(handle)
243
244 with self.assertRaisesRegex(
245 ValueError, r'This trace class destruction listener was already removed\.'
246 ):
247 trace_class.remove_destruction_listener(handle)
3db06b1d 248
b6932b96
SM
249 def test_raise_in_destruction_listener(self):
250 def on_trace_class_destruction(trace_class):
251 raise ValueError('it hurts')
252
253 trace_class = get_default_trace_class()
254 trace_class.add_destruction_listener(on_trace_class_destruction)
255
256 del trace_class
257
3db06b1d
SM
258
259if __name__ == '__main__':
260 unittest.main()
This page took 0.052941 seconds and 4 git commands to generate.