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