2 # Copyright (C) 2019 EfficiOS Inc.
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
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.
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.
21 from utils
import get_default_trace_class
24 class _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})
29 def test_create_invalid_user_attributes(self
):
30 with self
.assertRaises(TypeError):
31 self
._create
_default
_field
_class
(user_attributes
=object())
33 def test_create_invalid_user_attributes_value_type(self
):
34 with self
.assertRaises(TypeError):
35 self
._create
_default
_field
_class
(user_attributes
=23)
38 class BoolFieldClassTestCase(_TestFieldClass
, unittest
.TestCase
):
39 def _create_default_field_class(self
, **kwargs
):
40 tc
= get_default_trace_class()
41 return tc
.create_bool_field_class(**kwargs
)
44 self
._fc
= self
._create
_default
_field
_class
()
46 def test_create_default(self
):
47 self
.assertIsNotNone(self
._fc
)
48 self
.assertEqual(len(self
._fc
.user_attributes
), 0)
51 class 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
)
56 def _create_default_field_class(self
, **kwargs
):
57 return self
._create
_field
_class
(17, **kwargs
)
60 self
._fc
= self
._create
_default
_field
_class
()
62 def test_create_default(self
):
63 self
.assertIsNotNone(self
._fc
)
64 self
.assertEqual(len(self
._fc
.user_attributes
), 0)
66 def test_create_length_out_of_range(self
):
67 with self
.assertRaises(ValueError):
68 self
._create
_field
_class
(65)
70 def test_create_length_zero(self
):
71 with self
.assertRaises(ValueError):
72 self
._create
_field
_class
(0)
74 def test_create_length_invalid_type(self
):
75 with self
.assertRaises(TypeError):
76 self
._create
_field
_class
('lel')
78 def test_length_prop(self
):
79 self
.assertEqual(self
._fc
.length
, 17)
82 class _TestIntegerFieldClassProps
:
83 def test_create_default(self
):
84 fc
= self
._create
_default
_field
_class
()
85 self
.assertEqual(fc
.field_value_range
, 64)
86 self
.assertEqual(fc
.preferred_display_base
, bt2
.IntegerDisplayBase
.DECIMAL
)
87 self
.assertEqual(len(fc
.user_attributes
), 0)
89 def test_create_range(self
):
90 fc
= self
._create
_field
_class
(field_value_range
=35)
91 self
.assertEqual(fc
.field_value_range
, 35)
93 fc
= self
._create
_field
_class
(36)
94 self
.assertEqual(fc
.field_value_range
, 36)
96 def test_create_invalid_range(self
):
97 with self
.assertRaises(TypeError):
98 self
._create
_field
_class
('yes')
100 with self
.assertRaises(TypeError):
101 self
._create
_field
_class
(field_value_range
='yes')
103 with self
.assertRaises(ValueError):
104 self
._create
_field
_class
(field_value_range
=-2)
106 with self
.assertRaises(ValueError):
107 self
._create
_field
_class
(field_value_range
=0)
109 def test_create_base(self
):
110 fc
= self
._create
_field
_class
(
111 preferred_display_base
=bt2
.IntegerDisplayBase
.HEXADECIMAL
113 self
.assertEqual(fc
.preferred_display_base
, bt2
.IntegerDisplayBase
.HEXADECIMAL
)
115 def test_create_invalid_base_type(self
):
116 with self
.assertRaises(TypeError):
117 self
._create
_field
_class
(preferred_display_base
='yes')
119 def test_create_invalid_base_value(self
):
120 with self
.assertRaises(ValueError):
121 self
._create
_field
_class
(preferred_display_base
=444)
123 def test_create_full(self
):
124 fc
= self
._create
_field
_class
(
125 24, preferred_display_base
=bt2
.IntegerDisplayBase
.OCTAL
127 self
.assertEqual(fc
.field_value_range
, 24)
128 self
.assertEqual(fc
.preferred_display_base
, bt2
.IntegerDisplayBase
.OCTAL
)
131 class SignedIntegerFieldClassTestCase(
132 _TestIntegerFieldClassProps
, _TestFieldClass
, unittest
.TestCase
134 def _create_field_class(self
, *args
, **kwargs
):
135 tc
= get_default_trace_class()
136 return tc
.create_signed_integer_field_class(*args
, **kwargs
)
138 _create_default_field_class
= _create_field_class
141 class UnsignedIntegerFieldClassTestCase(
142 _TestIntegerFieldClassProps
, _TestFieldClass
, unittest
.TestCase
144 def _create_field_class(self
, *args
, **kwargs
):
145 tc
= get_default_trace_class()
146 return tc
.create_unsigned_integer_field_class(*args
, **kwargs
)
148 _create_default_field_class
= _create_field_class
151 class 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
)
156 _create_default_field_class
= _create_field_class
158 def test_create_default(self
):
159 fc
= self
._create
_field
_class
()
160 self
.assertFalse(fc
.is_single_precision
)
161 self
.assertEqual(len(fc
.user_attributes
), 0)
163 def test_create_is_single_precision(self
):
164 fc
= self
._create
_field
_class
(is_single_precision
=True)
165 self
.assertTrue(fc
.is_single_precision
)
167 def test_create_invalid_is_single_precision(self
):
168 with self
.assertRaises(TypeError):
169 self
._create
_field
_class
(is_single_precision
='hohoho')
172 # Converts an _EnumerationFieldClassMapping to a list of ranges:
174 # [(lower0, upper0), (lower1, upper1), ...]
177 def enum_mapping_to_set(mapping
):
178 return {(x
.lower
, x
.upper
) for x
in mapping
.ranges
}
181 class _EnumerationFieldClassTestCase(_TestIntegerFieldClassProps
):
184 self
._fc
= self
._create
_default
_field
_class
()
186 def test_create_from_invalid_type(self
):
187 with self
.assertRaises(TypeError):
188 self
._create
_field
_class
('coucou')
190 def test_add_mapping_simple(self
):
191 self
._fc
.add_mapping('hello', self
._ranges
1)
192 mapping
= self
._fc
['hello']
193 self
.assertEqual(mapping
.label
, 'hello')
194 self
.assertEqual(mapping
.ranges
, self
._ranges
1)
196 def test_add_mapping_simple_kwargs(self
):
197 self
._fc
.add_mapping(label
='hello', ranges
=self
._ranges
1)
198 mapping
= self
._fc
['hello']
199 self
.assertEqual(mapping
.label
, 'hello')
200 self
.assertEqual(mapping
.ranges
, self
._ranges
1)
202 def test_add_mapping_invalid_name(self
):
203 with self
.assertRaises(TypeError):
204 self
._fc
.add_mapping(17, self
._ranges
1)
206 def test_add_mapping_invalid_range(self
):
207 with self
.assertRaises(TypeError):
208 self
._fc
.add_mapping('allo', 'meow')
210 def test_add_mapping_dup_label(self
):
211 with self
.assertRaises(ValueError):
212 self
._fc
.add_mapping('a', self
._ranges
1)
213 self
._fc
.add_mapping('a', self
._ranges
2)
215 def test_add_mapping_invalid_ranges_signedness(self
):
216 with self
.assertRaises(TypeError):
217 self
._fc
.add_mapping('allo', self
._inval
_ranges
)
220 self
._fc
.add_mapping('c', self
._ranges
1)
222 self
._fc
+= [('d', self
._ranges
2), ('e', self
._ranges
3)]
224 self
.assertEqual(len(self
._fc
), 3)
225 self
.assertEqual(self
._fc
['c'].label
, 'c')
226 self
.assertEqual(self
._fc
['c'].ranges
, self
._ranges
1)
227 self
.assertEqual(self
._fc
['d'].label
, 'd')
228 self
.assertEqual(self
._fc
['d'].ranges
, self
._ranges
2)
229 self
.assertEqual(self
._fc
['e'].label
, 'e')
230 self
.assertEqual(self
._fc
['e'].ranges
, self
._ranges
3)
232 def test_bool_op(self
):
233 self
.assertFalse(self
._fc
)
234 self
._fc
.add_mapping('a', self
._ranges
1)
235 self
.assertTrue(self
._fc
)
238 self
._fc
.add_mapping('a', self
._ranges
1)
239 self
._fc
.add_mapping('b', self
._ranges
2)
240 self
._fc
.add_mapping('c', self
._ranges
3)
241 self
.assertEqual(len(self
._fc
), 3)
243 def test_getitem(self
):
244 self
._fc
.add_mapping('a', self
._ranges
1)
245 self
._fc
.add_mapping('b', self
._ranges
2)
246 self
._fc
.add_mapping('c', self
._ranges
3)
247 mapping
= self
._fc
['a']
248 self
.assertEqual(mapping
.label
, 'a')
249 self
.assertEqual(mapping
.ranges
, self
._ranges
1)
251 def test_getitem_nonexistent(self
):
252 with self
.assertRaises(KeyError):
253 self
._fc
['doesnotexist']
256 self
._fc
.add_mapping('a', self
._ranges
1)
257 self
._fc
.add_mapping('b', self
._ranges
2)
258 self
._fc
.add_mapping('c', self
._ranges
3)
260 # This exercises iteration.
261 labels
= sorted(self
._fc
)
263 self
.assertEqual(labels
, ['a', 'b', 'c'])
265 def test_find_by_value(self
):
266 self
._fc
.add_mapping('a', self
._ranges
1)
267 self
._fc
.add_mapping('b', self
._ranges
2)
268 self
._fc
.add_mapping('c', self
._ranges
3)
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
)
275 class UnsignedEnumerationFieldClassTestCase(
276 _EnumerationFieldClassTestCase
, _TestFieldClass
, unittest
.TestCase
278 def _spec_set_up(self
):
279 self
._ranges
1 = bt2
.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
280 self
._ranges
2 = bt2
.UnsignedIntegerRangeSet([(5, 5)])
281 self
._ranges
3 = 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
285 def _create_field_class(self
, *args
, **kwargs
):
286 tc
= get_default_trace_class()
287 return tc
.create_unsigned_enumeration_field_class(*args
, **kwargs
)
289 _create_default_field_class
= _create_field_class
292 class SignedEnumerationFieldClassTestCase(
293 _EnumerationFieldClassTestCase
, _TestFieldClass
, unittest
.TestCase
295 def _spec_set_up(self
):
296 self
._ranges
1 = bt2
.SignedIntegerRangeSet([(-10, -4), (18, 47)])
297 self
._ranges
2 = bt2
.SignedIntegerRangeSet([(-3, -3)])
298 self
._ranges
3 = 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
302 def _create_field_class(self
, *args
, **kwargs
):
303 tc
= get_default_trace_class()
304 return tc
.create_signed_enumeration_field_class(*args
, **kwargs
)
306 _create_default_field_class
= _create_field_class
309 class StringFieldClassTestCase(_TestFieldClass
, unittest
.TestCase
):
310 def _create_field_class(self
, *args
, **kwargs
):
311 tc
= get_default_trace_class()
312 return tc
.create_string_field_class(*args
, **kwargs
)
314 _create_default_field_class
= _create_field_class
317 self
._fc
= self
._create
_default
_field
_class
()
319 def test_create_default(self
):
320 self
.assertIsNotNone(self
._fc
)
321 self
.assertEqual(len(self
._fc
.user_attributes
), 0)
324 class _TestElementContainer
:
326 self
._tc
= get_default_trace_class()
327 self
._fc
= self
._create
_default
_field
_class
()
329 def test_create_default(self
):
330 self
.assertIsNotNone(self
._fc
)
331 self
.assertEqual(len(self
._fc
.user_attributes
), 0)
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
)
336 field_class
= self
._fc
['int32'].field_class
337 self
.assertEqual(field_class
.addr
, int_field_class
.addr
)
339 def test_append_element_kwargs(self
):
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
)
342 field_class
= self
._fc
['int32'].field_class
343 self
.assertEqual(field_class
.addr
, int_field_class
.addr
)
345 def test_append_element_invalid_name(self
):
346 sub_fc
= self
._tc
.create_string_field_class()
348 with self
.assertRaises(TypeError):
349 self
._append
_element
_method
(self
._fc
, 23, sub_fc
)
351 def test_append_element_invalid_field_class(self
):
352 with self
.assertRaises(TypeError):
353 self
._append
_element
_method
(self
._fc
, 'yes', object())
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()
359 with self
.assertRaises(ValueError):
360 self
._append
_element
_method
(self
._fc
, 'yes', sub_fc1
)
361 self
._append
_element
_method
(self
._fc
, 'yes', sub_fc2
)
364 other_fc
= self
._create
_default
_field
_class
()
365 a_field_class
= self
._tc
.create_real_field_class()
366 b_field_class
= self
._tc
.create_signed_integer_field_class(17)
367 self
._append
_element
_method
(self
._fc
, 'a_float', a_field_class
)
368 self
._append
_element
_method
(self
._fc
, 'b_int', b_field_class
)
369 c_field_class
= self
._tc
.create_string_field_class()
370 d_field_class
= self
._tc
.create_signed_enumeration_field_class(
373 e_field_class
= self
._tc
.create_structure_field_class()
375 ('c_string', c_field_class
),
376 ('d_enum', d_field_class
),
377 ('e_struct', e_field_class
),
379 self
.assertEqual(self
._fc
['a_float'].field_class
.addr
, a_field_class
.addr
)
380 self
.assertEqual(self
._fc
['a_float'].name
, 'a_float')
381 self
.assertEqual(self
._fc
['b_int'].field_class
.addr
, b_field_class
.addr
)
382 self
.assertEqual(self
._fc
['b_int'].name
, 'b_int')
383 self
.assertEqual(self
._fc
['c_string'].field_class
.addr
, c_field_class
.addr
)
384 self
.assertEqual(self
._fc
['c_string'].name
, 'c_string')
385 self
.assertEqual(self
._fc
['d_enum'].field_class
.addr
, d_field_class
.addr
)
386 self
.assertEqual(self
._fc
['d_enum'].name
, 'd_enum')
387 self
.assertEqual(self
._fc
['e_struct'].field_class
.addr
, e_field_class
.addr
)
388 self
.assertEqual(self
._fc
['e_struct'].name
, 'e_struct')
390 def test_bool_op(self
):
391 self
.assertFalse(self
._fc
)
392 self
._append
_element
_method
(self
._fc
, 'a', self
._tc
.create_string_field_class())
393 self
.assertTrue(self
._fc
)
396 self
._append
_element
_method
(self
._fc
, 'a', self
._tc
.create_string_field_class())
397 self
._append
_element
_method
(self
._fc
, 'b', self
._tc
.create_string_field_class())
398 self
._append
_element
_method
(self
._fc
, 'c', self
._tc
.create_string_field_class())
399 self
.assertEqual(len(self
._fc
), 3)
401 def test_getitem(self
):
402 a_fc
= self
._tc
.create_signed_integer_field_class(32)
403 b_fc
= self
._tc
.create_string_field_class()
404 c_fc
= self
._tc
.create_real_field_class()
405 self
._append
_element
_method
(self
._fc
, 'a', a_fc
)
406 self
._append
_element
_method
(self
._fc
, 'b', b_fc
)
407 self
._append
_element
_method
(self
._fc
, 'c', c_fc
)
408 self
.assertEqual(self
._fc
['b'].field_class
.addr
, b_fc
.addr
)
409 self
.assertEqual(self
._fc
['b'].name
, 'b')
411 def test_getitem_invalid_key_type(self
):
412 with self
.assertRaises(TypeError):
415 def test_getitem_invalid_key(self
):
416 with self
.assertRaises(KeyError):
419 def test_contains(self
):
420 self
.assertFalse('a' in self
._fc
)
421 self
._append
_element
_method
(self
._fc
, 'a', self
._tc
.create_string_field_class())
422 self
.assertTrue('a' in self
._fc
)
425 a_fc
= self
._tc
.create_signed_integer_field_class(32)
426 b_fc
= self
._tc
.create_string_field_class()
427 c_fc
= self
._tc
.create_real_field_class()
428 elements
= (('a', a_fc
), ('b', b_fc
), ('c', c_fc
))
430 for elem
in elements
:
431 self
._append
_element
_method
(self
._fc
, *elem
)
433 for (name
, element
), test_elem
in zip(self
._fc
.items(), elements
):
434 self
.assertEqual(element
.name
, test_elem
[0])
435 self
.assertEqual(name
, element
.name
)
436 self
.assertEqual(element
.field_class
.addr
, test_elem
[1].addr
)
437 self
.assertEqual(len(element
.user_attributes
), 0)
439 def test_at_index(self
):
440 a_fc
= self
._tc
.create_signed_integer_field_class(32)
441 b_fc
= self
._tc
.create_string_field_class()
442 c_fc
= self
._tc
.create_real_field_class()
443 self
._append
_element
_method
(self
._fc
, 'c', c_fc
)
444 self
._append
_element
_method
(self
._fc
, 'a', a_fc
)
445 self
._append
_element
_method
(self
._fc
, 'b', b_fc
)
446 elem
= self
._at
_index
_method
(self
._fc
, 1)
447 self
.assertEqual(elem
.field_class
.addr
, a_fc
.addr
)
448 self
.assertEqual(elem
.name
, 'a')
450 def test_at_index_invalid(self
):
451 self
._append
_element
_method
(
452 self
._fc
, 'c', self
._tc
.create_signed_integer_field_class(32)
455 with self
.assertRaises(TypeError):
456 self
._at
_index
_method
(self
._fc
, 'yes')
458 def test_at_index_out_of_bounds_after(self
):
459 self
._append
_element
_method
(
460 self
._fc
, 'c', self
._tc
.create_signed_integer_field_class(32)
463 with self
.assertRaises(IndexError):
464 self
._at
_index
_method
(self
._fc
, len(self
._fc
))
466 def test_user_attributes(self
):
467 self
._append
_element
_method
(
470 self
._tc
.create_string_field_class(),
471 user_attributes
={'salut': 23},
473 self
.assertEqual(self
._fc
['c'].user_attributes
, {'salut': 23})
475 def test_invalid_user_attributes(self
):
476 with self
.assertRaises(TypeError):
477 self
._append
_element
_method
(
480 self
._tc
.create_string_field_class(),
481 user_attributes
=object(),
484 def test_invalid_user_attributes_value_type(self
):
485 with self
.assertRaises(TypeError):
486 self
._append
_element
_method
(
487 self
._fc
, 'c', self
._tc
.create_string_field_class(), user_attributes
=23
491 class StructureFieldClassTestCase(
492 _TestFieldClass
, _TestElementContainer
, unittest
.TestCase
494 _append_element_method
= staticmethod(bt2
._StructureFieldClass
.append_member
)
495 _at_index_method
= staticmethod(bt2
._StructureFieldClass
.member_at_index
)
497 def _create_field_class(self
, *args
, **kwargs
):
498 tc
= get_default_trace_class()
499 return tc
.create_structure_field_class(*args
, **kwargs
)
501 _create_default_field_class
= _create_field_class
504 class OptionFieldClassTestCase(_TestFieldClass
, unittest
.TestCase
):
505 def _create_default_field_class(self
, *args
, **kwargs
):
506 return self
._tc
.create_option_field_class(self
._content
_fc
, **kwargs
)
509 self
._tc
= get_default_trace_class()
510 self
._content
_fc
= self
._tc
.create_signed_integer_field_class(23)
511 self
._tag
_fc
= self
._tc
.create_bool_field_class()
513 def test_create_default(self
):
514 fc
= self
._create
_default
_field
_class
()
515 self
.assertEqual(fc
.field_class
.addr
, self
._content
_fc
.addr
)
516 self
.assertIsNone(fc
.selector_field_path
, None)
517 self
.assertEqual(len(fc
.user_attributes
), 0)
519 def _create_field_class_for_field_path_test(self
):
520 fc
= self
._create
_default
_field
_class
(selector_fc
=self
._tag
_fc
)
522 foo_fc
= self
._tc
.create_real_field_class()
523 bar_fc
= self
._tc
.create_string_field_class()
524 baz_fc
= self
._tc
.create_string_field_class()
526 inner_struct_fc
= self
._tc
.create_structure_field_class()
527 inner_struct_fc
.append_member('bar', bar_fc
)
528 inner_struct_fc
.append_member('baz', baz_fc
)
529 inner_struct_fc
.append_member('tag', self
._tag
_fc
)
530 inner_struct_fc
.append_member('opt', fc
)
532 opt_struct_array_fc
= self
._tc
.create_option_field_class(inner_struct_fc
)
534 outer_struct_fc
= self
._tc
.create_structure_field_class()
535 outer_struct_fc
.append_member('foo', foo_fc
)
536 outer_struct_fc
.append_member('inner_opt', opt_struct_array_fc
)
538 # The path to the selector field class is resolved when the
539 # option field class is actually used, for example in a packet
541 self
._tc
.create_stream_class(
542 packet_context_field_class
=outer_struct_fc
, supports_packets
=True
547 def test_field_path_len(self
):
548 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
549 self
.assertEqual(len(fc
.selector_field_path
), 3)
551 def test_field_path_iter(self
):
552 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
553 path_items
= list(fc
.selector_field_path
)
555 self
.assertEqual(len(path_items
), 3)
557 self
.assertIsInstance(path_items
[0], bt2
._IndexFieldPathItem
)
558 self
.assertEqual(path_items
[0].index
, 1)
560 self
.assertIsInstance(path_items
[1], bt2
._CurrentOptionContentFieldPathItem
)
562 self
.assertIsInstance(path_items
[2], bt2
._IndexFieldPathItem
)
563 self
.assertEqual(path_items
[2].index
, 2)
565 def test_field_path_root_scope(self
):
566 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
568 fc
.selector_field_path
.root_scope
, bt2
.FieldPathScope
.PACKET_CONTEXT
571 def test_create_invalid_field_class(self
):
572 with self
.assertRaises(TypeError):
573 self
._tc
.create_option_field_class(object())
575 def test_create_invalid_selector_type(self
):
576 with self
.assertRaises(TypeError):
577 self
._tc
.create_option_field_class(self
._content
_fc
, 17)
580 class VariantFieldClassWithoutSelectorTestCase(
581 _TestFieldClass
, _TestElementContainer
, unittest
.TestCase
583 _append_element_method
= staticmethod(
584 bt2
._VariantFieldClassWithoutSelector
.append_option
586 _at_index_method
= staticmethod(
587 bt2
._VariantFieldClassWithoutSelector
.option_at_index
590 def _create_field_class(self
, *args
, **kwargs
):
591 tc
= get_default_trace_class()
592 return tc
.create_variant_field_class(*args
, **kwargs
)
594 _create_default_field_class
= _create_field_class
597 class _VariantFieldClassWithSelectorTestCase
:
598 def _create_default_field_class(self
, *args
, **kwargs
):
599 return self
._tc
.create_variant_field_class(
600 *args
, selector_fc
=self
._selector
_fc
, **kwargs
604 self
._tc
= get_default_trace_class()
606 self
._fc
= self
._create
_default
_field
_class
()
608 def test_create_default(self
):
609 self
.assertIsNotNone(self
._fc
)
610 self
.assertEqual(len(self
._fc
.user_attributes
), 0)
612 def test_append_element(self
):
613 str_field_class
= self
._tc
.create_string_field_class()
614 self
._fc
.append_option('str', str_field_class
, self
._ranges
1)
615 opt
= self
._fc
['str']
616 self
.assertEqual(opt
.field_class
.addr
, str_field_class
.addr
)
617 self
.assertEqual(opt
.name
, 'str')
618 self
.assertEqual(opt
.ranges
.addr
, self
._ranges
1.addr
)
620 def test_append_element_kwargs(self
):
621 int_field_class
= self
._tc
.create_signed_integer_field_class(32)
622 self
._fc
.append_option(
623 name
='int32', field_class
=int_field_class
, ranges
=self
._ranges
1
625 opt
= self
._fc
['int32']
626 self
.assertEqual(opt
.field_class
.addr
, int_field_class
.addr
)
627 self
.assertEqual(opt
.name
, 'int32')
628 self
.assertEqual(opt
.ranges
.addr
, self
._ranges
1.addr
)
630 def test_append_element_invalid_name(self
):
631 sub_fc
= self
._tc
.create_string_field_class()
633 with self
.assertRaises(TypeError):
634 self
._fc
.append_option(self
._fc
, 23, sub_fc
)
636 def test_append_element_invalid_field_class(self
):
637 with self
.assertRaises(TypeError):
638 self
._fc
.append_option(self
._fc
, 'yes', object())
640 def test_append_element_invalid_ranges(self
):
641 sub_fc
= self
._tc
.create_string_field_class()
643 with self
.assertRaises(TypeError):
644 self
._fc
.append_option(self
._fc
, sub_fc
, 'lel')
646 def test_append_element_dup_name(self
):
647 sub_fc1
= self
._tc
.create_string_field_class()
648 sub_fc2
= self
._tc
.create_string_field_class()
650 with self
.assertRaises(ValueError):
651 self
._fc
.append_option('yes', sub_fc1
, self
._ranges
1)
652 self
._fc
.append_option('yes', sub_fc2
, self
._ranges
2)
654 def test_append_element_invalid_ranges_signedness(self
):
655 sub_fc
= self
._tc
.create_string_field_class()
657 with self
.assertRaises(TypeError):
658 self
._fc
.append_option(self
._fc
, sub_fc
, self
._inval
_ranges
)
660 def test_user_attributes(self
):
661 self
._fc
.append_option(
663 self
._tc
.create_string_field_class(),
665 user_attributes
={'salut': 23},
667 self
.assertEqual(self
._fc
['c'].user_attributes
, {'salut': 23})
669 def test_invalid_user_attributes(self
):
670 with self
.assertRaises(TypeError):
671 self
._fc
.append_option(
673 self
._tc
.create_string_field_class(),
675 user_attributes
=object(),
678 def test_invalid_user_attributes_value_type(self
):
679 with self
.assertRaises(TypeError):
680 self
._fc
.append_option(
682 self
._tc
.create_string_field_class(),
688 other_fc
= self
._create
_default
_field
_class
()
689 a_field_class
= self
._tc
.create_real_field_class()
690 self
._fc
.append_option('a_float', a_field_class
, self
._ranges
1)
691 c_field_class
= self
._tc
.create_string_field_class()
692 d_field_class
= self
._tc
.create_signed_enumeration_field_class(
696 ('c_string', c_field_class
, self
._ranges
2),
697 ('d_enum', d_field_class
, self
._ranges
3),
699 self
.assertEqual(self
._fc
['a_float'].field_class
.addr
, a_field_class
.addr
)
700 self
.assertEqual(self
._fc
['a_float'].name
, 'a_float')
701 self
.assertEqual(self
._fc
['a_float'].ranges
, self
._ranges
1)
702 self
.assertEqual(self
._fc
['c_string'].field_class
.addr
, c_field_class
.addr
)
703 self
.assertEqual(self
._fc
['c_string'].name
, 'c_string')
704 self
.assertEqual(self
._fc
['c_string'].ranges
, self
._ranges
2)
705 self
.assertEqual(self
._fc
['d_enum'].field_class
.addr
, d_field_class
.addr
)
706 self
.assertEqual(self
._fc
['d_enum'].name
, 'd_enum')
707 self
.assertEqual(self
._fc
['d_enum'].ranges
, self
._ranges
3)
709 def test_bool_op(self
):
710 self
.assertFalse(self
._fc
)
711 self
._fc
.append_option('a', self
._tc
.create_string_field_class(), self
._ranges
1)
712 self
.assertTrue(self
._fc
)
715 self
._fc
.append_option('a', self
._tc
.create_string_field_class(), self
._ranges
1)
716 self
._fc
.append_option('b', self
._tc
.create_string_field_class(), self
._ranges
2)
717 self
._fc
.append_option('c', self
._tc
.create_string_field_class(), self
._ranges
3)
718 self
.assertEqual(len(self
._fc
), 3)
720 def test_getitem(self
):
721 a_fc
= self
._tc
.create_signed_integer_field_class(32)
722 b_fc
= self
._tc
.create_string_field_class()
723 c_fc
= self
._tc
.create_real_field_class()
724 self
._fc
.append_option('a', a_fc
, self
._ranges
1)
725 self
._fc
.append_option('b', b_fc
, self
._ranges
2)
726 self
._fc
.append_option('c', c_fc
, self
._ranges
3)
727 self
.assertEqual(self
._fc
['b'].field_class
.addr
, b_fc
.addr
)
728 self
.assertEqual(self
._fc
['b'].name
, 'b')
729 self
.assertEqual(self
._fc
['b'].ranges
.addr
, self
._ranges
2.addr
)
731 def test_getitem_invalid_key_type(self
):
732 with self
.assertRaises(TypeError):
735 def test_getitem_invalid_key(self
):
736 with self
.assertRaises(KeyError):
739 def test_contains(self
):
740 self
.assertFalse('a' in self
._fc
)
741 self
._fc
.append_option('a', self
._tc
.create_string_field_class(), self
._ranges
1)
742 self
.assertTrue('a' in self
._fc
)
745 a_fc
= self
._tc
.create_signed_integer_field_class(32)
746 b_fc
= self
._tc
.create_string_field_class()
747 c_fc
= self
._tc
.create_real_field_class()
749 ('a', a_fc
, self
._ranges
1),
750 ('b', b_fc
, self
._ranges
2),
751 ('c', c_fc
, self
._ranges
3),
755 self
._fc
.append_option(*opt
)
757 for (name
, opt
), test_opt
in zip(self
._fc
.items(), opts
):
758 self
.assertEqual(opt
.name
, test_opt
[0])
759 self
.assertEqual(name
, opt
.name
)
760 self
.assertEqual(opt
.field_class
.addr
, test_opt
[1].addr
)
761 self
.assertEqual(opt
.ranges
.addr
, test_opt
[2].addr
)
763 def test_at_index(self
):
764 a_fc
= self
._tc
.create_signed_integer_field_class(32)
765 b_fc
= self
._tc
.create_string_field_class()
766 c_fc
= self
._tc
.create_real_field_class()
767 self
._fc
.append_option('c', c_fc
, self
._ranges
1)
768 self
._fc
.append_option('a', a_fc
, self
._ranges
2)
769 self
._fc
.append_option('b', b_fc
, self
._ranges
3)
770 self
.assertEqual(self
._fc
.option_at_index(1).field_class
.addr
, a_fc
.addr
)
771 self
.assertEqual(self
._fc
.option_at_index(1).name
, 'a')
772 self
.assertEqual(self
._fc
.option_at_index(1).ranges
.addr
, self
._ranges
2.addr
)
774 def test_at_index_invalid(self
):
775 self
._fc
.append_option(
776 'c', self
._tc
.create_signed_integer_field_class(32), self
._ranges
3
779 with self
.assertRaises(TypeError):
780 self
._fc
.option_at_index('yes')
782 def test_at_index_out_of_bounds_after(self
):
783 self
._fc
.append_option(
784 'c', self
._tc
.create_signed_integer_field_class(32), self
._ranges
3
787 with self
.assertRaises(IndexError):
788 self
._fc
.option_at_index(len(self
._fc
))
790 def _fill_default_fc_for_field_path_test(self
):
791 # Create something equivalent to:
793 # struct outer_struct_fc {
795 # struct inner_struct_fc {
796 # [u]int64_t selector;
799 # variant <selector> {
800 # real a; // selected with self._ranges1
801 # int21_t b; // selected with self._ranges2
802 # uint34_t c; // selected with self._ranges3
806 self
._fc
.append_option('a', self
._tc
.create_real_field_class(), self
._ranges
1)
807 self
._fc
.append_option(
808 'b', self
._tc
.create_signed_integer_field_class(21), self
._ranges
2
810 self
._fc
.append_option(
811 'c', self
._tc
.create_unsigned_integer_field_class(34), self
._ranges
3
814 foo_fc
= self
._tc
.create_real_field_class()
815 bar_fc
= self
._tc
.create_string_field_class()
816 baz_fc
= self
._tc
.create_string_field_class()
818 inner_struct_fc
= self
._tc
.create_structure_field_class()
819 inner_struct_fc
.append_member('selector', self
._selector
_fc
)
820 inner_struct_fc
.append_member('bar', bar_fc
)
821 inner_struct_fc
.append_member('baz', baz_fc
)
822 inner_struct_fc
.append_member('variant', self
._fc
)
824 inner_struct_array_fc
= self
._tc
.create_static_array_field_class(
828 outer_struct_fc
= self
._tc
.create_structure_field_class()
829 outer_struct_fc
.append_member('foo', foo_fc
)
830 outer_struct_fc
.append_member('inner_struct', inner_struct_array_fc
)
832 # The path to the selector field is resolved when the sequence is
833 # actually used, for example in a packet context.
834 self
._tc
.create_stream_class(
835 supports_packets
=True, packet_context_field_class
=outer_struct_fc
838 def test_selector_field_path_length(self
):
839 self
._fill
_default
_fc
_for
_field
_path
_test
()
840 self
.assertEqual(len(self
._fc
.selector_field_path
), 3)
842 def test_selector_field_path_iter(self
):
843 self
._fill
_default
_fc
_for
_field
_path
_test
()
844 path_items
= list(self
._fc
.selector_field_path
)
846 self
.assertEqual(len(path_items
), 3)
848 self
.assertIsInstance(path_items
[0], bt2
._IndexFieldPathItem
)
849 self
.assertEqual(path_items
[0].index
, 1)
851 self
.assertIsInstance(path_items
[1], bt2
._CurrentArrayElementFieldPathItem
)
853 self
.assertIsInstance(path_items
[2], bt2
._IndexFieldPathItem
)
854 self
.assertEqual(path_items
[2].index
, 0)
856 def test_selector_field_path_root_scope(self
):
857 self
._fill
_default
_fc
_for
_field
_path
_test
()
859 self
._fc
.selector_field_path
.root_scope
, bt2
.FieldPathScope
.PACKET_CONTEXT
863 class VariantFieldClassWithUnsignedSelectorTestCase(
864 _VariantFieldClassWithSelectorTestCase
, unittest
.TestCase
866 def _spec_set_up(self
):
867 self
._ranges
1 = bt2
.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
868 self
._ranges
2 = bt2
.UnsignedIntegerRangeSet([(5, 5)])
869 self
._ranges
3 = bt2
.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
870 self
._inval
_ranges
= bt2
.SignedIntegerRangeSet([(-8, 16), (48, 99)])
871 self
._selector
_fc
= self
._tc
.create_unsigned_integer_field_class()
874 class VariantFieldClassWithSignedSelectorTestCase(
875 _VariantFieldClassWithSelectorTestCase
, unittest
.TestCase
877 def _spec_set_up(self
):
878 self
._ranges
1 = bt2
.SignedIntegerRangeSet([(-10, -4), (18, 47)])
879 self
._ranges
2 = bt2
.SignedIntegerRangeSet([(-3, -3)])
880 self
._ranges
3 = bt2
.SignedIntegerRangeSet([(8, 16), (48, 99)])
881 self
._inval
_ranges
= bt2
.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
882 self
._selector
_fc
= self
._tc
.create_signed_integer_field_class()
885 class StaticArrayFieldClassTestCase(unittest
.TestCase
):
887 self
._tc
= get_default_trace_class()
888 self
._elem
_fc
= self
._tc
.create_signed_integer_field_class(23)
890 def test_create_default(self
):
891 fc
= self
._tc
.create_static_array_field_class(self
._elem
_fc
, 45)
892 self
.assertEqual(fc
.element_field_class
.addr
, self
._elem
_fc
.addr
)
893 self
.assertEqual(fc
.length
, 45)
894 self
.assertEqual(len(fc
.user_attributes
), 0)
896 def test_create_invalid_elem_field_class(self
):
897 with self
.assertRaises(TypeError):
898 self
._tc
.create_static_array_field_class(object(), 45)
900 def test_create_invalid_length(self
):
901 with self
.assertRaises(ValueError):
902 self
._tc
.create_static_array_field_class(
903 self
._tc
.create_string_field_class(), -17
906 def test_create_invalid_length_type(self
):
907 with self
.assertRaises(TypeError):
908 self
._tc
.create_static_array_field_class(
909 self
._tc
.create_string_field_class(), 'the length'
913 class DynamicArrayFieldClassTestCase(unittest
.TestCase
):
915 self
._tc
= get_default_trace_class()
916 self
._elem
_fc
= self
._tc
.create_signed_integer_field_class(23)
917 self
._len
_fc
= self
._tc
.create_unsigned_integer_field_class(12)
919 def test_create_default(self
):
920 fc
= self
._tc
.create_dynamic_array_field_class(self
._elem
_fc
)
921 self
.assertEqual(fc
.element_field_class
.addr
, self
._elem
_fc
.addr
)
922 self
.assertIsNone(fc
.length_field_path
, None)
923 self
.assertEqual(len(fc
.user_attributes
), 0)
925 def _create_field_class_for_field_path_test(self
):
926 # Create something a field class that is equivalent to:
928 # struct outer_struct_fc {
930 # struct inner_struct_fc {
934 # uint23_t dyn_array[len];
938 fc
= self
._tc
.create_dynamic_array_field_class(self
._elem
_fc
, self
._len
_fc
)
940 foo_fc
= self
._tc
.create_real_field_class()
941 bar_fc
= self
._tc
.create_string_field_class()
942 baz_fc
= self
._tc
.create_string_field_class()
944 inner_struct_fc
= self
._tc
.create_structure_field_class()
945 inner_struct_fc
.append_member('bar', bar_fc
)
946 inner_struct_fc
.append_member('baz', baz_fc
)
947 inner_struct_fc
.append_member('len', self
._len
_fc
)
948 inner_struct_fc
.append_member('dyn_array', fc
)
950 inner_struct_array_fc
= self
._tc
.create_static_array_field_class(
954 outer_struct_fc
= self
._tc
.create_structure_field_class()
955 outer_struct_fc
.append_member('foo', foo_fc
)
956 outer_struct_fc
.append_member('inner_struct', inner_struct_array_fc
)
958 # The path to the length field is resolved when the sequence is
959 # actually used, for example in a packet context.
960 self
._tc
.create_stream_class(
961 packet_context_field_class
=outer_struct_fc
, supports_packets
=True
966 def test_field_path_len(self
):
967 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
968 self
.assertEqual(len(fc
.length_field_path
), 3)
970 def test_field_path_iter(self
):
971 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
972 path_items
= list(fc
.length_field_path
)
974 self
.assertEqual(len(path_items
), 3)
976 self
.assertIsInstance(path_items
[0], bt2
._IndexFieldPathItem
)
977 self
.assertEqual(path_items
[0].index
, 1)
979 self
.assertIsInstance(path_items
[1], bt2
._CurrentArrayElementFieldPathItem
)
981 self
.assertIsInstance(path_items
[2], bt2
._IndexFieldPathItem
)
982 self
.assertEqual(path_items
[2].index
, 2)
984 def test_field_path_root_scope(self
):
985 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
987 fc
.length_field_path
.root_scope
, bt2
.FieldPathScope
.PACKET_CONTEXT
990 def test_create_invalid_field_class(self
):
991 with self
.assertRaises(TypeError):
992 self
._tc
.create_dynamic_array_field_class(object())
994 def test_create_invalid_length_type(self
):
995 with self
.assertRaises(TypeError):
996 self
._tc
.create_dynamic_array_field_class(
997 self
._tc
.create_string_field_class(), 17
1001 if __name__
== "__main__":