test_value.py: make `BoolValueTestCase` inherit `_TestNumericValue`
[babeltrace.git] / tests / bindings / python / bt2 / test_field.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
9cf643d1
PP
19from functools import partial, partialmethod
20import operator
21import unittest
9cf643d1
PP
22import math
23import copy
b0bdda42 24import itertools
9cf643d1 25import bt2
1eccc498 26from utils import get_default_trace_class
9cf643d1
PP
27
28
29_COMP_BINOPS = (
30 operator.eq,
31 operator.ne,
32)
33
34
1eccc498
SM
35# Create and return a stream with the field classes part of its stream packet
36# context.
37#
38# The stream is part of a dummy trace created from trace class `tc`.
39
40def _create_stream(tc, ctx_field_classes):
41 packet_context_fc = tc.create_structure_field_class()
42 for name, fc in ctx_field_classes:
43 packet_context_fc.append_member(name, fc)
44
45 trace = tc()
46 stream_class = tc.create_stream_class(packet_context_field_class=packet_context_fc)
47
48 stream = trace.create_stream(stream_class)
49 return stream
50
51
52# Create a field of the given field class.
53#
54# The field is part of a dummy stream, itself part of a dummy trace created
55# from trace class `tc`.
56
57def _create_field(tc, field_class):
58 field_name = 'field'
59 stream = _create_stream(tc, [(field_name, field_class)])
60 packet = stream.create_packet()
61 return packet.context_field[field_name]
62
63
64# Create a field of type string.
65#
66# The field is part of a dummy stream, itself part of a dummy trace created
67# from trace class `tc`. It is made out of a dummy string field class.
68
69def _create_string_field(tc):
70 field_name = 'string_field'
71 stream = _create_stream(tc, [(field_name, tc.create_string_field_class())])
72 packet = stream.create_packet()
73 return packet.context_field[field_name]
74
75
76# Create a field of type static array of ints.
77#
78# The field is part of a dummy stream, itself part of a dummy trace created
79# from trace class `tc`. It is made out of a dummy static array field class,
80# with a dummy integer field class as element class.
81
82def _create_int_array_field(tc, length):
83 elem_fc = tc.create_signed_integer_field_class(32)
84 fc = tc.create_static_array_field_class(elem_fc, length)
85 field_name = 'int_array'
86 stream = _create_stream(tc, [(field_name, fc)])
87 packet = stream.create_packet()
88 return packet.context_field[field_name]
89
90
91# Create a field of type dynamic array of ints.
92#
93# The field is part of a dummy stream, itself part of a dummy trace created
94# from trace class `tc`. It is made out of a dummy static array field class,
95# with a dummy integer field class as element and length classes.
96
97def _create_dynamic_array(tc):
98 elem_fc = tc.create_signed_integer_field_class(32)
99 len_fc = tc.create_signed_integer_field_class(32)
100 fc = tc.create_dynamic_array_field_class(elem_fc)
101 field_name = 'int_dyn_array'
102 stream = _create_stream(tc, [('thelength', len_fc), (field_name, fc)])
103 packet = stream.create_packet()
104 packet.context_field[field_name].length = 3
105 return packet.context_field[field_name]
106
107
108# Create a field of type array of (empty) structures.
109#
110# The field is part of a dummy stream, itself part of a dummy trace created
111# from trace class `tc`. It is made out of a dummy static array field class,
112# with a dummy struct field class as element class.
113
114def _create_struct_array_field(tc, length):
115 elem_fc = tc.create_structure_field_class()
116 fc = tc.create_static_array_field_class(elem_fc, length)
117 field_name = 'struct_array'
118 stream = _create_stream(tc, [(field_name, fc)])
119 packet = stream.create_packet()
120 return packet.context_field[field_name]
121
122
21368027
PP
123# Base class for numeric field test cases.
124#
125# To be compatible with this base class, a derived class must, in its
126# setUp() method:
127#
128# * Set `self._def` to a field object with an arbitrary value.
129# * Set `self._def_value` to the equivalent value of `self._def`.
1eccc498 130class _TestNumericField:
21368027
PP
131 # Tries the binary operation `op`:
132 #
133 # 1. Between `self._def`, which is a field object, and `rhs`.
134 # 2. Between `self._def_value`, which is the raw value of
135 # `self._def`, and `rhs`.
136 #
137 # Returns the results of 1. and 2.
138 #
139 # If there's an exception while performing 1. or 2., asserts that
140 # both operations raised exceptions, that both exceptions have the
141 # same type, and returns `None` for both results.
9cf643d1 142 def _binop(self, op, rhs):
21368027
PP
143 type_rexc = None
144 type_rvexc = None
9cf643d1
PP
145 comp_value = rhs
146
21368027 147 # try with field object
9cf643d1
PP
148 try:
149 r = op(self._def, rhs)
150 except Exception as e:
21368027 151 type_rexc = type(e)
9cf643d1 152
21368027 153 # try with value
9cf643d1
PP
154 try:
155 rv = op(self._def_value, comp_value)
156 except Exception as e:
21368027 157 type_rvexc = type(e)
9cf643d1 158
21368027 159 if type_rexc is not None or type_rvexc is not None:
9cf643d1
PP
160 # at least one of the operations raised an exception: in
161 # this case both operations should have raised the same
162 # type of exception (division by zero, bit shift with a
163 # floating point number operand, etc.)
21368027 164 self.assertIs(type_rexc, type_rvexc)
9cf643d1
PP
165 return None, None
166
167 return r, rv
168
21368027
PP
169 # Tries the unary operation `op`:
170 #
171 # 1. On `self._def`, which is a field object.
172 # 2. On `self._def_value`, which is the value of `self._def`.
173 #
174 # Returns the results of 1. and 2.
175 #
176 # If there's an exception while performing 1. or 2., asserts that
177 # both operations raised exceptions, that both exceptions have the
178 # same type, and returns `None` for both results.
9cf643d1 179 def _unaryop(self, op):
21368027
PP
180 type_rexc = None
181 type_rvexc = None
9cf643d1 182
21368027 183 # try with field object
9cf643d1
PP
184 try:
185 r = op(self._def)
186 except Exception as e:
21368027 187 type_rexc = type(e)
9cf643d1 188
21368027 189 # try with value
9cf643d1
PP
190 try:
191 rv = op(self._def_value)
192 except Exception as e:
21368027 193 type_rvexc = type(e)
9cf643d1 194
21368027 195 if type_rexc is not None or type_rvexc is not None:
9cf643d1
PP
196 # at least one of the operations raised an exception: in
197 # this case both operations should have raised the same
198 # type of exception (division by zero, bit shift with a
199 # floating point number operand, etc.)
21368027 200 self.assertIs(type_rexc, type_rvexc)
9cf643d1
PP
201 return None, None
202
203 return r, rv
204
21368027
PP
205 # Tests that the unary operation `op` gives results with the same
206 # type for both `self._def` and `self._def_value`.
9cf643d1
PP
207 def _test_unaryop_type(self, op):
208 r, rv = self._unaryop(op)
209
210 if r is None:
211 return
212
213 self.assertIsInstance(r, type(rv))
214
21368027
PP
215 # Tests that the unary operation `op` gives results with the same
216 # value for both `self._def` and `self._def_value`. This uses the
217 # __eq__() operator of `self._def`.
9cf643d1
PP
218 def _test_unaryop_value(self, op):
219 r, rv = self._unaryop(op)
220
221 if r is None:
222 return
223
224 self.assertEqual(r, rv)
225
21368027
PP
226 # Tests that the unary operation `op`, when applied to `self._def`,
227 # does not change its underlying BT object address.
9cf643d1
PP
228 def _test_unaryop_addr_same(self, op):
229 addr_before = self._def.addr
230 self._unaryop(op)
231 self.assertEqual(self._def.addr, addr_before)
232
21368027
PP
233 # Tests that the unary operation `op`, when applied to `self._def`,
234 # does not change its value.
9cf643d1 235 def _test_unaryop_value_same(self, op):
e1c6bebd 236 value_before = copy.copy(self._def_value)
9cf643d1 237 self._unaryop(op)
e1c6bebd 238 self.assertEqual(self._def, value_before)
9cf643d1 239
21368027
PP
240 # Tests that the binary operation `op` gives results with the same
241 # type for both `self._def` and `self._def_value`.
9cf643d1
PP
242 def _test_binop_type(self, op, rhs):
243 r, rv = self._binop(op, rhs)
244
245 if r is None:
246 return
247
248 if op in _COMP_BINOPS:
249 # __eq__() and __ne__() always return a 'bool' object
250 self.assertIsInstance(r, bool)
251 else:
252 self.assertIsInstance(r, type(rv))
253
21368027
PP
254 # Tests that the binary operation `op` gives results with the same
255 # value for both `self._def` and `self._def_value`. This uses the
256 # __eq__() operator of `self._def`.
9cf643d1
PP
257 def _test_binop_value(self, op, rhs):
258 r, rv = self._binop(op, rhs)
259
260 if r is None:
261 return
262
263 self.assertEqual(r, rv)
264
21368027
PP
265 # Tests that the binary operation `op`, when applied to `self._def`,
266 # does not change its underlying BT object address.
9cf643d1
PP
267 def _test_binop_lhs_addr_same(self, op, rhs):
268 addr_before = self._def.addr
269 r, rv = self._binop(op, rhs)
270 self.assertEqual(self._def.addr, addr_before)
271
21368027
PP
272 # Tests that the binary operation `op`, when applied to `self._def`,
273 # does not change its value.
1eccc498 274 @unittest.skip('copy is not implemented')
9cf643d1 275 def _test_binop_lhs_value_same(self, op, rhs):
e1c6bebd 276 value_before = copy.copy(self._def)
9cf643d1 277 r, rv = self._binop(op, rhs)
e1c6bebd 278 self.assertEqual(self._def, value_before)
9cf643d1 279
21368027
PP
280 # The methods below which take the `test_cb` and/or `op` parameters
281 # are meant to be used with one of the _test_binop_*() functions
282 # above as `test_cb` and a binary operator function as `op`.
283 #
284 # For example:
285 #
286 # self._test_binop_rhs_pos_int(self._test_binop_value,
287 # operator.add)
288 #
289 # This tests that a numeric field object added to a positive integer
290 # value gives a result with the expected value.
291 #
292 # `vint` and `vfloat` mean a signed integer value object and a real
293 # value object.
294
9cf643d1
PP
295 def _test_binop_invalid_unknown(self, op):
296 if op in _COMP_BINOPS:
297 self.skipTest('not testing')
298
299 class A:
300 pass
301
302 with self.assertRaises(TypeError):
303 op(self._def, A())
304
305 def _test_binop_invalid_none(self, op):
306 if op in _COMP_BINOPS:
307 self.skipTest('not testing')
308
309 with self.assertRaises(TypeError):
310 op(self._def, None)
311
9cf643d1
PP
312 def _test_binop_rhs_false(self, test_cb, op):
313 test_cb(op, False)
314
315 def _test_binop_rhs_true(self, test_cb, op):
316 test_cb(op, True)
317
318 def _test_binop_rhs_pos_int(self, test_cb, op):
319 test_cb(op, 2)
320
321 def _test_binop_rhs_neg_int(self, test_cb, op):
322 test_cb(op, -23)
323
324 def _test_binop_rhs_zero_int(self, test_cb, op):
325 test_cb(op, 0)
326
327 def _test_binop_rhs_pos_vint(self, test_cb, op):
328 test_cb(op, bt2.create_value(2))
329
330 def _test_binop_rhs_neg_vint(self, test_cb, op):
331 test_cb(op, bt2.create_value(-23))
332
333 def _test_binop_rhs_zero_vint(self, test_cb, op):
334 test_cb(op, bt2.create_value(0))
335
336 def _test_binop_rhs_pos_float(self, test_cb, op):
337 test_cb(op, 2.2)
338
339 def _test_binop_rhs_neg_float(self, test_cb, op):
340 test_cb(op, -23.4)
341
342 def _test_binop_rhs_zero_float(self, test_cb, op):
343 test_cb(op, 0.0)
344
345 def _test_binop_rhs_pos_vfloat(self, test_cb, op):
346 test_cb(op, bt2.create_value(2.2))
347
348 def _test_binop_rhs_neg_vfloat(self, test_cb, op):
349 test_cb(op, bt2.create_value(-23.4))
350
351 def _test_binop_rhs_zero_vfloat(self, test_cb, op):
352 test_cb(op, bt2.create_value(0.0))
353
354 def _test_binop_type_false(self, op):
355 self._test_binop_rhs_false(self._test_binop_type, op)
356
357 def _test_binop_type_true(self, op):
358 self._test_binop_rhs_true(self._test_binop_type, op)
359
360 def _test_binop_type_pos_int(self, op):
361 self._test_binop_rhs_pos_int(self._test_binop_type, op)
362
363 def _test_binop_type_neg_int(self, op):
364 self._test_binop_rhs_neg_int(self._test_binop_type, op)
365
366 def _test_binop_type_zero_int(self, op):
367 self._test_binop_rhs_zero_int(self._test_binop_type, op)
368
369 def _test_binop_type_pos_vint(self, op):
370 self._test_binop_rhs_pos_vint(self._test_binop_type, op)
371
372 def _test_binop_type_neg_vint(self, op):
373 self._test_binop_rhs_neg_vint(self._test_binop_type, op)
374
375 def _test_binop_type_zero_vint(self, op):
376 self._test_binop_rhs_zero_vint(self._test_binop_type, op)
377
378 def _test_binop_type_pos_float(self, op):
379 self._test_binop_rhs_pos_float(self._test_binop_type, op)
380
381 def _test_binop_type_neg_float(self, op):
382 self._test_binop_rhs_neg_float(self._test_binop_type, op)
383
384 def _test_binop_type_zero_float(self, op):
385 self._test_binop_rhs_zero_float(self._test_binop_type, op)
386
387 def _test_binop_type_pos_vfloat(self, op):
388 self._test_binop_rhs_pos_vfloat(self._test_binop_type, op)
389
390 def _test_binop_type_neg_vfloat(self, op):
391 self._test_binop_rhs_neg_vfloat(self._test_binop_type, op)
392
393 def _test_binop_type_zero_vfloat(self, op):
394 self._test_binop_rhs_zero_vfloat(self._test_binop_type, op)
395
396 def _test_binop_value_false(self, op):
397 self._test_binop_rhs_false(self._test_binop_value, op)
398
399 def _test_binop_value_true(self, op):
400 self._test_binop_rhs_true(self._test_binop_value, op)
401
402 def _test_binop_value_pos_int(self, op):
403 self._test_binop_rhs_pos_int(self._test_binop_value, op)
404
405 def _test_binop_value_neg_int(self, op):
406 self._test_binop_rhs_neg_int(self._test_binop_value, op)
407
408 def _test_binop_value_zero_int(self, op):
409 self._test_binop_rhs_zero_int(self._test_binop_value, op)
410
411 def _test_binop_value_pos_vint(self, op):
412 self._test_binop_rhs_pos_vint(self._test_binop_value, op)
413
414 def _test_binop_value_neg_vint(self, op):
415 self._test_binop_rhs_neg_vint(self._test_binop_value, op)
416
417 def _test_binop_value_zero_vint(self, op):
418 self._test_binop_rhs_zero_vint(self._test_binop_value, op)
419
420 def _test_binop_value_pos_float(self, op):
421 self._test_binop_rhs_pos_float(self._test_binop_value, op)
422
423 def _test_binop_value_neg_float(self, op):
424 self._test_binop_rhs_neg_float(self._test_binop_value, op)
425
426 def _test_binop_value_zero_float(self, op):
427 self._test_binop_rhs_zero_float(self._test_binop_value, op)
428
429 def _test_binop_value_pos_vfloat(self, op):
430 self._test_binop_rhs_pos_vfloat(self._test_binop_value, op)
431
432 def _test_binop_value_neg_vfloat(self, op):
433 self._test_binop_rhs_neg_vfloat(self._test_binop_value, op)
434
435 def _test_binop_value_zero_vfloat(self, op):
436 self._test_binop_rhs_zero_vfloat(self._test_binop_value, op)
437
438 def _test_binop_lhs_addr_same_false(self, op):
439 self._test_binop_rhs_false(self._test_binop_lhs_addr_same, op)
440
441 def _test_binop_lhs_addr_same_true(self, op):
442 self._test_binop_rhs_true(self._test_binop_lhs_addr_same, op)
443
444 def _test_binop_lhs_addr_same_pos_int(self, op):
445 self._test_binop_rhs_pos_int(self._test_binop_lhs_addr_same, op)
446
447 def _test_binop_lhs_addr_same_neg_int(self, op):
448 self._test_binop_rhs_neg_int(self._test_binop_lhs_addr_same, op)
449
450 def _test_binop_lhs_addr_same_zero_int(self, op):
451 self._test_binop_rhs_zero_int(self._test_binop_lhs_addr_same, op)
452
453 def _test_binop_lhs_addr_same_pos_vint(self, op):
454 self._test_binop_rhs_pos_vint(self._test_binop_lhs_addr_same, op)
455
456 def _test_binop_lhs_addr_same_neg_vint(self, op):
457 self._test_binop_rhs_neg_vint(self._test_binop_lhs_addr_same, op)
458
459 def _test_binop_lhs_addr_same_zero_vint(self, op):
460 self._test_binop_rhs_zero_vint(self._test_binop_lhs_addr_same, op)
461
462 def _test_binop_lhs_addr_same_pos_float(self, op):
463 self._test_binop_rhs_pos_float(self._test_binop_lhs_addr_same, op)
464
465 def _test_binop_lhs_addr_same_neg_float(self, op):
466 self._test_binop_rhs_neg_float(self._test_binop_lhs_addr_same, op)
467
468 def _test_binop_lhs_addr_same_zero_float(self, op):
469 self._test_binop_rhs_zero_float(self._test_binop_lhs_addr_same, op)
470
471 def _test_binop_lhs_addr_same_pos_vfloat(self, op):
472 self._test_binop_rhs_pos_vfloat(self._test_binop_lhs_addr_same, op)
473
474 def _test_binop_lhs_addr_same_neg_vfloat(self, op):
475 self._test_binop_rhs_neg_vfloat(self._test_binop_lhs_addr_same, op)
476
477 def _test_binop_lhs_addr_same_zero_vfloat(self, op):
478 self._test_binop_rhs_zero_vfloat(self._test_binop_lhs_addr_same, op)
479
480 def _test_binop_lhs_value_same_false(self, op):
481 self._test_binop_rhs_false(self._test_binop_lhs_value_same, op)
482
483 def _test_binop_lhs_value_same_true(self, op):
484 self._test_binop_rhs_true(self._test_binop_lhs_value_same, op)
485
486 def _test_binop_lhs_value_same_pos_int(self, op):
487 self._test_binop_rhs_pos_int(self._test_binop_lhs_value_same, op)
488
489 def _test_binop_lhs_value_same_neg_int(self, op):
490 self._test_binop_rhs_neg_int(self._test_binop_lhs_value_same, op)
491
492 def _test_binop_lhs_value_same_zero_int(self, op):
493 self._test_binop_rhs_zero_int(self._test_binop_lhs_value_same, op)
494
495 def _test_binop_lhs_value_same_pos_vint(self, op):
496 self._test_binop_rhs_pos_vint(self._test_binop_lhs_value_same, op)
497
498 def _test_binop_lhs_value_same_neg_vint(self, op):
499 self._test_binop_rhs_neg_vint(self._test_binop_lhs_value_same, op)
500
501 def _test_binop_lhs_value_same_zero_vint(self, op):
502 self._test_binop_rhs_zero_vint(self._test_binop_lhs_value_same, op)
503
504 def _test_binop_lhs_value_same_pos_float(self, op):
505 self._test_binop_rhs_pos_float(self._test_binop_lhs_value_same, op)
506
507 def _test_binop_lhs_value_same_neg_float(self, op):
508 self._test_binop_rhs_neg_float(self._test_binop_lhs_value_same, op)
509
510 def _test_binop_lhs_value_same_zero_float(self, op):
511 self._test_binop_rhs_zero_float(self._test_binop_lhs_value_same, op)
512
513 def _test_binop_lhs_value_same_pos_vfloat(self, op):
514 self._test_binop_rhs_pos_vfloat(self._test_binop_lhs_value_same, op)
515
516 def _test_binop_lhs_value_same_neg_vfloat(self, op):
517 self._test_binop_rhs_neg_vfloat(self._test_binop_lhs_value_same, op)
518
519 def _test_binop_lhs_value_same_zero_vfloat(self, op):
520 self._test_binop_rhs_zero_vfloat(self._test_binop_lhs_value_same, op)
521
9cf643d1
PP
522 def test_bool_op(self):
523 self.assertEqual(bool(self._def), bool(self._def_value))
524
525 def test_int_op(self):
526 self.assertEqual(int(self._def), int(self._def_value))
527
528 def test_float_op(self):
529 self.assertEqual(float(self._def), float(self._def_value))
530
531 def test_complex_op(self):
532 self.assertEqual(complex(self._def), complex(self._def_value))
533
534 def test_str_op(self):
535 self.assertEqual(str(self._def), str(self._def_value))
536
537 def test_eq_none(self):
1eccc498
SM
538 # Ignore this lint error:
539 # E711 comparison to None should be 'if cond is None:'
540 # since this is what we want to test (even though not good practice).
541 self.assertFalse(self._def == None) # noqa: E711
9cf643d1
PP
542
543 def test_ne_none(self):
1eccc498
SM
544 # Ignore this lint error:
545 # E711 comparison to None should be 'if cond is not None:'
546 # since this is what we want to test (even though not good practice).
547 self.assertTrue(self._def != None) # noqa: E711
742e4747 548
9cf643d1 549
21368027
PP
550# This is a list of binary operators used for
551# _inject_numeric_testing_methods().
552#
553# Each entry is a pair of binary operator name (used as part of the
554# created testing method's name) and operator function.
9cf643d1
PP
555_BINOPS = (
556 ('lt', operator.lt),
557 ('le', operator.le),
558 ('eq', operator.eq),
559 ('ne', operator.ne),
560 ('ge', operator.ge),
561 ('gt', operator.gt),
562 ('add', operator.add),
563 ('radd', lambda a, b: operator.add(b, a)),
564 ('and', operator.and_),
565 ('rand', lambda a, b: operator.and_(b, a)),
566 ('floordiv', operator.floordiv),
567 ('rfloordiv', lambda a, b: operator.floordiv(b, a)),
568 ('lshift', operator.lshift),
569 ('rlshift', lambda a, b: operator.lshift(b, a)),
570 ('mod', operator.mod),
571 ('rmod', lambda a, b: operator.mod(b, a)),
572 ('mul', operator.mul),
573 ('rmul', lambda a, b: operator.mul(b, a)),
574 ('or', operator.or_),
575 ('ror', lambda a, b: operator.or_(b, a)),
576 ('pow', operator.pow),
577 ('rpow', lambda a, b: operator.pow(b, a)),
578 ('rshift', operator.rshift),
579 ('rrshift', lambda a, b: operator.rshift(b, a)),
580 ('sub', operator.sub),
581 ('rsub', lambda a, b: operator.sub(b, a)),
582 ('truediv', operator.truediv),
583 ('rtruediv', lambda a, b: operator.truediv(b, a)),
584 ('xor', operator.xor),
585 ('rxor', lambda a, b: operator.xor(b, a)),
586)
587
588
21368027
PP
589# This is a list of unary operators used for
590# _inject_numeric_testing_methods().
591#
592# Each entry is a pair of unary operator name (used as part of the
593# created testing method's name) and operator function.
9cf643d1
PP
594_UNARYOPS = (
595 ('neg', operator.neg),
596 ('pos', operator.pos),
597 ('abs', operator.abs),
598 ('invert', operator.invert),
599 ('round', round),
600 ('round_0', partial(round, ndigits=0)),
601 ('round_1', partial(round, ndigits=1)),
602 ('round_2', partial(round, ndigits=2)),
603 ('round_3', partial(round, ndigits=3)),
604 ('ceil', math.ceil),
605 ('floor', math.floor),
606 ('trunc', math.trunc),
607)
608
609
21368027
PP
610# This function injects a bunch of testing methods to a numeric
611# field test case.
612#
613# It is meant to be used like this:
614#
615# _inject_numeric_testing_methods(MyNumericFieldTestCase)
616#
617# This function injects:
618#
619# * One testing method for each _TestNumericField._test_binop_*()
620# method, for each binary operator in the _BINOPS tuple.
621#
622# * One testing method for each _TestNumericField._test_unaryop*()
623# method, for each unary operator in the _UNARYOPS tuple.
9cf643d1
PP
624def _inject_numeric_testing_methods(cls):
625 def test_binop_name(suffix):
626 return 'test_binop_{}_{}'.format(name, suffix)
627
9cf643d1
PP
628 def test_unaryop_name(suffix):
629 return 'test_unaryop_{}_{}'.format(name, suffix)
630
631 # inject testing methods for each binary operation
632 for name, binop in _BINOPS:
9cf643d1
PP
633 setattr(cls, test_binop_name('invalid_unknown'), partialmethod(_TestNumericField._test_binop_invalid_unknown, op=binop))
634 setattr(cls, test_binop_name('invalid_none'), partialmethod(_TestNumericField._test_binop_invalid_none, op=binop))
635 setattr(cls, test_binop_name('type_true'), partialmethod(_TestNumericField._test_binop_type_true, op=binop))
636 setattr(cls, test_binop_name('type_pos_int'), partialmethod(_TestNumericField._test_binop_type_pos_int, op=binop))
637 setattr(cls, test_binop_name('type_pos_vint'), partialmethod(_TestNumericField._test_binop_type_pos_vint, op=binop))
638 setattr(cls, test_binop_name('value_true'), partialmethod(_TestNumericField._test_binop_value_true, op=binop))
639 setattr(cls, test_binop_name('value_pos_int'), partialmethod(_TestNumericField._test_binop_value_pos_int, op=binop))
640 setattr(cls, test_binop_name('value_pos_vint'), partialmethod(_TestNumericField._test_binop_value_pos_vint, op=binop))
641 setattr(cls, test_binop_name('lhs_addr_same_true'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_true, op=binop))
642 setattr(cls, test_binop_name('lhs_addr_same_pos_int'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_pos_int, op=binop))
643 setattr(cls, test_binop_name('lhs_addr_same_pos_vint'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_pos_vint, op=binop))
644 setattr(cls, test_binop_name('lhs_value_same_true'), partialmethod(_TestNumericField._test_binop_lhs_value_same_true, op=binop))
645 setattr(cls, test_binop_name('lhs_value_same_pos_int'), partialmethod(_TestNumericField._test_binop_lhs_value_same_pos_int, op=binop))
646 setattr(cls, test_binop_name('lhs_value_same_pos_vint'), partialmethod(_TestNumericField._test_binop_lhs_value_same_pos_vint, op=binop))
647 setattr(cls, test_binop_name('type_neg_int'), partialmethod(_TestNumericField._test_binop_type_neg_int, op=binop))
648 setattr(cls, test_binop_name('type_neg_vint'), partialmethod(_TestNumericField._test_binop_type_neg_vint, op=binop))
649 setattr(cls, test_binop_name('value_neg_int'), partialmethod(_TestNumericField._test_binop_value_neg_int, op=binop))
650 setattr(cls, test_binop_name('value_neg_vint'), partialmethod(_TestNumericField._test_binop_value_neg_vint, op=binop))
651 setattr(cls, test_binop_name('lhs_addr_same_neg_int'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_neg_int, op=binop))
652 setattr(cls, test_binop_name('lhs_addr_same_neg_vint'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_neg_vint, op=binop))
653 setattr(cls, test_binop_name('lhs_value_same_neg_int'), partialmethod(_TestNumericField._test_binop_lhs_value_same_neg_int, op=binop))
654 setattr(cls, test_binop_name('lhs_value_same_neg_vint'), partialmethod(_TestNumericField._test_binop_lhs_value_same_neg_vint, op=binop))
655 setattr(cls, test_binop_name('type_false'), partialmethod(_TestNumericField._test_binop_type_false, op=binop))
656 setattr(cls, test_binop_name('type_zero_int'), partialmethod(_TestNumericField._test_binop_type_zero_int, op=binop))
657 setattr(cls, test_binop_name('type_zero_vint'), partialmethod(_TestNumericField._test_binop_type_zero_vint, op=binop))
658 setattr(cls, test_binop_name('value_false'), partialmethod(_TestNumericField._test_binop_value_false, op=binop))
659 setattr(cls, test_binop_name('value_zero_int'), partialmethod(_TestNumericField._test_binop_value_zero_int, op=binop))
660 setattr(cls, test_binop_name('value_zero_vint'), partialmethod(_TestNumericField._test_binop_value_zero_vint, op=binop))
661 setattr(cls, test_binop_name('lhs_addr_same_false'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_false, op=binop))
662 setattr(cls, test_binop_name('lhs_addr_same_zero_int'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_zero_int, op=binop))
663 setattr(cls, test_binop_name('lhs_addr_same_zero_vint'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_zero_vint, op=binop))
664 setattr(cls, test_binop_name('lhs_value_same_false'), partialmethod(_TestNumericField._test_binop_lhs_value_same_false, op=binop))
665 setattr(cls, test_binop_name('lhs_value_same_zero_int'), partialmethod(_TestNumericField._test_binop_lhs_value_same_zero_int, op=binop))
666 setattr(cls, test_binop_name('lhs_value_same_zero_vint'), partialmethod(_TestNumericField._test_binop_lhs_value_same_zero_vint, op=binop))
667 setattr(cls, test_binop_name('type_pos_float'), partialmethod(_TestNumericField._test_binop_type_pos_float, op=binop))
668 setattr(cls, test_binop_name('type_neg_float'), partialmethod(_TestNumericField._test_binop_type_neg_float, op=binop))
669 setattr(cls, test_binop_name('type_pos_vfloat'), partialmethod(_TestNumericField._test_binop_type_pos_vfloat, op=binop))
670 setattr(cls, test_binop_name('type_neg_vfloat'), partialmethod(_TestNumericField._test_binop_type_neg_vfloat, op=binop))
671 setattr(cls, test_binop_name('value_pos_float'), partialmethod(_TestNumericField._test_binop_value_pos_float, op=binop))
672 setattr(cls, test_binop_name('value_neg_float'), partialmethod(_TestNumericField._test_binop_value_neg_float, op=binop))
673 setattr(cls, test_binop_name('value_pos_vfloat'), partialmethod(_TestNumericField._test_binop_value_pos_vfloat, op=binop))
674 setattr(cls, test_binop_name('value_neg_vfloat'), partialmethod(_TestNumericField._test_binop_value_neg_vfloat, op=binop))
675 setattr(cls, test_binop_name('lhs_addr_same_pos_float'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_pos_float, op=binop))
676 setattr(cls, test_binop_name('lhs_addr_same_neg_float'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_neg_float, op=binop))
677 setattr(cls, test_binop_name('lhs_addr_same_pos_vfloat'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_pos_vfloat, op=binop))
678 setattr(cls, test_binop_name('lhs_addr_same_neg_vfloat'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_neg_vfloat, op=binop))
679 setattr(cls, test_binop_name('lhs_value_same_pos_float'), partialmethod(_TestNumericField._test_binop_lhs_value_same_pos_float, op=binop))
680 setattr(cls, test_binop_name('lhs_value_same_neg_float'), partialmethod(_TestNumericField._test_binop_lhs_value_same_neg_float, op=binop))
681 setattr(cls, test_binop_name('lhs_value_same_pos_vfloat'), partialmethod(_TestNumericField._test_binop_lhs_value_same_pos_vfloat, op=binop))
682 setattr(cls, test_binop_name('lhs_value_same_neg_vfloat'), partialmethod(_TestNumericField._test_binop_lhs_value_same_neg_vfloat, op=binop))
683 setattr(cls, test_binop_name('type_zero_float'), partialmethod(_TestNumericField._test_binop_type_zero_float, op=binop))
684 setattr(cls, test_binop_name('type_zero_vfloat'), partialmethod(_TestNumericField._test_binop_type_zero_vfloat, op=binop))
685 setattr(cls, test_binop_name('value_zero_float'), partialmethod(_TestNumericField._test_binop_value_zero_float, op=binop))
686 setattr(cls, test_binop_name('value_zero_vfloat'), partialmethod(_TestNumericField._test_binop_value_zero_vfloat, op=binop))
687 setattr(cls, test_binop_name('lhs_addr_same_zero_float'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_zero_float, op=binop))
688 setattr(cls, test_binop_name('lhs_addr_same_zero_vfloat'), partialmethod(_TestNumericField._test_binop_lhs_addr_same_zero_vfloat, op=binop))
689 setattr(cls, test_binop_name('lhs_value_same_zero_float'), partialmethod(_TestNumericField._test_binop_lhs_value_same_zero_float, op=binop))
690 setattr(cls, test_binop_name('lhs_value_same_zero_vfloat'), partialmethod(_TestNumericField._test_binop_lhs_value_same_zero_vfloat, op=binop))
691
692 # inject testing methods for each unary operation
693 for name, unaryop in _UNARYOPS:
694 setattr(cls, test_unaryop_name('type'), partialmethod(_TestNumericField._test_unaryop_type, op=unaryop))
695 setattr(cls, test_unaryop_name('value'), partialmethod(_TestNumericField._test_unaryop_value, op=unaryop))
696 setattr(cls, test_unaryop_name('addr_same'), partialmethod(_TestNumericField._test_unaryop_addr_same, op=unaryop))
697 setattr(cls, test_unaryop_name('value_same'), partialmethod(_TestNumericField._test_unaryop_value_same, op=unaryop))
698
9cf643d1
PP
699
700class _TestIntegerFieldCommon(_TestNumericField):
701 def test_assign_true(self):
702 raw = True
703 self._def.value = raw
704 self.assertEqual(self._def, raw)
9cf643d1
PP
705
706 def test_assign_false(self):
707 raw = False
708 self._def.value = raw
709 self.assertEqual(self._def, raw)
9cf643d1
PP
710
711 def test_assign_pos_int(self):
712 raw = 477
713 self._def.value = raw
714 self.assertEqual(self._def, raw)
9cf643d1
PP
715
716 def test_assign_neg_int(self):
717 raw = -13
718 self._def.value = raw
719 self.assertEqual(self._def, raw)
9cf643d1
PP
720
721 def test_assign_int_field(self):
722 raw = 999
1eccc498 723 field = _create_field(self._tc, self._create_fc(self._tc))
9cf643d1
PP
724 field.value = raw
725 self._def.value = field
726 self.assertEqual(self._def, raw)
9cf643d1 727
9cf643d1
PP
728 def test_assign_invalid_type(self):
729 with self.assertRaises(TypeError):
730 self._def.value = 'yes'
731
732 def test_assign_uint(self):
1eccc498
SM
733 uint_fc = self._tc.create_unsigned_integer_field_class(32)
734 field = _create_field(self._tc, uint_fc)
9cf643d1
PP
735 raw = 1777
736 field.value = 1777
737 self.assertEqual(field, raw)
9cf643d1 738
7bb4180f
FD
739 def test_assign_big_uint(self):
740 uint_fc = self._tc.create_unsigned_integer_field_class(64)
741 field = _create_field(self._tc, uint_fc)
742 # Larger than the IEEE 754 double-precision exact representation of
743 # integers.
744 raw = (2**53) + 1
745 field.value = (2**53) + 1
746 self.assertEqual(field, raw)
747
9cf643d1 748 def test_assign_uint_invalid_neg(self):
1eccc498
SM
749 uint_fc = self._tc.create_unsigned_integer_field_class(32)
750 field = _create_field(self._tc, uint_fc)
9cf643d1
PP
751
752 with self.assertRaises(ValueError):
753 field.value = -23
754
b0bdda42
JG
755 def test_str_op(self):
756 self.assertEqual(str(self._def), str(self._def_value))
757
9cf643d1
PP
758
759_inject_numeric_testing_methods(_TestIntegerFieldCommon)
760
761
1eccc498
SM
762class SignedIntegerFieldTestCase(_TestIntegerFieldCommon, unittest.TestCase):
763 def _create_fc(self, tc):
764 return tc.create_signed_integer_field_class(25)
765
9cf643d1 766 def setUp(self):
1eccc498
SM
767 self._tc = get_default_trace_class()
768 self._field = _create_field(self._tc, self._create_fc(self._tc))
769 self._field.value = 17
770 self._def = _create_field(self._tc, self._create_fc(self._tc))
9cf643d1
PP
771 self._def.value = 17
772 self._def_value = 17
773 self._def_new_value = -101
774
811644b8 775
1eccc498
SM
776class SignedEnumerationFieldTestCase(_TestIntegerFieldCommon, unittest.TestCase):
777 def _create_fc(self, tc):
778 fc = tc.create_signed_enumeration_field_class(32)
779 fc.map_range('something', 17)
780 fc.map_range('speaker', 12, 16)
781 fc.map_range('can', 18, 2540)
782 fc.map_range('whole range', -(2 ** 31), (2 ** 31) - 1)
783 fc.map_range('zip', -45, 1001)
784 return fc
9cf643d1 785
9cf643d1 786 def setUp(self):
1eccc498
SM
787 self._tc = get_default_trace_class()
788 self._field = _create_field(self._tc, self._create_fc(self._tc))
789 self._def = _create_field(self._tc, self._create_fc(self._tc))
9cf643d1
PP
790 self._def.value = 17
791 self._def_value = 17
792 self._def_new_value = -101
793
b0bdda42
JG
794 def test_str_op(self):
795 expected_string_found = False
796 s = str(self._def)
797
798 # Establish all permutations of the three expected matches since
799 # the order in which mappings are enumerated is not explicitly part of
800 # the API.
1eccc498
SM
801 for p in itertools.permutations(['whole range', 'something',
802 'zip']):
b0bdda42
JG
803 candidate = '{} ({})'.format(self._def_value, ', '.join(p))
804 if candidate == s:
805 expected_string_found = True
806 break
807
808 self.assertTrue(expected_string_found)
809
1eccc498
SM
810 def test_labels(self):
811 self._field.value = 17
812 labels = sorted(self._field.labels)
813 self.assertEqual(labels, ['something', 'whole range', 'zip'])
814
b0bdda42 815
1eccc498
SM
816class RealFieldTestCase(_TestNumericField, unittest.TestCase):
817 def _create_fc(self, tc):
818 return tc.create_real_field_class()
9cf643d1 819
9cf643d1 820 def setUp(self):
1eccc498
SM
821 self._tc = get_default_trace_class()
822 self._field = _create_field(self._tc, self._create_fc(self._tc))
823 self._def = _create_field(self._tc, self._create_fc(self._tc))
9cf643d1
PP
824 self._def.value = 52.7
825 self._def_value = 52.7
826 self._def_new_value = -17.164857
827
828 def _test_invalid_op(self, cb):
829 with self.assertRaises(TypeError):
830 cb()
831
832 def test_assign_true(self):
833 self._def.value = True
834 self.assertTrue(self._def)
9cf643d1
PP
835
836 def test_assign_false(self):
837 self._def.value = False
838 self.assertFalse(self._def)
9cf643d1
PP
839
840 def test_assign_pos_int(self):
841 raw = 477
842 self._def.value = raw
843 self.assertEqual(self._def, float(raw))
9cf643d1
PP
844
845 def test_assign_neg_int(self):
846 raw = -13
847 self._def.value = raw
848 self.assertEqual(self._def, float(raw))
9cf643d1
PP
849
850 def test_assign_int_field(self):
1eccc498
SM
851 int_fc = self._tc.create_signed_integer_field_class(32)
852 int_field = _create_field(self._tc, int_fc)
9cf643d1 853 raw = 999
1eccc498
SM
854 int_field.value = raw
855 self._def.value = int_field
9cf643d1 856 self.assertEqual(self._def, float(raw))
9cf643d1
PP
857
858 def test_assign_float(self):
859 raw = -19.23
860 self._def.value = raw
861 self.assertEqual(self._def, raw)
9cf643d1
PP
862
863 def test_assign_float_field(self):
1eccc498 864 field = _create_field(self._tc, self._create_fc(self._tc))
9cf643d1
PP
865 raw = 101.32
866 field.value = raw
867 self._def.value = field
868 self.assertEqual(self._def, raw)
9cf643d1
PP
869
870 def test_assign_invalid_type(self):
871 with self.assertRaises(TypeError):
872 self._def.value = 'yes'
873
874 def test_invalid_lshift(self):
875 self._test_invalid_op(lambda: self._def << 23)
876
877 def test_invalid_rshift(self):
878 self._test_invalid_op(lambda: self._def >> 23)
879
880 def test_invalid_and(self):
881 self._test_invalid_op(lambda: self._def & 23)
882
883 def test_invalid_or(self):
884 self._test_invalid_op(lambda: self._def | 23)
885
886 def test_invalid_xor(self):
887 self._test_invalid_op(lambda: self._def ^ 23)
888
889 def test_invalid_invert(self):
890 self._test_invalid_op(lambda: ~self._def)
891
b0bdda42
JG
892 def test_str_op(self):
893 self.assertEqual(str(self._def), str(self._def_value))
894
9cf643d1 895
1eccc498 896_inject_numeric_testing_methods(RealFieldTestCase)
9cf643d1
PP
897
898
1eccc498 899class StringFieldTestCase(unittest.TestCase):
9cf643d1 900 def setUp(self):
1eccc498 901 self._tc = get_default_trace_class()
9cf643d1 902 self._def_value = 'Hello, World!'
1eccc498 903 self._def = _create_string_field(self._tc)
9cf643d1
PP
904 self._def.value = self._def_value
905 self._def_new_value = 'Yes!'
906
907 def test_assign_int(self):
908 with self.assertRaises(TypeError):
909 self._def.value = 283
910
9cf643d1 911 def test_assign_string_field(self):
1eccc498 912 field = _create_string_field(self._tc)
9cf643d1
PP
913 raw = 'zorg'
914 field.value = raw
915 self.assertEqual(field, raw)
916
917 def test_eq(self):
918 self.assertEqual(self._def, self._def_value)
919
1eccc498 920 def test_not_eq(self):
9cf643d1
PP
921 self.assertNotEqual(self._def, 23)
922
923 def test_lt_vstring(self):
1eccc498 924 s1 = _create_string_field(self._tc)
9cf643d1 925 s1.value = 'allo'
1eccc498 926 s2 = _create_string_field(self._tc)
9cf643d1
PP
927 s2.value = 'bateau'
928 self.assertLess(s1, s2)
929
930 def test_lt_string(self):
1eccc498 931 s1 = _create_string_field(self._tc)
9cf643d1
PP
932 s1.value = 'allo'
933 self.assertLess(s1, 'bateau')
934
935 def test_le_vstring(self):
1eccc498 936 s1 = _create_string_field(self._tc)
9cf643d1 937 s1.value = 'allo'
1eccc498 938 s2 = _create_string_field(self._tc)
9cf643d1
PP
939 s2.value = 'bateau'
940 self.assertLessEqual(s1, s2)
941
942 def test_le_string(self):
1eccc498 943 s1 = _create_string_field(self._tc)
9cf643d1
PP
944 s1.value = 'allo'
945 self.assertLessEqual(s1, 'bateau')
946
947 def test_gt_vstring(self):
1eccc498 948 s1 = _create_string_field(self._tc)
9cf643d1 949 s1.value = 'allo'
1eccc498 950 s2 = _create_string_field(self._tc)
9cf643d1
PP
951 s2.value = 'bateau'
952 self.assertGreater(s2, s1)
953
954 def test_gt_string(self):
1eccc498 955 s1 = _create_string_field(self._tc)
9cf643d1
PP
956 s1.value = 'allo'
957 self.assertGreater('bateau', s1)
958
959 def test_ge_vstring(self):
1eccc498 960 s1 = _create_string_field(self._tc)
9cf643d1 961 s1.value = 'allo'
1eccc498 962 s2 = _create_string_field(self._tc)
9cf643d1
PP
963 s2.value = 'bateau'
964 self.assertGreaterEqual(s2, s1)
965
966 def test_ge_string(self):
1eccc498 967 s1 = _create_string_field(self._tc)
9cf643d1
PP
968 s1.value = 'allo'
969 self.assertGreaterEqual('bateau', s1)
970
971 def test_bool_op(self):
972 self.assertEqual(bool(self._def), bool(self._def_value))
973
974 def test_str_op(self):
975 self.assertEqual(str(self._def), str(self._def_value))
976
977 def test_len(self):
978 self.assertEqual(len(self._def), len(self._def_value))
979
980 def test_getitem(self):
981 self.assertEqual(self._def[5], self._def_value[5])
982
983 def test_append_str(self):
984 to_append = 'meow meow meow'
985 self._def += to_append
986 self._def_value += to_append
987 self.assertEqual(self._def, self._def_value)
988
989 def test_append_string_field(self):
1eccc498 990 field = _create_string_field(self._tc)
9cf643d1
PP
991 to_append = 'meow meow meow'
992 field.value = to_append
993 self._def += field
994 self._def_value += to_append
995 self.assertEqual(self._def, self._def_value)
996
742e4747 997
1eccc498 998class _TestArrayFieldCommon:
9cf643d1
PP
999 def _modify_def(self):
1000 self._def[2] = 23
1001
1002 def test_bool_op_true(self):
1003 self.assertTrue(self._def)
1004
1005 def test_len(self):
1006 self.assertEqual(len(self._def), 3)
1007
1eccc498
SM
1008 def test_length(self):
1009 self.assertEqual(self._def.length, 3)
1010
9cf643d1
PP
1011 def test_getitem(self):
1012 field = self._def[1]
1eccc498 1013 self.assertIs(type(field), bt2.field._SignedIntegerField)
9cf643d1
PP
1014 self.assertEqual(field, 1847)
1015
1016 def test_eq(self):
1eccc498 1017 field = _create_int_array_field(self._tc, 3)
9cf643d1
PP
1018 field[0] = 45
1019 field[1] = 1847
1020 field[2] = 1948754
1021 self.assertEqual(self._def, field)
1022
1023 def test_eq_invalid_type(self):
1024 self.assertNotEqual(self._def, 23)
1025
1026 def test_eq_diff_len(self):
1eccc498 1027 field = _create_int_array_field(self._tc, 2)
9cf643d1
PP
1028 field[0] = 45
1029 field[1] = 1847
1030 self.assertNotEqual(self._def, field)
1031
1032 def test_eq_diff_content_same_len(self):
1eccc498 1033 field = _create_int_array_field(self._tc, 3)
9cf643d1
PP
1034 field[0] = 45
1035 field[1] = 1846
1036 field[2] = 1948754
1037 self.assertNotEqual(self._def, field)
1038
1039 def test_setitem(self):
1040 self._def[2] = 24
1041 self.assertEqual(self._def[2], 24)
1042
1043 def test_setitem_int_field(self):
1eccc498
SM
1044 int_fc = self._tc.create_signed_integer_field_class(32)
1045 int_field = _create_field(self._tc, int_fc)
9cf643d1
PP
1046 int_field.value = 19487
1047 self._def[1] = int_field
1048 self.assertEqual(self._def[1], 19487)
1049
1050 def test_setitem_non_basic_field(self):
1eccc498 1051 array_field = _create_struct_array_field(self._tc, 2)
9cf643d1
PP
1052 with self.assertRaises(TypeError):
1053 array_field[1] = 23
1054
1055 def test_setitem_none(self):
1056 with self.assertRaises(TypeError):
1057 self._def[1] = None
1058
1059 def test_setitem_index_wrong_type(self):
1060 with self.assertRaises(TypeError):
1061 self._def['yes'] = 23
1062
1063 def test_setitem_index_neg(self):
1064 with self.assertRaises(IndexError):
1065 self._def[-2] = 23
1066
1067 def test_setitem_index_out_of_range(self):
1068 with self.assertRaises(IndexError):
1069 self._def[len(self._def)] = 134679
1070
1071 def test_iter(self):
1072 for field, value in zip(self._def, (45, 1847, 1948754)):
1073 self.assertEqual(field, value)
1074
7c54e2e7
JG
1075 def test_value_int_field(self):
1076 values = [45646, 145, 12145]
1077 self._def.value = values
1078 self.assertEqual(values, self._def)
1079
7c54e2e7
JG
1080 def test_value_check_sequence(self):
1081 values = 42
1082 with self.assertRaises(TypeError):
1083 self._def.value = values
1084
1085 def test_value_wrong_type_in_sequence(self):
1086 values = [32, 'hello', 11]
1087 with self.assertRaises(TypeError):
1088 self._def.value = values
1089
1090 def test_value_complex_type(self):
1eccc498
SM
1091 struct_fc = self._tc.create_structure_field_class()
1092 int_fc = self._tc.create_signed_integer_field_class(32)
1093 another_int_fc = self._tc.create_signed_integer_field_class(32)
1094 str_fc = self._tc.create_string_field_class()
1095 struct_fc.append_member(field_class=int_fc, name='an_int')
1096 struct_fc.append_member(field_class=str_fc, name='a_string')
1097 struct_fc.append_member(field_class=another_int_fc, name='another_int')
1098 array_fc = self._tc.create_static_array_field_class(struct_fc, 3)
1099 stream = _create_stream(self._tc, [('array_field', array_fc)])
7c54e2e7
JG
1100 values = [
1101 {
1102 'an_int': 42,
1103 'a_string': 'hello',
1104 'another_int': 66
1105 },
1106 {
1107 'an_int': 1,
1108 'a_string': 'goodbye',
1109 'another_int': 488
1110 },
1111 {
1112 'an_int': 156,
1113 'a_string': 'or not',
1114 'another_int': 4648
1115 },
1116 ]
1117
1eccc498 1118 array = stream.create_packet().context_field['array_field']
7c54e2e7
JG
1119 array.value = values
1120 self.assertEqual(values, array)
1121 values[0]['an_int'] = 'a string'
1122 with self.assertRaises(TypeError):
1123 array.value = values
9cf643d1 1124
b0bdda42
JG
1125 def test_str_op(self):
1126 s = str(self._def)
1127 expected_string = '[{}]'.format(', '.join(
1128 [repr(v) for v in self._def_value]))
1129 self.assertEqual(expected_string, s)
1130
742e4747 1131
1eccc498 1132class StaticArrayFieldTestCase(_TestArrayFieldCommon, unittest.TestCase):
9cf643d1 1133 def setUp(self):
1eccc498
SM
1134 self._tc = get_default_trace_class()
1135 self._def = _create_int_array_field(self._tc, 3)
9cf643d1
PP
1136 self._def[0] = 45
1137 self._def[1] = 1847
1138 self._def[2] = 1948754
7c54e2e7 1139 self._def_value = [45, 1847, 1948754]
9cf643d1 1140
7c54e2e7
JG
1141 def test_value_wrong_len(self):
1142 values = [45, 1847]
1143 with self.assertRaises(ValueError):
1144 self._def.value = values
1145
9cf643d1 1146
1eccc498 1147class DynamicArrayFieldTestCase(_TestArrayFieldCommon, unittest.TestCase):
9cf643d1 1148 def setUp(self):
1eccc498
SM
1149 self._tc = get_default_trace_class()
1150 self._def = _create_dynamic_array(self._tc)
9cf643d1
PP
1151 self._def[0] = 45
1152 self._def[1] = 1847
1153 self._def[2] = 1948754
7c54e2e7 1154 self._def_value = [45, 1847, 1948754]
9cf643d1 1155
7c54e2e7
JG
1156 def test_value_resize(self):
1157 new_values = [1, 2, 3, 4]
1158 self._def.value = new_values
1159 self.assertCountEqual(self._def, new_values)
1160
1eccc498
SM
1161 def test_set_length(self):
1162 self._def.length = 4
1163 self._def[3] = 0
1164 self.assertEqual(len(self._def), 4)
7c54e2e7 1165
1eccc498 1166 def test_set_invalid_length(self):
7c54e2e7 1167 with self.assertRaises(TypeError):
1eccc498
SM
1168 self._def.length = 'cheval'
1169
1170
1171class StructureFieldTestCase(unittest.TestCase):
1172 def _create_fc(self, tc):
1173 fc = tc.create_structure_field_class()
1174 fc.append_member('A', self._fc0_fn())
1175 fc.append_member('B', self._fc1_fn())
1176 fc.append_member('C', self._fc2_fn())
1177 fc.append_member('D', self._fc3_fn())
1178 fc.append_member('E', self._fc4_fn())
1179 fc5 = self._fc5_fn()
1180 fc5.append_member('F_1', self._fc5_inner_fn())
1181 fc.append_member('F', fc5)
1182 return fc
7c54e2e7 1183
9cf643d1 1184 def setUp(self):
1eccc498
SM
1185 self._tc = get_default_trace_class()
1186 self._fc0_fn = self._tc.create_signed_integer_field_class
1187 self._fc1_fn = self._tc.create_string_field_class
1188 self._fc2_fn = self._tc.create_real_field_class
1189 self._fc3_fn = self._tc.create_signed_integer_field_class
1190 self._fc4_fn = self._tc.create_structure_field_class
1191 self._fc5_fn = self._tc.create_structure_field_class
1192 self._fc5_inner_fn = self._tc.create_signed_integer_field_class
1193
1194 self._fc = self._create_fc(self._tc)
1195 self._def = _create_field(self._tc, self._fc)
9cf643d1
PP
1196 self._def['A'] = -1872
1197 self._def['B'] = 'salut'
1198 self._def['C'] = 17.5
1199 self._def['D'] = 16497
1eccc498
SM
1200 self._def['E'] = {}
1201 self._def['F'] = {'F_1': 52}
b0bdda42
JG
1202 self._def_value = {
1203 'A': -1872,
1204 'B': 'salut',
1205 'C': 17.5,
1eccc498
SM
1206 'D': 16497,
1207 'E': {},
1208 'F': {'F_1': 52}
b0bdda42 1209 }
9cf643d1
PP
1210
1211 def _modify_def(self):
1212 self._def['B'] = 'hola'
1213
1214 def test_bool_op_true(self):
1215 self.assertTrue(self._def)
1216
1217 def test_bool_op_false(self):
1eccc498 1218 field = self._def['E']
9cf643d1
PP
1219 self.assertFalse(field)
1220
1221 def test_len(self):
1eccc498 1222 self.assertEqual(len(self._def), len(self._def_value))
9cf643d1
PP
1223
1224 def test_getitem(self):
1225 field = self._def['A']
1eccc498 1226 self.assertIs(type(field), bt2.field._SignedIntegerField)
9cf643d1
PP
1227 self.assertEqual(field, -1872)
1228
1eccc498 1229 def test_member_at_index_out_of_bounds_after(self):
811644b8 1230 with self.assertRaises(IndexError):
1eccc498 1231 self._def.member_at_index(len(self._def_value))
811644b8 1232
9cf643d1 1233 def test_eq(self):
1eccc498 1234 field = _create_field(self._tc, self._create_fc(self._tc, ))
9cf643d1
PP
1235 field['A'] = -1872
1236 field['B'] = 'salut'
1237 field['C'] = 17.5
1238 field['D'] = 16497
1eccc498
SM
1239 field['E'] = {}
1240 field['F'] = {'F_1': 52}
9cf643d1
PP
1241 self.assertEqual(self._def, field)
1242
1243 def test_eq_invalid_type(self):
1244 self.assertNotEqual(self._def, 23)
1245
1246 def test_eq_diff_len(self):
1eccc498
SM
1247 fc = self._tc.create_structure_field_class()
1248 fc.append_member('A', self._fc0_fn())
1249 fc.append_member('B', self._fc1_fn())
1250 fc.append_member('C', self._fc2_fn())
1251
1252 field = _create_field(self._tc, fc)
9cf643d1
PP
1253 field['A'] = -1872
1254 field['B'] = 'salut'
1255 field['C'] = 17.5
1256 self.assertNotEqual(self._def, field)
1257
1eccc498
SM
1258 def test_eq_diff_keys(self):
1259 fc = self._tc.create_structure_field_class()
1260 fc.append_member('U', self._fc0_fn())
1261 fc.append_member('V', self._fc1_fn())
1262 fc.append_member('W', self._fc2_fn())
1263 fc.append_member('X', self._fc3_fn())
1264 fc.append_member('Y', self._fc4_fn())
1265 fc.append_member('Z', self._fc5_fn())
1266 field = _create_field(self._tc, fc)
1267 field['U'] = -1871
1268 field['V'] = "gerry"
1269 field['W'] = 18.19
1270 field['X'] = 16497
1271 field['Y'] = {}
1272 field['Z'] = {}
1273 self.assertNotEqual(self._def, field)
1274
9cf643d1 1275 def test_eq_diff_content_same_len(self):
1eccc498 1276 field = _create_field(self._tc, self._create_fc(self._tc))
9cf643d1
PP
1277 field['A'] = -1872
1278 field['B'] = 'salut'
1279 field['C'] = 17.4
1280 field['D'] = 16497
1eccc498
SM
1281 field['E'] = {}
1282 field['F'] = {'F_1': 0}
9cf643d1
PP
1283 self.assertNotEqual(self._def, field)
1284
1285 def test_eq_same_content_diff_keys(self):
1eccc498
SM
1286 fc = self._tc.create_structure_field_class()
1287 fc.append_member('A', self._fc0_fn())
1288 fc.append_member('B', self._fc1_fn())
1289 fc.append_member('E', self._fc2_fn())
1290 fc.append_member('D', self._fc3_fn())
1291 fc.append_member('C', self._fc4_fn())
1292 fc.append_member('F', self._fc5_fn())
1293 field = _create_field(self._tc, fc)
9cf643d1
PP
1294 field['A'] = -1872
1295 field['B'] = 'salut'
1eccc498 1296 field['E'] = 17.5
9cf643d1 1297 field['D'] = 16497
1eccc498
SM
1298 field['C'] = {}
1299 field['F'] = {}
9cf643d1
PP
1300 self.assertNotEqual(self._def, field)
1301
1302 def test_setitem(self):
1303 self._def['C'] = -18.47
1304 self.assertEqual(self._def['C'], -18.47)
1305
1306 def test_setitem_int_field(self):
1eccc498
SM
1307 int_fc = self._tc.create_signed_integer_field_class(32)
1308 int_field = _create_field(self._tc, int_fc)
9cf643d1
PP
1309 int_field.value = 19487
1310 self._def['D'] = int_field
1311 self.assertEqual(self._def['D'], 19487)
1312
1313 def test_setitem_non_basic_field(self):
1eccc498
SM
1314 elem_fc = self._tc.create_structure_field_class()
1315 struct_fc = self._tc.create_structure_field_class()
1316 struct_fc.append_member('A', elem_fc)
1317 struct_field = _create_field(self._tc, struct_fc)
9cf643d1 1318
236355c2
JG
1319 # Will fail on access to .items() of the value
1320 with self.assertRaises(AttributeError):
9cf643d1
PP
1321 struct_field['A'] = 23
1322
1323 def test_setitem_none(self):
1324 with self.assertRaises(TypeError):
1325 self._def['C'] = None
1326
1327 def test_setitem_key_wrong_type(self):
1328 with self.assertRaises(TypeError):
1329 self._def[3] = 23
1330
1331 def test_setitem_wrong_key(self):
1332 with self.assertRaises(KeyError):
1333 self._def['hi'] = 134679
1334
1eccc498
SM
1335 def test_member_at_index(self):
1336 self.assertEqual(self._def.member_at_index(1), 'salut')
9cf643d1
PP
1337
1338 def test_iter(self):
1339 orig_values = {
1340 'A': -1872,
1341 'B': 'salut',
1342 'C': 17.5,
1343 'D': 16497,
1eccc498
SM
1344 'E': {},
1345 'F': {'F_1': 52}
9cf643d1
PP
1346 }
1347
1348 for vkey, vval in self._def.items():
1349 val = orig_values[vkey]
1350 self.assertEqual(vval, val)
811644b8 1351
7c54e2e7
JG
1352 def test_value(self):
1353 orig_values = {
1354 'A': -1872,
1355 'B': 'salut',
1356 'C': 17.5,
1357 'D': 16497,
1eccc498
SM
1358 'E': {},
1359 'F': {'F_1': 52}
7c54e2e7
JG
1360 }
1361 self.assertEqual(self._def, orig_values)
1362
1363 def test_set_value(self):
1eccc498
SM
1364 int_fc = self._tc.create_signed_integer_field_class(32)
1365 another_int_fc = self._tc.create_signed_integer_field_class(32)
1366 str_fc = self._tc.create_string_field_class()
1367 struct_fc = self._tc.create_structure_field_class()
1368 struct_fc.append_member(field_class=int_fc, name='an_int')
1369 struct_fc.append_member(field_class=str_fc, name='a_string')
1370 struct_fc.append_member(field_class=another_int_fc, name='another_int')
7c54e2e7
JG
1371 values = {
1372 'an_int': 42,
1373 'a_string': 'hello',
1374 'another_int': 66
1375 }
1376
1eccc498 1377 struct = _create_field(self._tc, struct_fc)
7c54e2e7
JG
1378 struct.value = values
1379 self.assertEqual(values, struct)
1380
1381 bad_type_values = copy.deepcopy(values)
1382 bad_type_values['an_int'] = 'a string'
1383 with self.assertRaises(TypeError):
1384 struct.value = bad_type_values
1385
1386 unknown_key_values = copy.deepcopy(values)
1387 unknown_key_values['unknown_key'] = 16546
1388 with self.assertRaises(KeyError):
1389 struct.value = unknown_key_values
1390
b0bdda42
JG
1391 def test_str_op(self):
1392 expected_string_found = False
1393 s = str(self._def)
1394 # Establish all permutations of the three expected matches since
1395 # the order in which mappings are enumerated is not explicitly part of
1396 # the API.
1397 for p in itertools.permutations([(k, v) for k, v in self._def.items()]):
1398 items = ['{}: {}'.format(repr(k), repr(v)) for k, v in p]
1399 candidate = '{{{}}}'.format(', '.join(items))
1400 if candidate == s:
1401 expected_string_found = True
1402 break
1403
1404 self.assertTrue(expected_string_found)
1405
b0bdda42 1406
1eccc498
SM
1407class VariantFieldTestCase(unittest.TestCase):
1408 def _create_fc(self, tc):
1409 selector_fc = tc.create_signed_enumeration_field_class(field_value_range=32)
1410 selector_fc.map_range('corner', 23)
1411 selector_fc.map_range('zoom', 17, 20)
1412 selector_fc.map_range('mellotron', 1001)
1413 selector_fc.map_range('giorgio', 2000, 3000)
1414
1415 ft0 = tc.create_signed_integer_field_class(32)
1416 ft1 = tc.create_string_field_class()
1417 ft2 = tc.create_real_field_class()
1418 ft3 = tc.create_signed_integer_field_class(17)
1419
1420 fc = tc.create_variant_field_class()
1421 fc.append_option('corner', ft0)
1422 fc.append_option('zoom', ft1)
1423 fc.append_option('mellotron', ft2)
1424 fc.append_option('giorgio', ft3)
1425 fc.selector_field_class = selector_fc
1426
1427 top_fc = tc.create_structure_field_class()
1428 top_fc.append_member('selector_field', selector_fc)
1429 top_fc.append_member('variant_field', fc)
1430 return top_fc
811644b8 1431
811644b8 1432 def setUp(self):
1eccc498
SM
1433 self._tc = get_default_trace_class()
1434 fld = _create_field(self._tc, self._create_fc(self._tc))
1435 self._def = fld['variant_field']
811644b8 1436
1eccc498
SM
1437 def test_bool_op(self):
1438 self._def.selected_option_index = 2
1439 self._def.value = -17.34
1440 with self.assertRaises(NotImplementedError):
1441 bool(self._def)
811644b8 1442
1eccc498
SM
1443 def test_selected_option_index(self):
1444 self._def.selected_option_index = 2
1445 self.assertEqual(self._def.selected_option_index, 2)
811644b8 1446
1eccc498
SM
1447 def test_selected_option(self):
1448 self._def.selected_option_index = 2
1449 self._def.value = -17.34
1450 self.assertEqual(self._def.selected_option, -17.34)
1451
1452 self._def.selected_option_index = 3
1453 self._def.value = 1921
1454 self.assertEqual(self._def.selected_option, 1921)
811644b8
PP
1455
1456 def test_eq(self):
1eccc498
SM
1457 field = _create_field(self._tc, self._create_fc(self._tc))
1458 field = field['variant_field']
1459 field.selected_option_index = 0
1460 field.value = 1774
1461 self._def.selected_option_index = 0
1462 self._def.value = 1774
811644b8
PP
1463 self.assertEqual(self._def, field)
1464
1465 def test_eq_invalid_type(self):
1eccc498
SM
1466 self._def.selected_option_index = 1
1467 self._def.value = 'gerry'
811644b8 1468 self.assertNotEqual(self._def, 23)
742e4747 1469
b0bdda42 1470 def test_str_op_int(self):
1eccc498
SM
1471 field = _create_field(self._tc, self._create_fc(self._tc))
1472 field = field['variant_field']
1473 field.selected_option_index = 0
1474 field.value = 1774
1475 other_field = _create_field(self._tc, self._create_fc(self._tc))
1476 other_field = other_field['variant_field']
1477 other_field.selected_option_index = 0
1478 other_field.value = 1774
1479 self.assertEqual(str(field), str(other_field))
b0bdda42
JG
1480
1481 def test_str_op_str(self):
1eccc498
SM
1482 field = _create_field(self._tc, self._create_fc(self._tc))
1483 field = field['variant_field']
1484 field.selected_option_index = 1
1485 field.value = 'un beau grand bateau'
1486 other_field = _create_field(self._tc, self._create_fc(self._tc))
1487 other_field = other_field['variant_field']
1488 other_field.selected_option_index = 1
1489 other_field.value = 'un beau grand bateau'
1490 self.assertEqual(str(field), str(other_field))
1491
1492 def test_str_op_float(self):
1493 field = _create_field(self._tc, self._create_fc(self._tc))
1494 field = field['variant_field']
1495 field.selected_option_index = 2
1496 field.value = 14.4245
1497 other_field = _create_field(self._tc, self._create_fc(self._tc))
1498 other_field = other_field['variant_field']
1499 other_field.selected_option_index = 2
1500 other_field.value = 14.4245
1501 self.assertEqual(str(field), str(other_field))
This page took 0.125529 seconds and 4 git commands to generate.