bt2: Sync native_bt_field_class.i with field-class-const.h
[babeltrace.git] / tests / bindings / python / bt2 / test_graph.py
CommitLineData
811644b8
PP
1from bt2 import values
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):
58 class MyIter(bt2._UserNotificationIterator):
59 def __next__(self):
60 raise bt2.Stop
61
62 class MySource(bt2._UserSourceComponent,
63 notification_iterator_class=MyIter):
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):
84 class MyIter(bt2._UserNotificationIterator):
85 def __next__(self):
86 raise bt2.Stop
87
88 class MySource(bt2._UserSourceComponent,
89 notification_iterator_class=MyIter):
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):
108 class MyIter(bt2._UserNotificationIterator):
109 def __next__(self):
110 raise bt2.Stop
111
112 class MySource(bt2._UserSourceComponent,
113 notification_iterator_class=MyIter):
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):
135 class MyIter(bt2._UserNotificationIterator):
136 def __next__(self):
137 raise bt2.Stop
138
139 class MySource(bt2._UserSourceComponent,
140 notification_iterator_class=MyIter):
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
PP
159 def test_connect_ports_cannot_consume_accept(self):
160 class MyIter(bt2._UserNotificationIterator):
161 def __next__(self):
162 raise bt2.Stop
163
164 class MySource(bt2._UserSourceComponent,
165 notification_iterator_class=MyIter):
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):
194 class MyIter(bt2._UserNotificationIterator):
195 def __next__(self):
196 raise bt2.Stop
197
198 class MySource(bt2._UserSourceComponent,
199 notification_iterator_class=MyIter):
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):
234 class MyIter(bt2._UserNotificationIterator):
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')
243 self._my_int_ft = bt2.IntegerFieldType(32)
244 self._ec.payload_field_type = bt2.StructureFieldType()
245 self._ec.payload_field_type += collections.OrderedDict([
246 ('my_int', self._my_int_ft),
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
263 notif = bt2.EventNotification(self._create_event(self._at * 3))
264 self._at += 1
265 return notif
266
267 class MySource(bt2._UserSourceComponent,
268 notification_iterator_class=MyIter):
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):
278 notif = next(comp_self._notif_iter)
279
280 if comp_self._at == 0:
281 self.assertIsInstance(notif, bt2.StreamBeginningNotification)
282 elif comp_self._at == 1:
283 self.assertIsInstance(notif, bt2.PacketBeginningNotification)
284 elif comp_self._at >= 2 and comp_self._at <= 6:
285 self.assertIsInstance(notif, bt2.EventNotification)
286 self.assertEqual(notif.event.event_class.name, 'salut')
287 field = notif.event.payload_field['my_int']
288 self.assertEqual(field, (comp_self._at - 2) * 3)
289 elif comp_self._at == 7:
290 self.assertIsInstance(notif, bt2.PacketEndNotification)
291 elif comp_self._at == 8:
292 self.assertIsInstance(notif, bt2.StreamEndNotification)
293
294 comp_self._at += 1
295
296 def _port_connected(self, port, other_port):
297 self._notif_iter = port.connection.create_notification_iterator()
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):
306 class MyIter(bt2._UserNotificationIterator):
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')
315 self._my_int_ft = bt2.IntegerFieldType(32)
316 self._ec.payload_field_type = bt2.StructureFieldType()
317 self._ec.payload_field_type += collections.OrderedDict([
318 ('my_int', self._my_int_ft),
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
335 notif = bt2.EventNotification(self._create_event(self._at * 3))
336 self._at += 1
337 return notif
338
339 class MySource(bt2._UserSourceComponent,
340 notification_iterator_class=MyIter):
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:
351 notif = next(comp_self._notif_iter)
352 self.assertIsInstance(notif, bt2.EventNotification)
353 elif comp_self._at == 1:
354 with self.assertRaises(bt2.TryAgain):
355 notif = next(comp_self._notif_iter)
356
357 raise bt2.TryAgain
358
359 comp_self._at += 1
360
361 def _port_connected(self, port, other_port):
362 types = [bt2.EventNotification]
363 self._notif_iter = port.connection.create_notification_iterator(types)
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
373 def test_run_no_sink(self):
374 class MyIter(bt2._UserNotificationIterator):
375 pass
376
377 class MySource(bt2._UserSourceComponent,
378 notification_iterator_class=MyIter):
379 def __init__(self, params):
380 self._add_output_port('out')
381
382 class MyFilter(bt2._UserFilterComponent,
383 notification_iterator_class=MyIter):
384 def __init__(self, params):
385 self._add_output_port('out')
386 self._add_input_port('in')
387
388 src = self._graph.add_component(MySource, 'src')
389 flt = self._graph.add_component(MyFilter, 'flt')
390 conn = self._graph.connect_ports(src.output_ports['out'],
391 flt.input_ports['in'])
392
393 with self.assertRaises(bt2.NoSinkComponent):
394 self._graph.run()
395
396 def test_run_error(self):
397 class MyIter(bt2._UserNotificationIterator):
398 def __init__(self):
399 self._build_meta()
400 self._at = 0
401
402 def _build_meta(self):
403 self._trace = bt2.Trace()
404 self._sc = bt2.StreamClass()
405 self._ec = bt2.EventClass('salut')
406 self._my_int_ft = bt2.IntegerFieldType(32)
407 self._ec.payload_field_type = bt2.StructureFieldType()
408 self._ec.payload_field_type += collections.OrderedDict([
409 ('my_int', self._my_int_ft),
410 ])
411 self._sc.add_event_class(self._ec)
412 self._trace.add_stream_class(self._sc)
413 self._stream = self._sc()
414 self._packet = self._stream.create_packet()
415
416 def _create_event(self, value):
417 ev = self._ec()
418 ev.payload_field['my_int'] = value
419 ev.packet = self._packet
420 return ev
421
422 def __next__(self):
423 if self._at == 1:
424 raise bt2.TryAgain
425
426 notif = bt2.EventNotification(self._create_event(self._at * 3))
427 self._at += 1
428 return notif
429
430 class MySource(bt2._UserSourceComponent,
431 notification_iterator_class=MyIter):
432 def __init__(self, params):
433 self._add_output_port('out')
434
435 class MySink(bt2._UserSinkComponent):
436 def __init__(self, params):
437 self._add_input_port('in')
438 self._at = 0
439
440 def _consume(comp_self):
441 if comp_self._at == 0:
442 notif = next(comp_self._notif_iter)
443 self.assertIsInstance(notif, bt2.EventNotification)
444 elif comp_self._at == 1:
445 raise RuntimeError('error!')
446
447 comp_self._at += 1
448
449 def _port_connected(self, port, other_port):
450 types = [bt2.EventNotification]
451 self._notif_iter = port.connection.create_notification_iterator(types)
452
453 src = self._graph.add_component(MySource, 'src')
454 sink = self._graph.add_component(MySink, 'sink')
455 conn = self._graph.connect_ports(src.output_ports['out'],
456 sink.input_ports['in'])
457
458 with self.assertRaises(bt2.Error):
459 self._graph.run()
460
1d915789
PP
461 def test_run_cannot_consume(self):
462 class MyIter(bt2._UserNotificationIterator):
463 pass
464
465 class MySource(bt2._UserSourceComponent,
466 notification_iterator_class=MyIter):
467 def __init__(self, params):
468 self._add_output_port('out')
469
470 class MySink(bt2._UserSinkComponent):
471 def __init__(self, params):
472 self._add_input_port('in')
473 self._at = 0
474
475 def _consume(comp_self):
476 nonlocal exc
477
478 try:
479 print('going in')
480 comp_self.graph.run()
481 print('going out')
482 except Exception as e:
483 exc = e
484
485 raise bt2.Stop
486
487 exc = None
488 src = self._graph.add_component(MySource, 'src')
489 sink = self._graph.add_component(MySink, 'sink')
490 conn = self._graph.connect_ports(src.output_ports['out'],
491 sink.input_ports['in'])
492 self._graph.run()
493 self.assertIs(type(exc), bt2.CannotConsumeGraph)
494
811644b8
PP
495 def test_listeners(self):
496 class MyIter(bt2._UserNotificationIterator):
497 def __next__(self):
498 raise bt2.Stop
499
500 class MySource(bt2._UserSourceComponent,
501 notification_iterator_class=MyIter):
502 def __init__(self, params):
503 self._add_output_port('out')
504 self._add_output_port('zero')
505
506 def _port_connected(self, port, other_port):
507 self._output_ports['zero'].remove_from_component()
508
509 class MySink(bt2._UserSinkComponent):
510 def __init__(self, params):
511 self._add_input_port('in')
512
513 def _consume(self):
514 raise bt2.Stop
515
516 def _port_connected(self, port, other_port):
517 self._add_input_port('taste')
518
519 def _port_disconnected(self, port):
520 port.remove_from_component()
521
522 def port_added_listener(port):
523 nonlocal calls
524 calls.append((port_added_listener, port))
525
526 def port_removed_listener(port):
527 nonlocal calls
528 calls.append((port_removed_listener, port))
529
530 def ports_connected_listener(upstream_port, downstream_port):
531 nonlocal calls
532 calls.append((ports_connected_listener, upstream_port,
533 downstream_port))
534
535 def ports_disconnected_listener(upstream_comp, downstream_comp,
536 upstream_port, downstream_port):
537 nonlocal calls
538 calls.append((ports_disconnected_listener, upstream_comp,
539 downstream_comp, upstream_port, downstream_port))
540
541 calls = []
542 self._graph.add_listener(bt2.GraphListenerType.PORT_ADDED,
543 port_added_listener)
544 self._graph.add_listener(bt2.GraphListenerType.PORT_REMOVED,
545 port_removed_listener)
546 self._graph.add_listener(bt2.GraphListenerType.PORTS_CONNECTED,
547 ports_connected_listener)
548 self._graph.add_listener(bt2.GraphListenerType.PORTS_DISCONNECTED,
549 ports_disconnected_listener)
550 src = self._graph.add_component(MySource, 'src')
551 sink = self._graph.add_component(MySink, 'sink')
552 self._graph.connect_ports(src.output_ports['out'],
553 sink.input_ports['in'])
554 sink.input_ports['in'].disconnect()
555 self.assertIs(calls[0][0], port_added_listener)
556 self.assertEqual(calls[0][1].name, 'out')
557 self.assertIs(calls[1][0], port_added_listener)
558 self.assertEqual(calls[1][1].name, 'zero')
559 self.assertIs(calls[2][0], port_added_listener)
560 self.assertEqual(calls[2][1].name, 'in')
561 self.assertIs(calls[3][0], port_removed_listener)
562 self.assertEqual(calls[3][1].name, 'zero')
563 self.assertIs(calls[4][0], port_added_listener)
564 self.assertEqual(calls[4][1].name, 'taste')
565 self.assertIs(calls[5][0], ports_connected_listener)
566 self.assertEqual(calls[5][1].name, 'out')
567 self.assertEqual(calls[5][2].name, 'in')
568 self.assertIs(calls[6][0], port_removed_listener)
569 self.assertEqual(calls[6][1].name, 'in')
570 self.assertIs(calls[7][0], ports_disconnected_listener)
571 self.assertEqual(calls[7][1].name, 'src')
572 self.assertEqual(calls[7][2].name, 'sink')
573 self.assertEqual(calls[7][3].name, 'out')
574 self.assertEqual(calls[7][4].name, 'in')
575 del calls
This page took 0.050419 seconds and 4 git commands to generate.