lib: make packets and packet messages optional, disabled by default
[babeltrace.git] / tests / bindings / python / bt2 / test_field_class.py
CommitLineData
d2d857a8
MJ
1#
2# Copyright (C) 2019 EfficiOS Inc.
3#
4# This program is free software; you can redistribute it and/or
5# modify it under the terms of the GNU General Public License
6# as published by the Free Software Foundation; only version 2
7# of the License.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program; if not, write to the Free Software
16# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17#
18
c4239792 19import bt2.field
b4f45851 20import unittest
b4f45851 21import bt2
d47b87ac 22from utils import get_default_trace_class
b4f45851
SM
23
24
d47b87ac
SM
25class _TestIntegerFieldClassProps:
26 def test_create_default(self):
27 fc = self._create_func()
28 self.assertEqual(fc.field_value_range, 64)
29 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.DECIMAL)
b4f45851 30
d47b87ac
SM
31 def test_create_range(self):
32 fc = self._create_func(field_value_range=35)
33 self.assertEqual(fc.field_value_range, 35)
b4f45851 34
d47b87ac
SM
35 fc = self._create_func(36)
36 self.assertEqual(fc.field_value_range, 36)
b4f45851 37
d47b87ac
SM
38 def test_create_invalid_range(self):
39 with self.assertRaises(TypeError):
40 self._create_func('yes')
b4f45851 41
d47b87ac
SM
42 with self.assertRaises(TypeError):
43 self._create_func(field_value_range='yes')
b4f45851 44
b4f45851 45 with self.assertRaises(ValueError):
d47b87ac 46 self._create_func(field_value_range=-2)
b4f45851 47
d47b87ac
SM
48 with self.assertRaises(ValueError):
49 self._create_func(field_value_range=0)
b4f45851 50
d47b87ac
SM
51 def test_create_base(self):
52 fc = self._create_func(preferred_display_base=bt2.IntegerDisplayBase.HEXADECIMAL)
53 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.HEXADECIMAL)
b4f45851 54
d47b87ac 55 def test_create_invalid_base_type(self):
b4f45851 56 with self.assertRaises(TypeError):
d47b87ac 57 self._create_func(preferred_display_base='yes')
b4f45851 58
d47b87ac
SM
59 def test_create_invalid_base_value(self):
60 with self.assertRaises(ValueError):
61 self._create_func(preferred_display_base=444)
b4f45851 62
d47b87ac
SM
63 def test_create_full(self):
64 fc = self._create_func(24, preferred_display_base=bt2.IntegerDisplayBase.OCTAL)
65 self.assertEqual(fc.field_value_range, 24)
66 self.assertEqual(fc.preferred_display_base, bt2.IntegerDisplayBase.OCTAL)
b4f45851
SM
67
68
d47b87ac
SM
69class IntegerFieldClassTestCase(_TestIntegerFieldClassProps, unittest.TestCase):
70 def setUp(self):
71 self._tc = get_default_trace_class()
72 self._create_func = self._tc.create_signed_integer_field_class
b4f45851 73
b4f45851 74
d47b87ac
SM
75class RealFieldClassTestCase(unittest.TestCase):
76 def setUp(self):
77 self._tc = get_default_trace_class()
b4f45851 78
d47b87ac
SM
79 def test_create_default(self):
80 fc = self._tc.create_real_field_class()
81 self.assertFalse(fc.is_single_precision)
b4f45851 82
d47b87ac
SM
83 def test_create_is_single_precision(self):
84 fc = self._tc.create_real_field_class(is_single_precision=True)
85 self.assertTrue(fc.is_single_precision)
86
87 def test_create_invalid_is_single_precision(self):
b4f45851 88 with self.assertRaises(TypeError):
d47b87ac 89 self._tc.create_real_field_class(is_single_precision='hohoho')
b4f45851 90
b4f45851 91
d47b87ac
SM
92# Converts an _EnumerationFieldClassMapping to a list of ranges:
93#
94# [(lower0, upper0), (lower1, upper1), ...]
95
96def enum_mapping_to_list(mapping):
97 return sorted([(x.lower, x.upper) for x in mapping])
b4f45851 98
b4f45851 99
d47b87ac
SM
100class EnumerationFieldClassTestCase(_TestIntegerFieldClassProps):
101 def setUp(self):
102 self._tc = get_default_trace_class()
103
104 def test_create_from_invalid_type(self):
b4f45851 105 with self.assertRaises(TypeError):
d47b87ac 106 self._create_func('coucou')
b4f45851 107
d47b87ac
SM
108 def test_add_mapping_simple(self):
109 self._fc.map_range('hello', 24)
110 mapping = self._fc['hello']
111 self.assertEqual(mapping.label, 'hello')
b4f45851 112
d47b87ac
SM
113 ranges = enum_mapping_to_list(mapping)
114 self.assertEqual(ranges, [(24, 24)])
b4f45851 115
d47b87ac
SM
116 def test_add_mapping_simple_kwargs(self):
117 self._fc.map_range(label='hello', lower=17, upper=23)
118 mapping = self._fc['hello']
119 self.assertEqual(mapping.label, 'hello')
b4f45851 120
d47b87ac
SM
121 ranges = enum_mapping_to_list(mapping)
122 self.assertEqual(ranges, [(17, 23)])
b4f45851 123
d47b87ac
SM
124 def test_add_mapping_range(self):
125 self._fc.map_range('hello', 21, 199)
126 mapping = self._fc['hello']
127 self.assertEqual(mapping.label, 'hello')
128
129 ranges = enum_mapping_to_list(mapping)
130 self.assertEqual(ranges, [(21, 199)])
131
132 def test_add_mapping_invalid_name(self):
b4f45851 133 with self.assertRaises(TypeError):
d47b87ac 134 self._fc.map_range(17, 21, 199)
b4f45851 135
d47b87ac
SM
136 def test_iadd(self):
137 enum_fc = self._tc.create_signed_enumeration_field_class(field_value_range=16)
138 enum_fc.map_range('c', 4, 5)
139 enum_fc.map_range('d', 6, 18)
140 enum_fc.map_range('e', 20, 27)
141 self._fc.map_range('a', 0, 2)
142 self._fc.map_range('b', 3)
143 self._fc += enum_fc
b4f45851 144
d47b87ac
SM
145 self.assertEqual(self._fc['a'].label, 'a')
146 self.assertEqual(enum_mapping_to_list(self._fc['a']), [(0, 2)])
b4f45851 147
d47b87ac
SM
148 self.assertEqual(self._fc['b'].label, 'b')
149 self.assertEqual(enum_mapping_to_list(self._fc['b']), [(3, 3)])
b4f45851 150
d47b87ac
SM
151 self.assertEqual(self._fc['c'].label, 'c')
152 self.assertEqual(enum_mapping_to_list(self._fc['c']), [(4, 5)])
b4f45851 153
d47b87ac
SM
154 self.assertEqual(self._fc['d'].label, 'd')
155 self.assertEqual(enum_mapping_to_list(self._fc['d']), [(6, 18)])
b4f45851 156
d47b87ac
SM
157 self.assertEqual(self._fc['e'].label, 'e')
158 self.assertEqual(enum_mapping_to_list(self._fc['e']), [(20, 27)])
b4f45851 159
d47b87ac
SM
160 def test_bool_op(self):
161 self.assertFalse(self._fc)
162 self._fc.map_range('a', 0)
163 self.assertTrue(self._fc)
b4f45851 164
d47b87ac
SM
165 def test_len(self):
166 self._fc.map_range('a', 0)
167 self._fc.map_range('b', 1)
168 self._fc.map_range('c', 2)
169 self.assertEqual(len(self._fc), 3)
b4f45851 170
d47b87ac
SM
171 def test_getitem(self):
172 self._fc.map_range('a', 0)
173 self._fc.map_range('b', 1, 3)
174 self._fc.map_range('a', 5)
175 self._fc.map_range('a', 17, 123)
176 self._fc.map_range('C', 5)
177 mapping = self._fc['a']
b4f45851 178
d47b87ac
SM
179 self.assertEqual(mapping.label, 'a')
180 ranges = enum_mapping_to_list(mapping)
181 self.assertEqual(ranges, [(0, 0), (5, 5), (17, 123)])
b4f45851 182
d47b87ac
SM
183 with self.assertRaises(KeyError):
184 self._fc['doesnotexist']
b4f45851 185
d47b87ac
SM
186 def test_contains(self):
187 self._fc.map_range('a', 0)
188 self._fc.map_range('a', 2, 23)
189 self._fc.map_range('b', 2)
190 self._fc.map_range('c', 5)
b4f45851 191
d47b87ac
SM
192 a_mapping = self._fc['a']
193 b_mapping = self._fc['b']
194 first_range = next(iter(a_mapping))
b4f45851 195
d47b87ac
SM
196 self.assertIn(first_range, a_mapping)
197 self.assertNotIn(first_range, b_mapping)
b4f45851 198
d47b87ac
SM
199 def test_iter(self):
200 self._fc.map_range('a', 1, 5)
201 self._fc.map_range('b', 10, 17)
202 self._fc.map_range('c', 20, 1504)
b4f45851 203
d47b87ac 204 self._fc.map_range('d', 22510, 99999)
b4f45851 205
d47b87ac
SM
206 # This exercises iteration.
207 labels = sorted(self._fc)
b4f45851 208
d47b87ac 209 self.assertEqual(labels, ['a', 'b', 'c', 'd'])
b4f45851 210
d47b87ac
SM
211 def test_find_by_value(self):
212 self._fc.map_range('a', 0)
213 self._fc.map_range('b', 1, 3)
214 self._fc.map_range('c', 5, 19)
215 self._fc.map_range('d', 8, 15)
216 self._fc.map_range('e', 10, 21)
217 self._fc.map_range('f', 0)
218 self._fc.map_range('g', 14)
b4f45851 219
d47b87ac 220 labels = self._fc.labels_by_value(14)
b4f45851 221
d47b87ac
SM
222 expected_labels = ['c', 'd', 'e', 'g']
223
224 self.assertTrue(all(label in labels for label in expected_labels))
225
226
227class UnsignedEnumerationFieldClassTestCase(EnumerationFieldClassTestCase, unittest.TestCase):
228 def setUp(self):
229 super().setUp()
230 self._create_func = self._tc.create_unsigned_enumeration_field_class
231 self._fc = self._tc.create_unsigned_enumeration_field_class()
b4f45851
SM
232
233 def test_add_mapping_invalid_signedness_lower(self):
234 with self.assertRaises(ValueError):
d47b87ac 235 self._fc.map_range('hello', -21, 199)
b4f45851
SM
236
237 def test_add_mapping_invalid_signedness_upper(self):
238 with self.assertRaises(ValueError):
d47b87ac 239 self._fc.map_range('hello', 21, -199)
b4f45851 240
b4f45851 241
d47b87ac
SM
242class SignedEnumerationFieldClassTestCase(EnumerationFieldClassTestCase, unittest.TestCase):
243 def setUp(self):
244 super().setUp()
245 self._create_func = self._tc.create_signed_enumeration_field_class
246 self._fc = self._tc.create_signed_enumeration_field_class()
b4f45851 247
d47b87ac
SM
248 def test_add_mapping_simple_signed(self):
249 self._fc.map_range('hello', -24)
250 mapping = self._fc['hello']
251 self.assertEqual(mapping.label, 'hello')
b4f45851 252
d47b87ac
SM
253 ranges = enum_mapping_to_list(mapping)
254 self.assertEqual(ranges, [(-24, -24)])
b4f45851 255
d47b87ac
SM
256 def test_add_mapping_range_signed(self):
257 self._fc.map_range('hello', -21, 199)
258 mapping = self._fc['hello']
259 self.assertEqual(mapping.label, 'hello')
260 ranges = enum_mapping_to_list(mapping)
261 self.assertEqual(ranges, [(-21, 199)])
b4f45851 262
b4f45851 263
d47b87ac 264class StringFieldClassTestCase(unittest.TestCase):
b4f45851 265 def setUp(self):
d47b87ac
SM
266 tc = get_default_trace_class()
267 self._fc = tc.create_string_field_class()
b4f45851
SM
268
269 def test_create_default(self):
d47b87ac 270 self.assertIsNotNone(self._fc)
b4f45851 271
b4f45851 272
d47b87ac
SM
273class _TestFieldContainer():
274 def test_append_element(self):
275 int_field_class = self._tc.create_signed_integer_field_class(32)
276 self._append_element_method(self._fc, 'int32', int_field_class)
b4f45851 277 field_class = self._fc['int32']
d47b87ac 278 self.assertEqual(field_class.addr, int_field_class.addr)
b4f45851 279
d47b87ac
SM
280 def test_append_elemenbt_kwargs(self):
281 int_field_class = self._tc.create_signed_integer_field_class(32)
282 self._append_element_method(self._fc, name='int32', field_class=int_field_class)
b4f45851 283 field_class = self._fc['int32']
d47b87ac
SM
284 self.assertEqual(field_class.addr, int_field_class.addr)
285
286 def test_append_element_invalid_name(self):
287 sub_fc = self._tc.create_string_field_class()
b4f45851 288
b4f45851 289 with self.assertRaises(TypeError):
d47b87ac 290 self._append_element_method(self._fc, 23, sub_fc)
b4f45851 291
d47b87ac 292 def test_append_element_invalid_field_class(self):
b4f45851 293 with self.assertRaises(TypeError):
d47b87ac 294 self._append_element_method(self._fc, 'yes', object())
b4f45851
SM
295
296 def test_iadd(self):
d47b87ac
SM
297 struct_fc = self._tc.create_structure_field_class()
298 c_field_class = self._tc.create_string_field_class()
299 d_field_class = self._tc.create_signed_enumeration_field_class(field_value_range=32)
300 e_field_class = self._tc.create_structure_field_class()
301 self._append_element_method(struct_fc, 'c_string', c_field_class)
302 self._append_element_method(struct_fc, 'd_enum', d_field_class)
303 self._append_element_method(struct_fc, 'e_struct', e_field_class)
304 a_field_class = self._tc.create_real_field_class()
305 b_field_class = self._tc.create_signed_integer_field_class(17)
306 self._append_element_method(self._fc, 'a_float', a_field_class)
307 self._append_element_method(self._fc, 'b_int', b_field_class)
b4f45851 308 self._fc += struct_fc
d47b87ac
SM
309 self.assertEqual(self._fc['a_float'].addr, a_field_class.addr)
310 self.assertEqual(self._fc['b_int'].addr, b_field_class.addr)
311 self.assertEqual(self._fc['c_string'].addr, c_field_class.addr)
312 self.assertEqual(self._fc['d_enum'].addr, d_field_class.addr)
313 self.assertEqual(self._fc['e_struct'].addr, e_field_class.addr)
b4f45851
SM
314
315 def test_bool_op(self):
316 self.assertFalse(self._fc)
d47b87ac 317 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
b4f45851
SM
318 self.assertTrue(self._fc)
319
320 def test_len(self):
d47b87ac
SM
321 fc = self._tc.create_string_field_class()
322 self._append_element_method(self._fc, 'a', fc)
323 self._append_element_method(self._fc, 'b', fc)
324 self._append_element_method(self._fc, 'c', fc)
b4f45851
SM
325 self.assertEqual(len(self._fc), 3)
326
327 def test_getitem(self):
d47b87ac
SM
328 a_fc = self._tc.create_signed_integer_field_class(32)
329 b_fc = self._tc.create_string_field_class()
330 c_fc = self._tc.create_real_field_class()
331 self._append_element_method(self._fc, 'a', a_fc)
332 self._append_element_method(self._fc, 'b', b_fc)
333 self._append_element_method(self._fc, 'c', c_fc)
334 self.assertEqual(self._fc['b'].addr, b_fc.addr)
b4f45851
SM
335
336 def test_getitem_invalid_key_type(self):
337 with self.assertRaises(TypeError):
338 self._fc[0]
339
340 def test_getitem_invalid_key(self):
341 with self.assertRaises(KeyError):
342 self._fc['no way']
343
344 def test_contains(self):
345 self.assertFalse('a' in self._fc)
d47b87ac 346 self._append_element_method(self._fc, 'a', self._tc.create_string_field_class())
b4f45851
SM
347 self.assertTrue('a' in self._fc)
348
349 def test_iter(self):
d47b87ac
SM
350 a_fc = self._tc.create_signed_integer_field_class(32)
351 b_fc = self._tc.create_string_field_class()
352 c_fc = self._tc.create_real_field_class()
b4f45851
SM
353 fields = (
354 ('a', a_fc),
355 ('b', b_fc),
356 ('c', c_fc),
357 )
358
359 for field in fields:
d47b87ac 360 self._append_element_method(self._fc, *field)
b4f45851
SM
361
362 for (name, fc_field_class), field in zip(self._fc.items(), fields):
363 self.assertEqual(name, field[0])
d47b87ac 364 self.assertEqual(fc_field_class.addr, field[1].addr)
b4f45851
SM
365
366 def test_at_index(self):
d47b87ac
SM
367 a_fc = self._tc.create_signed_integer_field_class(32)
368 b_fc = self._tc.create_string_field_class()
369 c_fc = self._tc.create_real_field_class()
370 self._append_element_method(self._fc, 'c', c_fc)
371 self._append_element_method(self._fc, 'a', a_fc)
372 self._append_element_method(self._fc, 'b', b_fc)
373 self.assertEqual(self._at_index_method(self._fc, 1).addr, a_fc.addr)
b4f45851
SM
374
375 def test_at_index_invalid(self):
d47b87ac 376 self._append_element_method(self._fc, 'c', self._tc.create_signed_integer_field_class(32))
b4f45851
SM
377
378 with self.assertRaises(TypeError):
d47b87ac 379 self._at_index_method(self._fc, 'yes')
b4f45851
SM
380
381 def test_at_index_out_of_bounds_after(self):
d47b87ac 382 self._append_element_method(self._fc, 'c', self._tc.create_signed_integer_field_class(32))
b4f45851
SM
383
384 with self.assertRaises(IndexError):
d47b87ac 385 self._at_index_method(self._fc, len(self._fc))
b4f45851
SM
386
387
b4f45851
SM
388class StructureFieldClassTestCase(_TestFieldContainer, unittest.TestCase):
389 def setUp(self):
d47b87ac
SM
390 self._append_element_method = bt2.field_class._StructureFieldClass.append_member
391 self._at_index_method = bt2.field_class._StructureFieldClass.member_at_index
392 self._tc = get_default_trace_class()
393 self._fc = self._tc.create_structure_field_class()
394
395 def test_create_default(self):
396 self.assertIsNotNone(self._fc)
b4f45851 397
d47b87ac
SM
398
399class VariantFieldClassTestCase(_TestFieldContainer, unittest.TestCase):
400 def setUp(self):
401 self._append_element_method = bt2.field_class._VariantFieldClass.append_option
402 self._at_index_method = bt2.field_class._VariantFieldClass.option_at_index
403 self._tc = get_default_trace_class()
404 self._fc = self._tc.create_variant_field_class()
b4f45851
SM
405
406 def test_create_default(self):
d47b87ac 407 fc = self._tc.create_variant_field_class()
b4f45851 408
d47b87ac 409 self.assertIsNone(fc.selector_field_path)
b4f45851 410
d47b87ac
SM
411 def _create_field_class_for_field_path_test(self):
412 # Create something equivalent to:
413 #
414 # struct outer_struct_fc {
415 # real foo;
416 # struct inner_struct_fc {
417 # enum { first = 1, second = 2..434 } selector;
418 # string bar;
419 # string baz;
420 # variant<selector> {
421 # real a;
422 # int21_t b;
423 # uint34_t c;
424 # } variant;
425 # } inner_struct[2];
426 # };
427 selector_fc = self._tc.create_unsigned_enumeration_field_class(field_value_range=42)
428 selector_fc.map_range('first', 1)
429 selector_fc.map_range('second', 2, 434)
b4f45851 430
d47b87ac
SM
431 fc = self._tc.create_variant_field_class(selector_fc)
432 fc.append_option('a', self._tc.create_real_field_class())
433 fc.append_option('b', self._tc.create_signed_integer_field_class(21))
434 fc.append_option('c', self._tc.create_unsigned_integer_field_class(34))
b4f45851 435
d47b87ac
SM
436 foo_fc = self._tc.create_real_field_class()
437 bar_fc = self._tc.create_string_field_class()
438 baz_fc = self._tc.create_string_field_class()
b4f45851 439
d47b87ac
SM
440 inner_struct_fc = self._tc.create_structure_field_class()
441 inner_struct_fc.append_member('selector', selector_fc)
442 inner_struct_fc.append_member('bar', bar_fc)
443 inner_struct_fc.append_member('baz', baz_fc)
444 inner_struct_fc.append_member('variant', fc)
b4f45851 445
d47b87ac 446 inner_struct_array_fc = self._tc.create_static_array_field_class(inner_struct_fc, 2)
b4f45851 447
d47b87ac
SM
448 outer_struct_fc = self._tc.create_structure_field_class()
449 outer_struct_fc.append_member('foo', foo_fc)
450 outer_struct_fc.append_member('inner_struct', inner_struct_array_fc)
b4f45851 451
d47b87ac
SM
452 # The path to the selector field is resolved when the sequence is
453 # actually used, for example in a packet context.
26fc5aed 454 self._tc.create_stream_class(supports_packets=True, packet_context_field_class=outer_struct_fc)
b4f45851 455
d47b87ac 456 return fc
b4f45851 457
d47b87ac
SM
458 def test_selector_field_path_length(self):
459 fc = self._create_field_class_for_field_path_test()
460 self.assertEqual(len(fc.selector_field_path), 3)
b4f45851 461
d47b87ac
SM
462 def test_selector_field_path_iter(self):
463 fc = self._create_field_class_for_field_path_test()
464 path_items = list(fc.selector_field_path)
b4f45851 465
d47b87ac 466 self.assertEqual(len(path_items), 3)
b4f45851 467
d47b87ac
SM
468 self.assertIsInstance(path_items[0], bt2.field_path._IndexFieldPathItem)
469 self.assertEqual(path_items[0].index, 1)
b4f45851 470
d47b87ac 471 self.assertIsInstance(path_items[1], bt2.field_path._CurrentArrayElementFieldPathItem)
b4f45851 472
d47b87ac
SM
473 self.assertIsInstance(path_items[2], bt2.field_path._IndexFieldPathItem)
474 self.assertEqual(path_items[2].index, 0)
b4f45851 475
d47b87ac
SM
476 def test_selector_field_path_root_scope(self):
477 fc = self._create_field_class_for_field_path_test()
478 self.assertEqual(fc.selector_field_path.root_scope, bt2.field_path.Scope.PACKET_CONTEXT)
b4f45851 479
d47b87ac
SM
480
481class StaticArrayFieldClassTestCase(unittest.TestCase):
482 def setUp(self):
483 self._tc = get_default_trace_class()
484 self._elem_fc = self._tc.create_signed_integer_field_class(23)
b4f45851
SM
485
486 def test_create_default(self):
d47b87ac
SM
487 fc = self._tc.create_static_array_field_class(self._elem_fc, 45)
488 self.assertEqual(fc.element_field_class.addr, self._elem_fc.addr)
489 self.assertEqual(fc.length, 45)
b4f45851 490
d47b87ac 491 def test_create_invalid_elem_field_class(self):
b4f45851 492 with self.assertRaises(TypeError):
d47b87ac 493 self._tc.create_static_array_field_class(object(), 45)
b4f45851
SM
494
495 def test_create_invalid_length(self):
496 with self.assertRaises(ValueError):
d47b87ac 497 self._tc.create_static_array_field_class(self._tc.create_string_field_class(), -17)
b4f45851
SM
498
499 def test_create_invalid_length_type(self):
500 with self.assertRaises(TypeError):
d47b87ac
SM
501 self._tc.create_static_array_field_class(self._tc.create_string_field_class(), 'the length')
502
503
504class DynamicArrayFieldClassTestCase(unittest.TestCase):
505 def setUp(self):
506 self._tc = get_default_trace_class()
507 self._elem_fc = self._tc.create_signed_integer_field_class(23)
508 self._len_fc = self._tc.create_unsigned_integer_field_class(12)
b4f45851 509
d47b87ac
SM
510 def test_create_default(self):
511 fc = self._tc.create_dynamic_array_field_class(self._elem_fc)
512 self.assertEqual(fc.element_field_class.addr, self._elem_fc.addr)
513 self.assertIsNone(fc.length_field_path, None)
b4f45851 514
d47b87ac
SM
515 def _create_field_class_for_field_path_test(self):
516 # Create something a field class that is equivalent to:
517 #
518 # struct outer_struct_fc {
519 # real foo;
520 # struct inner_struct_fc {
521 # string bar;
522 # string baz;
523 # uint12_t len;
524 # uint23_t dyn_array[len];
525 # } inner_struct[2];
526 # };
b4f45851 527
d47b87ac 528 fc = self._tc.create_dynamic_array_field_class(self._elem_fc, self._len_fc)
b4f45851 529
d47b87ac
SM
530 foo_fc = self._tc.create_real_field_class()
531 bar_fc = self._tc.create_string_field_class()
532 baz_fc = self._tc.create_string_field_class()
b4f45851 533
d47b87ac
SM
534 inner_struct_fc = self._tc.create_structure_field_class()
535 inner_struct_fc.append_member('bar', bar_fc)
536 inner_struct_fc.append_member('baz', baz_fc)
537 inner_struct_fc.append_member('len', self._len_fc)
538 inner_struct_fc.append_member('dyn_array', fc)
b4f45851 539
d47b87ac
SM
540 inner_struct_array_fc = self._tc.create_static_array_field_class(inner_struct_fc, 2)
541
542 outer_struct_fc = self._tc.create_structure_field_class()
543 outer_struct_fc.append_member('foo', foo_fc)
544 outer_struct_fc.append_member('inner_struct', inner_struct_array_fc)
545
546 # The path to the length field is resolved when the sequence is
547 # actually used, for example in a packet context.
26fc5aed
PP
548 self._tc.create_stream_class(packet_context_field_class=outer_struct_fc,
549 supports_packets=True)
d47b87ac
SM
550
551 return fc
552
553 def test_field_path_len(self):
554 fc = self._create_field_class_for_field_path_test()
555 self.assertEqual(len(fc.length_field_path), 3)
556
557 def test_field_path_iter(self):
558 fc = self._create_field_class_for_field_path_test()
559 path_items = list(fc.length_field_path)
560
561 self.assertEqual(len(path_items), 3)
562
563 self.assertIsInstance(path_items[0], bt2.field_path._IndexFieldPathItem)
564 self.assertEqual(path_items[0].index, 1)
565
566 self.assertIsInstance(path_items[1], bt2.field_path._CurrentArrayElementFieldPathItem)
567
568 self.assertIsInstance(path_items[2], bt2.field_path._IndexFieldPathItem)
569 self.assertEqual(path_items[2].index, 2)
570
571 def test_field_path_root_scope(self):
572 fc = self._create_field_class_for_field_path_test()
573 self.assertEqual(fc.length_field_path.root_scope, bt2.field_path.Scope.PACKET_CONTEXT)
b4f45851
SM
574
575 def test_create_invalid_field_class(self):
576 with self.assertRaises(TypeError):
d47b87ac 577 self._tc.create_dynamic_array_field_class(object())
b4f45851
SM
578
579 def test_create_invalid_length_type(self):
580 with self.assertRaises(TypeError):
d47b87ac 581 self._tc.create_dynamic_array_field_class(self._tc.create_string_field_class(), 17)
b4f45851 582
b4f45851 583
d47b87ac
SM
584if __name__ == "__main__":
585 unittest.main()
This page took 0.055398 seconds and 4 git commands to generate.