Fix: tests: live: listen on python < 3.5 needs backlog parameter
[babeltrace.git] / tests / bindings / python / bt2 / test_message_iterator.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
811644b8 19import unittest
811644b8 20import bt2
8e97c333 21import sys
6c373cc9 22from utils import TestOutputPortMessageIterator
14503fb1 23from bt2 import port as bt2_port
811644b8
PP
24
25
0a6d7302
SM
26class SimpleSink(bt2._UserSinkComponent):
27 # Straightforward sink that creates one input port (`in`) and consumes from
28 # it.
811644b8 29
59225a3e 30 def __init__(self, config, params, obj):
0a6d7302 31 self._add_input_port('in')
811644b8 32
0a6d7302
SM
33 def _user_consume(self):
34 next(self._msg_iter)
811644b8 35
0a6d7302
SM
36 def _user_graph_is_configured(self):
37 self._msg_iter = self._create_input_port_message_iterator(
38 self._input_ports['in']
39 )
ca02df0a 40
ca02df0a 41
0a6d7302
SM
42def _create_graph(src_comp_cls, sink_comp_cls, flt_comp_cls=None):
43 graph = bt2.Graph()
ca02df0a 44
0a6d7302
SM
45 src_comp = graph.add_component(src_comp_cls, 'src')
46 sink_comp = graph.add_component(sink_comp_cls, 'sink')
ca02df0a 47
0a6d7302
SM
48 if flt_comp_cls is not None:
49 flt_comp = graph.add_component(flt_comp_cls, 'flt')
50 graph.connect_ports(src_comp.output_ports['out'], flt_comp.input_ports['in'])
51 graph.connect_ports(flt_comp.output_ports['out'], sink_comp.input_ports['in'])
52 else:
53 graph.connect_ports(src_comp.output_ports['out'], sink_comp.input_ports['in'])
811644b8 54
0a6d7302
SM
55 return graph
56
57
58class UserMessageIteratorTestCase(unittest.TestCase):
811644b8 59 def test_init(self):
c5f330cd
SM
60 the_output_port_from_source = None
61 the_output_port_from_iter = None
62
5602ef81 63 class MyIter(bt2._UserMessageIterator):
c5f330cd 64 def __init__(self, self_port_output):
811644b8 65 nonlocal initialized
c5f330cd 66 nonlocal the_output_port_from_iter
811644b8 67 initialized = True
c5f330cd 68 the_output_port_from_iter = self_port_output
811644b8 69
cfbd7cf3 70 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
59225a3e 71 def __init__(self, config, params, obj):
c5f330cd 72 nonlocal the_output_port_from_source
2e00bc76 73 the_output_port_from_source = self._add_output_port('out', 'user data')
811644b8
PP
74
75 initialized = False
0a6d7302 76 graph = _create_graph(MySource, SimpleSink)
c5f330cd 77 graph.run()
811644b8 78 self.assertTrue(initialized)
cfbd7cf3
FD
79 self.assertEqual(
80 the_output_port_from_source.addr, the_output_port_from_iter.addr
81 )
2e00bc76 82 self.assertEqual(the_output_port_from_iter.user_data, 'user data')
811644b8 83
ca02df0a
PP
84 def test_create_from_message_iterator(self):
85 class MySourceIter(bt2._UserMessageIterator):
86 def __init__(self, self_port_output):
87 nonlocal src_iter_initialized
88 src_iter_initialized = True
89
90 class MySource(bt2._UserSourceComponent, message_iterator_class=MySourceIter):
59225a3e 91 def __init__(self, config, params, obj):
ca02df0a
PP
92 self._add_output_port('out')
93
94 class MyFilterIter(bt2._UserMessageIterator):
95 def __init__(self, self_port_output):
96 nonlocal flt_iter_initialized
97 flt_iter_initialized = True
98 self._up_iter = self._create_input_port_message_iterator(
99 self._component._input_ports['in']
100 )
101
102 def __next__(self):
103 return next(self._up_iter)
104
105 class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyFilterIter):
59225a3e 106 def __init__(self, config, params, obj):
ca02df0a
PP
107 self._add_input_port('in')
108 self._add_output_port('out')
109
110 src_iter_initialized = False
111 flt_iter_initialized = False
0a6d7302 112 graph = _create_graph(MySource, SimpleSink, MyFilter)
ca02df0a
PP
113 graph.run()
114 self.assertTrue(src_iter_initialized)
115 self.assertTrue(flt_iter_initialized)
116
e803df70
SM
117 def test_create_user_error(self):
118 # This tests both error handling by
119 # _UserSinkComponent._create_input_port_message_iterator
120 # and _UserMessageIterator._create_input_port_message_iterator, as they
121 # are both used in the graph.
122 class MySourceIter(bt2._UserMessageIterator):
123 def __init__(self, self_port_output):
124 raise ValueError('Very bad error')
125
126 class MySource(bt2._UserSourceComponent, message_iterator_class=MySourceIter):
59225a3e 127 def __init__(self, config, params, obj):
e803df70
SM
128 self._add_output_port('out')
129
130 class MyFilterIter(bt2._UserMessageIterator):
131 def __init__(self, self_port_output):
132 # This is expected to raise because of the error in
133 # MySourceIter.__init__.
134 self._create_input_port_message_iterator(
135 self._component._input_ports['in']
136 )
137
138 class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyFilterIter):
59225a3e 139 def __init__(self, config, params, obj):
e803df70
SM
140 self._add_input_port('in')
141 self._add_output_port('out')
142
0a6d7302 143 graph = _create_graph(MySource, SimpleSink, MyFilter)
e803df70
SM
144
145 with self.assertRaises(bt2._Error) as ctx:
146 graph.run()
147
148 exc = ctx.exception
149 cause = exc[0]
150
151 self.assertIsInstance(cause, bt2._MessageIteratorErrorCause)
152 self.assertEqual(cause.component_name, 'src')
153 self.assertEqual(cause.component_output_port_name, 'out')
154 self.assertIn('ValueError: Very bad error', cause.message)
155
811644b8 156 def test_finalize(self):
5602ef81 157 class MyIter(bt2._UserMessageIterator):
6a91742b 158 def _user_finalize(self):
811644b8
PP
159 nonlocal finalized
160 finalized = True
161
cfbd7cf3 162 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
59225a3e 163 def __init__(self, config, params, obj):
811644b8
PP
164 self._add_output_port('out')
165
166 finalized = False
0a6d7302 167 graph = _create_graph(MySource, SimpleSink)
c5f330cd 168 graph.run()
811644b8
PP
169 del graph
170 self.assertTrue(finalized)
171
172 def test_component(self):
5602ef81 173 class MyIter(bt2._UserMessageIterator):
c5f330cd 174 def __init__(self, self_port_output):
811644b8
PP
175 nonlocal salut
176 salut = self._component._salut
177
cfbd7cf3 178 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
59225a3e 179 def __init__(self, config, params, obj):
811644b8
PP
180 self._add_output_port('out')
181 self._salut = 23
182
183 salut = None
0a6d7302 184 graph = _create_graph(MySource, SimpleSink)
c5f330cd 185 graph.run()
811644b8
PP
186 self.assertEqual(salut, 23)
187
14503fb1
SM
188 def test_port(self):
189 class MyIter(bt2._UserMessageIterator):
190 def __init__(self_iter, self_port_output):
191 nonlocal called
192 called = True
193 port = self_iter._port
194 self.assertIs(type(self_port_output), bt2_port._UserComponentOutputPort)
195 self.assertIs(type(port), bt2_port._UserComponentOutputPort)
196 self.assertEqual(self_port_output.addr, port.addr)
197
198 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
59225a3e 199 def __init__(self, config, params, obj):
14503fb1
SM
200 self._add_output_port('out')
201
202 called = False
0a6d7302 203 graph = _create_graph(MySource, SimpleSink)
14503fb1
SM
204 graph.run()
205 self.assertTrue(called)
206
811644b8 207 def test_addr(self):
5602ef81 208 class MyIter(bt2._UserMessageIterator):
c5f330cd 209 def __init__(self, self_port_output):
811644b8
PP
210 nonlocal addr
211 addr = self.addr
212
cfbd7cf3 213 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
59225a3e 214 def __init__(self, config, params, obj):
811644b8
PP
215 self._add_output_port('out')
216
217 addr = None
0a6d7302 218 graph = _create_graph(MySource, SimpleSink)
c5f330cd 219 graph.run()
811644b8
PP
220 self.assertIsNotNone(addr)
221 self.assertNotEqual(addr, 0)
222
d79a8353
SM
223 # Test that messages returned by _UserMessageIterator.__next__ remain valid
224 # and can be re-used.
225 def test_reuse_message(self):
226 class MyIter(bt2._UserMessageIterator):
227 def __init__(self, port):
228 tc, sc, ec = port.user_data
229 trace = tc()
230 stream = trace.create_stream(sc)
231 packet = stream.create_packet()
232
233 # This message will be returned twice by __next__.
234 event_message = self._create_event_message(ec, packet)
235
236 self._msgs = [
237 self._create_stream_beginning_message(stream),
d79a8353
SM
238 self._create_packet_beginning_message(packet),
239 event_message,
240 event_message,
241 ]
242
243 def __next__(self):
244 return self._msgs.pop(0)
245
246 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
59225a3e 247 def __init__(self, config, params, obj):
d79a8353 248 tc = self._create_trace_class()
26fc5aed 249 sc = tc.create_stream_class(supports_packets=True)
d79a8353
SM
250 ec = sc.create_event_class()
251 self._add_output_port('out', (tc, sc, ec))
252
253 graph = bt2.Graph()
254 src = graph.add_component(MySource, 'src')
6c373cc9 255 it = TestOutputPortMessageIterator(graph, src.output_ports['out'])
d79a8353
SM
256
257 # Skip beginning messages.
188edac1 258 msg = next(it)
f0a42b33 259 self.assertIs(type(msg), bt2._StreamBeginningMessageConst)
188edac1 260 msg = next(it)
f0a42b33 261 self.assertIs(type(msg), bt2._PacketBeginningMessageConst)
d79a8353
SM
262
263 msg_ev1 = next(it)
264 msg_ev2 = next(it)
265
f0a42b33
FD
266 self.assertIs(type(msg_ev1), bt2._EventMessageConst)
267 self.assertIs(type(msg_ev2), bt2._EventMessageConst)
d79a8353
SM
268 self.assertEqual(msg_ev1.addr, msg_ev2.addr)
269
0a6d7302
SM
270 # Try consuming many times from an iterator that always returns TryAgain.
271 # This verifies that we are not missing an incref of Py_None, making the
272 # refcount of Py_None reach 0.
273 def test_try_again_many_times(self):
274 class MyIter(bt2._UserMessageIterator):
f00b8d40 275 def __next__(self):
0a6d7302 276 raise bt2.TryAgain
f00b8d40 277
0a6d7302 278 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
59225a3e 279 def __init__(self, config, params, obj):
0a6d7302 280 self._add_output_port('out')
f00b8d40
SM
281
282 class MyFilterIter(bt2._UserMessageIterator):
283 def __init__(self, port):
284 input_port = port.user_data
ca02df0a
PP
285 self._upstream_iter = self._create_input_port_message_iterator(
286 input_port
287 )
f00b8d40
SM
288
289 def __next__(self):
290 return next(self._upstream_iter)
291
6a91742b 292 def _user_seek_beginning(self):
f00b8d40
SM
293 self._upstream_iter.seek_beginning()
294
6a91742b 295 def _user_can_seek_beginning(self):
14cfc8ce 296 return self._upstream_iter.can_seek_beginning()
f00b8d40
SM
297
298 class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyFilterIter):
59225a3e 299 def __init__(self, config, params, obj):
f00b8d40
SM
300 input_port = self._add_input_port('in')
301 self._add_output_port('out', input_port)
302
f00b8d40
SM
303 graph = bt2.Graph()
304 src = graph.add_component(MySource, 'src')
0a6d7302
SM
305 it = TestOutputPortMessageIterator(graph, src.output_ports['out'])
306
307 # Three times the initial ref count of `None` iterations should
308 # be enough to catch the bug even if there are small differences
309 # between configurations.
310 none_ref_count = sys.getrefcount(None) * 3
311
312 for i in range(none_ref_count):
313 with self.assertRaises(bt2.TryAgain):
314 next(it)
315
316
c182d7dd
SM
317def _setup_seek_test(
318 sink_cls,
319 user_seek_beginning=None,
320 user_can_seek_beginning=None,
321 user_seek_ns_from_origin=None,
322 user_can_seek_ns_from_origin=None,
323):
0a6d7302
SM
324 class MySourceIter(bt2._UserMessageIterator):
325 def __init__(self, port):
326 tc, sc, ec = port.user_data
327 trace = tc()
328 stream = trace.create_stream(sc)
329 packet = stream.create_packet()
330
331 self._msgs = [
332 self._create_stream_beginning_message(stream),
333 self._create_packet_beginning_message(packet),
334 self._create_event_message(ec, packet),
335 self._create_event_message(ec, packet),
336 self._create_packet_end_message(packet),
337 self._create_stream_end_message(stream),
338 ]
339 self._at = 0
340
341 def __next__(self):
342 if self._at < len(self._msgs):
343 msg = self._msgs[self._at]
344 self._at += 1
345 return msg
346 else:
347 raise StopIteration
348
349 if user_seek_beginning is not None:
350 MySourceIter._user_seek_beginning = user_seek_beginning
351
352 if user_can_seek_beginning is not None:
14cfc8ce 353 MySourceIter._user_can_seek_beginning = user_can_seek_beginning
0a6d7302 354
c182d7dd
SM
355 if user_seek_ns_from_origin is not None:
356 MySourceIter._user_seek_ns_from_origin = user_seek_ns_from_origin
357
358 if user_can_seek_ns_from_origin is not None:
359 MySourceIter._user_can_seek_ns_from_origin = user_can_seek_ns_from_origin
360
0a6d7302 361 class MySource(bt2._UserSourceComponent, message_iterator_class=MySourceIter):
59225a3e 362 def __init__(self, config, params, obj):
0a6d7302
SM
363 tc = self._create_trace_class()
364 sc = tc.create_stream_class(supports_packets=True)
365 ec = sc.create_event_class()
366
367 self._add_output_port('out', (tc, sc, ec))
368
369 class MyFilterIter(bt2._UserMessageIterator):
370 def __init__(self, port):
371 self._upstream_iter = self._create_input_port_message_iterator(
372 self._component._input_ports['in']
373 )
374
375 def __next__(self):
376 return next(self._upstream_iter)
377
0a6d7302 378 def _user_can_seek_beginning(self):
14cfc8ce 379 return self._upstream_iter.can_seek_beginning()
0a6d7302
SM
380
381 def _user_seek_beginning(self):
382 self._upstream_iter.seek_beginning()
383
c182d7dd
SM
384 def _user_can_seek_ns_from_origin(self, ns_from_origin):
385 return self._upstream_iter.can_seek_ns_from_origin(ns_from_origin)
386
387 def _user_seek_ns_from_origin(self, ns_from_origin):
388 self._upstream_iter.seek_ns_from_origin(ns_from_origin)
389
0a6d7302 390 class MyFilter(bt2._UserFilterComponent, message_iterator_class=MyFilterIter):
59225a3e 391 def __init__(self, config, params, obj):
0a6d7302
SM
392 self._add_input_port('in')
393 self._add_output_port('out')
394
395 return _create_graph(MySource, sink_cls, flt_comp_cls=MyFilter)
f00b8d40 396
0a6d7302
SM
397
398class UserMessageIteratorSeekBeginningTestCase(unittest.TestCase):
f00b8d40 399 def test_can_seek_beginning(self):
6c373cc9 400 class MySink(bt2._UserSinkComponent):
59225a3e 401 def __init__(self, config, params, obj):
6c373cc9
PP
402 self._add_input_port('in')
403
404 def _user_graph_is_configured(self):
405 self._msg_iter = self._create_input_port_message_iterator(
406 self._input_ports['in']
407 )
408
409 def _user_consume(self):
410 nonlocal can_seek_beginning
14cfc8ce 411 can_seek_beginning = self._msg_iter.can_seek_beginning()
6c373cc9 412
6a91742b 413 def _user_can_seek_beginning(self):
6c373cc9
PP
414 nonlocal input_port_iter_can_seek_beginning
415 return input_port_iter_can_seek_beginning
f00b8d40 416
0a6d7302
SM
417 graph = _setup_seek_test(
418 MySink, user_can_seek_beginning=_user_can_seek_beginning
419 )
f00b8d40 420
6c373cc9
PP
421 input_port_iter_can_seek_beginning = True
422 can_seek_beginning = None
423 graph.run_once()
7f0c21bb 424 self.assertIs(can_seek_beginning, True)
f00b8d40 425
6c373cc9
PP
426 input_port_iter_can_seek_beginning = False
427 can_seek_beginning = None
428 graph.run_once()
7f0c21bb 429 self.assertIs(can_seek_beginning, False)
f00b8d40 430
0a6d7302
SM
431 def test_no_can_seek_beginning_with_seek_beginning(self):
432 # Test an iterator without a _user_can_seek_beginning method, but with
433 # a _user_seek_beginning method.
434 class MySink(bt2._UserSinkComponent):
59225a3e 435 def __init__(self, config, params, obj):
0a6d7302
SM
436 self._add_input_port('in')
437
438 def _user_graph_is_configured(self):
439 self._msg_iter = self._create_input_port_message_iterator(
440 self._input_ports['in']
441 )
442
443 def _user_consume(self):
444 nonlocal can_seek_beginning
14cfc8ce 445 can_seek_beginning = self._msg_iter.can_seek_beginning()
0a6d7302
SM
446
447 def _user_seek_beginning(self):
448 pass
f00b8d40 449
0a6d7302 450 graph = _setup_seek_test(MySink, user_seek_beginning=_user_seek_beginning)
6c373cc9
PP
451 can_seek_beginning = None
452 graph.run_once()
7f0c21bb 453 self.assertIs(can_seek_beginning, True)
f00b8d40 454
0a6d7302
SM
455 def test_no_can_seek_beginning(self):
456 # Test an iterator without a _user_can_seek_beginning method, without
457 # a _user_seek_beginning method.
458 class MySink(bt2._UserSinkComponent):
59225a3e 459 def __init__(self, config, params, obj):
0a6d7302
SM
460 self._add_input_port('in')
461
462 def _user_graph_is_configured(self):
463 self._msg_iter = self._create_input_port_message_iterator(
464 self._input_ports['in']
465 )
466
467 def _user_consume(self):
468 nonlocal can_seek_beginning
14cfc8ce 469 can_seek_beginning = self._msg_iter.can_seek_beginning()
0a6d7302
SM
470
471 graph = _setup_seek_test(MySink)
6c373cc9
PP
472 can_seek_beginning = None
473 graph.run_once()
7f0c21bb 474 self.assertIs(can_seek_beginning, False)
f00b8d40 475
f2fb1b32
SM
476 def test_can_seek_beginning_user_error(self):
477 class MySink(bt2._UserSinkComponent):
59225a3e 478 def __init__(self, config, params, obj):
f2fb1b32
SM
479 self._add_input_port('in')
480
481 def _user_graph_is_configured(self):
482 self._msg_iter = self._create_input_port_message_iterator(
483 self._input_ports['in']
484 )
485
486 def _user_consume(self):
487 # This is expected to raise.
14cfc8ce 488 self._msg_iter.can_seek_beginning()
f2fb1b32
SM
489
490 def _user_can_seek_beginning(self):
491 raise ValueError('moustiquaire')
492
493 graph = _setup_seek_test(
494 MySink, user_can_seek_beginning=_user_can_seek_beginning
495 )
496
497 with self.assertRaises(bt2._Error) as ctx:
498 graph.run_once()
499
500 cause = ctx.exception[0]
501 self.assertIn('ValueError: moustiquaire', cause.message)
502
503 def test_can_seek_beginning_wrong_return_value(self):
504 class MySink(bt2._UserSinkComponent):
59225a3e 505 def __init__(self, config, params, obj):
f2fb1b32
SM
506 self._add_input_port('in')
507
508 def _user_graph_is_configured(self):
509 self._msg_iter = self._create_input_port_message_iterator(
510 self._input_ports['in']
511 )
512
513 def _user_consume(self):
514 # This is expected to raise.
14cfc8ce 515 self._msg_iter.can_seek_beginning()
f2fb1b32
SM
516
517 def _user_can_seek_beginning(self):
518 return 'Amqui'
519
520 graph = _setup_seek_test(
521 MySink, user_can_seek_beginning=_user_can_seek_beginning
522 )
523
524 with self.assertRaises(bt2._Error) as ctx:
525 graph.run_once()
526
527 cause = ctx.exception[0]
528 self.assertIn("TypeError: 'str' is not a 'bool' object", cause.message)
529
f00b8d40 530 def test_seek_beginning(self):
6c373cc9 531 class MySink(bt2._UserSinkComponent):
59225a3e 532 def __init__(self, config, params, obj):
6c373cc9 533 self._add_input_port('in')
f00b8d40 534
6c373cc9
PP
535 def _user_graph_is_configured(self):
536 self._msg_iter = self._create_input_port_message_iterator(
537 self._input_ports['in']
538 )
539
540 def _user_consume(self):
541 nonlocal do_seek_beginning
542 nonlocal msg
543
544 if do_seek_beginning:
545 self._msg_iter.seek_beginning()
546 return
547
548 msg = next(self._msg_iter)
549
0a6d7302
SM
550 def _user_seek_beginning(self):
551 self._at = 0
552
6c373cc9 553 msg = None
0a6d7302
SM
554 graph = _setup_seek_test(MySink, user_seek_beginning=_user_seek_beginning)
555
556 # Consume message.
557 do_seek_beginning = False
6c373cc9 558 graph.run_once()
f0a42b33 559 self.assertIs(type(msg), bt2._StreamBeginningMessageConst)
0a6d7302
SM
560
561 # Consume message.
6c373cc9 562 graph.run_once()
f0a42b33 563 self.assertIs(type(msg), bt2._PacketBeginningMessageConst)
0a6d7302
SM
564
565 # Seek beginning.
6c373cc9
PP
566 do_seek_beginning = True
567 graph.run_once()
0a6d7302
SM
568
569 # Consume message.
6c373cc9
PP
570 do_seek_beginning = False
571 graph.run_once()
f0a42b33 572 self.assertIs(type(msg), bt2._StreamBeginningMessageConst)
f00b8d40 573
6c373cc9
PP
574 def test_seek_beginning_user_error(self):
575 class MySink(bt2._UserSinkComponent):
59225a3e 576 def __init__(self, config, params, obj):
6c373cc9 577 self._add_input_port('in')
f00b8d40 578
6c373cc9
PP
579 def _user_graph_is_configured(self):
580 self._msg_iter = self._create_input_port_message_iterator(
581 self._input_ports['in']
582 )
f00b8d40 583
6c373cc9
PP
584 def _user_consume(self):
585 self._msg_iter.seek_beginning()
f00b8d40 586
0a6d7302 587 def _user_seek_beginning(self):
cfbd7cf3 588 raise ValueError('ouch')
f00b8d40 589
0a6d7302 590 graph = _setup_seek_test(MySink, user_seek_beginning=_user_seek_beginning)
f00b8d40 591
694c792b 592 with self.assertRaises(bt2._Error):
6c373cc9 593 graph.run_once()
f00b8d40
SM
594
595
c182d7dd
SM
596class UserMessageIteratorSeekNsFromOriginTestCase(unittest.TestCase):
597 def test_can_seek_ns_from_origin(self):
598 class MySink(bt2._UserSinkComponent):
59225a3e 599 def __init__(self, config, params, obj):
c182d7dd
SM
600 self._add_input_port('in')
601
602 def _user_graph_is_configured(self):
603 self._msg_iter = self._create_input_port_message_iterator(
604 self._input_ports['in']
605 )
606
607 def _user_consume(self):
608 nonlocal can_seek_ns_from_origin
609 nonlocal test_ns_from_origin
610 can_seek_ns_from_origin = self._msg_iter.can_seek_ns_from_origin(
611 test_ns_from_origin
612 )
613
614 def _user_can_seek_ns_from_origin(iter_self, ns_from_origin):
615 nonlocal input_port_iter_can_seek_ns_from_origin
616 nonlocal test_ns_from_origin
617 self.assertEqual(ns_from_origin, test_ns_from_origin)
618 return input_port_iter_can_seek_ns_from_origin
619
620 graph = _setup_seek_test(
621 MySink, user_can_seek_ns_from_origin=_user_can_seek_ns_from_origin
622 )
623
624 input_port_iter_can_seek_ns_from_origin = True
625 can_seek_ns_from_origin = None
626 test_ns_from_origin = 1
627 graph.run_once()
628 self.assertIs(can_seek_ns_from_origin, True)
629
630 input_port_iter_can_seek_ns_from_origin = False
631 can_seek_ns_from_origin = None
632 test_ns_from_origin = 2
633 graph.run_once()
634 self.assertIs(can_seek_ns_from_origin, False)
635
636 def test_no_can_seek_ns_from_origin_with_seek_ns_from_origin(self):
637 # Test an iterator without a _user_can_seek_ns_from_origin method, but
638 # with a _user_seek_ns_from_origin method.
639 class MySink(bt2._UserSinkComponent):
59225a3e 640 def __init__(self, config, params, obj):
c182d7dd
SM
641 self._add_input_port('in')
642
643 def _user_graph_is_configured(self):
644 self._msg_iter = self._create_input_port_message_iterator(
645 self._input_ports['in']
646 )
647
648 def _user_consume(self):
649 nonlocal can_seek_ns_from_origin
650 nonlocal test_ns_from_origin
651 can_seek_ns_from_origin = self._msg_iter.can_seek_ns_from_origin(
652 test_ns_from_origin
653 )
654
655 def _user_seek_ns_from_origin(self):
656 pass
657
658 graph = _setup_seek_test(
659 MySink, user_seek_ns_from_origin=_user_seek_ns_from_origin
660 )
661 can_seek_ns_from_origin = None
662 test_ns_from_origin = 2
663 graph.run_once()
664 self.assertIs(can_seek_ns_from_origin, True)
665
666 def test_no_can_seek_ns_from_origin_with_seek_beginning(self):
667 # Test an iterator without a _user_can_seek_ns_from_origin method, but
668 # with a _user_seek_beginning method.
669 class MySink(bt2._UserSinkComponent):
59225a3e 670 def __init__(self, config, params, obj):
c182d7dd
SM
671 self._add_input_port('in')
672
673 def _user_graph_is_configured(self):
674 self._msg_iter = self._create_input_port_message_iterator(
675 self._input_ports['in']
676 )
677
678 def _user_consume(self):
679 nonlocal can_seek_ns_from_origin
680 nonlocal test_ns_from_origin
681 can_seek_ns_from_origin = self._msg_iter.can_seek_ns_from_origin(
682 test_ns_from_origin
683 )
684
685 def _user_seek_beginning(self):
686 pass
687
688 graph = _setup_seek_test(MySink, user_seek_beginning=_user_seek_beginning)
689 can_seek_ns_from_origin = None
690 test_ns_from_origin = 2
691 graph.run_once()
692 self.assertIs(can_seek_ns_from_origin, True)
693
694 def test_no_can_seek_ns_from_origin(self):
695 # Test an iterator without a _user_can_seek_ns_from_origin method
696 # and no other related method.
697 class MySink(bt2._UserSinkComponent):
59225a3e 698 def __init__(self, config, params, obj):
c182d7dd
SM
699 self._add_input_port('in')
700
701 def _user_graph_is_configured(self):
702 self._msg_iter = self._create_input_port_message_iterator(
703 self._input_ports['in']
704 )
705
706 def _user_consume(self):
707 nonlocal can_seek_ns_from_origin
708 nonlocal test_ns_from_origin
709 can_seek_ns_from_origin = self._msg_iter.can_seek_ns_from_origin(
710 test_ns_from_origin
711 )
712
713 graph = _setup_seek_test(MySink)
714 can_seek_ns_from_origin = None
715 test_ns_from_origin = 2
716 graph.run_once()
717 self.assertIs(can_seek_ns_from_origin, False)
718
719 def test_can_seek_ns_from_origin_user_error(self):
720 class MySink(bt2._UserSinkComponent):
59225a3e 721 def __init__(self, config, params, obj):
c182d7dd
SM
722 self._add_input_port('in')
723
724 def _user_graph_is_configured(self):
725 self._msg_iter = self._create_input_port_message_iterator(
726 self._input_ports['in']
727 )
728
729 def _user_consume(self):
730 # This is expected to raise.
731 self._msg_iter.can_seek_ns_from_origin(2)
732
733 def _user_can_seek_ns_from_origin(self, ns_from_origin):
734 raise ValueError('Joutel')
735
736 graph = _setup_seek_test(
737 MySink, user_can_seek_ns_from_origin=_user_can_seek_ns_from_origin
738 )
739
740 with self.assertRaises(bt2._Error) as ctx:
741 graph.run_once()
742
743 cause = ctx.exception[0]
744 self.assertIn('ValueError: Joutel', cause.message)
745
746 def test_can_seek_ns_from_origin_wrong_return_value(self):
747 class MySink(bt2._UserSinkComponent):
59225a3e 748 def __init__(self, config, params, obj):
c182d7dd
SM
749 self._add_input_port('in')
750
751 def _user_graph_is_configured(self):
752 self._msg_iter = self._create_input_port_message_iterator(
753 self._input_ports['in']
754 )
755
756 def _user_consume(self):
757 # This is expected to raise.
758 self._msg_iter.can_seek_ns_from_origin(2)
759
760 def _user_can_seek_ns_from_origin(self, ns_from_origin):
761 return 'Nitchequon'
762
763 graph = _setup_seek_test(
764 MySink, user_can_seek_ns_from_origin=_user_can_seek_ns_from_origin
765 )
766
767 with self.assertRaises(bt2._Error) as ctx:
768 graph.run_once()
769
770 cause = ctx.exception[0]
771 self.assertIn("TypeError: 'str' is not a 'bool' object", cause.message)
772
773 def test_seek_ns_from_origin(self):
774 class MySink(bt2._UserSinkComponent):
59225a3e 775 def __init__(self, config, params, obj):
c182d7dd
SM
776 self._add_input_port('in')
777
778 def _user_graph_is_configured(self):
779 self._msg_iter = self._create_input_port_message_iterator(
780 self._input_ports['in']
781 )
782
783 def _user_consume(self):
784 self._msg_iter.seek_ns_from_origin(17)
785
786 def _user_seek_ns_from_origin(self, ns_from_origin):
787 nonlocal actual_ns_from_origin
788 actual_ns_from_origin = ns_from_origin
789
790 msg = None
791 graph = _setup_seek_test(
792 MySink, user_seek_ns_from_origin=_user_seek_ns_from_origin
793 )
794
795 actual_ns_from_origin = None
796 graph.run_once()
797 self.assertEqual(actual_ns_from_origin, 17)
798
799
f00b8d40
SM
800if __name__ == '__main__':
801 unittest.main()
This page took 0.076988 seconds and 4 git commands to generate.