Fix: bt2: use of undefined variable in _VariantFieldClassWithSelectorTestCase.test_co...
[babeltrace.git] / tests / bindings / python / bt2 / test_field_class.py
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
19 import unittest
20 import bt2
21 from utils import get_default_trace_class, TestOutputPortMessageIterator
22 from bt2 import value as bt2_value
23 from bt2 import field_class as bt2_field_class
24
25
26 def _create_stream(tc, ctx_field_classes):
27 packet_context_fc = tc.create_structure_field_class()
28 for name, fc in ctx_field_classes:
29 packet_context_fc.append_member(name, fc)
30
31 trace = tc()
32 stream_class = tc.create_stream_class(
33 packet_context_field_class=packet_context_fc, supports_packets=True
34 )
35
36 stream = trace.create_stream(stream_class)
37 return stream
38
39
40 def _create_const_field_class(tc, field_class, value_setter_fn):
41 field_name = 'const field'
42
43 class MyIter(bt2._UserMessageIterator):
44 def __init__(self, config, self_port_output):
45 nonlocal field_class
46 nonlocal value_setter_fn
47 stream = _create_stream(tc, [(field_name, field_class)])
48 packet = stream.create_packet()
49
50 value_setter_fn(packet.context_field[field_name])
51
52 self._msgs = [
53 self._create_stream_beginning_message(stream),
54 self._create_packet_beginning_message(packet),
55 ]
56
57 def __next__(self):
58 if len(self._msgs) == 0:
59 raise StopIteration
60
61 return self._msgs.pop(0)
62
63 class MySrc(bt2._UserSourceComponent, message_iterator_class=MyIter):
64 def __init__(self, config, params, obj):
65 self._add_output_port('out', params)
66
67 graph = bt2.Graph()
68 src_comp = graph.add_component(MySrc, 'my_source', None)
69 msg_iter = TestOutputPortMessageIterator(graph, src_comp.output_ports['out'])
70
71 # Ignore first message, stream beginning
72 _ = next(msg_iter)
73 packet_beg_msg = next(msg_iter)
74
75 return packet_beg_msg.packet.context_field[field_name].cls
76
77
78 class _TestFieldClass:
79 def test_create_user_attributes(self):
80 fc = self._create_default_field_class(user_attributes={'salut': 23})
81 self.assertEqual(fc.user_attributes, {'salut': 23})
82 self.assertIs(type(fc.user_attributes), bt2_value.MapValue)
83
84 def test_const_create_user_attributes(self):
85 fc = self._create_default_const_field_class(user_attributes={'salut': 23})
86 self.assertEqual(fc.user_attributes, {'salut': 23})
87 self.assertIs(type(fc.user_attributes), bt2_value._MapValueConst)
88
89 def test_create_invalid_user_attributes(self):
90 with self.assertRaises(TypeError):
91 self._create_default_field_class(user_attributes=object())
92
93 def test_create_invalid_user_attributes_value_type(self):
94 with self.assertRaises(TypeError):
95 self._create_default_field_class(user_attributes=23)
96
97
98 class BoolFieldClassTestCase(_TestFieldClass, unittest.TestCase):
99 @staticmethod
100 def _const_value_setter(field):
101 field.value = False
102
103 def _create_default_field_class(self, **kwargs):
104 tc = get_default_trace_class()
105 return tc.create_bool_field_class(**kwargs)
106
107 def _create_default_const_field_class(self, *args, **kwargs):
108 tc = get_default_trace_class()
109 fc = tc.create_bool_field_class(*args, **kwargs)
110 return _create_const_field_class(tc, fc, self._const_value_setter)
111
112 def setUp(self):
113 self._fc = self._create_default_field_class()
114 self._fc_const = self._create_default_const_field_class()
115
116 def test_create_default(self):
117 self.assertIsNotNone(self._fc)
118 self.assertEqual(len(self._fc.user_attributes), 0)
119
120
121 class BitArrayFieldClassTestCase(_TestFieldClass, unittest.TestCase):
122 @staticmethod
123 def _const_value_setter(field):
124 field.value = []
125
126 def _create_field_class(self, *args, **kwargs):
127 tc = get_default_trace_class()
128 return tc.create_bit_array_field_class(*args, **kwargs)
129
130 def _create_default_field_class(self, **kwargs):
131 return self._create_field_class(17, **kwargs)
132
133 def _create_default_const_field_class(self, *args, **kwargs):
134 tc = get_default_trace_class()
135 fc = tc.create_bit_array_field_class(17, **kwargs)
136 return _create_const_field_class(tc, fc, self._const_value_setter)
137
138 def setUp(self):
139 self._fc = self._create_default_field_class()
140
141 def test_create_default(self):
142 self.assertIsNotNone(self._fc)
143 self.assertEqual(len(self._fc.user_attributes), 0)
144
145 def test_create_length_out_of_range(self):
146 with self.assertRaises(ValueError):
147 self._create_field_class(65)
148
149 def test_create_length_zero(self):
150 with self.assertRaises(ValueError):
151 self._create_field_class(0)
152
153 def test_create_length_invalid_type(self):
154 with self.assertRaises(TypeError):
155 self._create_field_class('lel')
156
157 def test_length_prop(self):
158 self.assertEqual(self._fc.length, 17)
159
160
161 class _TestIntegerFieldClassProps:
162 def test_create_default(self):
163 fc = self._create_default_field_class()
164 self.assertEqual(fc.field_value_range, 64)
165 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.DECIMAL)
166 self.assertEqual(len(fc.user_attributes), 0)
167
168 def test_create_range(self):
169 fc = self._create_field_class(field_value_range=35)
170 self.assertEqual(fc.field_value_range, 35)
171
172 fc = self._create_field_class(36)
173 self.assertEqual(fc.field_value_range, 36)
174
175 def test_create_invalid_range(self):
176 with self.assertRaises(TypeError):
177 self._create_field_class('yes')
178
179 with self.assertRaises(TypeError):
180 self._create_field_class(field_value_range='yes')
181
182 with self.assertRaises(ValueError):
183 self._create_field_class(field_value_range=-2)
184
185 with self.assertRaises(ValueError):
186 self._create_field_class(field_value_range=0)
187
188 def test_create_base(self):
189 fc = self._create_field_class(
190 preferred_display_base=bt2.IntegerDisplayBase.HEXADECIMAL
191 )
192 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.HEXADECIMAL)
193
194 def test_create_invalid_base_type(self):
195 with self.assertRaises(TypeError):
196 self._create_field_class(preferred_display_base='yes')
197
198 def test_create_invalid_base_value(self):
199 with self.assertRaises(ValueError):
200 self._create_field_class(preferred_display_base=444)
201
202 def test_create_full(self):
203 fc = self._create_field_class(
204 24, preferred_display_base=bt2.IntegerDisplayBase.OCTAL
205 )
206 self.assertEqual(fc.field_value_range, 24)
207 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.OCTAL)
208
209
210 class SignedIntegerFieldClassTestCase(
211 _TestIntegerFieldClassProps, _TestFieldClass, unittest.TestCase
212 ):
213 @staticmethod
214 def _const_value_setter(field):
215 field.value = -18
216
217 def _create_field_class(self, *args, **kwargs):
218 tc = get_default_trace_class()
219 return tc.create_signed_integer_field_class(*args, **kwargs)
220
221 def _create_default_const_field_class(self, *args, **kwargs):
222 tc = get_default_trace_class()
223 fc = tc.create_signed_integer_field_class(*args, **kwargs)
224 return _create_const_field_class(tc, fc, self._const_value_setter)
225
226 _create_default_field_class = _create_field_class
227
228
229 class UnsignedIntegerFieldClassTestCase(
230 _TestIntegerFieldClassProps, _TestFieldClass, unittest.TestCase
231 ):
232 @staticmethod
233 def _const_value_setter(field):
234 field.value = 18
235
236 def _create_field_class(self, *args, **kwargs):
237 tc = get_default_trace_class()
238 return tc.create_unsigned_integer_field_class(*args, **kwargs)
239
240 def _create_default_const_field_class(self, *args, **kwargs):
241 tc = get_default_trace_class()
242 fc = tc.create_signed_integer_field_class(*args, **kwargs)
243 return _create_const_field_class(tc, fc, self._const_value_setter)
244
245 _create_default_field_class = _create_field_class
246
247
248 class RealFieldClassTestCase(_TestFieldClass, unittest.TestCase):
249 @staticmethod
250 def _const_value_setter(field):
251 field.value = -18
252
253 def _create_field_class(self, *args, **kwargs):
254 tc = get_default_trace_class()
255 return tc.create_real_field_class(*args, **kwargs)
256
257 def _create_default_const_field_class(self, *args, **kwargs):
258 tc = get_default_trace_class()
259 fc = tc.create_real_field_class(*args, **kwargs)
260 return _create_const_field_class(tc, fc, self._const_value_setter)
261
262 _create_default_field_class = _create_field_class
263
264 def test_create_default(self):
265 fc = self._create_field_class()
266 self.assertFalse(fc.is_single_precision)
267 self.assertEqual(len(fc.user_attributes), 0)
268
269 def test_create_is_single_precision(self):
270 fc = self._create_field_class(is_single_precision=True)
271 self.assertTrue(fc.is_single_precision)
272
273 def test_create_invalid_is_single_precision(self):
274 with self.assertRaises(TypeError):
275 self._create_field_class(is_single_precision='hohoho')
276
277
278 # Converts an _EnumerationFieldClassMapping to a list of ranges:
279 #
280 # [(lower0, upper0), (lower1, upper1), ...]
281
282
283 def enum_mapping_to_set(mapping):
284 return {(x.lower, x.upper) for x in mapping.ranges}
285
286
287 class _EnumerationFieldClassTestCase(_TestIntegerFieldClassProps):
288 def setUp(self):
289 self._spec_set_up()
290 self._fc = self._create_default_field_class()
291 self._fc_const = self._create_default_const_field_class()
292
293 def test_create_from_invalid_type(self):
294 with self.assertRaises(TypeError):
295 self._create_field_class('coucou')
296
297 def test_add_mapping_simple(self):
298 self._fc.add_mapping('hello', self._ranges1)
299 mapping = self._fc['hello']
300 self.assertEqual(mapping.label, 'hello')
301 self.assertEqual(mapping.ranges, self._ranges1)
302
303 def test_const_add_mapping(self):
304 with self.assertRaises(AttributeError):
305 self._fc_const.add_mapping('hello', self._ranges1)
306
307 def test_add_mapping_simple_kwargs(self):
308 self._fc.add_mapping(label='hello', ranges=self._ranges1)
309 mapping = self._fc['hello']
310 self.assertEqual(mapping.label, 'hello')
311 self.assertEqual(mapping.ranges, self._ranges1)
312
313 def test_add_mapping_invalid_name(self):
314 with self.assertRaises(TypeError):
315 self._fc.add_mapping(17, self._ranges1)
316
317 def test_add_mapping_invalid_range(self):
318 with self.assertRaises(TypeError):
319 self._fc.add_mapping('allo', 'meow')
320
321 def test_add_mapping_dup_label(self):
322 with self.assertRaises(ValueError):
323 self._fc.add_mapping('a', self._ranges1)
324 self._fc.add_mapping('a', self._ranges2)
325
326 def test_add_mapping_invalid_ranges_signedness(self):
327 with self.assertRaises(TypeError):
328 self._fc.add_mapping('allo', self._inval_ranges)
329
330 def test_iadd(self):
331 self._fc.add_mapping('c', self._ranges1)
332
333 self._fc += [('d', self._ranges2), ('e', self._ranges3)]
334
335 self.assertEqual(len(self._fc), 3)
336 self.assertEqual(self._fc['c'].label, 'c')
337 self.assertEqual(self._fc['c'].ranges, self._ranges1)
338 self.assertEqual(self._fc['d'].label, 'd')
339 self.assertEqual(self._fc['d'].ranges, self._ranges2)
340 self.assertEqual(self._fc['e'].label, 'e')
341 self.assertEqual(self._fc['e'].ranges, self._ranges3)
342
343 def test_const_iadd(self):
344 with self.assertRaises(TypeError):
345 self._fc_const += [('d', self._ranges2), ('e', self._ranges3)]
346
347 def test_bool_op(self):
348 self.assertFalse(self._fc)
349 self._fc.add_mapping('a', self._ranges1)
350 self.assertTrue(self._fc)
351
352 def test_len(self):
353 self._fc.add_mapping('a', self._ranges1)
354 self._fc.add_mapping('b', self._ranges2)
355 self._fc.add_mapping('c', self._ranges3)
356 self.assertEqual(len(self._fc), 3)
357
358 def test_getitem(self):
359 self._fc.add_mapping('a', self._ranges1)
360 self._fc.add_mapping('b', self._ranges2)
361 self._fc.add_mapping('c', self._ranges3)
362 mapping = self._fc['a']
363 self.assertEqual(mapping.label, 'a')
364 self.assertEqual(mapping.ranges, self._ranges1)
365
366 def test_getitem_nonexistent(self):
367 with self.assertRaises(KeyError):
368 self._fc['doesnotexist']
369
370 def test_iter(self):
371 self._fc.add_mapping('a', self._ranges1)
372 self._fc.add_mapping('b', self._ranges2)
373 self._fc.add_mapping('c', self._ranges3)
374
375 # This exercises iteration.
376 labels = sorted(self._fc)
377
378 self.assertEqual(labels, ['a', 'b', 'c'])
379
380 def test_find_by_value(self):
381 self._fc.add_mapping('a', self._ranges1)
382 self._fc.add_mapping('b', self._ranges2)
383 self._fc.add_mapping('c', self._ranges3)
384 mappings = self._fc.mappings_for_value(self._value_in_range_1_and_3)
385 labels = set([mapping.label for mapping in mappings])
386 expected_labels = set(['a', 'c'])
387 self.assertEqual(labels, expected_labels)
388
389
390 class UnsignedEnumerationFieldClassTestCase(
391 _EnumerationFieldClassTestCase, _TestFieldClass, unittest.TestCase
392 ):
393 def _spec_set_up(self):
394 self._ranges1 = bt2.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
395 self._ranges2 = bt2.UnsignedIntegerRangeSet([(5, 5)])
396 self._ranges3 = bt2.UnsignedIntegerRangeSet([(8, 22), (48, 99)])
397 self._inval_ranges = bt2.SignedIntegerRangeSet([(-8, -5), (48, 1928)])
398 self._value_in_range_1_and_3 = 20
399
400 @staticmethod
401 def _const_value_setter(field):
402 field.value = 0
403
404 def _create_field_class(self, *args, **kwargs):
405 tc = get_default_trace_class()
406 return tc.create_unsigned_enumeration_field_class(*args, **kwargs)
407
408 def _create_default_const_field_class(self, *args, **kwargs):
409 tc = get_default_trace_class()
410 fc = tc.create_unsigned_enumeration_field_class(*args, **kwargs)
411 return _create_const_field_class(tc, fc, self._const_value_setter)
412
413 _create_default_field_class = _create_field_class
414
415
416 class SignedEnumerationFieldClassTestCase(
417 _EnumerationFieldClassTestCase, _TestFieldClass, unittest.TestCase
418 ):
419 def _spec_set_up(self):
420 self._ranges1 = bt2.SignedIntegerRangeSet([(-10, -4), (18, 47)])
421 self._ranges2 = bt2.SignedIntegerRangeSet([(-3, -3)])
422 self._ranges3 = bt2.SignedIntegerRangeSet([(-100, -1), (8, 16), (48, 99)])
423 self._inval_ranges = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
424 self._value_in_range_1_and_3 = -7
425
426 @staticmethod
427 def _const_value_setter(field):
428 field.value = 0
429
430 def _create_field_class(self, *args, **kwargs):
431 tc = get_default_trace_class()
432 return tc.create_signed_enumeration_field_class(*args, **kwargs)
433
434 def _create_default_const_field_class(self, *args, **kwargs):
435 tc = get_default_trace_class()
436 fc = tc.create_signed_enumeration_field_class(*args, **kwargs)
437 return _create_const_field_class(tc, fc, self._const_value_setter)
438
439 _create_default_field_class = _create_field_class
440
441
442 class StringFieldClassTestCase(_TestFieldClass, unittest.TestCase):
443 @staticmethod
444 def _const_value_setter(field):
445 field.value = 'chaine'
446
447 def _create_field_class(self, *args, **kwargs):
448 tc = get_default_trace_class()
449 return tc.create_string_field_class(*args, **kwargs)
450
451 def _create_default_const_field_class(self, *args, **kwargs):
452 tc = get_default_trace_class()
453 fc = tc.create_string_field_class(*args, **kwargs)
454 return _create_const_field_class(tc, fc, self._const_value_setter)
455
456 _create_default_field_class = _create_field_class
457
458 def setUp(self):
459 self._fc = self._create_default_field_class()
460
461 def test_create_default(self):
462 self.assertIsNotNone(self._fc)
463 self.assertEqual(len(self._fc.user_attributes), 0)
464
465
466 class _TestElementContainer:
467 def setUp(self):
468 self._tc = get_default_trace_class()
469 self._fc = self._create_default_field_class()
470 self._fc_const = self._create_default_const_field_class()
471
472 def test_create_default(self):
473 self.assertIsNotNone(self._fc)
474 self.assertEqual(len(self._fc.user_attributes), 0)
475
476 def test_append_element(self):
477 int_field_class = self._tc.create_signed_integer_field_class(32)
478 self._append_element_method(self._fc, 'int32', int_field_class)
479 field_class = self._fc['int32'].field_class
480 self.assertEqual(field_class.addr, int_field_class.addr)
481
482 def test_append_element_kwargs(self):
483 int_field_class = self._tc.create_signed_integer_field_class(32)
484 self._append_element_method(self._fc, name='int32', field_class=int_field_class)
485 field_class = self._fc['int32'].field_class
486 self.assertEqual(field_class.addr, int_field_class.addr)
487
488 def test_append_element_invalid_name(self):
489 sub_fc = self._tc.create_string_field_class()
490
491 with self.assertRaises(TypeError):
492 self._append_element_method(self._fc, 23, sub_fc)
493
494 def test_append_element_invalid_field_class(self):
495 with self.assertRaises(TypeError):
496 self._append_element_method(self._fc, 'yes', object())
497
498 def test_append_element_dup_name(self):
499 sub_fc1 = self._tc.create_string_field_class()
500 sub_fc2 = self._tc.create_string_field_class()
501
502 with self.assertRaises(ValueError):
503 self._append_element_method(self._fc, 'yes', sub_fc1)
504 self._append_element_method(self._fc, 'yes', sub_fc2)
505
506 def test_attr_field_class(self):
507 int_field_class = self._tc.create_signed_integer_field_class(32)
508 self._append_element_method(self._fc, 'int32', int_field_class)
509 field_class = self._fc['int32'].field_class
510
511 self.assertIs(type(field_class), bt2_field_class._SignedIntegerFieldClass)
512
513 def test_const_attr_field_class(self):
514 int_field_class = self._tc.create_signed_integer_field_class(32)
515 self._append_element_method(self._fc, 'int32', int_field_class)
516 field_class = self._fc['int32'].field_class
517 const_fc = _create_const_field_class(
518 self._tc, self._fc, self._const_value_setter
519 )
520 field_class = const_fc['int32'].field_class
521
522 self.assertIs(type(field_class), bt2_field_class._SignedIntegerFieldClassConst)
523
524 def test_iadd(self):
525 a_field_class = self._tc.create_real_field_class()
526 b_field_class = self._tc.create_signed_integer_field_class(17)
527 self._append_element_method(self._fc, 'a_float', a_field_class)
528 self._append_element_method(self._fc, 'b_int', b_field_class)
529 c_field_class = self._tc.create_string_field_class()
530 d_field_class = self._tc.create_signed_enumeration_field_class(
531 field_value_range=32
532 )
533 e_field_class = self._tc.create_structure_field_class()
534 self._fc += [
535 ('c_string', c_field_class),
536 ('d_enum', d_field_class),
537 ('e_struct', e_field_class),
538 ]
539 self.assertEqual(self._fc['a_float'].field_class.addr, a_field_class.addr)
540 self.assertEqual(self._fc['a_float'].name, 'a_float')
541 self.assertEqual(self._fc['b_int'].field_class.addr, b_field_class.addr)
542 self.assertEqual(self._fc['b_int'].name, 'b_int')
543 self.assertEqual(self._fc['c_string'].field_class.addr, c_field_class.addr)
544 self.assertEqual(self._fc['c_string'].name, 'c_string')
545 self.assertEqual(self._fc['d_enum'].field_class.addr, d_field_class.addr)
546 self.assertEqual(self._fc['d_enum'].name, 'd_enum')
547 self.assertEqual(self._fc['e_struct'].field_class.addr, e_field_class.addr)
548 self.assertEqual(self._fc['e_struct'].name, 'e_struct')
549
550 def test_const_iadd(self):
551 a_field_class = self._tc.create_real_field_class()
552 with self.assertRaises(TypeError):
553 self._fc_const += a_field_class
554
555 def test_bool_op(self):
556 self.assertFalse(self._fc)
557 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
558 self.assertTrue(self._fc)
559
560 def test_len(self):
561 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
562 self._append_element_method(self._fc, 'b', self._tc.create_string_field_class())
563 self._append_element_method(self._fc, 'c', self._tc.create_string_field_class())
564 self.assertEqual(len(self._fc), 3)
565
566 def test_getitem(self):
567 a_fc = self._tc.create_signed_integer_field_class(32)
568 b_fc = self._tc.create_string_field_class()
569 c_fc = self._tc.create_real_field_class()
570 self._append_element_method(self._fc, 'a', a_fc)
571 self._append_element_method(self._fc, 'b', b_fc)
572 self._append_element_method(self._fc, 'c', c_fc)
573 self.assertEqual(self._fc['b'].field_class.addr, b_fc.addr)
574 self.assertEqual(self._fc['b'].name, 'b')
575
576 def test_getitem_invalid_key_type(self):
577 with self.assertRaises(TypeError):
578 self._fc[0]
579
580 def test_getitem_invalid_key(self):
581 with self.assertRaises(KeyError):
582 self._fc['no way']
583
584 def test_contains(self):
585 self.assertFalse('a' in self._fc)
586 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
587 self.assertTrue('a' in self._fc)
588
589 def test_iter(self):
590 a_fc = self._tc.create_signed_integer_field_class(32)
591 b_fc = self._tc.create_string_field_class()
592 c_fc = self._tc.create_real_field_class()
593 elements = (('a', a_fc), ('b', b_fc), ('c', c_fc))
594
595 for elem in elements:
596 self._append_element_method(self._fc, *elem)
597
598 for (name, element), test_elem in zip(self._fc.items(), elements):
599 self.assertEqual(element.name, test_elem[0])
600 self.assertEqual(name, element.name)
601 self.assertEqual(element.field_class.addr, test_elem[1].addr)
602 self.assertEqual(len(element.user_attributes), 0)
603
604 def test_at_index(self):
605 a_fc = self._tc.create_signed_integer_field_class(32)
606 b_fc = self._tc.create_string_field_class()
607 c_fc = self._tc.create_real_field_class()
608 self._append_element_method(self._fc, 'c', c_fc)
609 self._append_element_method(self._fc, 'a', a_fc)
610 self._append_element_method(self._fc, 'b', b_fc)
611 elem = self._at_index_method(self._fc, 1)
612 self.assertEqual(elem.field_class.addr, a_fc.addr)
613 self.assertEqual(elem.name, 'a')
614
615 def test_at_index_invalid(self):
616 self._append_element_method(
617 self._fc, 'c', self._tc.create_signed_integer_field_class(32)
618 )
619
620 with self.assertRaises(TypeError):
621 self._at_index_method(self._fc, 'yes')
622
623 def test_at_index_out_of_bounds_after(self):
624 self._append_element_method(
625 self._fc, 'c', self._tc.create_signed_integer_field_class(32)
626 )
627
628 with self.assertRaises(IndexError):
629 self._at_index_method(self._fc, len(self._fc))
630
631 def test_user_attributes(self):
632 self._append_element_method(
633 self._fc,
634 'c',
635 self._tc.create_string_field_class(),
636 user_attributes={'salut': 23},
637 )
638 self.assertEqual(self._fc['c'].user_attributes, {'salut': 23})
639 self.assertIs(type(self._fc.user_attributes), bt2_value.MapValue)
640 self.assertIs(type(self._fc['c'].user_attributes), bt2_value.MapValue)
641
642 def test_invalid_user_attributes(self):
643 with self.assertRaises(TypeError):
644 self._append_element_method(
645 self._fc,
646 'c',
647 self._tc.create_string_field_class(),
648 user_attributes=object(),
649 )
650
651 def test_invalid_user_attributes_value_type(self):
652 with self.assertRaises(TypeError):
653 self._append_element_method(
654 self._fc, 'c', self._tc.create_string_field_class(), user_attributes=23
655 )
656
657
658 class StructureFieldClassTestCase(
659 _TestFieldClass, _TestElementContainer, unittest.TestCase
660 ):
661 _append_element_method = staticmethod(bt2._StructureFieldClass.append_member)
662 _at_index_method = staticmethod(bt2._StructureFieldClass.member_at_index)
663
664 @staticmethod
665 def _const_value_setter(field):
666 field.value = {}
667
668 def _create_field_class(self, *args, **kwargs):
669 tc = get_default_trace_class()
670 return tc.create_structure_field_class(*args, **kwargs)
671
672 def _create_default_const_field_class(self, *args, **kwargs):
673 tc = get_default_trace_class()
674 fc = tc.create_structure_field_class(*args, **kwargs)
675 return _create_const_field_class(tc, fc, self._const_value_setter)
676
677 _create_default_field_class = _create_field_class
678
679 def test_const_member_field_class(self):
680 def _real_value_setter(field):
681 field.value = {'real': 0}
682
683 tc = get_default_trace_class()
684 fc = tc.create_structure_field_class()
685 member_fc = self._tc.create_real_field_class()
686 fc.append_member('real', member_fc)
687 const_fc = _create_const_field_class(tc, fc, _real_value_setter)
688
689 self.assertIs(
690 type(const_fc['real'].field_class), bt2_field_class._RealFieldClassConst
691 )
692
693 def test_member_field_class(self):
694 tc = get_default_trace_class()
695 fc = tc.create_structure_field_class()
696 member_fc = self._tc.create_real_field_class()
697 fc.append_member('real', member_fc)
698
699 self.assertIs(type(fc['real'].field_class), bt2_field_class._RealFieldClass)
700
701
702 class OptionFieldClassTestCase(_TestFieldClass, unittest.TestCase):
703 @staticmethod
704 def _const_value_setter(field):
705 field.has_field = True
706 field.value = 12
707
708 def _create_default_field_class(self, *args, **kwargs):
709 return self._tc.create_option_field_class(self._content_fc, **kwargs)
710
711 def _create_default_const_field_class(self, *args, **kwargs):
712 fc = self._tc.create_option_field_class(self._content_fc, **kwargs)
713 return _create_const_field_class(self._tc, fc, self._const_value_setter)
714
715 def setUp(self):
716 self._tc = get_default_trace_class()
717 self._content_fc = self._tc.create_signed_integer_field_class(23)
718 self._tag_fc = self._tc.create_bool_field_class()
719
720 def test_create_default(self):
721 fc = self._create_default_field_class()
722 self.assertEqual(fc.field_class.addr, self._content_fc.addr)
723 self.assertIsNone(fc.selector_field_path, None)
724 self.assertEqual(len(fc.user_attributes), 0)
725
726 def test_attr_field_class(self):
727 fc = self._create_default_field_class()
728 self.assertIs(type(fc.field_class), bt2_field_class._SignedIntegerFieldClass)
729
730 def test_const_attr_field_class(self):
731 fc = self._create_default_const_field_class()
732 self.assertIs(
733 type(fc.field_class), bt2_field_class._SignedIntegerFieldClassConst
734 )
735
736 def _create_field_class_for_field_path_test(self):
737 fc = self._create_default_field_class(selector_fc=self._tag_fc)
738
739 foo_fc = self._tc.create_real_field_class()
740 bar_fc = self._tc.create_string_field_class()
741 baz_fc = self._tc.create_string_field_class()
742
743 inner_struct_fc = self._tc.create_structure_field_class()
744 inner_struct_fc.append_member('bar', bar_fc)
745 inner_struct_fc.append_member('baz', baz_fc)
746 inner_struct_fc.append_member('tag', self._tag_fc)
747 inner_struct_fc.append_member('opt', fc)
748
749 opt_struct_array_fc = self._tc.create_option_field_class(inner_struct_fc)
750
751 outer_struct_fc = self._tc.create_structure_field_class()
752 outer_struct_fc.append_member('foo', foo_fc)
753 outer_struct_fc.append_member('inner_opt', opt_struct_array_fc)
754
755 # The path to the selector field class is resolved when the
756 # option field class is actually used, for example in a packet
757 # context.
758 self._tc.create_stream_class(
759 packet_context_field_class=outer_struct_fc, supports_packets=True
760 )
761
762 return fc
763
764 def test_field_path_len(self):
765 fc = self._create_field_class_for_field_path_test()
766 self.assertEqual(len(fc.selector_field_path), 3)
767
768 def test_field_path_iter(self):
769 fc = self._create_field_class_for_field_path_test()
770 path_items = list(fc.selector_field_path)
771
772 self.assertEqual(len(path_items), 3)
773
774 self.assertIsInstance(path_items[0], bt2._IndexFieldPathItem)
775 self.assertEqual(path_items[0].index, 1)
776
777 self.assertIsInstance(path_items[1], bt2._CurrentOptionContentFieldPathItem)
778
779 self.assertIsInstance(path_items[2], bt2._IndexFieldPathItem)
780 self.assertEqual(path_items[2].index, 2)
781
782 def test_field_path_root_scope(self):
783 fc = self._create_field_class_for_field_path_test()
784 self.assertEqual(
785 fc.selector_field_path.root_scope, bt2.FieldPathScope.PACKET_CONTEXT
786 )
787
788 def test_create_invalid_field_class(self):
789 with self.assertRaises(TypeError):
790 self._tc.create_option_field_class(object())
791
792 def test_create_invalid_selector_type(self):
793 with self.assertRaises(TypeError):
794 self._tc.create_option_field_class(self._content_fc, 17)
795
796
797 class VariantFieldClassWithoutSelectorTestCase(
798 _TestFieldClass, _TestElementContainer, unittest.TestCase
799 ):
800 _append_element_method = staticmethod(
801 bt2._VariantFieldClassWithoutSelector.append_option
802 )
803 _at_index_method = staticmethod(
804 bt2._VariantFieldClassWithoutSelector.option_at_index
805 )
806
807 @staticmethod
808 def _const_value_setter(variant_field):
809 variant_field.selected_option_index = 0
810 variant_field.value = 12
811
812 def _create_field_class(self, *args, **kwargs):
813 tc = get_default_trace_class()
814 return tc.create_variant_field_class(*args, **kwargs)
815
816 def _create_default_const_field_class(self, *args, **kwargs):
817 tc = get_default_trace_class()
818 fc = tc.create_variant_field_class(*args, **kwargs)
819 int_field_class = self._tc.create_signed_integer_field_class(32)
820 fc.append_option('int32', int_field_class)
821
822 return _create_const_field_class(tc, fc, self._const_value_setter)
823
824 _create_default_field_class = _create_field_class
825
826
827 class _VariantFieldClassWithSelectorTestCase:
828 @staticmethod
829 def _const_value_setter(field):
830 field['variant'].selected_option_index = 0
831 field['variant'] = 12
832
833 def _create_default_field_class(self, *args, **kwargs):
834 return self._tc.create_variant_field_class(
835 *args, selector_fc=self._selector_fc, **kwargs
836 )
837
838 def _create_default_const_field_class(self, *args, **kwargs):
839 # Create a struct to contain the variant and its selector else we can't
840 # create the non-const field necessary to get the the const field_class
841 struct_fc = self._tc.create_structure_field_class()
842 struct_fc.append_member('selecteux', self._selector_fc)
843 variant_fc = self._tc.create_variant_field_class(
844 *args, selector_fc=self._selector_fc
845 )
846 variant_fc.append_option(
847 'a', self._tc.create_signed_integer_field_class(32), self._ranges1
848 )
849 struct_fc.append_member('variant', variant_fc, **kwargs)
850
851 return _create_const_field_class(self._tc, struct_fc, self._const_value_setter)[
852 'variant'
853 ].field_class
854
855 def setUp(self):
856 self._tc = get_default_trace_class()
857 self._spec_set_up()
858 self._fc = self._create_default_field_class()
859
860 def test_create_default(self):
861 self.assertIsNotNone(self._fc)
862 self.assertEqual(len(self._fc.user_attributes), 0)
863
864 def test_append_element(self):
865 str_field_class = self._tc.create_string_field_class()
866 self._fc.append_option('str', str_field_class, self._ranges1)
867 opt = self._fc['str']
868 self.assertEqual(opt.field_class.addr, str_field_class.addr)
869 self.assertEqual(opt.name, 'str')
870 self.assertEqual(opt.ranges.addr, self._ranges1.addr)
871
872 def test_const_append(self):
873 fc_const = self._create_default_const_field_class()
874 str_field_class = self._tc.create_string_field_class()
875 with self.assertRaises(AttributeError):
876 fc_const.append_option('str', str_field_class, self._ranges1)
877
878 def test_append_element_kwargs(self):
879 int_field_class = self._tc.create_signed_integer_field_class(32)
880 self._fc.append_option(
881 name='int32', field_class=int_field_class, ranges=self._ranges1
882 )
883 opt = self._fc['int32']
884 self.assertEqual(opt.field_class.addr, int_field_class.addr)
885 self.assertEqual(opt.name, 'int32')
886 self.assertEqual(opt.ranges.addr, self._ranges1.addr)
887
888 def test_append_element_invalid_name(self):
889 sub_fc = self._tc.create_string_field_class()
890
891 with self.assertRaises(TypeError):
892 self._fc.append_option(self._fc, 23, sub_fc)
893
894 def test_append_element_invalid_field_class(self):
895 with self.assertRaises(TypeError):
896 self._fc.append_option(self._fc, 'yes', object())
897
898 def test_append_element_invalid_ranges(self):
899 sub_fc = self._tc.create_string_field_class()
900
901 with self.assertRaises(TypeError):
902 self._fc.append_option(self._fc, sub_fc, 'lel')
903
904 def test_append_element_dup_name(self):
905 sub_fc1 = self._tc.create_string_field_class()
906 sub_fc2 = self._tc.create_string_field_class()
907
908 with self.assertRaises(ValueError):
909 self._fc.append_option('yes', sub_fc1, self._ranges1)
910 self._fc.append_option('yes', sub_fc2, self._ranges2)
911
912 def test_append_element_invalid_ranges_signedness(self):
913 sub_fc = self._tc.create_string_field_class()
914
915 with self.assertRaises(TypeError):
916 self._fc.append_option(self._fc, sub_fc, self._inval_ranges)
917
918 def test_user_attributes(self):
919 self._fc.append_option(
920 'c',
921 self._tc.create_string_field_class(),
922 self._ranges1,
923 user_attributes={'salut': 23},
924 )
925 self.assertEqual(self._fc['c'].user_attributes, {'salut': 23})
926 self.assertIs(type(self._fc.user_attributes), bt2_value.MapValue)
927
928 def test_const_user_attributes(self):
929 fc_const = self._create_default_const_field_class()
930 self.assertIs(type(fc_const.user_attributes), bt2_value._MapValueConst)
931
932 def test_invalid_user_attributes(self):
933 with self.assertRaises(TypeError):
934 self._fc.append_option(
935 'c',
936 self._tc.create_string_field_class(),
937 self._ranges1,
938 user_attributes=object(),
939 )
940
941 def test_invalid_user_attributes_value_type(self):
942 with self.assertRaises(TypeError):
943 self._fc.append_option(
944 'c',
945 self._tc.create_string_field_class(),
946 self._ranges1,
947 user_attributes=23,
948 )
949
950 def test_iadd(self):
951 a_field_class = self._tc.create_real_field_class()
952 self._fc.append_option('a_float', a_field_class, self._ranges1)
953 c_field_class = self._tc.create_string_field_class()
954 d_field_class = self._tc.create_signed_enumeration_field_class(
955 field_value_range=32
956 )
957 self._fc += [
958 ('c_string', c_field_class, self._ranges2),
959 ('d_enum', d_field_class, self._ranges3),
960 ]
961 self.assertEqual(self._fc['a_float'].field_class.addr, a_field_class.addr)
962 self.assertEqual(self._fc['a_float'].name, 'a_float')
963 self.assertEqual(self._fc['a_float'].ranges, self._ranges1)
964 self.assertEqual(self._fc['c_string'].field_class.addr, c_field_class.addr)
965 self.assertEqual(self._fc['c_string'].name, 'c_string')
966 self.assertEqual(self._fc['c_string'].ranges, self._ranges2)
967 self.assertEqual(self._fc['d_enum'].field_class.addr, d_field_class.addr)
968 self.assertEqual(self._fc['d_enum'].name, 'd_enum')
969 self.assertEqual(self._fc['d_enum'].ranges, self._ranges3)
970
971 def test_const_iadd(self):
972 fc_const = self._create_default_const_field_class()
973 a_field_class = self._tc.create_real_field_class()
974 with self.assertRaises(TypeError):
975 fc_const += [('a_float', a_field_class, self._ranges1)]
976
977 def test_bool_op(self):
978 self.assertFalse(self._fc)
979 self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
980 self.assertTrue(self._fc)
981
982 def test_len(self):
983 self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
984 self._fc.append_option('b', self._tc.create_string_field_class(), self._ranges2)
985 self._fc.append_option('c', self._tc.create_string_field_class(), self._ranges3)
986 self.assertEqual(len(self._fc), 3)
987
988 def test_getitem(self):
989 a_fc = self._tc.create_signed_integer_field_class(32)
990 b_fc = self._tc.create_string_field_class()
991 c_fc = self._tc.create_real_field_class()
992 self._fc.append_option('a', a_fc, self._ranges1)
993 self._fc.append_option('b', b_fc, self._ranges2)
994 self._fc.append_option('c', c_fc, self._ranges3)
995 self.assertEqual(self._fc['b'].field_class.addr, b_fc.addr)
996 self.assertEqual(self._fc['b'].name, 'b')
997 self.assertEqual(self._fc['b'].ranges.addr, self._ranges2.addr)
998
999 def test_option_field_class(self):
1000 a_fc = self._tc.create_signed_integer_field_class(32)
1001 self._fc.append_option('a', a_fc, self._ranges1)
1002 self.assertIs(
1003 type(self._fc['a'].field_class), bt2_field_class._SignedIntegerFieldClass
1004 )
1005
1006 def test_const_option_field_class(self):
1007 fc_const = self._create_default_const_field_class()
1008 self.assertIs(
1009 type(fc_const['a'].field_class),
1010 bt2_field_class._SignedIntegerFieldClassConst,
1011 )
1012
1013 def test_getitem_invalid_key_type(self):
1014 with self.assertRaises(TypeError):
1015 self._fc[0]
1016
1017 def test_getitem_invalid_key(self):
1018 with self.assertRaises(KeyError):
1019 self._fc['no way']
1020
1021 def test_contains(self):
1022 self.assertFalse('a' in self._fc)
1023 self._fc.append_option('a', self._tc.create_string_field_class(), self._ranges1)
1024 self.assertTrue('a' in self._fc)
1025
1026 def test_iter(self):
1027 a_fc = self._tc.create_signed_integer_field_class(32)
1028 b_fc = self._tc.create_string_field_class()
1029 c_fc = self._tc.create_real_field_class()
1030 opts = (
1031 ('a', a_fc, self._ranges1),
1032 ('b', b_fc, self._ranges2),
1033 ('c', c_fc, self._ranges3),
1034 )
1035
1036 for opt in opts:
1037 self._fc.append_option(*opt)
1038
1039 for (name, opt), test_opt in zip(self._fc.items(), opts):
1040 self.assertEqual(opt.name, test_opt[0])
1041 self.assertEqual(name, opt.name)
1042 self.assertEqual(opt.field_class.addr, test_opt[1].addr)
1043 self.assertEqual(opt.ranges.addr, test_opt[2].addr)
1044
1045 def test_at_index(self):
1046 a_fc = self._tc.create_signed_integer_field_class(32)
1047 b_fc = self._tc.create_string_field_class()
1048 c_fc = self._tc.create_real_field_class()
1049 self._fc.append_option('c', c_fc, self._ranges1)
1050 self._fc.append_option('a', a_fc, self._ranges2)
1051 self._fc.append_option('b', b_fc, self._ranges3)
1052 self.assertEqual(self._fc.option_at_index(1).field_class.addr, a_fc.addr)
1053 self.assertEqual(self._fc.option_at_index(1).name, 'a')
1054 self.assertEqual(self._fc.option_at_index(1).ranges.addr, self._ranges2.addr)
1055
1056 def test_at_index_invalid(self):
1057 self._fc.append_option(
1058 'c', self._tc.create_signed_integer_field_class(32), self._ranges3
1059 )
1060
1061 with self.assertRaises(TypeError):
1062 self._fc.option_at_index('yes')
1063
1064 def test_at_index_out_of_bounds_after(self):
1065 self._fc.append_option(
1066 'c', self._tc.create_signed_integer_field_class(32), self._ranges3
1067 )
1068
1069 with self.assertRaises(IndexError):
1070 self._fc.option_at_index(len(self._fc))
1071
1072 def _fill_default_fc_for_field_path_test(self):
1073 # Create something equivalent to:
1074 #
1075 # struct outer_struct_fc {
1076 # real foo;
1077 # struct inner_struct_fc {
1078 # [u]int64_t selector;
1079 # string bar;
1080 # string baz;
1081 # variant <selector> {
1082 # real a; // selected with self._ranges1
1083 # int21_t b; // selected with self._ranges2
1084 # uint34_t c; // selected with self._ranges3
1085 # } variant;
1086 # } inner_struct[2];
1087 # };
1088 self._fc.append_option('a', self._tc.create_real_field_class(), self._ranges1)
1089 self._fc.append_option(
1090 'b', self._tc.create_signed_integer_field_class(21), self._ranges2
1091 )
1092 self._fc.append_option(
1093 'c', self._tc.create_unsigned_integer_field_class(34), self._ranges3
1094 )
1095
1096 foo_fc = self._tc.create_real_field_class()
1097 bar_fc = self._tc.create_string_field_class()
1098 baz_fc = self._tc.create_string_field_class()
1099
1100 inner_struct_fc = self._tc.create_structure_field_class()
1101 inner_struct_fc.append_member('selector', self._selector_fc)
1102 inner_struct_fc.append_member('bar', bar_fc)
1103 inner_struct_fc.append_member('baz', baz_fc)
1104 inner_struct_fc.append_member('variant', self._fc)
1105
1106 inner_struct_array_fc = self._tc.create_static_array_field_class(
1107 inner_struct_fc, 2
1108 )
1109
1110 outer_struct_fc = self._tc.create_structure_field_class()
1111 outer_struct_fc.append_member('foo', foo_fc)
1112 outer_struct_fc.append_member('inner_struct', inner_struct_array_fc)
1113
1114 # The path to the selector field is resolved when the sequence is
1115 # actually used, for example in a packet context.
1116 self._tc.create_stream_class(
1117 supports_packets=True, packet_context_field_class=outer_struct_fc
1118 )
1119
1120 def test_selector_field_path_length(self):
1121 self._fill_default_fc_for_field_path_test()
1122 self.assertEqual(len(self._fc.selector_field_path), 3)
1123
1124 def test_selector_field_path_iter(self):
1125 self._fill_default_fc_for_field_path_test()
1126 path_items = list(self._fc.selector_field_path)
1127
1128 self.assertEqual(len(path_items), 3)
1129
1130 self.assertIsInstance(path_items[0], bt2._IndexFieldPathItem)
1131 self.assertEqual(path_items[0].index, 1)
1132
1133 self.assertIsInstance(path_items[1], bt2._CurrentArrayElementFieldPathItem)
1134
1135 self.assertIsInstance(path_items[2], bt2._IndexFieldPathItem)
1136 self.assertEqual(path_items[2].index, 0)
1137
1138 def test_selector_field_path_root_scope(self):
1139 self._fill_default_fc_for_field_path_test()
1140 self.assertEqual(
1141 self._fc.selector_field_path.root_scope, bt2.FieldPathScope.PACKET_CONTEXT
1142 )
1143
1144
1145 class VariantFieldClassWithUnsignedSelectorTestCase(
1146 _VariantFieldClassWithSelectorTestCase, unittest.TestCase
1147 ):
1148 def _spec_set_up(self):
1149 self._ranges1 = bt2.UnsignedIntegerRangeSet([(1, 4), (18, 47)])
1150 self._ranges2 = bt2.UnsignedIntegerRangeSet([(5, 5)])
1151 self._ranges3 = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
1152 self._inval_ranges = bt2.SignedIntegerRangeSet([(-8, 16), (48, 99)])
1153 self._selector_fc = self._tc.create_unsigned_integer_field_class()
1154
1155
1156 class VariantFieldClassWithSignedSelectorTestCase(
1157 _VariantFieldClassWithSelectorTestCase, unittest.TestCase
1158 ):
1159 def _spec_set_up(self):
1160 self._ranges1 = bt2.SignedIntegerRangeSet([(-10, -4), (18, 47)])
1161 self._ranges2 = bt2.SignedIntegerRangeSet([(-3, -3)])
1162 self._ranges3 = bt2.SignedIntegerRangeSet([(8, 16), (48, 99)])
1163 self._inval_ranges = bt2.UnsignedIntegerRangeSet([(8, 16), (48, 99)])
1164 self._selector_fc = self._tc.create_signed_integer_field_class()
1165
1166
1167 class _ArrayFieldClassTestCase:
1168 def test_attr_element_field_class(self):
1169 fc = self._create_array()
1170 self.assertIs(
1171 type(fc.element_field_class), bt2_field_class._SignedIntegerFieldClass
1172 )
1173
1174 def test_const_attr_element_field_class(self):
1175 fc = self._create_const_array()
1176 self.assertIs(
1177 type(fc.element_field_class), bt2_field_class._SignedIntegerFieldClassConst
1178 )
1179
1180
1181 class StaticArrayFieldClassTestCase(_ArrayFieldClassTestCase, unittest.TestCase):
1182 @staticmethod
1183 def _const_value_setter(field):
1184 field.value = [9] * 45
1185
1186 def _create_array(self):
1187 return self._tc.create_static_array_field_class(self._elem_fc, 45)
1188
1189 def _create_const_array(self):
1190 fc = self._tc.create_static_array_field_class(self._elem_fc, 45)
1191 return _create_const_field_class(self._tc, fc, self._const_value_setter)
1192
1193 def setUp(self):
1194 self._tc = get_default_trace_class()
1195 self._elem_fc = self._tc.create_signed_integer_field_class(23)
1196
1197 def test_create_default(self):
1198 fc = self._tc.create_static_array_field_class(self._elem_fc, 45)
1199 self.assertEqual(fc.element_field_class.addr, self._elem_fc.addr)
1200 self.assertEqual(fc.length, 45)
1201 self.assertEqual(len(fc.user_attributes), 0)
1202
1203 def test_create_invalid_elem_field_class(self):
1204 with self.assertRaises(TypeError):
1205 self._tc.create_static_array_field_class(object(), 45)
1206
1207 def test_create_invalid_length(self):
1208 with self.assertRaises(ValueError):
1209 self._tc.create_static_array_field_class(
1210 self._tc.create_string_field_class(), -17
1211 )
1212
1213 def test_create_invalid_length_type(self):
1214 with self.assertRaises(TypeError):
1215 self._tc.create_static_array_field_class(
1216 self._tc.create_string_field_class(), 'the length'
1217 )
1218
1219
1220 class DynamicArrayFieldClassTestCase(_ArrayFieldClassTestCase, unittest.TestCase):
1221 @staticmethod
1222 def _const_value_setter(field):
1223 field.value = []
1224
1225 def _create_array(self):
1226 return self._tc.create_dynamic_array_field_class(self._elem_fc)
1227
1228 def _create_const_array(self):
1229 fc = self._tc.create_dynamic_array_field_class(self._elem_fc)
1230 return _create_const_field_class(self._tc, fc, self._const_value_setter)
1231
1232 def setUp(self):
1233 self._tc = get_default_trace_class()
1234 self._elem_fc = self._tc.create_signed_integer_field_class(23)
1235 self._len_fc = self._tc.create_unsigned_integer_field_class(12)
1236
1237 def test_create_default(self):
1238 fc = self._tc.create_dynamic_array_field_class(self._elem_fc)
1239 self.assertEqual(fc.element_field_class.addr, self._elem_fc.addr)
1240 self.assertIsNone(fc.length_field_path, None)
1241 self.assertEqual(len(fc.user_attributes), 0)
1242
1243 def _create_field_class_for_field_path_test(self):
1244 # Create something a field class that is equivalent to:
1245 #
1246 # struct outer_struct_fc {
1247 # real foo;
1248 # struct inner_struct_fc {
1249 # string bar;
1250 # string baz;
1251 # uint12_t len;
1252 # uint23_t dyn_array[len];
1253 # } inner_struct[2];
1254 # };
1255
1256 fc = self._tc.create_dynamic_array_field_class(self._elem_fc, self._len_fc)
1257
1258 foo_fc = self._tc.create_real_field_class()
1259 bar_fc = self._tc.create_string_field_class()
1260 baz_fc = self._tc.create_string_field_class()
1261
1262 inner_struct_fc = self._tc.create_structure_field_class()
1263 inner_struct_fc.append_member('bar', bar_fc)
1264 inner_struct_fc.append_member('baz', baz_fc)
1265 inner_struct_fc.append_member('len', self._len_fc)
1266 inner_struct_fc.append_member('dyn_array', fc)
1267
1268 inner_struct_array_fc = self._tc.create_static_array_field_class(
1269 inner_struct_fc, 2
1270 )
1271
1272 outer_struct_fc = self._tc.create_structure_field_class()
1273 outer_struct_fc.append_member('foo', foo_fc)
1274 outer_struct_fc.append_member('inner_struct', inner_struct_array_fc)
1275
1276 # The path to the length field is resolved when the sequence is
1277 # actually used, for example in a packet context.
1278 self._tc.create_stream_class(
1279 packet_context_field_class=outer_struct_fc, supports_packets=True
1280 )
1281
1282 return fc
1283
1284 def test_field_path_len(self):
1285 fc = self._create_field_class_for_field_path_test()
1286 self.assertEqual(len(fc.length_field_path), 3)
1287
1288 def test_field_path_iter(self):
1289 fc = self._create_field_class_for_field_path_test()
1290 path_items = list(fc.length_field_path)
1291
1292 self.assertEqual(len(path_items), 3)
1293
1294 self.assertIsInstance(path_items[0], bt2._IndexFieldPathItem)
1295 self.assertEqual(path_items[0].index, 1)
1296
1297 self.assertIsInstance(path_items[1], bt2._CurrentArrayElementFieldPathItem)
1298
1299 self.assertIsInstance(path_items[2], bt2._IndexFieldPathItem)
1300 self.assertEqual(path_items[2].index, 2)
1301
1302 def test_field_path_root_scope(self):
1303 fc = self._create_field_class_for_field_path_test()
1304 self.assertEqual(
1305 fc.length_field_path.root_scope, bt2.FieldPathScope.PACKET_CONTEXT
1306 )
1307
1308 def test_create_invalid_field_class(self):
1309 with self.assertRaises(TypeError):
1310 self._tc.create_dynamic_array_field_class(object())
1311
1312 def test_create_invalid_length_type(self):
1313 with self.assertRaises(TypeError):
1314 self._tc.create_dynamic_array_field_class(
1315 self._tc.create_string_field_class(), 17
1316 )
1317
1318
1319 if __name__ == "__main__":
1320 unittest.main()
This page took 0.108195 seconds and 5 git commands to generate.