bt2: Add `_Clock*Const` classes and adapt tests
[babeltrace.git] / tests / bindings / python / bt2 / test_field_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
32656995 19import unittest
32656995 20import bt2
c8820b76 21from utils import get_default_trace_class
32656995
SM
22
23
b2df5780
PP
24class _TestFieldClass:
25 def test_create_user_attributes(self):
26 fc = self._create_default_field_class(user_attributes={'salut': 23})
27 self.assertEqual(fc.user_attributes, {'salut': 23})
28
29 def test_create_invalid_user_attributes(self):
30 with self.assertRaises(TypeError):
31 self._create_default_field_class(user_attributes=object())
32
33 def test_create_invalid_user_attributes_value_type(self):
34 with self.assertRaises(TypeError):
35 self._create_default_field_class(user_attributes=23)
36
37
38class BoolFieldClassTestCase(_TestFieldClass, unittest.TestCase):
39 def _create_default_field_class(self, **kwargs):
a07f15cb 40 tc = get_default_trace_class()
b2df5780
PP
41 return tc.create_bool_field_class(**kwargs)
42
43 def setUp(self):
44 self._fc = self._create_default_field_class()
a07f15cb
PP
45
46 def test_create_default(self):
47 self.assertIsNotNone(self._fc)
b2df5780 48 self.assertEqual(len(self._fc.user_attributes), 0)
a07f15cb
PP
49
50
b2df5780
PP
51class BitArrayFieldClassTestCase(_TestFieldClass, unittest.TestCase):
52 def _create_field_class(self, *args, **kwargs):
53 tc = get_default_trace_class()
54 return tc.create_bit_array_field_class(*args, **kwargs)
55
56 def _create_default_field_class(self, **kwargs):
57 return self._create_field_class(17, **kwargs)
58
6b29f2d4 59 def setUp(self):
b2df5780 60 self._fc = self._create_default_field_class()
6b29f2d4
PP
61
62 def test_create_default(self):
63 self.assertIsNotNone(self._fc)
b2df5780 64 self.assertEqual(len(self._fc.user_attributes), 0)
6b29f2d4
PP
65
66 def test_create_length_out_of_range(self):
67 with self.assertRaises(ValueError):
b2df5780 68 self._create_field_class(65)
6b29f2d4
PP
69
70 def test_create_length_zero(self):
71 with self.assertRaises(ValueError):
b2df5780 72 self._create_field_class(0)
6b29f2d4
PP
73
74 def test_create_length_invalid_type(self):
75 with self.assertRaises(TypeError):
b2df5780 76 self._create_field_class('lel')
6b29f2d4
PP
77
78 def test_length_prop(self):
79 self.assertEqual(self._fc.length, 17)
80
81
c8820b76
SM
82class _TestIntegerFieldClassProps:
83 def test_create_default(self):
b2df5780 84 fc = self._create_default_field_class()
c8820b76
SM
85 self.assertEqual(fc.field_value_range, 64)
86 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.DECIMAL)
b2df5780 87 self.assertEqual(len(fc.user_attributes), 0)
32656995 88
c8820b76 89 def test_create_range(self):
b2df5780 90 fc = self._create_field_class(field_value_range=35)
c8820b76 91 self.assertEqual(fc.field_value_range, 35)
32656995 92
b2df5780 93 fc = self._create_field_class(36)
c8820b76 94 self.assertEqual(fc.field_value_range, 36)
32656995 95
c8820b76
SM
96 def test_create_invalid_range(self):
97 with self.assertRaises(TypeError):
b2df5780 98 self._create_field_class('yes')
32656995 99
c8820b76 100 with self.assertRaises(TypeError):
b2df5780 101 self._create_field_class(field_value_range='yes')
32656995 102
32656995 103 with self.assertRaises(ValueError):
b2df5780 104 self._create_field_class(field_value_range=-2)
32656995 105
c8820b76 106 with self.assertRaises(ValueError):
b2df5780 107 self._create_field_class(field_value_range=0)
32656995 108
c8820b76 109 def test_create_base(self):
b2df5780 110 fc = self._create_field_class(
61d96b89
FD
111 preferred_display_base=bt2.IntegerDisplayBase.HEXADECIMAL
112 )
c8820b76 113 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.HEXADECIMAL)
32656995 114
c8820b76 115 def test_create_invalid_base_type(self):
32656995 116 with self.assertRaises(TypeError):
b2df5780 117 self._create_field_class(preferred_display_base='yes')
32656995 118
c8820b76
SM
119 def test_create_invalid_base_value(self):
120 with self.assertRaises(ValueError):
b2df5780 121 self._create_field_class(preferred_display_base=444)
32656995 122
c8820b76 123 def test_create_full(self):
b2df5780
PP
124 fc = self._create_field_class(
125 24, preferred_display_base=bt2.IntegerDisplayBase.OCTAL
126 )
c8820b76
SM
127 self.assertEqual(fc.field_value_range, 24)
128 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.OCTAL)
32656995
SM
129
130
b2df5780
PP
131class SignedIntegerFieldClassTestCase(
132 _TestIntegerFieldClassProps, _TestFieldClass, unittest.TestCase
133):
134 def _create_field_class(self, *args, **kwargs):
135 tc = get_default_trace_class()
136 return tc.create_signed_integer_field_class(*args, **kwargs)
32656995 137
b2df5780
PP
138 _create_default_field_class = _create_field_class
139
140
141class UnsignedIntegerFieldClassTestCase(
142 _TestIntegerFieldClassProps, _TestFieldClass, unittest.TestCase
143):
144 def _create_field_class(self, *args, **kwargs):
145 tc = get_default_trace_class()
146 return tc.create_unsigned_integer_field_class(*args, **kwargs)
147
148 _create_default_field_class = _create_field_class
32656995 149
b2df5780
PP
150
151class RealFieldClassTestCase(_TestFieldClass, unittest.TestCase):
152 def _create_field_class(self, *args, **kwargs):
153 tc = get_default_trace_class()
154 return tc.create_real_field_class(*args, **kwargs)
155
156 _create_default_field_class = _create_field_class
32656995 157
c8820b76 158 def test_create_default(self):
b2df5780 159 fc = self._create_field_class()
c8820b76 160 self.assertFalse(fc.is_single_precision)
b2df5780 161 self.assertEqual(len(fc.user_attributes), 0)
32656995 162
c8820b76 163 def test_create_is_single_precision(self):
b2df5780 164 fc = self._create_field_class(is_single_precision=True)
c8820b76
SM
165 self.assertTrue(fc.is_single_precision)
166
167 def test_create_invalid_is_single_precision(self):
32656995 168 with self.assertRaises(TypeError):
b2df5780 169 self._create_field_class(is_single_precision='hohoho')
32656995 170
32656995 171
c8820b76
SM
172# Converts an _EnumerationFieldClassMapping to a list of ranges:
173#
174# [(lower0, upper0), (lower1, upper1), ...]
175
61d96b89 176
02b61fe0
PP
177def enum_mapping_to_set(mapping):
178 return {(x.lower, x.upper) for x in mapping.ranges}
32656995 179
32656995 180
02b61fe0 181class _EnumerationFieldClassTestCase(_TestIntegerFieldClassProps):
c8820b76 182 def setUp(self):
02b61fe0 183 self._spec_set_up()
b2df5780 184 self._fc = self._create_default_field_class()
c8820b76
SM
185
186 def test_create_from_invalid_type(self):
32656995 187 with self.assertRaises(TypeError):
b2df5780 188 self._create_field_class('coucou')
32656995 189
c8820b76 190 def test_add_mapping_simple(self):
02b61fe0 191 self._fc.add_mapping('hello', self._ranges1)
c8820b76
SM
192 mapping = self._fc['hello']
193 self.assertEqual(mapping.label, 'hello')
02b61fe0 194 self.assertEqual(mapping.ranges, self._ranges1)
32656995 195
c8820b76 196 def test_add_mapping_simple_kwargs(self):
02b61fe0 197 self._fc.add_mapping(label='hello', ranges=self._ranges1)
c8820b76
SM
198 mapping = self._fc['hello']
199 self.assertEqual(mapping.label, 'hello')
02b61fe0 200 self.assertEqual(mapping.ranges, self._ranges1)
32656995 201
02b61fe0
PP
202 def test_add_mapping_invalid_name(self):
203 with self.assertRaises(TypeError):
204 self._fc.add_mapping(17, self._ranges1)
32656995 205
02b61fe0
PP
206 def test_add_mapping_invalid_range(self):
207 with self.assertRaises(TypeError):
208 self._fc.add_mapping('allo', 'meow')
c8820b76 209
02b61fe0 210 def test_add_mapping_dup_label(self):
3b2be708 211 with self.assertRaises(ValueError):
02b61fe0
PP
212 self._fc.add_mapping('a', self._ranges1)
213 self._fc.add_mapping('a', self._ranges2)
c8820b76 214
02b61fe0 215 def test_add_mapping_invalid_ranges_signedness(self):
32656995 216 with self.assertRaises(TypeError):
02b61fe0 217 self._fc.add_mapping('allo', self._inval_ranges)
32656995 218
c8820b76 219 def test_iadd(self):
02b61fe0 220 self._fc.add_mapping('c', self._ranges1)
32656995 221
61d96b89 222 self._fc += [('d', self._ranges2), ('e', self._ranges3)]
32656995 223
02b61fe0 224 self.assertEqual(len(self._fc), 3)
c8820b76 225 self.assertEqual(self._fc['c'].label, 'c')
02b61fe0 226 self.assertEqual(self._fc['c'].ranges, self._ranges1)
c8820b76 227 self.assertEqual(self._fc['d'].label, 'd')
02b61fe0 228 self.assertEqual(self._fc['d'].ranges, self._ranges2)
c8820b76 229 self.assertEqual(self._fc['e'].label, 'e')
02b61fe0 230 self.assertEqual(self._fc['e'].ranges, self._ranges3)
32656995 231
c8820b76
SM
232 def test_bool_op(self):
233 self.assertFalse(self._fc)
02b61fe0 234 self._fc.add_mapping('a', self._ranges1)
c8820b76 235 self.assertTrue(self._fc)
32656995 236
c8820b76 237 def test_len(self):
02b61fe0
PP
238 self._fc.add_mapping('a', self._ranges1)
239 self._fc.add_mapping('b', self._ranges2)
240 self._fc.add_mapping('c', self._ranges3)
c8820b76 241 self.assertEqual(len(self._fc), 3)
32656995 242
c8820b76 243 def test_getitem(self):
02b61fe0
PP
244 self._fc.add_mapping('a', self._ranges1)
245 self._fc.add_mapping('b', self._ranges2)
246 self._fc.add_mapping('c', self._ranges3)
c8820b76 247 mapping = self._fc['a']
c8820b76 248 self.assertEqual(mapping.label, 'a')
02b61fe0 249 self.assertEqual(mapping.ranges, self._ranges1)
32656995 250
02b61fe0 251 def test_getitem_nonexistent(self):
c8820b76
SM
252 with self.assertRaises(KeyError):
253 self._fc['doesnotexist']
32656995 254
c8820b76 255 def test_iter(self):
02b61fe0
PP
256 self._fc.add_mapping('a', self._ranges1)
257 self._fc.add_mapping('b', self._ranges2)
258 self._fc.add_mapping('c', self._ranges3)
32656995 259
c8820b76
SM
260 # This exercises iteration.
261 labels = sorted(self._fc)
32656995 262
02b61fe0 263 self.assertEqual(labels, ['a', 'b', 'c'])
32656995 264
c8820b76 265 def test_find_by_value(self):
02b61fe0
PP
266 self._fc.add_mapping('a', self._ranges1)
267 self._fc.add_mapping('b', self._ranges2)
268 self._fc.add_mapping('c', self._ranges3)
269 mappings = self._fc.mappings_for_value(self._value_in_range_1_and_3)
270 labels = set([mapping.label for mapping in mappings])
271 expected_labels = set(['a', 'c'])
272 self.assertEqual(labels, expected_labels)
273
274
61d96b89 275class UnsignedEnumerationFieldClassTestCase(
b2df5780 276 _EnumerationFieldClassTestCase, _TestFieldClass, unittest.TestCase
61d96b89 277):
02b61fe0
PP
278 def _spec_set_up(self):
279 self._ranges1 = bt2.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
280 self._ranges2 = bt2.UnsignedIntegerRangeSet([(5, 5)])
281 self._ranges3 = bt2.UnsignedIntegerRangeSet([(8, 22), (48, 99)])
282 self._inval_ranges = bt2.SignedIntegerRangeSet([(-8, -5), (48, 1928)])
283 self._value_in_range_1_and_3 = 20
b2df5780
PP
284
285 def _create_field_class(self, *args, **kwargs):
286 tc = get_default_trace_class()
287 return tc.create_unsigned_enumeration_field_class(*args, **kwargs)
288
289 _create_default_field_class = _create_field_class
32656995 290
32656995 291
61d96b89 292class SignedEnumerationFieldClassTestCase(
b2df5780 293 _EnumerationFieldClassTestCase, _TestFieldClass, unittest.TestCase
61d96b89 294):
02b61fe0
PP
295 def _spec_set_up(self):
296 self._ranges1 = bt2.SignedIntegerRangeSet([(-10, -4), (18, 47)])
297 self._ranges2 = bt2.SignedIntegerRangeSet([(-3, -3)])
298 self._ranges3 = bt2.SignedIntegerRangeSet([(-100, -1), (8, 16), (48, 99)])
299 self._inval_ranges = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
300 self._value_in_range_1_and_3 = -7
32656995 301
b2df5780
PP
302 def _create_field_class(self, *args, **kwargs):
303 tc = get_default_trace_class()
304 return tc.create_signed_enumeration_field_class(*args, **kwargs)
305
306 _create_default_field_class = _create_field_class
32656995 307
b2df5780
PP
308
309class StringFieldClassTestCase(_TestFieldClass, unittest.TestCase):
310 def _create_field_class(self, *args, **kwargs):
c8820b76 311 tc = get_default_trace_class()
b2df5780
PP
312 return tc.create_string_field_class(*args, **kwargs)
313
314 _create_default_field_class = _create_field_class
315
316 def setUp(self):
317 self._fc = self._create_default_field_class()
32656995
SM
318
319 def test_create_default(self):
c8820b76 320 self.assertIsNotNone(self._fc)
b2df5780 321 self.assertEqual(len(self._fc.user_attributes), 0)
32656995 322
32656995 323
61d96b89 324class _TestElementContainer:
02b61fe0
PP
325 def setUp(self):
326 self._tc = get_default_trace_class()
b2df5780 327 self._fc = self._create_default_field_class()
02b61fe0
PP
328
329 def test_create_default(self):
330 self.assertIsNotNone(self._fc)
b2df5780 331 self.assertEqual(len(self._fc.user_attributes), 0)
02b61fe0 332
c8820b76
SM
333 def test_append_element(self):
334 int_field_class = self._tc.create_signed_integer_field_class(32)
335 self._append_element_method(self._fc, 'int32', int_field_class)
02b61fe0 336 field_class = self._fc['int32'].field_class
c8820b76 337 self.assertEqual(field_class.addr, int_field_class.addr)
32656995 338
02b61fe0 339 def test_append_element_kwargs(self):
c8820b76
SM
340 int_field_class = self._tc.create_signed_integer_field_class(32)
341 self._append_element_method(self._fc, name='int32', field_class=int_field_class)
02b61fe0 342 field_class = self._fc['int32'].field_class
c8820b76
SM
343 self.assertEqual(field_class.addr, int_field_class.addr)
344
345 def test_append_element_invalid_name(self):
346 sub_fc = self._tc.create_string_field_class()
32656995 347
32656995 348 with self.assertRaises(TypeError):
c8820b76 349 self._append_element_method(self._fc, 23, sub_fc)
32656995 350
c8820b76 351 def test_append_element_invalid_field_class(self):
32656995 352 with self.assertRaises(TypeError):
c8820b76 353 self._append_element_method(self._fc, 'yes', object())
32656995 354
02b61fe0
PP
355 def test_append_element_dup_name(self):
356 sub_fc1 = self._tc.create_string_field_class()
357 sub_fc2 = self._tc.create_string_field_class()
358
3b2be708 359 with self.assertRaises(ValueError):
02b61fe0
PP
360 self._append_element_method(self._fc, 'yes', sub_fc1)
361 self._append_element_method(self._fc, 'yes', sub_fc2)
362
32656995 363 def test_iadd(self):
c8820b76
SM
364 a_field_class = self._tc.create_real_field_class()
365 b_field_class = self._tc.create_signed_integer_field_class(17)
366 self._append_element_method(self._fc, 'a_float', a_field_class)
367 self._append_element_method(self._fc, 'b_int', b_field_class)
02b61fe0 368 c_field_class = self._tc.create_string_field_class()
61d96b89
FD
369 d_field_class = self._tc.create_signed_enumeration_field_class(
370 field_value_range=32
371 )
02b61fe0
PP
372 e_field_class = self._tc.create_structure_field_class()
373 self._fc += [
374 ('c_string', c_field_class),
375 ('d_enum', d_field_class),
376 ('e_struct', e_field_class),
377 ]
378 self.assertEqual(self._fc['a_float'].field_class.addr, a_field_class.addr)
379 self.assertEqual(self._fc['a_float'].name, 'a_float')
380 self.assertEqual(self._fc['b_int'].field_class.addr, b_field_class.addr)
381 self.assertEqual(self._fc['b_int'].name, 'b_int')
382 self.assertEqual(self._fc['c_string'].field_class.addr, c_field_class.addr)
383 self.assertEqual(self._fc['c_string'].name, 'c_string')
384 self.assertEqual(self._fc['d_enum'].field_class.addr, d_field_class.addr)
385 self.assertEqual(self._fc['d_enum'].name, 'd_enum')
386 self.assertEqual(self._fc['e_struct'].field_class.addr, e_field_class.addr)
387 self.assertEqual(self._fc['e_struct'].name, 'e_struct')
32656995
SM
388
389 def test_bool_op(self):
390 self.assertFalse(self._fc)
c8820b76 391 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
32656995
SM
392 self.assertTrue(self._fc)
393
394 def test_len(self):
02b61fe0
PP
395 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
396 self._append_element_method(self._fc, 'b', self._tc.create_string_field_class())
397 self._append_element_method(self._fc, 'c', self._tc.create_string_field_class())
32656995
SM
398 self.assertEqual(len(self._fc), 3)
399
400 def test_getitem(self):
c8820b76
SM
401 a_fc = self._tc.create_signed_integer_field_class(32)
402 b_fc = self._tc.create_string_field_class()
403 c_fc = self._tc.create_real_field_class()
404 self._append_element_method(self._fc, 'a', a_fc)
405 self._append_element_method(self._fc, 'b', b_fc)
406 self._append_element_method(self._fc, 'c', c_fc)
02b61fe0
PP
407 self.assertEqual(self._fc['b'].field_class.addr, b_fc.addr)
408 self.assertEqual(self._fc['b'].name, 'b')
32656995
SM
409
410 def test_getitem_invalid_key_type(self):
411 with self.assertRaises(TypeError):
412 self._fc[0]
413
414 def test_getitem_invalid_key(self):
415 with self.assertRaises(KeyError):
416 self._fc['no way']
417
418 def test_contains(self):
419 self.assertFalse('a' in self._fc)
c8820b76 420 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
32656995
SM
421 self.assertTrue('a' in self._fc)
422
423 def test_iter(self):
c8820b76
SM
424 a_fc = self._tc.create_signed_integer_field_class(32)
425 b_fc = self._tc.create_string_field_class()
426 c_fc = self._tc.create_real_field_class()
61d96b89 427 elements = (('a', a_fc), ('b', b_fc), ('c', c_fc))
32656995 428
02b61fe0
PP
429 for elem in elements:
430 self._append_element_method(self._fc, *elem)
32656995 431
02b61fe0
PP
432 for (name, element), test_elem in zip(self._fc.items(), elements):
433 self.assertEqual(element.name, test_elem[0])
434 self.assertEqual(name, element.name)
435 self.assertEqual(element.field_class.addr, test_elem[1].addr)
b2df5780 436 self.assertEqual(len(element.user_attributes), 0)
32656995
SM
437
438 def test_at_index(self):
c8820b76
SM
439 a_fc = self._tc.create_signed_integer_field_class(32)
440 b_fc = self._tc.create_string_field_class()
441 c_fc = self._tc.create_real_field_class()
442 self._append_element_method(self._fc, 'c', c_fc)
443 self._append_element_method(self._fc, 'a', a_fc)
444 self._append_element_method(self._fc, 'b', b_fc)
02b61fe0
PP
445 elem = self._at_index_method(self._fc, 1)
446 self.assertEqual(elem.field_class.addr, a_fc.addr)
447 self.assertEqual(elem.name, 'a')
32656995
SM
448
449 def test_at_index_invalid(self):
61d96b89
FD
450 self._append_element_method(
451 self._fc, 'c', self._tc.create_signed_integer_field_class(32)
452 )
32656995
SM
453
454 with self.assertRaises(TypeError):
c8820b76 455 self._at_index_method(self._fc, 'yes')
32656995
SM
456
457 def test_at_index_out_of_bounds_after(self):
61d96b89
FD
458 self._append_element_method(
459 self._fc, 'c', self._tc.create_signed_integer_field_class(32)
460 )
32656995
SM
461
462 with self.assertRaises(IndexError):
c8820b76 463 self._at_index_method(self._fc, len(self._fc))
32656995 464
b2df5780
PP
465 def test_user_attributes(self):
466 self._append_element_method(
467 self._fc,
468 'c',
469 self._tc.create_string_field_class(),
470 user_attributes={'salut': 23},
471 )
472 self.assertEqual(self._fc['c'].user_attributes, {'salut': 23})
32656995 473
b2df5780
PP
474 def test_invalid_user_attributes(self):
475 with self.assertRaises(TypeError):
476 self._append_element_method(
477 self._fc,
478 'c',
479 self._tc.create_string_field_class(),
480 user_attributes=object(),
481 )
482
483 def test_invalid_user_attributes_value_type(self):
484 with self.assertRaises(TypeError):
485 self._append_element_method(
486 self._fc, 'c', self._tc.create_string_field_class(), user_attributes=23
487 )
488
489
490class StructureFieldClassTestCase(
491 _TestFieldClass, _TestElementContainer, unittest.TestCase
492):
c946c9de
PP
493 _append_element_method = staticmethod(bt2._StructureFieldClass.append_member)
494 _at_index_method = staticmethod(bt2._StructureFieldClass.member_at_index)
02b61fe0 495
b2df5780
PP
496 def _create_field_class(self, *args, **kwargs):
497 tc = get_default_trace_class()
498 return tc.create_structure_field_class(*args, **kwargs)
02b61fe0 499
b2df5780
PP
500 _create_default_field_class = _create_field_class
501
502
503class OptionFieldClassTestCase(_TestFieldClass, unittest.TestCase):
504 def _create_default_field_class(self, *args, **kwargs):
505 return self._tc.create_option_field_class(self._content_fc, **kwargs)
02b61fe0 506
84eba0d9
PP
507 def setUp(self):
508 self._tc = get_default_trace_class()
509 self._content_fc = self._tc.create_signed_integer_field_class(23)
510 self._tag_fc = self._tc.create_bool_field_class()
511
512 def test_create_default(self):
b2df5780 513 fc = self._create_default_field_class()
84eba0d9
PP
514 self.assertEqual(fc.field_class.addr, self._content_fc.addr)
515 self.assertIsNone(fc.selector_field_path, None)
b2df5780 516 self.assertEqual(len(fc.user_attributes), 0)
84eba0d9
PP
517
518 def _create_field_class_for_field_path_test(self):
b2df5780 519 fc = self._create_default_field_class(selector_fc=self._tag_fc)
84eba0d9
PP
520
521 foo_fc = self._tc.create_real_field_class()
522 bar_fc = self._tc.create_string_field_class()
523 baz_fc = self._tc.create_string_field_class()
524
525 inner_struct_fc = self._tc.create_structure_field_class()
526 inner_struct_fc.append_member('bar', bar_fc)
527 inner_struct_fc.append_member('baz', baz_fc)
528 inner_struct_fc.append_member('tag', self._tag_fc)
529 inner_struct_fc.append_member('opt', fc)
530
531 opt_struct_array_fc = self._tc.create_option_field_class(inner_struct_fc)
532
533 outer_struct_fc = self._tc.create_structure_field_class()
534 outer_struct_fc.append_member('foo', foo_fc)
535 outer_struct_fc.append_member('inner_opt', opt_struct_array_fc)
536
537 # The path to the selector field class is resolved when the
538 # option field class is actually used, for example in a packet
539 # context.
540 self._tc.create_stream_class(
541 packet_context_field_class=outer_struct_fc, supports_packets=True
542 )
543
544 return fc
545
546 def test_field_path_len(self):
547 fc = self._create_field_class_for_field_path_test()
548 self.assertEqual(len(fc.selector_field_path), 3)
549
550 def test_field_path_iter(self):
551 fc = self._create_field_class_for_field_path_test()
552 path_items = list(fc.selector_field_path)
553
554 self.assertEqual(len(path_items), 3)
555
556 self.assertIsInstance(path_items[0], bt2._IndexFieldPathItem)
557 self.assertEqual(path_items[0].index, 1)
558
559 self.assertIsInstance(path_items[1], bt2._CurrentOptionContentFieldPathItem)
560
561 self.assertIsInstance(path_items[2], bt2._IndexFieldPathItem)
562 self.assertEqual(path_items[2].index, 2)
563
564 def test_field_path_root_scope(self):
565 fc = self._create_field_class_for_field_path_test()
566 self.assertEqual(
567 fc.selector_field_path.root_scope, bt2.FieldPathScope.PACKET_CONTEXT
568 )
569
570 def test_create_invalid_field_class(self):
571 with self.assertRaises(TypeError):
572 self._tc.create_option_field_class(object())
573
574 def test_create_invalid_selector_type(self):
575 with self.assertRaises(TypeError):
576 self._tc.create_option_field_class(self._content_fc, 17)
577
578
61d96b89 579class VariantFieldClassWithoutSelectorTestCase(
b2df5780 580 _TestFieldClass, _TestElementContainer, unittest.TestCase
61d96b89
FD
581):
582 _append_element_method = staticmethod(
c946c9de 583 bt2._VariantFieldClassWithoutSelector.append_option
61d96b89
FD
584 )
585 _at_index_method = staticmethod(
c946c9de 586 bt2._VariantFieldClassWithoutSelector.option_at_index
61d96b89 587 )
02b61fe0 588
b2df5780
PP
589 def _create_field_class(self, *args, **kwargs):
590 tc = get_default_trace_class()
591 return tc.create_variant_field_class(*args, **kwargs)
592
593 _create_default_field_class = _create_field_class
02b61fe0
PP
594
595
596class _VariantFieldClassWithSelectorTestCase:
b2df5780
PP
597 def _create_default_field_class(self, *args, **kwargs):
598 return self._tc.create_variant_field_class(
599 *args, selector_fc=self._selector_fc, **kwargs
600 )
601
32656995 602 def setUp(self):
c8820b76 603 self._tc = get_default_trace_class()
02b61fe0 604 self._spec_set_up()
b2df5780 605 self._fc = self._create_default_field_class()
c8820b76
SM
606
607 def test_create_default(self):
608 self.assertIsNotNone(self._fc)
b2df5780 609 self.assertEqual(len(self._fc.user_attributes), 0)
32656995 610
02b61fe0
PP
611 def test_append_element(self):
612 str_field_class = self._tc.create_string_field_class()
613 self._fc.append_option('str', str_field_class, self._ranges1)
614 opt = self._fc['str']
615 self.assertEqual(opt.field_class.addr, str_field_class.addr)
616 self.assertEqual(opt.name, 'str')
617 self.assertEqual(opt.ranges.addr, self._ranges1.addr)
618
619 def test_append_element_kwargs(self):
620 int_field_class = self._tc.create_signed_integer_field_class(32)
61d96b89
FD
621 self._fc.append_option(
622 name='int32', field_class=int_field_class, ranges=self._ranges1
623 )
02b61fe0
PP
624 opt = self._fc['int32']
625 self.assertEqual(opt.field_class.addr, int_field_class.addr)
626 self.assertEqual(opt.name, 'int32')
627 self.assertEqual(opt.ranges.addr, self._ranges1.addr)
c8820b76 628
02b61fe0
PP
629 def test_append_element_invalid_name(self):
630 sub_fc = self._tc.create_string_field_class()
32656995 631
02b61fe0
PP
632 with self.assertRaises(TypeError):
633 self._fc.append_option(self._fc, 23, sub_fc)
32656995 634
02b61fe0
PP
635 def test_append_element_invalid_field_class(self):
636 with self.assertRaises(TypeError):
637 self._fc.append_option(self._fc, 'yes', object())
638
639 def test_append_element_invalid_ranges(self):
640 sub_fc = self._tc.create_string_field_class()
641
642 with self.assertRaises(TypeError):
643 self._fc.append_option(self._fc, sub_fc, 'lel')
644
645 def test_append_element_dup_name(self):
646 sub_fc1 = self._tc.create_string_field_class()
647 sub_fc2 = self._tc.create_string_field_class()
648
3b2be708 649 with self.assertRaises(ValueError):
02b61fe0
PP
650 self._fc.append_option('yes', sub_fc1, self._ranges1)
651 self._fc.append_option('yes', sub_fc2, self._ranges2)
652
653 def test_append_element_invalid_ranges_signedness(self):
654 sub_fc = self._tc.create_string_field_class()
655
656 with self.assertRaises(TypeError):
657 self._fc.append_option(self._fc, sub_fc, self._inval_ranges)
658
b2df5780
PP
659 def test_user_attributes(self):
660 self._fc.append_option(
661 'c',
662 self._tc.create_string_field_class(),
663 self._ranges1,
664 user_attributes={'salut': 23},
665 )
666 self.assertEqual(self._fc['c'].user_attributes, {'salut': 23})
667
668 def test_invalid_user_attributes(self):
669 with self.assertRaises(TypeError):
670 self._fc.append_option(
671 'c',
672 self._tc.create_string_field_class(),
673 self._ranges1,
674 user_attributes=object(),
675 )
676
677 def test_invalid_user_attributes_value_type(self):
678 with self.assertRaises(TypeError):
679 self._fc.append_option(
680 'c',
681 self._tc.create_string_field_class(),
682 self._ranges1,
683 user_attributes=23,
684 )
685
02b61fe0 686 def test_iadd(self):
02b61fe0
PP
687 a_field_class = self._tc.create_real_field_class()
688 self._fc.append_option('a_float', a_field_class, self._ranges1)
689 c_field_class = self._tc.create_string_field_class()
61d96b89
FD
690 d_field_class = self._tc.create_signed_enumeration_field_class(
691 field_value_range=32
692 )
02b61fe0
PP
693 self._fc += [
694 ('c_string', c_field_class, self._ranges2),
695 ('d_enum', d_field_class, self._ranges3),
696 ]
697 self.assertEqual(self._fc['a_float'].field_class.addr, a_field_class.addr)
698 self.assertEqual(self._fc['a_float'].name, 'a_float')
699 self.assertEqual(self._fc['a_float'].ranges, self._ranges1)
700 self.assertEqual(self._fc['c_string'].field_class.addr, c_field_class.addr)
701 self.assertEqual(self._fc['c_string'].name, 'c_string')
702 self.assertEqual(self._fc['c_string'].ranges, self._ranges2)
703 self.assertEqual(self._fc['d_enum'].field_class.addr, d_field_class.addr)
704 self.assertEqual(self._fc['d_enum'].name, 'd_enum')
705 self.assertEqual(self._fc['d_enum'].ranges, self._ranges3)
706
707 def test_bool_op(self):
708 self.assertFalse(self._fc)
709 self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
710 self.assertTrue(self._fc)
711
712 def test_len(self):
713 self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
714 self._fc.append_option('b', self._tc.create_string_field_class(), self._ranges2)
715 self._fc.append_option('c', self._tc.create_string_field_class(), self._ranges3)
716 self.assertEqual(len(self._fc), 3)
717
718 def test_getitem(self):
719 a_fc = self._tc.create_signed_integer_field_class(32)
720 b_fc = self._tc.create_string_field_class()
721 c_fc = self._tc.create_real_field_class()
722 self._fc.append_option('a', a_fc, self._ranges1)
723 self._fc.append_option('b', b_fc, self._ranges2)
724 self._fc.append_option('c', c_fc, self._ranges3)
725 self.assertEqual(self._fc['b'].field_class.addr, b_fc.addr)
726 self.assertEqual(self._fc['b'].name, 'b')
727 self.assertEqual(self._fc['b'].ranges.addr, self._ranges2.addr)
728
729 def test_getitem_invalid_key_type(self):
730 with self.assertRaises(TypeError):
731 self._fc[0]
732
733 def test_getitem_invalid_key(self):
734 with self.assertRaises(KeyError):
735 self._fc['no way']
736
737 def test_contains(self):
738 self.assertFalse('a' in self._fc)
739 self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
740 self.assertTrue('a' in self._fc)
741
742 def test_iter(self):
743 a_fc = self._tc.create_signed_integer_field_class(32)
744 b_fc = self._tc.create_string_field_class()
745 c_fc = self._tc.create_real_field_class()
746 opts = (
747 ('a', a_fc, self._ranges1),
748 ('b', b_fc, self._ranges2),
749 ('c', c_fc, self._ranges3),
750 )
751
752 for opt in opts:
753 self._fc.append_option(*opt)
32656995 754
02b61fe0
PP
755 for (name, opt), test_opt in zip(self._fc.items(), opts):
756 self.assertEqual(opt.name, test_opt[0])
757 self.assertEqual(name, opt.name)
758 self.assertEqual(opt.field_class.addr, test_opt[1].addr)
759 self.assertEqual(opt.ranges.addr, test_opt[2].addr)
760
761 def test_at_index(self):
762 a_fc = self._tc.create_signed_integer_field_class(32)
763 b_fc = self._tc.create_string_field_class()
764 c_fc = self._tc.create_real_field_class()
765 self._fc.append_option('c', c_fc, self._ranges1)
766 self._fc.append_option('a', a_fc, self._ranges2)
767 self._fc.append_option('b', b_fc, self._ranges3)
768 self.assertEqual(self._fc.option_at_index(1).field_class.addr, a_fc.addr)
769 self.assertEqual(self._fc.option_at_index(1).name, 'a')
770 self.assertEqual(self._fc.option_at_index(1).ranges.addr, self._ranges2.addr)
771
772 def test_at_index_invalid(self):
61d96b89
FD
773 self._fc.append_option(
774 'c', self._tc.create_signed_integer_field_class(32), self._ranges3
775 )
02b61fe0
PP
776
777 with self.assertRaises(TypeError):
778 self._fc.option_at_index('yes')
779
780 def test_at_index_out_of_bounds_after(self):
61d96b89
FD
781 self._fc.append_option(
782 'c', self._tc.create_signed_integer_field_class(32), self._ranges3
783 )
02b61fe0
PP
784
785 with self.assertRaises(IndexError):
786 self._fc.option_at_index(len(self._fc))
787
788 def _fill_default_fc_for_field_path_test(self):
c8820b76
SM
789 # Create something equivalent to:
790 #
791 # struct outer_struct_fc {
792 # real foo;
793 # struct inner_struct_fc {
02b61fe0 794 # [u]int64_t selector;
c8820b76
SM
795 # string bar;
796 # string baz;
02b61fe0
PP
797 # variant <selector> {
798 # real a; // selected with self._ranges1
799 # int21_t b; // selected with self._ranges2
800 # uint34_t c; // selected with self._ranges3
c8820b76
SM
801 # } variant;
802 # } inner_struct[2];
803 # };
02b61fe0 804 self._fc.append_option('a', self._tc.create_real_field_class(), self._ranges1)
61d96b89
FD
805 self._fc.append_option(
806 'b', self._tc.create_signed_integer_field_class(21), self._ranges2
807 )
808 self._fc.append_option(
809 'c', self._tc.create_unsigned_integer_field_class(34), self._ranges3
810 )
32656995 811
c8820b76
SM
812 foo_fc = self._tc.create_real_field_class()
813 bar_fc = self._tc.create_string_field_class()
814 baz_fc = self._tc.create_string_field_class()
32656995 815
c8820b76 816 inner_struct_fc = self._tc.create_structure_field_class()
02b61fe0 817 inner_struct_fc.append_member('selector', self._selector_fc)
c8820b76
SM
818 inner_struct_fc.append_member('bar', bar_fc)
819 inner_struct_fc.append_member('baz', baz_fc)
02b61fe0 820 inner_struct_fc.append_member('variant', self._fc)
32656995 821
61d96b89
FD
822 inner_struct_array_fc = self._tc.create_static_array_field_class(
823 inner_struct_fc, 2
824 )
32656995 825
c8820b76
SM
826 outer_struct_fc = self._tc.create_structure_field_class()
827 outer_struct_fc.append_member('foo', foo_fc)
828 outer_struct_fc.append_member('inner_struct', inner_struct_array_fc)
32656995 829
c8820b76
SM
830 # The path to the selector field is resolved when the sequence is
831 # actually used, for example in a packet context.
61d96b89
FD
832 self._tc.create_stream_class(
833 supports_packets=True, packet_context_field_class=outer_struct_fc
834 )
32656995 835
c8820b76 836 def test_selector_field_path_length(self):
02b61fe0
PP
837 self._fill_default_fc_for_field_path_test()
838 self.assertEqual(len(self._fc.selector_field_path), 3)
32656995 839
c8820b76 840 def test_selector_field_path_iter(self):
02b61fe0
PP
841 self._fill_default_fc_for_field_path_test()
842 path_items = list(self._fc.selector_field_path)
32656995 843
c8820b76 844 self.assertEqual(len(path_items), 3)
32656995 845
c946c9de 846 self.assertIsInstance(path_items[0], bt2._IndexFieldPathItem)
c8820b76 847 self.assertEqual(path_items[0].index, 1)
32656995 848
c946c9de 849 self.assertIsInstance(path_items[1], bt2._CurrentArrayElementFieldPathItem)
32656995 850
c946c9de 851 self.assertIsInstance(path_items[2], bt2._IndexFieldPathItem)
c8820b76 852 self.assertEqual(path_items[2].index, 0)
32656995 853
c8820b76 854 def test_selector_field_path_root_scope(self):
02b61fe0 855 self._fill_default_fc_for_field_path_test()
61d96b89 856 self.assertEqual(
056995e5 857 self._fc.selector_field_path.root_scope, bt2.FieldPathScope.PACKET_CONTEXT
61d96b89 858 )
02b61fe0
PP
859
860
61d96b89
FD
861class VariantFieldClassWithUnsignedSelectorTestCase(
862 _VariantFieldClassWithSelectorTestCase, unittest.TestCase
863):
02b61fe0
PP
864 def _spec_set_up(self):
865 self._ranges1 = bt2.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
866 self._ranges2 = bt2.UnsignedIntegerRangeSet([(5, 5)])
867 self._ranges3 = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
868 self._inval_ranges = bt2.SignedIntegerRangeSet([(-8, 16), (48, 99)])
869 self._selector_fc = self._tc.create_unsigned_integer_field_class()
870
871
61d96b89
FD
872class VariantFieldClassWithSignedSelectorTestCase(
873 _VariantFieldClassWithSelectorTestCase, unittest.TestCase
874):
02b61fe0
PP
875 def _spec_set_up(self):
876 self._ranges1 = bt2.SignedIntegerRangeSet([(-10, -4), (18, 47)])
877 self._ranges2 = bt2.SignedIntegerRangeSet([(-3, -3)])
878 self._ranges3 = bt2.SignedIntegerRangeSet([(8, 16), (48, 99)])
879 self._inval_ranges = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
880 self._selector_fc = self._tc.create_signed_integer_field_class()
32656995 881
c8820b76
SM
882
883class StaticArrayFieldClassTestCase(unittest.TestCase):
884 def setUp(self):
885 self._tc = get_default_trace_class()
886 self._elem_fc = self._tc.create_signed_integer_field_class(23)
32656995
SM
887
888 def test_create_default(self):
c8820b76
SM
889 fc = self._tc.create_static_array_field_class(self._elem_fc, 45)
890 self.assertEqual(fc.element_field_class.addr, self._elem_fc.addr)
891 self.assertEqual(fc.length, 45)
b2df5780 892 self.assertEqual(len(fc.user_attributes), 0)
32656995 893
c8820b76 894 def test_create_invalid_elem_field_class(self):
32656995 895 with self.assertRaises(TypeError):
c8820b76 896 self._tc.create_static_array_field_class(object(), 45)
32656995
SM
897
898 def test_create_invalid_length(self):
899 with self.assertRaises(ValueError):
61d96b89
FD
900 self._tc.create_static_array_field_class(
901 self._tc.create_string_field_class(), -17
902 )
32656995
SM
903
904 def test_create_invalid_length_type(self):
905 with self.assertRaises(TypeError):
61d96b89
FD
906 self._tc.create_static_array_field_class(
907 self._tc.create_string_field_class(), 'the length'
908 )
c8820b76
SM
909
910
911class DynamicArrayFieldClassTestCase(unittest.TestCase):
912 def setUp(self):
913 self._tc = get_default_trace_class()
914 self._elem_fc = self._tc.create_signed_integer_field_class(23)
915 self._len_fc = self._tc.create_unsigned_integer_field_class(12)
32656995 916
c8820b76
SM
917 def test_create_default(self):
918 fc = self._tc.create_dynamic_array_field_class(self._elem_fc)
919 self.assertEqual(fc.element_field_class.addr, self._elem_fc.addr)
920 self.assertIsNone(fc.length_field_path, None)
b2df5780 921 self.assertEqual(len(fc.user_attributes), 0)
32656995 922
c8820b76
SM
923 def _create_field_class_for_field_path_test(self):
924 # Create something a field class that is equivalent to:
925 #
926 # struct outer_struct_fc {
927 # real foo;
928 # struct inner_struct_fc {
929 # string bar;
930 # string baz;
931 # uint12_t len;
932 # uint23_t dyn_array[len];
933 # } inner_struct[2];
934 # };
32656995 935
c8820b76 936 fc = self._tc.create_dynamic_array_field_class(self._elem_fc, self._len_fc)
32656995 937
c8820b76
SM
938 foo_fc = self._tc.create_real_field_class()
939 bar_fc = self._tc.create_string_field_class()
940 baz_fc = self._tc.create_string_field_class()
32656995 941
c8820b76
SM
942 inner_struct_fc = self._tc.create_structure_field_class()
943 inner_struct_fc.append_member('bar', bar_fc)
944 inner_struct_fc.append_member('baz', baz_fc)
945 inner_struct_fc.append_member('len', self._len_fc)
946 inner_struct_fc.append_member('dyn_array', fc)
32656995 947
61d96b89
FD
948 inner_struct_array_fc = self._tc.create_static_array_field_class(
949 inner_struct_fc, 2
950 )
c8820b76
SM
951
952 outer_struct_fc = self._tc.create_structure_field_class()
953 outer_struct_fc.append_member('foo', foo_fc)
954 outer_struct_fc.append_member('inner_struct', inner_struct_array_fc)
955
956 # The path to the length field is resolved when the sequence is
957 # actually used, for example in a packet context.
61d96b89
FD
958 self._tc.create_stream_class(
959 packet_context_field_class=outer_struct_fc, supports_packets=True
960 )
c8820b76
SM
961
962 return fc
963
964 def test_field_path_len(self):
965 fc = self._create_field_class_for_field_path_test()
966 self.assertEqual(len(fc.length_field_path), 3)
967
968 def test_field_path_iter(self):
969 fc = self._create_field_class_for_field_path_test()
970 path_items = list(fc.length_field_path)
971
972 self.assertEqual(len(path_items), 3)
973
c946c9de 974 self.assertIsInstance(path_items[0], bt2._IndexFieldPathItem)
c8820b76
SM
975 self.assertEqual(path_items[0].index, 1)
976
c946c9de 977 self.assertIsInstance(path_items[1], bt2._CurrentArrayElementFieldPathItem)
c8820b76 978
c946c9de 979 self.assertIsInstance(path_items[2], bt2._IndexFieldPathItem)
c8820b76
SM
980 self.assertEqual(path_items[2].index, 2)
981
982 def test_field_path_root_scope(self):
983 fc = self._create_field_class_for_field_path_test()
056995e5
PP
984 self.assertEqual(
985 fc.length_field_path.root_scope, bt2.FieldPathScope.PACKET_CONTEXT
986 )
32656995
SM
987
988 def test_create_invalid_field_class(self):
989 with self.assertRaises(TypeError):
c8820b76 990 self._tc.create_dynamic_array_field_class(object())
32656995
SM
991
992 def test_create_invalid_length_type(self):
993 with self.assertRaises(TypeError):
61d96b89
FD
994 self._tc.create_dynamic_array_field_class(
995 self._tc.create_string_field_class(), 17
996 )
32656995 997
32656995 998
c8820b76
SM
999if __name__ == "__main__":
1000 unittest.main()
This page took 0.080207 seconds and 4 git commands to generate.