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 BoolFieldClassTestCase(unittest
.TestCase
):
26 tc
= get_default_trace_class()
27 self
._fc
= tc
.create_bool_field_class()
29 def test_create_default(self
):
30 self
.assertIsNotNone(self
._fc
)
33 class _TestIntegerFieldClassProps
:
34 def test_create_default(self
):
35 fc
= self
._create
_func
()
36 self
.assertEqual(fc
.field_value_range
, 64)
37 self
.assertEqual(fc
.preferred_display_base
, bt2
.IntegerDisplayBase
.DECIMAL
)
39 def test_create_range(self
):
40 fc
= self
._create
_func
(field_value_range
=35)
41 self
.assertEqual(fc
.field_value_range
, 35)
43 fc
= self
._create
_func
(36)
44 self
.assertEqual(fc
.field_value_range
, 36)
46 def test_create_invalid_range(self
):
47 with self
.assertRaises(TypeError):
48 self
._create
_func
('yes')
50 with self
.assertRaises(TypeError):
51 self
._create
_func
(field_value_range
='yes')
53 with self
.assertRaises(ValueError):
54 self
._create
_func
(field_value_range
=-2)
56 with self
.assertRaises(ValueError):
57 self
._create
_func
(field_value_range
=0)
59 def test_create_base(self
):
60 fc
= self
._create
_func
(
61 preferred_display_base
=bt2
.IntegerDisplayBase
.HEXADECIMAL
63 self
.assertEqual(fc
.preferred_display_base
, bt2
.IntegerDisplayBase
.HEXADECIMAL
)
65 def test_create_invalid_base_type(self
):
66 with self
.assertRaises(TypeError):
67 self
._create
_func
(preferred_display_base
='yes')
69 def test_create_invalid_base_value(self
):
70 with self
.assertRaises(ValueError):
71 self
._create
_func
(preferred_display_base
=444)
73 def test_create_full(self
):
74 fc
= self
._create
_func
(24, preferred_display_base
=bt2
.IntegerDisplayBase
.OCTAL
)
75 self
.assertEqual(fc
.field_value_range
, 24)
76 self
.assertEqual(fc
.preferred_display_base
, bt2
.IntegerDisplayBase
.OCTAL
)
79 class IntegerFieldClassTestCase(_TestIntegerFieldClassProps
, unittest
.TestCase
):
81 self
._tc
= get_default_trace_class()
82 self
._create
_func
= self
._tc
.create_signed_integer_field_class
85 class RealFieldClassTestCase(unittest
.TestCase
):
87 self
._tc
= get_default_trace_class()
89 def test_create_default(self
):
90 fc
= self
._tc
.create_real_field_class()
91 self
.assertFalse(fc
.is_single_precision
)
93 def test_create_is_single_precision(self
):
94 fc
= self
._tc
.create_real_field_class(is_single_precision
=True)
95 self
.assertTrue(fc
.is_single_precision
)
97 def test_create_invalid_is_single_precision(self
):
98 with self
.assertRaises(TypeError):
99 self
._tc
.create_real_field_class(is_single_precision
='hohoho')
102 # Converts an _EnumerationFieldClassMapping to a list of ranges:
104 # [(lower0, upper0), (lower1, upper1), ...]
107 def enum_mapping_to_set(mapping
):
108 return {(x
.lower
, x
.upper
) for x
in mapping
.ranges
}
111 class _EnumerationFieldClassTestCase(_TestIntegerFieldClassProps
):
113 self
._tc
= get_default_trace_class()
115 self
._fc
= self
._create
_func
()
117 def test_create_from_invalid_type(self
):
118 with self
.assertRaises(TypeError):
119 self
._create
_func
('coucou')
121 def test_add_mapping_simple(self
):
122 self
._fc
.add_mapping('hello', self
._ranges
1)
123 mapping
= self
._fc
['hello']
124 self
.assertEqual(mapping
.label
, 'hello')
125 self
.assertEqual(mapping
.ranges
, self
._ranges
1)
127 def test_add_mapping_simple_kwargs(self
):
128 self
._fc
.add_mapping(label
='hello', ranges
=self
._ranges
1)
129 mapping
= self
._fc
['hello']
130 self
.assertEqual(mapping
.label
, 'hello')
131 self
.assertEqual(mapping
.ranges
, self
._ranges
1)
133 def test_add_mapping_invalid_name(self
):
134 with self
.assertRaises(TypeError):
135 self
._fc
.add_mapping(17, self
._ranges
1)
137 def test_add_mapping_invalid_range(self
):
138 with self
.assertRaises(TypeError):
139 self
._fc
.add_mapping('allo', 'meow')
141 def test_add_mapping_dup_label(self
):
142 with self
.assertRaises(ValueError):
143 self
._fc
.add_mapping('a', self
._ranges
1)
144 self
._fc
.add_mapping('a', self
._ranges
2)
146 def test_add_mapping_invalid_ranges_signedness(self
):
147 with self
.assertRaises(TypeError):
148 self
._fc
.add_mapping('allo', self
._inval
_ranges
)
151 self
._fc
.add_mapping('c', self
._ranges
1)
153 self
._fc
+= [('d', self
._ranges
2), ('e', self
._ranges
3)]
155 self
.assertEqual(len(self
._fc
), 3)
156 self
.assertEqual(self
._fc
['c'].label
, 'c')
157 self
.assertEqual(self
._fc
['c'].ranges
, self
._ranges
1)
158 self
.assertEqual(self
._fc
['d'].label
, 'd')
159 self
.assertEqual(self
._fc
['d'].ranges
, self
._ranges
2)
160 self
.assertEqual(self
._fc
['e'].label
, 'e')
161 self
.assertEqual(self
._fc
['e'].ranges
, self
._ranges
3)
163 def test_bool_op(self
):
164 self
.assertFalse(self
._fc
)
165 self
._fc
.add_mapping('a', self
._ranges
1)
166 self
.assertTrue(self
._fc
)
169 self
._fc
.add_mapping('a', self
._ranges
1)
170 self
._fc
.add_mapping('b', self
._ranges
2)
171 self
._fc
.add_mapping('c', self
._ranges
3)
172 self
.assertEqual(len(self
._fc
), 3)
174 def test_getitem(self
):
175 self
._fc
.add_mapping('a', self
._ranges
1)
176 self
._fc
.add_mapping('b', self
._ranges
2)
177 self
._fc
.add_mapping('c', self
._ranges
3)
178 mapping
= self
._fc
['a']
179 self
.assertEqual(mapping
.label
, 'a')
180 self
.assertEqual(mapping
.ranges
, self
._ranges
1)
182 def test_getitem_nonexistent(self
):
183 with self
.assertRaises(KeyError):
184 self
._fc
['doesnotexist']
187 self
._fc
.add_mapping('a', self
._ranges
1)
188 self
._fc
.add_mapping('b', self
._ranges
2)
189 self
._fc
.add_mapping('c', self
._ranges
3)
191 # This exercises iteration.
192 labels
= sorted(self
._fc
)
194 self
.assertEqual(labels
, ['a', 'b', 'c'])
196 def test_find_by_value(self
):
197 self
._fc
.add_mapping('a', self
._ranges
1)
198 self
._fc
.add_mapping('b', self
._ranges
2)
199 self
._fc
.add_mapping('c', self
._ranges
3)
200 mappings
= self
._fc
.mappings_for_value(self
._value
_in
_range
_1_and
_3)
201 labels
= set([mapping
.label
for mapping
in mappings
])
202 expected_labels
= set(['a', 'c'])
203 self
.assertEqual(labels
, expected_labels
)
206 class UnsignedEnumerationFieldClassTestCase(
207 _EnumerationFieldClassTestCase
, unittest
.TestCase
209 def _spec_set_up(self
):
210 self
._ranges
1 = bt2
.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
211 self
._ranges
2 = bt2
.UnsignedIntegerRangeSet([(5, 5)])
212 self
._ranges
3 = bt2
.UnsignedIntegerRangeSet([(8, 22), (48, 99)])
213 self
._inval
_ranges
= bt2
.SignedIntegerRangeSet([(-8, -5), (48, 1928)])
214 self
._value
_in
_range
_1_and
_3 = 20
215 self
._create
_func
= self
._tc
.create_unsigned_enumeration_field_class
218 class SignedEnumerationFieldClassTestCase(
219 _EnumerationFieldClassTestCase
, unittest
.TestCase
221 def _spec_set_up(self
):
222 self
._ranges
1 = bt2
.SignedIntegerRangeSet([(-10, -4), (18, 47)])
223 self
._ranges
2 = bt2
.SignedIntegerRangeSet([(-3, -3)])
224 self
._ranges
3 = bt2
.SignedIntegerRangeSet([(-100, -1), (8, 16), (48, 99)])
225 self
._inval
_ranges
= bt2
.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
226 self
._value
_in
_range
_1_and
_3 = -7
227 self
._create
_func
= self
._tc
.create_signed_enumeration_field_class
230 class StringFieldClassTestCase(unittest
.TestCase
):
232 tc
= get_default_trace_class()
233 self
._fc
= tc
.create_string_field_class()
235 def test_create_default(self
):
236 self
.assertIsNotNone(self
._fc
)
239 class _TestElementContainer
:
241 self
._tc
= get_default_trace_class()
242 self
._fc
= self
._create
_default
_fc
()
244 def test_create_default(self
):
245 self
.assertIsNotNone(self
._fc
)
247 def test_append_element(self
):
248 int_field_class
= self
._tc
.create_signed_integer_field_class(32)
249 self
._append
_element
_method
(self
._fc
, 'int32', int_field_class
)
250 field_class
= self
._fc
['int32'].field_class
251 self
.assertEqual(field_class
.addr
, int_field_class
.addr
)
253 def test_append_element_kwargs(self
):
254 int_field_class
= self
._tc
.create_signed_integer_field_class(32)
255 self
._append
_element
_method
(self
._fc
, name
='int32', field_class
=int_field_class
)
256 field_class
= self
._fc
['int32'].field_class
257 self
.assertEqual(field_class
.addr
, int_field_class
.addr
)
259 def test_append_element_invalid_name(self
):
260 sub_fc
= self
._tc
.create_string_field_class()
262 with self
.assertRaises(TypeError):
263 self
._append
_element
_method
(self
._fc
, 23, sub_fc
)
265 def test_append_element_invalid_field_class(self
):
266 with self
.assertRaises(TypeError):
267 self
._append
_element
_method
(self
._fc
, 'yes', object())
269 def test_append_element_dup_name(self
):
270 sub_fc1
= self
._tc
.create_string_field_class()
271 sub_fc2
= self
._tc
.create_string_field_class()
273 with self
.assertRaises(ValueError):
274 self
._append
_element
_method
(self
._fc
, 'yes', sub_fc1
)
275 self
._append
_element
_method
(self
._fc
, 'yes', sub_fc2
)
278 other_fc
= self
._create
_default
_fc
()
279 a_field_class
= self
._tc
.create_real_field_class()
280 b_field_class
= self
._tc
.create_signed_integer_field_class(17)
281 self
._append
_element
_method
(self
._fc
, 'a_float', a_field_class
)
282 self
._append
_element
_method
(self
._fc
, 'b_int', b_field_class
)
283 c_field_class
= self
._tc
.create_string_field_class()
284 d_field_class
= self
._tc
.create_signed_enumeration_field_class(
287 e_field_class
= self
._tc
.create_structure_field_class()
289 ('c_string', c_field_class
),
290 ('d_enum', d_field_class
),
291 ('e_struct', e_field_class
),
293 self
.assertEqual(self
._fc
['a_float'].field_class
.addr
, a_field_class
.addr
)
294 self
.assertEqual(self
._fc
['a_float'].name
, 'a_float')
295 self
.assertEqual(self
._fc
['b_int'].field_class
.addr
, b_field_class
.addr
)
296 self
.assertEqual(self
._fc
['b_int'].name
, 'b_int')
297 self
.assertEqual(self
._fc
['c_string'].field_class
.addr
, c_field_class
.addr
)
298 self
.assertEqual(self
._fc
['c_string'].name
, 'c_string')
299 self
.assertEqual(self
._fc
['d_enum'].field_class
.addr
, d_field_class
.addr
)
300 self
.assertEqual(self
._fc
['d_enum'].name
, 'd_enum')
301 self
.assertEqual(self
._fc
['e_struct'].field_class
.addr
, e_field_class
.addr
)
302 self
.assertEqual(self
._fc
['e_struct'].name
, 'e_struct')
304 def test_bool_op(self
):
305 self
.assertFalse(self
._fc
)
306 self
._append
_element
_method
(self
._fc
, 'a', self
._tc
.create_string_field_class())
307 self
.assertTrue(self
._fc
)
310 self
._append
_element
_method
(self
._fc
, 'a', self
._tc
.create_string_field_class())
311 self
._append
_element
_method
(self
._fc
, 'b', self
._tc
.create_string_field_class())
312 self
._append
_element
_method
(self
._fc
, 'c', self
._tc
.create_string_field_class())
313 self
.assertEqual(len(self
._fc
), 3)
315 def test_getitem(self
):
316 a_fc
= self
._tc
.create_signed_integer_field_class(32)
317 b_fc
= self
._tc
.create_string_field_class()
318 c_fc
= self
._tc
.create_real_field_class()
319 self
._append
_element
_method
(self
._fc
, 'a', a_fc
)
320 self
._append
_element
_method
(self
._fc
, 'b', b_fc
)
321 self
._append
_element
_method
(self
._fc
, 'c', c_fc
)
322 self
.assertEqual(self
._fc
['b'].field_class
.addr
, b_fc
.addr
)
323 self
.assertEqual(self
._fc
['b'].name
, 'b')
325 def test_getitem_invalid_key_type(self
):
326 with self
.assertRaises(TypeError):
329 def test_getitem_invalid_key(self
):
330 with self
.assertRaises(KeyError):
333 def test_contains(self
):
334 self
.assertFalse('a' in self
._fc
)
335 self
._append
_element
_method
(self
._fc
, 'a', self
._tc
.create_string_field_class())
336 self
.assertTrue('a' in self
._fc
)
339 a_fc
= self
._tc
.create_signed_integer_field_class(32)
340 b_fc
= self
._tc
.create_string_field_class()
341 c_fc
= self
._tc
.create_real_field_class()
342 elements
= (('a', a_fc
), ('b', b_fc
), ('c', c_fc
))
344 for elem
in elements
:
345 self
._append
_element
_method
(self
._fc
, *elem
)
347 for (name
, element
), test_elem
in zip(self
._fc
.items(), elements
):
348 self
.assertEqual(element
.name
, test_elem
[0])
349 self
.assertEqual(name
, element
.name
)
350 self
.assertEqual(element
.field_class
.addr
, test_elem
[1].addr
)
352 def test_at_index(self
):
353 a_fc
= self
._tc
.create_signed_integer_field_class(32)
354 b_fc
= self
._tc
.create_string_field_class()
355 c_fc
= self
._tc
.create_real_field_class()
356 self
._append
_element
_method
(self
._fc
, 'c', c_fc
)
357 self
._append
_element
_method
(self
._fc
, 'a', a_fc
)
358 self
._append
_element
_method
(self
._fc
, 'b', b_fc
)
359 elem
= self
._at
_index
_method
(self
._fc
, 1)
360 self
.assertEqual(elem
.field_class
.addr
, a_fc
.addr
)
361 self
.assertEqual(elem
.name
, 'a')
363 def test_at_index_invalid(self
):
364 self
._append
_element
_method
(
365 self
._fc
, 'c', self
._tc
.create_signed_integer_field_class(32)
368 with self
.assertRaises(TypeError):
369 self
._at
_index
_method
(self
._fc
, 'yes')
371 def test_at_index_out_of_bounds_after(self
):
372 self
._append
_element
_method
(
373 self
._fc
, 'c', self
._tc
.create_signed_integer_field_class(32)
376 with self
.assertRaises(IndexError):
377 self
._at
_index
_method
(self
._fc
, len(self
._fc
))
380 class StructureFieldClassTestCase(_TestElementContainer
, unittest
.TestCase
):
381 _append_element_method
= staticmethod(bt2
._StructureFieldClass
.append_member
)
382 _at_index_method
= staticmethod(bt2
._StructureFieldClass
.member_at_index
)
384 def _create_default_fc(self
):
385 return self
._tc
.create_structure_field_class()
388 class OptionFieldClassTestCase(unittest
.TestCase
):
390 self
._tc
= get_default_trace_class()
391 self
._content
_fc
= self
._tc
.create_signed_integer_field_class(23)
392 self
._tag
_fc
= self
._tc
.create_bool_field_class()
394 def test_create_default(self
):
395 fc
= self
._tc
.create_option_field_class(self
._content
_fc
)
396 self
.assertEqual(fc
.field_class
.addr
, self
._content
_fc
.addr
)
397 self
.assertIsNone(fc
.selector_field_path
, None)
399 def _create_field_class_for_field_path_test(self
):
400 fc
= self
._tc
.create_option_field_class(self
._content
_fc
, self
._tag
_fc
)
402 foo_fc
= self
._tc
.create_real_field_class()
403 bar_fc
= self
._tc
.create_string_field_class()
404 baz_fc
= self
._tc
.create_string_field_class()
406 inner_struct_fc
= self
._tc
.create_structure_field_class()
407 inner_struct_fc
.append_member('bar', bar_fc
)
408 inner_struct_fc
.append_member('baz', baz_fc
)
409 inner_struct_fc
.append_member('tag', self
._tag
_fc
)
410 inner_struct_fc
.append_member('opt', fc
)
412 opt_struct_array_fc
= self
._tc
.create_option_field_class(inner_struct_fc
)
414 outer_struct_fc
= self
._tc
.create_structure_field_class()
415 outer_struct_fc
.append_member('foo', foo_fc
)
416 outer_struct_fc
.append_member('inner_opt', opt_struct_array_fc
)
418 # The path to the selector field class is resolved when the
419 # option field class is actually used, for example in a packet
421 self
._tc
.create_stream_class(
422 packet_context_field_class
=outer_struct_fc
, supports_packets
=True
427 def test_field_path_len(self
):
428 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
429 self
.assertEqual(len(fc
.selector_field_path
), 3)
431 def test_field_path_iter(self
):
432 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
433 path_items
= list(fc
.selector_field_path
)
435 self
.assertEqual(len(path_items
), 3)
437 self
.assertIsInstance(path_items
[0], bt2
._IndexFieldPathItem
)
438 self
.assertEqual(path_items
[0].index
, 1)
440 self
.assertIsInstance(path_items
[1], bt2
._CurrentOptionContentFieldPathItem
)
442 self
.assertIsInstance(path_items
[2], bt2
._IndexFieldPathItem
)
443 self
.assertEqual(path_items
[2].index
, 2)
445 def test_field_path_root_scope(self
):
446 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
448 fc
.selector_field_path
.root_scope
, bt2
.FieldPathScope
.PACKET_CONTEXT
451 def test_create_invalid_field_class(self
):
452 with self
.assertRaises(TypeError):
453 self
._tc
.create_option_field_class(object())
455 def test_create_invalid_selector_type(self
):
456 with self
.assertRaises(TypeError):
457 self
._tc
.create_option_field_class(self
._content
_fc
, 17)
460 class VariantFieldClassWithoutSelectorTestCase(
461 _TestElementContainer
, unittest
.TestCase
463 _append_element_method
= staticmethod(
464 bt2
._VariantFieldClassWithoutSelector
.append_option
466 _at_index_method
= staticmethod(
467 bt2
._VariantFieldClassWithoutSelector
.option_at_index
470 def _create_default_fc(self
):
471 return self
._tc
.create_variant_field_class()
474 class _VariantFieldClassWithSelectorTestCase
:
476 self
._tc
= get_default_trace_class()
478 self
._fc
= self
._create
_default
_fc
()
480 def _create_default_fc(self
):
481 return self
._tc
.create_variant_field_class(self
._selector
_fc
)
483 def test_create_default(self
):
484 self
.assertIsNotNone(self
._fc
)
486 def test_append_element(self
):
487 str_field_class
= self
._tc
.create_string_field_class()
488 self
._fc
.append_option('str', str_field_class
, self
._ranges
1)
489 opt
= self
._fc
['str']
490 self
.assertEqual(opt
.field_class
.addr
, str_field_class
.addr
)
491 self
.assertEqual(opt
.name
, 'str')
492 self
.assertEqual(opt
.ranges
.addr
, self
._ranges
1.addr
)
494 def test_append_element_kwargs(self
):
495 int_field_class
= self
._tc
.create_signed_integer_field_class(32)
496 self
._fc
.append_option(
497 name
='int32', field_class
=int_field_class
, ranges
=self
._ranges
1
499 opt
= self
._fc
['int32']
500 self
.assertEqual(opt
.field_class
.addr
, int_field_class
.addr
)
501 self
.assertEqual(opt
.name
, 'int32')
502 self
.assertEqual(opt
.ranges
.addr
, self
._ranges
1.addr
)
504 def test_append_element_invalid_name(self
):
505 sub_fc
= self
._tc
.create_string_field_class()
507 with self
.assertRaises(TypeError):
508 self
._fc
.append_option(self
._fc
, 23, sub_fc
)
510 def test_append_element_invalid_field_class(self
):
511 with self
.assertRaises(TypeError):
512 self
._fc
.append_option(self
._fc
, 'yes', object())
514 def test_append_element_invalid_ranges(self
):
515 sub_fc
= self
._tc
.create_string_field_class()
517 with self
.assertRaises(TypeError):
518 self
._fc
.append_option(self
._fc
, sub_fc
, 'lel')
520 def test_append_element_dup_name(self
):
521 sub_fc1
= self
._tc
.create_string_field_class()
522 sub_fc2
= self
._tc
.create_string_field_class()
524 with self
.assertRaises(ValueError):
525 self
._fc
.append_option('yes', sub_fc1
, self
._ranges
1)
526 self
._fc
.append_option('yes', sub_fc2
, self
._ranges
2)
528 def test_append_element_invalid_ranges_signedness(self
):
529 sub_fc
= self
._tc
.create_string_field_class()
531 with self
.assertRaises(TypeError):
532 self
._fc
.append_option(self
._fc
, sub_fc
, self
._inval
_ranges
)
535 other_fc
= self
._create
_default
_fc
()
536 a_field_class
= self
._tc
.create_real_field_class()
537 self
._fc
.append_option('a_float', a_field_class
, self
._ranges
1)
538 c_field_class
= self
._tc
.create_string_field_class()
539 d_field_class
= self
._tc
.create_signed_enumeration_field_class(
543 ('c_string', c_field_class
, self
._ranges
2),
544 ('d_enum', d_field_class
, self
._ranges
3),
546 self
.assertEqual(self
._fc
['a_float'].field_class
.addr
, a_field_class
.addr
)
547 self
.assertEqual(self
._fc
['a_float'].name
, 'a_float')
548 self
.assertEqual(self
._fc
['a_float'].ranges
, self
._ranges
1)
549 self
.assertEqual(self
._fc
['c_string'].field_class
.addr
, c_field_class
.addr
)
550 self
.assertEqual(self
._fc
['c_string'].name
, 'c_string')
551 self
.assertEqual(self
._fc
['c_string'].ranges
, self
._ranges
2)
552 self
.assertEqual(self
._fc
['d_enum'].field_class
.addr
, d_field_class
.addr
)
553 self
.assertEqual(self
._fc
['d_enum'].name
, 'd_enum')
554 self
.assertEqual(self
._fc
['d_enum'].ranges
, self
._ranges
3)
556 def test_bool_op(self
):
557 self
.assertFalse(self
._fc
)
558 self
._fc
.append_option('a', self
._tc
.create_string_field_class(), self
._ranges
1)
559 self
.assertTrue(self
._fc
)
562 self
._fc
.append_option('a', self
._tc
.create_string_field_class(), self
._ranges
1)
563 self
._fc
.append_option('b', self
._tc
.create_string_field_class(), self
._ranges
2)
564 self
._fc
.append_option('c', self
._tc
.create_string_field_class(), self
._ranges
3)
565 self
.assertEqual(len(self
._fc
), 3)
567 def test_getitem(self
):
568 a_fc
= self
._tc
.create_signed_integer_field_class(32)
569 b_fc
= self
._tc
.create_string_field_class()
570 c_fc
= self
._tc
.create_real_field_class()
571 self
._fc
.append_option('a', a_fc
, self
._ranges
1)
572 self
._fc
.append_option('b', b_fc
, self
._ranges
2)
573 self
._fc
.append_option('c', c_fc
, self
._ranges
3)
574 self
.assertEqual(self
._fc
['b'].field_class
.addr
, b_fc
.addr
)
575 self
.assertEqual(self
._fc
['b'].name
, 'b')
576 self
.assertEqual(self
._fc
['b'].ranges
.addr
, self
._ranges
2.addr
)
578 def test_getitem_invalid_key_type(self
):
579 with self
.assertRaises(TypeError):
582 def test_getitem_invalid_key(self
):
583 with self
.assertRaises(KeyError):
586 def test_contains(self
):
587 self
.assertFalse('a' in self
._fc
)
588 self
._fc
.append_option('a', self
._tc
.create_string_field_class(), self
._ranges
1)
589 self
.assertTrue('a' in self
._fc
)
592 a_fc
= self
._tc
.create_signed_integer_field_class(32)
593 b_fc
= self
._tc
.create_string_field_class()
594 c_fc
= self
._tc
.create_real_field_class()
596 ('a', a_fc
, self
._ranges
1),
597 ('b', b_fc
, self
._ranges
2),
598 ('c', c_fc
, self
._ranges
3),
602 self
._fc
.append_option(*opt
)
604 for (name
, opt
), test_opt
in zip(self
._fc
.items(), opts
):
605 self
.assertEqual(opt
.name
, test_opt
[0])
606 self
.assertEqual(name
, opt
.name
)
607 self
.assertEqual(opt
.field_class
.addr
, test_opt
[1].addr
)
608 self
.assertEqual(opt
.ranges
.addr
, test_opt
[2].addr
)
610 def test_at_index(self
):
611 a_fc
= self
._tc
.create_signed_integer_field_class(32)
612 b_fc
= self
._tc
.create_string_field_class()
613 c_fc
= self
._tc
.create_real_field_class()
614 self
._fc
.append_option('c', c_fc
, self
._ranges
1)
615 self
._fc
.append_option('a', a_fc
, self
._ranges
2)
616 self
._fc
.append_option('b', b_fc
, self
._ranges
3)
617 self
.assertEqual(self
._fc
.option_at_index(1).field_class
.addr
, a_fc
.addr
)
618 self
.assertEqual(self
._fc
.option_at_index(1).name
, 'a')
619 self
.assertEqual(self
._fc
.option_at_index(1).ranges
.addr
, self
._ranges
2.addr
)
621 def test_at_index_invalid(self
):
622 self
._fc
.append_option(
623 'c', self
._tc
.create_signed_integer_field_class(32), self
._ranges
3
626 with self
.assertRaises(TypeError):
627 self
._fc
.option_at_index('yes')
629 def test_at_index_out_of_bounds_after(self
):
630 self
._fc
.append_option(
631 'c', self
._tc
.create_signed_integer_field_class(32), self
._ranges
3
634 with self
.assertRaises(IndexError):
635 self
._fc
.option_at_index(len(self
._fc
))
637 def _fill_default_fc_for_field_path_test(self
):
638 # Create something equivalent to:
640 # struct outer_struct_fc {
642 # struct inner_struct_fc {
643 # [u]int64_t selector;
646 # variant <selector> {
647 # real a; // selected with self._ranges1
648 # int21_t b; // selected with self._ranges2
649 # uint34_t c; // selected with self._ranges3
653 self
._fc
.append_option('a', self
._tc
.create_real_field_class(), self
._ranges
1)
654 self
._fc
.append_option(
655 'b', self
._tc
.create_signed_integer_field_class(21), self
._ranges
2
657 self
._fc
.append_option(
658 'c', self
._tc
.create_unsigned_integer_field_class(34), self
._ranges
3
661 foo_fc
= self
._tc
.create_real_field_class()
662 bar_fc
= self
._tc
.create_string_field_class()
663 baz_fc
= self
._tc
.create_string_field_class()
665 inner_struct_fc
= self
._tc
.create_structure_field_class()
666 inner_struct_fc
.append_member('selector', self
._selector
_fc
)
667 inner_struct_fc
.append_member('bar', bar_fc
)
668 inner_struct_fc
.append_member('baz', baz_fc
)
669 inner_struct_fc
.append_member('variant', self
._fc
)
671 inner_struct_array_fc
= self
._tc
.create_static_array_field_class(
675 outer_struct_fc
= self
._tc
.create_structure_field_class()
676 outer_struct_fc
.append_member('foo', foo_fc
)
677 outer_struct_fc
.append_member('inner_struct', inner_struct_array_fc
)
679 # The path to the selector field is resolved when the sequence is
680 # actually used, for example in a packet context.
681 self
._tc
.create_stream_class(
682 supports_packets
=True, packet_context_field_class
=outer_struct_fc
685 def test_selector_field_path_length(self
):
686 self
._fill
_default
_fc
_for
_field
_path
_test
()
687 self
.assertEqual(len(self
._fc
.selector_field_path
), 3)
689 def test_selector_field_path_iter(self
):
690 self
._fill
_default
_fc
_for
_field
_path
_test
()
691 path_items
= list(self
._fc
.selector_field_path
)
693 self
.assertEqual(len(path_items
), 3)
695 self
.assertIsInstance(path_items
[0], bt2
._IndexFieldPathItem
)
696 self
.assertEqual(path_items
[0].index
, 1)
698 self
.assertIsInstance(path_items
[1], bt2
._CurrentArrayElementFieldPathItem
)
700 self
.assertIsInstance(path_items
[2], bt2
._IndexFieldPathItem
)
701 self
.assertEqual(path_items
[2].index
, 0)
703 def test_selector_field_path_root_scope(self
):
704 self
._fill
_default
_fc
_for
_field
_path
_test
()
706 self
._fc
.selector_field_path
.root_scope
, bt2
.FieldPathScope
.PACKET_CONTEXT
710 class VariantFieldClassWithUnsignedSelectorTestCase(
711 _VariantFieldClassWithSelectorTestCase
, unittest
.TestCase
713 def _spec_set_up(self
):
714 self
._ranges
1 = bt2
.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
715 self
._ranges
2 = bt2
.UnsignedIntegerRangeSet([(5, 5)])
716 self
._ranges
3 = bt2
.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
717 self
._inval
_ranges
= bt2
.SignedIntegerRangeSet([(-8, 16), (48, 99)])
718 self
._selector
_fc
= self
._tc
.create_unsigned_integer_field_class()
721 class VariantFieldClassWithSignedSelectorTestCase(
722 _VariantFieldClassWithSelectorTestCase
, unittest
.TestCase
724 def _spec_set_up(self
):
725 self
._ranges
1 = bt2
.SignedIntegerRangeSet([(-10, -4), (18, 47)])
726 self
._ranges
2 = bt2
.SignedIntegerRangeSet([(-3, -3)])
727 self
._ranges
3 = bt2
.SignedIntegerRangeSet([(8, 16), (48, 99)])
728 self
._inval
_ranges
= bt2
.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
729 self
._selector
_fc
= self
._tc
.create_signed_integer_field_class()
732 class StaticArrayFieldClassTestCase(unittest
.TestCase
):
734 self
._tc
= get_default_trace_class()
735 self
._elem
_fc
= self
._tc
.create_signed_integer_field_class(23)
737 def test_create_default(self
):
738 fc
= self
._tc
.create_static_array_field_class(self
._elem
_fc
, 45)
739 self
.assertEqual(fc
.element_field_class
.addr
, self
._elem
_fc
.addr
)
740 self
.assertEqual(fc
.length
, 45)
742 def test_create_invalid_elem_field_class(self
):
743 with self
.assertRaises(TypeError):
744 self
._tc
.create_static_array_field_class(object(), 45)
746 def test_create_invalid_length(self
):
747 with self
.assertRaises(ValueError):
748 self
._tc
.create_static_array_field_class(
749 self
._tc
.create_string_field_class(), -17
752 def test_create_invalid_length_type(self
):
753 with self
.assertRaises(TypeError):
754 self
._tc
.create_static_array_field_class(
755 self
._tc
.create_string_field_class(), 'the length'
759 class DynamicArrayFieldClassTestCase(unittest
.TestCase
):
761 self
._tc
= get_default_trace_class()
762 self
._elem
_fc
= self
._tc
.create_signed_integer_field_class(23)
763 self
._len
_fc
= self
._tc
.create_unsigned_integer_field_class(12)
765 def test_create_default(self
):
766 fc
= self
._tc
.create_dynamic_array_field_class(self
._elem
_fc
)
767 self
.assertEqual(fc
.element_field_class
.addr
, self
._elem
_fc
.addr
)
768 self
.assertIsNone(fc
.length_field_path
, None)
770 def _create_field_class_for_field_path_test(self
):
771 # Create something a field class that is equivalent to:
773 # struct outer_struct_fc {
775 # struct inner_struct_fc {
779 # uint23_t dyn_array[len];
783 fc
= self
._tc
.create_dynamic_array_field_class(self
._elem
_fc
, self
._len
_fc
)
785 foo_fc
= self
._tc
.create_real_field_class()
786 bar_fc
= self
._tc
.create_string_field_class()
787 baz_fc
= self
._tc
.create_string_field_class()
789 inner_struct_fc
= self
._tc
.create_structure_field_class()
790 inner_struct_fc
.append_member('bar', bar_fc
)
791 inner_struct_fc
.append_member('baz', baz_fc
)
792 inner_struct_fc
.append_member('len', self
._len
_fc
)
793 inner_struct_fc
.append_member('dyn_array', fc
)
795 inner_struct_array_fc
= self
._tc
.create_static_array_field_class(
799 outer_struct_fc
= self
._tc
.create_structure_field_class()
800 outer_struct_fc
.append_member('foo', foo_fc
)
801 outer_struct_fc
.append_member('inner_struct', inner_struct_array_fc
)
803 # The path to the length field is resolved when the sequence is
804 # actually used, for example in a packet context.
805 self
._tc
.create_stream_class(
806 packet_context_field_class
=outer_struct_fc
, supports_packets
=True
811 def test_field_path_len(self
):
812 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
813 self
.assertEqual(len(fc
.length_field_path
), 3)
815 def test_field_path_iter(self
):
816 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
817 path_items
= list(fc
.length_field_path
)
819 self
.assertEqual(len(path_items
), 3)
821 self
.assertIsInstance(path_items
[0], bt2
._IndexFieldPathItem
)
822 self
.assertEqual(path_items
[0].index
, 1)
824 self
.assertIsInstance(path_items
[1], bt2
._CurrentArrayElementFieldPathItem
)
826 self
.assertIsInstance(path_items
[2], bt2
._IndexFieldPathItem
)
827 self
.assertEqual(path_items
[2].index
, 2)
829 def test_field_path_root_scope(self
):
830 fc
= self
._create
_field
_class
_for
_field
_path
_test
()
832 fc
.length_field_path
.root_scope
, bt2
.FieldPathScope
.PACKET_CONTEXT
835 def test_create_invalid_field_class(self
):
836 with self
.assertRaises(TypeError):
837 self
._tc
.create_dynamic_array_field_class(object())
839 def test_create_invalid_length_type(self
):
840 with self
.assertRaises(TypeError):
841 self
._tc
.create_dynamic_array_field_class(
842 self
._tc
.create_string_field_class(), 17
846 if __name__
== "__main__":