bt2: Add `_Clock*Const` classes and adapt tests
[babeltrace.git] / tests / bindings / python / bt2 / test_graph.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
PP
20import bt2
21
22
5f25509b 23class _MyIter(bt2._UserMessageIterator):
c5f330cd 24 def __init__(self, self_output_port):
5f25509b
SM
25 self._build_meta()
26 self._at = 0
27
28 def _build_meta(self):
29 self._tc = self._component._create_trace_class()
30 self._t = self._tc()
26fc5aed 31 self._sc = self._tc.create_stream_class(supports_packets=True)
5f25509b
SM
32 self._ec = self._sc.create_event_class(name='salut')
33 self._my_int_ft = self._tc.create_signed_integer_field_class(32)
34 payload_ft = self._tc.create_structure_field_class()
cfbd7cf3 35 payload_ft += [('my_int', self._my_int_ft)]
5f25509b
SM
36 self._ec.payload_field_type = payload_ft
37 self._stream = self._t.create_stream(self._sc)
38 self._packet = self._stream.create_packet()
39
40 def _create_event(self, value):
41 ev = self._ec()
42 ev.payload_field['my_int'] = value
43 ev.packet = self._packet
44 return ev
45
46
811644b8
PP
47class GraphTestCase(unittest.TestCase):
48 def setUp(self):
49 self._graph = bt2.Graph()
50
51 def tearDown(self):
52 del self._graph
53
056deb59
PP
54 def test_create_default(self):
55 bt2.Graph()
56
57 def test_create_known_mip_version(self):
58 bt2.Graph(0)
59
60 def test_create_invalid_mip_version_type(self):
61 with self.assertRaises(TypeError):
62 bt2.Graph('')
63
64 def test_create_unknown_mip_version(self):
65 with self.assertRaisesRegex(ValueError, 'unknown MIP version'):
66 bt2.Graph(1)
811644b8
PP
67
68 def test_add_component_user_cls(self):
69 class MySink(bt2._UserSinkComponent):
6a91742b 70 def _user_consume(self):
a01b452b 71 pass
811644b8
PP
72
73 comp = self._graph.add_component(MySink, 'salut')
74 self.assertEqual(comp.name, 'salut')
75
76 def test_add_component_gen_cls(self):
77 class MySink(bt2._UserSinkComponent):
6a91742b 78 def _user_consume(self):
a01b452b 79 pass
811644b8
PP
80
81 comp = self._graph.add_component(MySink, 'salut')
5f25509b 82 assert comp
e8ac1aae 83 comp2 = self._graph.add_component(comp.cls, 'salut2')
811644b8
PP
84 self.assertEqual(comp2.name, 'salut2')
85
86 def test_add_component_params(self):
87 comp_params = None
88
89 class MySink(bt2._UserSinkComponent):
66964f3f 90 def __init__(self, params, obj):
811644b8
PP
91 nonlocal comp_params
92 comp_params = params
93
6a91742b 94 def _user_consume(self):
a01b452b 95 pass
811644b8
PP
96
97 params = {'hello': 23, 'path': '/path/to/stuff'}
082db648 98 self._graph.add_component(MySink, 'salut', params)
811644b8
PP
99 self.assertEqual(params, comp_params)
100 del comp_params
101
66964f3f
PP
102 def test_add_component_obj_python_comp_cls(self):
103 comp_obj = None
104
105 class MySink(bt2._UserSinkComponent):
106 def __init__(self, params, obj):
107 nonlocal comp_obj
108 comp_obj = obj
109
110 def _user_consume(self):
111 pass
112
113 obj = object()
082db648 114 self._graph.add_component(MySink, 'salut', obj=obj)
66964f3f
PP
115 self.assertIs(comp_obj, obj)
116 del comp_obj
117
118 def test_add_component_obj_none_python_comp_cls(self):
119 comp_obj = None
120
121 class MySink(bt2._UserSinkComponent):
122 def __init__(self, params, obj):
123 nonlocal comp_obj
124 comp_obj = obj
125
126 def _user_consume(self):
127 pass
128
082db648 129 self._graph.add_component(MySink, 'salut')
66964f3f
PP
130 self.assertIsNone(comp_obj)
131 del comp_obj
132
133 def test_add_component_obj_non_python_comp_cls(self):
66964f3f
PP
134 plugin = bt2.find_plugin('text', find_in_user_dir=False, find_in_sys_dir=False)
135 assert plugin is not None
136 cc = plugin.source_component_classes['dmesg']
137 assert cc is not None
138
139 with self.assertRaises(ValueError):
082db648 140 self._graph.add_component(cc, 'salut', obj=57)
66964f3f 141
811644b8
PP
142 def test_add_component_invalid_cls_type(self):
143 with self.assertRaises(TypeError):
144 self._graph.add_component(int, 'salut')
145
8ef46e79
PP
146 def test_add_component_invalid_logging_level_type(self):
147 class MySink(bt2._UserSinkComponent):
6a91742b 148 def _user_consume(self):
a01b452b 149 pass
8ef46e79
PP
150
151 with self.assertRaises(TypeError):
152 self._graph.add_component(MySink, 'salut', logging_level='yo')
153
154 def test_add_component_invalid_logging_level_value(self):
155 class MySink(bt2._UserSinkComponent):
6a91742b 156 def _user_consume(self):
a01b452b 157 pass
8ef46e79
PP
158
159 with self.assertRaises(ValueError):
160 self._graph.add_component(MySink, 'salut', logging_level=12345)
161
162 def test_add_component_logging_level(self):
163 class MySink(bt2._UserSinkComponent):
6a91742b 164 def _user_consume(self):
a01b452b 165 pass
8ef46e79 166
cfbd7cf3
FD
167 comp = self._graph.add_component(
168 MySink, 'salut', logging_level=bt2.LoggingLevel.DEBUG
169 )
8ef46e79
PP
170 self.assertEqual(comp.logging_level, bt2.LoggingLevel.DEBUG)
171
811644b8 172 def test_connect_ports(self):
5602ef81 173 class MyIter(bt2._UserMessageIterator):
811644b8
PP
174 def __next__(self):
175 raise bt2.Stop
176
cfbd7cf3 177 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 178 def __init__(self, params, obj):
811644b8
PP
179 self._add_output_port('out')
180
181 class MySink(bt2._UserSinkComponent):
66964f3f 182 def __init__(self, params, obj):
811644b8
PP
183 self._add_input_port('in')
184
6a91742b 185 def _user_consume(self):
811644b8
PP
186 raise bt2.Stop
187
188 src = self._graph.add_component(MySource, 'src')
189 sink = self._graph.add_component(MySink, 'sink')
5f25509b 190
cfbd7cf3
FD
191 conn = self._graph.connect_ports(
192 src.output_ports['out'], sink.input_ports['in']
193 )
811644b8
PP
194 self.assertTrue(src.output_ports['out'].is_connected)
195 self.assertTrue(sink.input_ports['in'].is_connected)
89b5033a
FD
196 self.assertEqual(src.output_ports['out'].connection.addr, conn.addr)
197 self.assertEqual(sink.input_ports['in'].connection.addr, conn.addr)
811644b8
PP
198
199 def test_connect_ports_invalid_direction(self):
5602ef81 200 class MyIter(bt2._UserMessageIterator):
811644b8
PP
201 def __next__(self):
202 raise bt2.Stop
203
cfbd7cf3 204 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 205 def __init__(self, params, obj):
811644b8
PP
206 self._add_output_port('out')
207
208 class MySink(bt2._UserSinkComponent):
66964f3f 209 def __init__(self, params, obj):
811644b8
PP
210 self._add_input_port('in')
211
6a91742b 212 def _user_consume(self):
811644b8
PP
213 raise bt2.Stop
214
215 src = self._graph.add_component(MySource, 'src')
216 sink = self._graph.add_component(MySink, 'sink')
217
218 with self.assertRaises(TypeError):
082db648 219 self._graph.connect_ports(sink.input_ports['in'], src.output_ports['out'])
811644b8 220
9b4f9b42
PP
221 def test_add_interrupter(self):
222 class MyIter(bt2._UserMessageIterator):
223 def __next__(self):
224 raise TypeError
225
226 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 227 def __init__(self, params, obj):
9b4f9b42
PP
228 self._add_output_port('out')
229
230 class MySink(bt2._UserSinkComponent):
66964f3f 231 def __init__(self, params, obj):
9b4f9b42
PP
232 self._add_input_port('in')
233
6a91742b 234 def _user_consume(self):
9b4f9b42
PP
235 next(self._msg_iter)
236
6a91742b 237 def _user_graph_is_configured(self):
9b4f9b42
PP
238 self._msg_iter = self._create_input_port_message_iterator(
239 self._input_ports['in']
240 )
241
242 # add two interrupters, set one of them
243 interrupter1 = bt2.Interrupter()
244 interrupter2 = bt2.Interrupter()
245 self._graph.add_interrupter(interrupter1)
246 src = self._graph.add_component(MySource, 'src')
247 sink = self._graph.add_component(MySink, 'sink')
248 self._graph.connect_ports(src.output_ports['out'], sink.input_ports['in'])
249 self._graph.add_interrupter(interrupter2)
250
251 with self.assertRaises(bt2._Error):
252 self._graph.run()
253
254 interrupter2.set()
255
256 with self.assertRaises(bt2.TryAgain):
257 self._graph.run()
258
259 interrupter2.reset()
260
261 with self.assertRaises(bt2._Error):
262 self._graph.run()
263
264 # Test that Graph.run() raises bt2.Interrupted if the graph gets
265 # interrupted during execution.
266 def test_interrupt_while_running(self):
5f25509b 267 class MyIter(_MyIter):
1d915789 268 def __next__(self):
5f25509b 269 return self._create_stream_beginning_message(self._stream)
1d915789 270
cfbd7cf3 271 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 272 def __init__(self, params, obj):
1d915789
PP
273 self._add_output_port('out')
274
275 class MySink(bt2._UserSinkComponent):
66964f3f 276 def __init__(self, params, obj):
1d915789
PP
277 self._add_input_port('in')
278
6a91742b 279 def _user_consume(self):
9b4f9b42 280 # Pretend that somebody asynchronously interrupted the graph.
5f25509b 281 nonlocal graph
9b4f9b42 282 graph.interrupt()
5f25509b 283 return next(self._msg_iter)
1d915789 284
6a91742b 285 def _user_graph_is_configured(self):
ca02df0a
PP
286 self._msg_iter = self._create_input_port_message_iterator(
287 self._input_ports['in']
288 )
1d915789 289
9b4f9b42
PP
290 graph = self._graph
291 up = self._graph.add_component(MySource, 'down')
292 down = self._graph.add_component(MySink, 'up')
293 self._graph.connect_ports(up.output_ports['out'], down.input_ports['in'])
294
295 with self.assertRaises(bt2.TryAgain):
296 self._graph.run()
811644b8
PP
297
298 def test_run(self):
5f25509b 299 class MyIter(_MyIter):
811644b8 300 def __next__(self):
5f25509b
SM
301 if self._at == 9:
302 raise StopIteration
303
304 if self._at == 0:
305 msg = self._create_stream_beginning_message(self._stream)
306 elif self._at == 1:
307 msg = self._create_packet_beginning_message(self._packet)
308 elif self._at == 7:
309 msg = self._create_packet_end_message(self._packet)
310 elif self._at == 8:
311 msg = self._create_stream_end_message(self._stream)
312 else:
313 msg = self._create_event_message(self._ec, self._packet)
811644b8 314
811644b8 315 self._at += 1
5602ef81 316 return msg
811644b8 317
cfbd7cf3 318 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 319 def __init__(self, params, obj):
811644b8
PP
320 self._add_output_port('out')
321
322 class MySink(bt2._UserSinkComponent):
66964f3f 323 def __init__(self, params, obj):
5f25509b 324 self._input_port = self._add_input_port('in')
811644b8
PP
325 self._at = 0
326
6a91742b 327 def _user_consume(comp_self):
5602ef81 328 msg = next(comp_self._msg_iter)
811644b8
PP
329
330 if comp_self._at == 0:
3fb99a22 331 self.assertIsInstance(msg, bt2._StreamBeginningMessage)
811644b8 332 elif comp_self._at == 1:
3fb99a22 333 self.assertIsInstance(msg, bt2._PacketBeginningMessage)
811644b8 334 elif comp_self._at >= 2 and comp_self._at <= 6:
3fb99a22 335 self.assertIsInstance(msg, bt2._EventMessage)
e8ac1aae 336 self.assertEqual(msg.event.cls.name, 'salut')
811644b8 337 elif comp_self._at == 7:
3fb99a22 338 self.assertIsInstance(msg, bt2._PacketEndMessage)
811644b8 339 elif comp_self._at == 8:
3fb99a22 340 self.assertIsInstance(msg, bt2._StreamEndMessage)
811644b8
PP
341
342 comp_self._at += 1
343
6a91742b 344 def _user_graph_is_configured(self):
ca02df0a
PP
345 self._msg_iter = self._create_input_port_message_iterator(
346 self._input_port
347 )
811644b8
PP
348
349 src = self._graph.add_component(MySource, 'src')
350 sink = self._graph.add_component(MySink, 'sink')
082db648 351 self._graph.connect_ports(src.output_ports['out'], sink.input_ports['in'])
811644b8
PP
352 self._graph.run()
353
8cc0e6ea
PP
354 def test_run_once(self):
355 class MyIter(_MyIter):
356 pass
357
358 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
359 def __init__(self, params, obj):
360 self._add_output_port('out')
361
362 class MySink(bt2._UserSinkComponent):
363 def __init__(self, params, obj):
364 self._input_port = self._add_input_port('in')
365
366 def _user_consume(comp_self):
367 nonlocal run_count
368 run_count += 1
369 raise bt2.TryAgain
370
371 run_count = 0
372 src = self._graph.add_component(MySource, 'src')
373 sink = self._graph.add_component(MySink, 'sink')
082db648 374 self._graph.connect_ports(src.output_ports['out'], sink.input_ports['in'])
8cc0e6ea
PP
375
376 with self.assertRaises(bt2.TryAgain):
377 self._graph.run_once()
378
379 self.assertEqual(run_count, 1)
380
381 def test_run_once_stops(self):
382 class MyIter(_MyIter):
383 pass
384
385 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
386 def __init__(self, params, obj):
387 self._add_output_port('out')
388
389 class MySink(bt2._UserSinkComponent):
390 def __init__(self, params, obj):
391 self._input_port = self._add_input_port('in')
392
393 def _user_consume(comp_self):
394 raise bt2.Stop
395
396 src = self._graph.add_component(MySource, 'src')
397 sink = self._graph.add_component(MySink, 'sink')
082db648 398 self._graph.connect_ports(src.output_ports['out'], sink.input_ports['in'])
8cc0e6ea
PP
399
400 with self.assertRaises(bt2.Stop):
401 self._graph.run_once()
402
811644b8 403 def test_run_again(self):
5f25509b 404 class MyIter(_MyIter):
811644b8 405 def __next__(self):
5f25509b 406 if self._at == 3:
811644b8
PP
407 raise bt2.TryAgain
408
5f25509b
SM
409 if self._at == 0:
410 msg = self._create_stream_beginning_message(self._stream)
411 elif self._at == 1:
412 msg = self._create_packet_beginning_message(self._packet)
413 elif self._at == 2:
414 msg = self._create_event_message(self._ec, self._packet)
415
811644b8 416 self._at += 1
5602ef81 417 return msg
811644b8 418
cfbd7cf3 419 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 420 def __init__(self, params, obj):
811644b8
PP
421 self._add_output_port('out')
422
423 class MySink(bt2._UserSinkComponent):
66964f3f 424 def __init__(self, params, obj):
5f25509b 425 self._input_port = self._add_input_port('in')
811644b8
PP
426 self._at = 0
427
6a91742b 428 def _user_consume(comp_self):
5f25509b 429 msg = next(comp_self._msg_iter)
811644b8 430 if comp_self._at == 0:
3fb99a22 431 self.assertIsInstance(msg, bt2._StreamBeginningMessage)
811644b8 432 elif comp_self._at == 1:
3fb99a22 433 self.assertIsInstance(msg, bt2._PacketBeginningMessage)
5f25509b 434 elif comp_self._at == 2:
3fb99a22 435 self.assertIsInstance(msg, bt2._EventMessage)
811644b8 436 raise bt2.TryAgain
5f25509b
SM
437 else:
438 pass
811644b8
PP
439
440 comp_self._at += 1
441
6a91742b 442 def _user_graph_is_configured(self):
ca02df0a
PP
443 self._msg_iter = self._create_input_port_message_iterator(
444 self._input_port
445 )
811644b8
PP
446
447 src = self._graph.add_component(MySource, 'src')
448 sink = self._graph.add_component(MySink, 'sink')
082db648 449 self._graph.connect_ports(src.output_ports['out'], sink.input_ports['in'])
811644b8
PP
450
451 with self.assertRaises(bt2.TryAgain):
452 self._graph.run()
453
811644b8 454 def test_run_error(self):
5f25509b 455 raised_in_sink = False
811644b8 456
5f25509b 457 class MyIter(_MyIter):
811644b8 458 def __next__(self):
5f25509b
SM
459 # If this gets called after the sink raised an exception, it is
460 # an error.
461 nonlocal raised_in_sink
462 assert raised_in_sink is False
463
464 if self._at == 0:
465 msg = self._create_stream_beginning_message(self._stream)
466 elif self._at == 1:
467 msg = self._create_packet_beginning_message(self._packet)
468 elif self._at == 2 or self._at == 3:
469 msg = self._create_event_message(self._ec, self._packet)
470 else:
811644b8 471 raise bt2.TryAgain
811644b8 472 self._at += 1
5602ef81 473 return msg
811644b8 474
cfbd7cf3 475 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 476 def __init__(self, params, obj):
811644b8
PP
477 self._add_output_port('out')
478
479 class MySink(bt2._UserSinkComponent):
66964f3f 480 def __init__(self, params, obj):
5f25509b 481 self._input_port = self._add_input_port('in')
811644b8
PP
482 self._at = 0
483
6a91742b 484 def _user_consume(comp_self):
5f25509b 485 msg = next(comp_self._msg_iter)
811644b8 486 if comp_self._at == 0:
3fb99a22 487 self.assertIsInstance(msg, bt2._StreamBeginningMessage)
811644b8 488 elif comp_self._at == 1:
3fb99a22 489 self.assertIsInstance(msg, bt2._PacketBeginningMessage)
5f25509b 490 elif comp_self._at == 2:
3fb99a22 491 self.assertIsInstance(msg, bt2._EventMessage)
5f25509b
SM
492 elif comp_self._at == 3:
493 nonlocal raised_in_sink
494 raised_in_sink = True
811644b8
PP
495 raise RuntimeError('error!')
496
497 comp_self._at += 1
498
6a91742b 499 def _user_graph_is_configured(self):
ca02df0a
PP
500 self._msg_iter = self._create_input_port_message_iterator(
501 self._input_port
502 )
811644b8
PP
503
504 src = self._graph.add_component(MySource, 'src')
505 sink = self._graph.add_component(MySink, 'sink')
082db648 506 self._graph.connect_ports(src.output_ports['out'], sink.input_ports['in'])
811644b8 507
694c792b 508 with self.assertRaises(bt2._Error):
811644b8
PP
509 self._graph.run()
510
5f25509b 511 def test_listeners(self):
5602ef81 512 class MyIter(bt2._UserMessageIterator):
5f25509b
SM
513 def __next__(self):
514 raise bt2.Stop
1d915789 515
cfbd7cf3 516 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 517 def __init__(self, params, obj):
1d915789 518 self._add_output_port('out')
5f25509b 519 self._add_output_port('zero')
1d915789
PP
520
521 class MySink(bt2._UserSinkComponent):
66964f3f 522 def __init__(self, params, obj):
1d915789 523 self._add_input_port('in')
1d915789 524
6a91742b 525 def _user_consume(self):
5f25509b 526 raise bt2.Stop
1d915789 527
6a91742b 528 def _user_port_connected(self, port, other_port):
5f25509b 529 self._add_input_port('taste')
1d915789 530
5f25509b
SM
531 def port_added_listener(component, port):
532 nonlocal calls
533 calls.append((port_added_listener, component, port))
1d915789 534
cfbd7cf3
FD
535 def ports_connected_listener(
536 upstream_component, upstream_port, downstream_component, downstream_port
537 ):
5f25509b 538 nonlocal calls
cfbd7cf3
FD
539 calls.append(
540 (
541 ports_connected_listener,
542 upstream_component,
543 upstream_port,
544 downstream_component,
545 downstream_port,
546 )
547 )
5f25509b
SM
548
549 calls = []
550 self._graph.add_port_added_listener(port_added_listener)
551 self._graph.add_ports_connected_listener(ports_connected_listener)
1d915789
PP
552 src = self._graph.add_component(MySource, 'src')
553 sink = self._graph.add_component(MySink, 'sink')
cfbd7cf3 554 self._graph.connect_ports(src.output_ports['out'], sink.input_ports['in'])
1d915789 555
5f25509b
SM
556 self.assertEqual(len(calls), 5)
557
558 self.assertIs(calls[0][0], port_added_listener)
559 self.assertEqual(calls[0][1].name, 'src')
560 self.assertEqual(calls[0][2].name, 'out')
561
562 self.assertIs(calls[1][0], port_added_listener)
563 self.assertEqual(calls[1][1].name, 'src')
564 self.assertEqual(calls[1][2].name, 'zero')
565
566 self.assertIs(calls[2][0], port_added_listener)
567 self.assertEqual(calls[2][1].name, 'sink')
568 self.assertEqual(calls[2][2].name, 'in')
569
570 self.assertIs(calls[3][0], port_added_listener)
571 self.assertEqual(calls[3][1].name, 'sink')
572 self.assertEqual(calls[3][2].name, 'taste')
573
574 self.assertIs(calls[4][0], ports_connected_listener)
575 self.assertEqual(calls[4][1].name, 'src')
576 self.assertEqual(calls[4][2].name, 'out')
577 self.assertEqual(calls[4][3].name, 'sink')
578 self.assertEqual(calls[4][4].name, 'in')
579
580 def test_invalid_listeners(self):
5602ef81 581 class MyIter(bt2._UserMessageIterator):
811644b8
PP
582 def __next__(self):
583 raise bt2.Stop
584
cfbd7cf3 585 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 586 def __init__(self, params, obj):
811644b8
PP
587 self._add_output_port('out')
588 self._add_output_port('zero')
589
811644b8 590 class MySink(bt2._UserSinkComponent):
66964f3f 591 def __init__(self, params, obj):
811644b8
PP
592 self._add_input_port('in')
593
6a91742b 594 def _user_consume(self):
811644b8
PP
595 raise bt2.Stop
596
6a91742b 597 def _user_port_connected(self, port, other_port):
811644b8
PP
598 self._add_input_port('taste')
599
5f25509b
SM
600 with self.assertRaises(TypeError):
601 self._graph.add_port_added_listener(1234)
602 with self.assertRaises(TypeError):
603 self._graph.add_ports_connected_listener(1234)
811644b8 604
5f25509b
SM
605 def test_raise_in_component_init(self):
606 class MySink(bt2._UserSinkComponent):
66964f3f 607 def __init__(self, params, obj):
5f25509b 608 raise ValueError('oops!')
811644b8 609
6a91742b 610 def _user_consume(self):
5f25509b
SM
611 raise bt2.Stop
612
613 graph = bt2.Graph()
614
694c792b 615 with self.assertRaises(bt2._Error):
5f25509b
SM
616 graph.add_component(MySink, 'comp')
617
618 def test_raise_in_port_added_listener(self):
619 class MySink(bt2._UserSinkComponent):
66964f3f 620 def __init__(self, params, obj):
5f25509b
SM
621 self._add_input_port('in')
622
6a91742b 623 def _user_consume(self):
5f25509b
SM
624 raise bt2.Stop
625
626 def port_added_listener(component, port):
627 raise ValueError('oh noes!')
628
629 graph = bt2.Graph()
630 graph.add_port_added_listener(port_added_listener)
631
694c792b 632 with self.assertRaises(bt2._Error):
5f25509b
SM
633 graph.add_component(MySink, 'comp')
634
635 def test_raise_in_ports_connected_listener(self):
636 class MyIter(bt2._UserMessageIterator):
637 def __next__(self):
638 raise bt2.Stop
639
cfbd7cf3 640 class MySource(bt2._UserSourceComponent, message_iterator_class=MyIter):
66964f3f 641 def __init__(self, params, obj):
5f25509b
SM
642 self._add_output_port('out')
643
644 class MySink(bt2._UserSinkComponent):
66964f3f 645 def __init__(self, params, obj):
5f25509b
SM
646 self._add_input_port('in')
647
6a91742b 648 def _user_consume(self):
5f25509b 649 raise bt2.Stop
811644b8 650
cfbd7cf3
FD
651 def ports_connected_listener(
652 upstream_component, upstream_port, downstream_component, downstream_port
653 ):
5f25509b 654 raise ValueError('oh noes!')
811644b8 655
5f25509b
SM
656 graph = bt2.Graph()
657 graph.add_ports_connected_listener(ports_connected_listener)
658 up = graph.add_component(MySource, 'down')
659 down = graph.add_component(MySink, 'up')
811644b8 660
694c792b 661 with self.assertRaises(bt2._Error):
5f25509b 662 graph.connect_ports(up.output_ports['out'], down.input_ports['in'])
This page took 0.073928 seconds and 4 git commands to generate.