lib: Make graph listeners return an error status
[babeltrace.git] / tests / bindings / python / bt2 / test_graph.py
CommitLineData
c4239792 1from bt2 import value
811644b8
PP
2import collections
3import unittest
4import copy
5import bt2
6
7
976c241d 8@unittest.skip("this is broken")
811644b8
PP
9class GraphTestCase(unittest.TestCase):
10 def setUp(self):
11 self._graph = bt2.Graph()
12
13 def tearDown(self):
14 del self._graph
15
16 def test_create_empty(self):
17 graph = bt2.Graph()
18
19 def test_add_component_user_cls(self):
20 class MySink(bt2._UserSinkComponent):
21 def _consume(self):
22 pass
23
24 comp = self._graph.add_component(MySink, 'salut')
25 self.assertEqual(comp.name, 'salut')
26
27 def test_add_component_gen_cls(self):
28 class MySink(bt2._UserSinkComponent):
29 def _consume(self):
30 pass
31
32 comp = self._graph.add_component(MySink, 'salut')
33 assert(comp)
34 comp2 = self._graph.add_component(comp.component_class, 'salut2')
35 self.assertEqual(comp2.name, 'salut2')
36
37 def test_add_component_params(self):
38 comp_params = None
39
40 class MySink(bt2._UserSinkComponent):
41 def __init__(self, params):
42 nonlocal comp_params
43 comp_params = params
44
45 def _consume(self):
46 pass
47
48 params = {'hello': 23, 'path': '/path/to/stuff'}
49 comp = self._graph.add_component(MySink, 'salut', params)
50 self.assertEqual(params, comp_params)
51 del comp_params
52
53 def test_add_component_invalid_cls_type(self):
54 with self.assertRaises(TypeError):
55 self._graph.add_component(int, 'salut')
56
57 def test_connect_ports(self):
5602ef81 58 class MyIter(bt2._UserMessageIterator):
811644b8
PP
59 def __next__(self):
60 raise bt2.Stop
61
62 class MySource(bt2._UserSourceComponent,
5602ef81 63 message_iterator_class=MyIter):
811644b8
PP
64 def __init__(self, params):
65 self._add_output_port('out')
66
67 class MySink(bt2._UserSinkComponent):
68 def __init__(self, params):
69 self._add_input_port('in')
70
71 def _consume(self):
72 raise bt2.Stop
73
74 src = self._graph.add_component(MySource, 'src')
75 sink = self._graph.add_component(MySink, 'sink')
76 conn = self._graph.connect_ports(src.output_ports['out'],
77 sink.input_ports['in'])
78 self.assertTrue(src.output_ports['out'].is_connected)
79 self.assertTrue(sink.input_ports['in'].is_connected)
80 self.assertEqual(src.output_ports['out'].connection, conn)
81 self.assertEqual(sink.input_ports['in'].connection, conn)
82
83 def test_connect_ports_invalid_direction(self):
5602ef81 84 class MyIter(bt2._UserMessageIterator):
811644b8
PP
85 def __next__(self):
86 raise bt2.Stop
87
88 class MySource(bt2._UserSourceComponent,
5602ef81 89 message_iterator_class=MyIter):
811644b8
PP
90 def __init__(self, params):
91 self._add_output_port('out')
92
93 class MySink(bt2._UserSinkComponent):
94 def __init__(self, params):
95 self._add_input_port('in')
96
97 def _consume(self):
98 raise bt2.Stop
99
100 src = self._graph.add_component(MySource, 'src')
101 sink = self._graph.add_component(MySink, 'sink')
102
103 with self.assertRaises(TypeError):
104 conn = self._graph.connect_ports(sink.input_ports['in'],
105 src.output_ports['out'])
106
107 def test_connect_ports_refused(self):
5602ef81 108 class MyIter(bt2._UserMessageIterator):
811644b8
PP
109 def __next__(self):
110 raise bt2.Stop
111
112 class MySource(bt2._UserSourceComponent,
5602ef81 113 message_iterator_class=MyIter):
811644b8
PP
114 def __init__(self, params):
115 self._add_output_port('out')
116
117 class MySink(bt2._UserSinkComponent):
118 def __init__(self, params):
119 self._add_input_port('in')
120
121 def _consume(self):
122 raise bt2.Stop
123
124 def _accept_port_connection(self, port, other_port):
125 return False
126
127 src = self._graph.add_component(MySource, 'src')
128 sink = self._graph.add_component(MySink, 'sink')
129
130 with self.assertRaises(bt2.PortConnectionRefused):
131 conn = self._graph.connect_ports(src.output_ports['out'],
132 sink.input_ports['in'])
133
134 def test_connect_ports_canceled(self):
5602ef81 135 class MyIter(bt2._UserMessageIterator):
811644b8
PP
136 def __next__(self):
137 raise bt2.Stop
138
139 class MySource(bt2._UserSourceComponent,
5602ef81 140 message_iterator_class=MyIter):
811644b8
PP
141 def __init__(self, params):
142 self._add_output_port('out')
143
144 class MySink(bt2._UserSinkComponent):
145 def __init__(self, params):
146 self._add_input_port('in')
147
148 def _consume(self):
149 raise bt2.Stop
150
151 src = self._graph.add_component(MySource, 'src')
152 sink = self._graph.add_component(MySink, 'sink')
153 self._graph.cancel()
154
155 with self.assertRaises(bt2.GraphCanceled):
156 conn = self._graph.connect_ports(src.output_ports['out'],
157 sink.input_ports['in'])
158
1d915789 159 def test_connect_ports_cannot_consume_accept(self):
5602ef81 160 class MyIter(bt2._UserMessageIterator):
1d915789
PP
161 def __next__(self):
162 raise bt2.Stop
163
164 class MySource(bt2._UserSourceComponent,
5602ef81 165 message_iterator_class=MyIter):
1d915789
PP
166 def __init__(self, params):
167 self._add_output_port('out')
168
169 class MySink(bt2._UserSinkComponent):
170 def __init__(self, params):
171 self._add_input_port('in')
172
173 def _consume(self):
174 raise bt2.Stop
175
176 def _accept_port_connection(self, port, other_port):
177 nonlocal exc
178
179 try:
180 self.graph.run()
181 except Exception as e:
182 exc = e
183
184 return True
185
186 exc = None
187 src = self._graph.add_component(MySource, 'src')
188 sink = self._graph.add_component(MySink, 'sink')
189 self._graph.connect_ports(src.output_ports['out'],
190 sink.input_ports['in'])
191 self.assertIs(type(exc), bt2.CannotConsumeGraph)
192
193 def test_connect_ports_cannot_consume_connected(self):
5602ef81 194 class MyIter(bt2._UserMessageIterator):
1d915789
PP
195 def __next__(self):
196 raise bt2.Stop
197
198 class MySource(bt2._UserSourceComponent,
5602ef81 199 message_iterator_class=MyIter):
1d915789
PP
200 def __init__(self, params):
201 self._add_output_port('out')
202
203 class MySink(bt2._UserSinkComponent):
204 def __init__(self, params):
205 self._add_input_port('in')
206
207 def _consume(self):
208 raise bt2.Stop
209
210 def _port_connected(self, port, other_port):
211 nonlocal exc
212
213 try:
214 self.graph.run()
215 except Exception as e:
216 exc = e
217
218 return True
219
220 exc = None
221 src = self._graph.add_component(MySource, 'src')
222 sink = self._graph.add_component(MySink, 'sink')
223 self._graph.connect_ports(src.output_ports['out'],
224 sink.input_ports['in'])
225 self._graph.run()
226 self.assertIs(type(exc), bt2.CannotConsumeGraph)
227
811644b8
PP
228 def test_cancel(self):
229 self.assertFalse(self._graph.is_canceled)
230 self._graph.cancel()
231 self.assertTrue(self._graph.is_canceled)
232
233 def test_run(self):
5602ef81 234 class MyIter(bt2._UserMessageIterator):
811644b8
PP
235 def __init__(self):
236 self._build_meta()
237 self._at = 0
238
239 def _build_meta(self):
240 self._trace = bt2.Trace()
241 self._sc = bt2.StreamClass()
242 self._ec = bt2.EventClass('salut')
b4f45851
SM
243 self._my_int_fc = bt2.IntegerFieldClass(32)
244 self._ec.payload_field_class = bt2.StructureFieldClass()
245 self._ec.payload_field_class += collections.OrderedDict([
246 ('my_int', self._my_int_fc),
811644b8
PP
247 ])
248 self._sc.add_event_class(self._ec)
249 self._trace.add_stream_class(self._sc)
250 self._stream = self._sc()
251 self._packet = self._stream.create_packet()
252
253 def _create_event(self, value):
254 ev = self._ec()
255 ev.payload_field['my_int'] = value
256 ev.packet = self._packet
257 return ev
258
259 def __next__(self):
260 if self._at == 5:
261 raise bt2.Stop
262
5602ef81 263 msg = bt2.EventMessage(self._create_event(self._at * 3))
811644b8 264 self._at += 1
5602ef81 265 return msg
811644b8
PP
266
267 class MySource(bt2._UserSourceComponent,
5602ef81 268 message_iterator_class=MyIter):
811644b8
PP
269 def __init__(self, params):
270 self._add_output_port('out')
271
272 class MySink(bt2._UserSinkComponent):
273 def __init__(self, params):
274 self._add_input_port('in')
275 self._at = 0
276
277 def _consume(comp_self):
5602ef81 278 msg = next(comp_self._msg_iter)
811644b8
PP
279
280 if comp_self._at == 0:
5602ef81 281 self.assertIsInstance(msg, bt2.StreamBeginningMessage)
811644b8 282 elif comp_self._at == 1:
5602ef81 283 self.assertIsInstance(msg, bt2.PacketBeginningMessage)
811644b8 284 elif comp_self._at >= 2 and comp_self._at <= 6:
5602ef81
SM
285 self.assertIsInstance(msg, bt2.EventMessage)
286 self.assertEqual(msg.event.event_class.name, 'salut')
287 field = msg.event.payload_field['my_int']
811644b8
PP
288 self.assertEqual(field, (comp_self._at - 2) * 3)
289 elif comp_self._at == 7:
5602ef81 290 self.assertIsInstance(msg, bt2.PacketEndMessage)
811644b8 291 elif comp_self._at == 8:
5602ef81 292 self.assertIsInstance(msg, bt2.StreamEndMessage)
811644b8
PP
293
294 comp_self._at += 1
295
296 def _port_connected(self, port, other_port):
5602ef81 297 self._msg_iter = port.connection.create_message_iterator()
811644b8
PP
298
299 src = self._graph.add_component(MySource, 'src')
300 sink = self._graph.add_component(MySink, 'sink')
301 conn = self._graph.connect_ports(src.output_ports['out'],
302 sink.input_ports['in'])
303 self._graph.run()
304
305 def test_run_again(self):
5602ef81 306 class MyIter(bt2._UserMessageIterator):
811644b8
PP
307 def __init__(self):
308 self._build_meta()
309 self._at = 0
310
311 def _build_meta(self):
312 self._trace = bt2.Trace()
313 self._sc = bt2.StreamClass()
314 self._ec = bt2.EventClass('salut')
b4f45851
SM
315 self._my_int_fc = bt2.IntegerFieldClass(32)
316 self._ec.payload_field_class = bt2.StructureFieldClass()
317 self._ec.payload_field_class += collections.OrderedDict([
318 ('my_int', self._my_int_fc),
811644b8
PP
319 ])
320 self._sc.add_event_class(self._ec)
321 self._trace.add_stream_class(self._sc)
322 self._stream = self._sc()
323 self._packet = self._stream.create_packet()
324
325 def _create_event(self, value):
326 ev = self._ec()
327 ev.payload_field['my_int'] = value
328 ev.packet = self._packet
329 return ev
330
331 def __next__(self):
332 if self._at == 1:
333 raise bt2.TryAgain
334
5602ef81 335 msg = bt2.EventMessage(self._create_event(self._at * 3))
811644b8 336 self._at += 1
5602ef81 337 return msg
811644b8
PP
338
339 class MySource(bt2._UserSourceComponent,
5602ef81 340 message_iterator_class=MyIter):
811644b8
PP
341 def __init__(self, params):
342 self._add_output_port('out')
343
344 class MySink(bt2._UserSinkComponent):
345 def __init__(self, params):
346 self._add_input_port('in')
347 self._at = 0
348
349 def _consume(comp_self):
350 if comp_self._at == 0:
5602ef81
SM
351 msg = next(comp_self._msg_iter)
352 self.assertIsInstance(msg, bt2.EventMessage)
811644b8
PP
353 elif comp_self._at == 1:
354 with self.assertRaises(bt2.TryAgain):
5602ef81 355 msg = next(comp_self._msg_iter)
811644b8
PP
356
357 raise bt2.TryAgain
358
359 comp_self._at += 1
360
361 def _port_connected(self, port, other_port):
5602ef81
SM
362 types = [bt2.EventMessage]
363 self._msg_iter = port.connection.create_message_iterator(types)
811644b8
PP
364
365 src = self._graph.add_component(MySource, 'src')
366 sink = self._graph.add_component(MySink, 'sink')
367 conn = self._graph.connect_ports(src.output_ports['out'],
368 sink.input_ports['in'])
369
370 with self.assertRaises(bt2.TryAgain):
371 self._graph.run()
372
811644b8 373 def test_run_error(self):
5602ef81 374 class MyIter(bt2._UserMessageIterator):
811644b8
PP
375 def __init__(self):
376 self._build_meta()
377 self._at = 0
378
379 def _build_meta(self):
380 self._trace = bt2.Trace()
381 self._sc = bt2.StreamClass()
382 self._ec = bt2.EventClass('salut')
b4f45851
SM
383 self._my_int_fc = bt2.IntegerFieldClass(32)
384 self._ec.payload_field_class = bt2.StructureFieldClass()
385 self._ec.payload_field_class += collections.OrderedDict([
386 ('my_int', self._my_int_fc),
811644b8
PP
387 ])
388 self._sc.add_event_class(self._ec)
389 self._trace.add_stream_class(self._sc)
390 self._stream = self._sc()
391 self._packet = self._stream.create_packet()
392
393 def _create_event(self, value):
394 ev = self._ec()
395 ev.payload_field['my_int'] = value
396 ev.packet = self._packet
397 return ev
398
399 def __next__(self):
400 if self._at == 1:
401 raise bt2.TryAgain
402
5602ef81 403 msg = bt2.EventMessage(self._create_event(self._at * 3))
811644b8 404 self._at += 1
5602ef81 405 return msg
811644b8
PP
406
407 class MySource(bt2._UserSourceComponent,
5602ef81 408 message_iterator_class=MyIter):
811644b8
PP
409 def __init__(self, params):
410 self._add_output_port('out')
411
412 class MySink(bt2._UserSinkComponent):
413 def __init__(self, params):
414 self._add_input_port('in')
415 self._at = 0
416
417 def _consume(comp_self):
418 if comp_self._at == 0:
5602ef81
SM
419 msg = next(comp_self._msg_iter)
420 self.assertIsInstance(msg, bt2.EventMessage)
811644b8
PP
421 elif comp_self._at == 1:
422 raise RuntimeError('error!')
423
424 comp_self._at += 1
425
426 def _port_connected(self, port, other_port):
5602ef81
SM
427 types = [bt2.EventMessage]
428 self._msg_iter = port.connection.create_message_iterator(types)
811644b8
PP
429
430 src = self._graph.add_component(MySource, 'src')
431 sink = self._graph.add_component(MySink, 'sink')
432 conn = self._graph.connect_ports(src.output_ports['out'],
433 sink.input_ports['in'])
434
435 with self.assertRaises(bt2.Error):
436 self._graph.run()
437
1d915789 438 def test_run_cannot_consume(self):
5602ef81 439 class MyIter(bt2._UserMessageIterator):
1d915789
PP
440 pass
441
442 class MySource(bt2._UserSourceComponent,
5602ef81 443 message_iterator_class=MyIter):
1d915789
PP
444 def __init__(self, params):
445 self._add_output_port('out')
446
447 class MySink(bt2._UserSinkComponent):
448 def __init__(self, params):
449 self._add_input_port('in')
450 self._at = 0
451
452 def _consume(comp_self):
453 nonlocal exc
454
455 try:
456 print('going in')
457 comp_self.graph.run()
458 print('going out')
459 except Exception as e:
460 exc = e
461
462 raise bt2.Stop
463
464 exc = None
465 src = self._graph.add_component(MySource, 'src')
466 sink = self._graph.add_component(MySink, 'sink')
467 conn = self._graph.connect_ports(src.output_ports['out'],
468 sink.input_ports['in'])
469 self._graph.run()
470 self.assertIs(type(exc), bt2.CannotConsumeGraph)
471
811644b8 472 def test_listeners(self):
5602ef81 473 class MyIter(bt2._UserMessageIterator):
811644b8
PP
474 def __next__(self):
475 raise bt2.Stop
476
477 class MySource(bt2._UserSourceComponent,
5602ef81 478 message_iterator_class=MyIter):
811644b8
PP
479 def __init__(self, params):
480 self._add_output_port('out')
481 self._add_output_port('zero')
482
483 def _port_connected(self, port, other_port):
484 self._output_ports['zero'].remove_from_component()
485
486 class MySink(bt2._UserSinkComponent):
487 def __init__(self, params):
488 self._add_input_port('in')
489
490 def _consume(self):
491 raise bt2.Stop
492
493 def _port_connected(self, port, other_port):
494 self._add_input_port('taste')
495
496 def _port_disconnected(self, port):
497 port.remove_from_component()
498
499 def port_added_listener(port):
500 nonlocal calls
501 calls.append((port_added_listener, port))
502
503 def port_removed_listener(port):
504 nonlocal calls
505 calls.append((port_removed_listener, port))
506
507 def ports_connected_listener(upstream_port, downstream_port):
508 nonlocal calls
509 calls.append((ports_connected_listener, upstream_port,
510 downstream_port))
511
512 def ports_disconnected_listener(upstream_comp, downstream_comp,
513 upstream_port, downstream_port):
514 nonlocal calls
515 calls.append((ports_disconnected_listener, upstream_comp,
516 downstream_comp, upstream_port, downstream_port))
517
518 calls = []
519 self._graph.add_listener(bt2.GraphListenerType.PORT_ADDED,
520 port_added_listener)
521 self._graph.add_listener(bt2.GraphListenerType.PORT_REMOVED,
522 port_removed_listener)
523 self._graph.add_listener(bt2.GraphListenerType.PORTS_CONNECTED,
524 ports_connected_listener)
525 self._graph.add_listener(bt2.GraphListenerType.PORTS_DISCONNECTED,
526 ports_disconnected_listener)
527 src = self._graph.add_component(MySource, 'src')
528 sink = self._graph.add_component(MySink, 'sink')
529 self._graph.connect_ports(src.output_ports['out'],
530 sink.input_ports['in'])
531 sink.input_ports['in'].disconnect()
532 self.assertIs(calls[0][0], port_added_listener)
533 self.assertEqual(calls[0][1].name, 'out')
534 self.assertIs(calls[1][0], port_added_listener)
535 self.assertEqual(calls[1][1].name, 'zero')
536 self.assertIs(calls[2][0], port_added_listener)
537 self.assertEqual(calls[2][1].name, 'in')
538 self.assertIs(calls[3][0], port_removed_listener)
539 self.assertEqual(calls[3][1].name, 'zero')
540 self.assertIs(calls[4][0], port_added_listener)
541 self.assertEqual(calls[4][1].name, 'taste')
542 self.assertIs(calls[5][0], ports_connected_listener)
543 self.assertEqual(calls[5][1].name, 'out')
544 self.assertEqual(calls[5][2].name, 'in')
545 self.assertIs(calls[6][0], port_removed_listener)
546 self.assertEqual(calls[6][1].name, 'in')
547 self.assertIs(calls[7][0], ports_disconnected_listener)
548 self.assertEqual(calls[7][1].name, 'src')
549 self.assertEqual(calls[7][2].name, 'sink')
550 self.assertEqual(calls[7][3].name, 'out')
551 self.assertEqual(calls[7][4].name, 'in')
552 del calls
This page took 0.05128 seconds and 4 git commands to generate.