2 # Copyright (C) 2019 EfficiOS Inc.
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
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.
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.
26 class _MyIter(bt2
._UserMessageIterator
):
27 def __init__(self
, self_output_port
):
31 def _build_meta(self
):
32 self
._tc
= self
._component
._create
_trace
_class
()
34 self
._sc
= self
._tc
.create_stream_class()
35 self
._ec
= self
._sc
.create_event_class(name
='salut')
36 self
._my
_int
_ft
= self
._tc
.create_signed_integer_field_class(32)
37 payload_ft
= self
._tc
.create_structure_field_class()
38 payload_ft
+= collections
.OrderedDict([
39 ('my_int', self
._my
_int
_ft
),
41 self
._ec
.payload_field_type
= payload_ft
42 self
._stream
= self
._t
.create_stream(self
._sc
)
43 self
._packet
= self
._stream
.create_packet()
45 def _create_event(self
, value
):
47 ev
.payload_field
['my_int'] = value
48 ev
.packet
= self
._packet
52 class GraphTestCase(unittest
.TestCase
):
54 self
._graph
= bt2
.Graph()
59 def test_create_empty(self
):
62 def test_add_component_user_cls(self
):
63 class MySink(bt2
._UserSinkComponent
):
67 comp
= self
._graph
.add_component(MySink
, 'salut')
68 self
.assertEqual(comp
.name
, 'salut')
70 def test_add_component_gen_cls(self
):
71 class MySink(bt2
._UserSinkComponent
):
75 comp
= self
._graph
.add_component(MySink
, 'salut')
77 comp2
= self
._graph
.add_component(comp
.cls
, 'salut2')
78 self
.assertEqual(comp2
.name
, 'salut2')
80 def test_add_component_params(self
):
83 class MySink(bt2
._UserSinkComponent
):
84 def __init__(self
, params
):
91 params
= {'hello': 23, 'path': '/path/to/stuff'}
92 comp
= self
._graph
.add_component(MySink
, 'salut', params
)
93 self
.assertEqual(params
, comp_params
)
96 def test_add_component_invalid_cls_type(self
):
97 with self
.assertRaises(TypeError):
98 self
._graph
.add_component(int, 'salut')
100 def test_add_component_invalid_logging_level_type(self
):
101 class MySink(bt2
._UserSinkComponent
):
105 with self
.assertRaises(TypeError):
106 self
._graph
.add_component(MySink
, 'salut', logging_level
='yo')
108 def test_add_component_invalid_logging_level_value(self
):
109 class MySink(bt2
._UserSinkComponent
):
113 with self
.assertRaises(ValueError):
114 self
._graph
.add_component(MySink
, 'salut', logging_level
=12345)
116 def test_add_component_logging_level(self
):
117 class MySink(bt2
._UserSinkComponent
):
121 comp
= self
._graph
.add_component(MySink
, 'salut',
122 logging_level
=bt2
.LoggingLevel
.DEBUG
)
123 self
.assertEqual(comp
.logging_level
, bt2
.LoggingLevel
.DEBUG
)
125 def test_connect_ports(self
):
126 class MyIter(bt2
._UserMessageIterator
):
130 class MySource(bt2
._UserSourceComponent
,
131 message_iterator_class
=MyIter
):
132 def __init__(self
, params
):
133 self
._add
_output
_port
('out')
135 class MySink(bt2
._UserSinkComponent
):
136 def __init__(self
, params
):
137 self
._add
_input
_port
('in')
142 src
= self
._graph
.add_component(MySource
, 'src')
143 sink
= self
._graph
.add_component(MySink
, 'sink')
145 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
146 sink
.input_ports
['in'])
147 self
.assertTrue(src
.output_ports
['out'].is_connected
)
148 self
.assertTrue(sink
.input_ports
['in'].is_connected
)
149 self
.assertEqual(src
.output_ports
['out'].connection
._ptr
, conn
._ptr
)
150 self
.assertEqual(sink
.input_ports
['in'].connection
._ptr
, conn
._ptr
)
152 def test_connect_ports_invalid_direction(self
):
153 class MyIter(bt2
._UserMessageIterator
):
157 class MySource(bt2
._UserSourceComponent
,
158 message_iterator_class
=MyIter
):
159 def __init__(self
, params
):
160 self
._add
_output
_port
('out')
162 class MySink(bt2
._UserSinkComponent
):
163 def __init__(self
, params
):
164 self
._add
_input
_port
('in')
169 src
= self
._graph
.add_component(MySource
, 'src')
170 sink
= self
._graph
.add_component(MySink
, 'sink')
172 with self
.assertRaises(TypeError):
173 conn
= self
._graph
.connect_ports(sink
.input_ports
['in'],
174 src
.output_ports
['out'])
176 def test_connect_ports_refused(self
):
177 class MyIter(bt2
._UserMessageIterator
):
181 class MySource(bt2
._UserSourceComponent
,
182 message_iterator_class
=MyIter
):
183 def __init__(self
, params
):
184 self
._add
_output
_port
('out')
186 class MySink(bt2
._UserSinkComponent
):
187 def __init__(self
, params
):
188 self
._add
_input
_port
('in')
193 def _accept_port_connection(self
, port
, other_port
):
196 src
= self
._graph
.add_component(MySource
, 'src')
197 sink
= self
._graph
.add_component(MySink
, 'sink')
199 with self
.assertRaises(bt2
.PortConnectionRefused
):
200 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
201 sink
.input_ports
['in'])
203 def test_cancel(self
):
204 self
.assertFalse(self
._graph
.is_canceled
)
206 self
.assertTrue(self
._graph
.is_canceled
)
208 # Test that Graph.run() raises bt2.GraphCanceled if the graph gets canceled
210 def test_cancel_while_running(self
):
211 class MyIter(_MyIter
):
213 return self
._create
_stream
_beginning
_message
(self
._stream
)
215 class MySource(bt2
._UserSourceComponent
,
216 message_iterator_class
=MyIter
):
217 def __init__(self
, params
):
218 self
._add
_output
_port
('out')
220 class MySink(bt2
._UserSinkComponent
):
221 def __init__(self
, params
):
222 self
._add
_input
_port
('in')
225 # Pretend that somebody asynchronously cancelled the graph.
229 return next(self
._msg
_iter
)
231 def _graph_is_configured(self
):
232 self
._msg
_iter
= self
._input
_ports
['in'].create_message_iterator()
235 up
= graph
.add_component(MySource
, 'down')
236 down
= graph
.add_component(MySink
, 'up')
237 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
238 with self
.assertRaises(bt2
.GraphCanceled
):
242 class MyIter(_MyIter
):
248 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
250 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
252 msg
= self
._create
_packet
_end
_message
(self
._packet
)
254 msg
= self
._create
_stream
_end
_message
(self
._stream
)
256 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
261 class MySource(bt2
._UserSourceComponent
,
262 message_iterator_class
=MyIter
):
263 def __init__(self
, params
):
264 self
._add
_output
_port
('out')
266 class MySink(bt2
._UserSinkComponent
):
267 def __init__(self
, params
):
268 self
._input
_port
= self
._add
_input
_port
('in')
271 def _consume(comp_self
):
272 msg
= next(comp_self
._msg
_iter
)
274 if comp_self
._at
== 0:
275 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
276 elif comp_self
._at
== 1:
277 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
278 elif comp_self
._at
>= 2 and comp_self
._at
<= 6:
279 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
280 self
.assertEqual(msg
.event
.cls
.name
, 'salut')
281 elif comp_self
._at
== 7:
282 self
.assertIsInstance(msg
, bt2
.message
._PacketEndMessage
)
283 elif comp_self
._at
== 8:
284 self
.assertIsInstance(msg
, bt2
.message
._StreamEndMessage
)
288 def _graph_is_configured(self
):
289 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
291 src
= self
._graph
.add_component(MySource
, 'src')
292 sink
= self
._graph
.add_component(MySink
, 'sink')
293 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
294 sink
.input_ports
['in'])
297 def test_run_again(self
):
298 class MyIter(_MyIter
):
304 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
306 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
308 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
313 class MySource(bt2
._UserSourceComponent
,
314 message_iterator_class
=MyIter
):
315 def __init__(self
, params
):
316 self
._add
_output
_port
('out')
318 class MySink(bt2
._UserSinkComponent
):
319 def __init__(self
, params
):
320 self
._input
_port
= self
._add
_input
_port
('in')
323 def _consume(comp_self
):
324 msg
= next(comp_self
._msg
_iter
)
325 if comp_self
._at
== 0:
326 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
327 elif comp_self
._at
== 1:
328 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
329 elif comp_self
._at
== 2:
330 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
337 def _graph_is_configured(self
):
338 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
340 src
= self
._graph
.add_component(MySource
, 'src')
341 sink
= self
._graph
.add_component(MySink
, 'sink')
342 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
343 sink
.input_ports
['in'])
345 with self
.assertRaises(bt2
.TryAgain
):
348 def test_run_error(self
):
349 raised_in_sink
= False
351 class MyIter(_MyIter
):
353 # If this gets called after the sink raised an exception, it is
355 nonlocal raised_in_sink
356 assert raised_in_sink
is False
359 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
361 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
362 elif self
._at
== 2 or self
._at
== 3:
363 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
369 class MySource(bt2
._UserSourceComponent
,
370 message_iterator_class
=MyIter
):
371 def __init__(self
, params
):
372 self
._add
_output
_port
('out')
374 class MySink(bt2
._UserSinkComponent
):
375 def __init__(self
, params
):
376 self
._input
_port
= self
._add
_input
_port
('in')
379 def _consume(comp_self
):
380 msg
= next(comp_self
._msg
_iter
)
381 if comp_self
._at
== 0:
382 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
383 elif comp_self
._at
== 1:
384 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
385 elif comp_self
._at
== 2:
386 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
387 elif comp_self
._at
== 3:
388 nonlocal raised_in_sink
389 raised_in_sink
= True
390 raise RuntimeError('error!')
394 def _graph_is_configured(self
):
395 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
397 src
= self
._graph
.add_component(MySource
, 'src')
398 sink
= self
._graph
.add_component(MySink
, 'sink')
399 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
400 sink
.input_ports
['in'])
402 with self
.assertRaises(bt2
.Error
):
405 def test_listeners(self
):
406 class MyIter(bt2
._UserMessageIterator
):
410 class MySource(bt2
._UserSourceComponent
,
411 message_iterator_class
=MyIter
):
412 def __init__(self
, params
):
413 self
._add
_output
_port
('out')
414 self
._add
_output
_port
('zero')
416 class MySink(bt2
._UserSinkComponent
):
417 def __init__(self
, params
):
418 self
._add
_input
_port
('in')
423 def _port_connected(self
, port
, other_port
):
424 self
._add
_input
_port
('taste')
426 def port_added_listener(component
, port
):
428 calls
.append((port_added_listener
, component
, port
))
430 def ports_connected_listener(upstream_component
, upstream_port
,
431 downstream_component
, downstream_port
):
433 calls
.append((ports_connected_listener
,
434 upstream_component
, upstream_port
,
435 downstream_component
, downstream_port
))
438 self
._graph
.add_port_added_listener(port_added_listener
)
439 self
._graph
.add_ports_connected_listener(ports_connected_listener
)
440 src
= self
._graph
.add_component(MySource
, 'src')
441 sink
= self
._graph
.add_component(MySink
, 'sink')
442 self
._graph
.connect_ports(src
.output_ports
['out'],
443 sink
.input_ports
['in'])
445 self
.assertEqual(len(calls
), 5)
447 self
.assertIs(calls
[0][0], port_added_listener
)
448 self
.assertEqual(calls
[0][1].name
, 'src')
449 self
.assertEqual(calls
[0][2].name
, 'out')
451 self
.assertIs(calls
[1][0], port_added_listener
)
452 self
.assertEqual(calls
[1][1].name
, 'src')
453 self
.assertEqual(calls
[1][2].name
, 'zero')
455 self
.assertIs(calls
[2][0], port_added_listener
)
456 self
.assertEqual(calls
[2][1].name
, 'sink')
457 self
.assertEqual(calls
[2][2].name
, 'in')
459 self
.assertIs(calls
[3][0], port_added_listener
)
460 self
.assertEqual(calls
[3][1].name
, 'sink')
461 self
.assertEqual(calls
[3][2].name
, 'taste')
463 self
.assertIs(calls
[4][0], ports_connected_listener
)
464 self
.assertEqual(calls
[4][1].name
, 'src')
465 self
.assertEqual(calls
[4][2].name
, 'out')
466 self
.assertEqual(calls
[4][3].name
, 'sink')
467 self
.assertEqual(calls
[4][4].name
, 'in')
469 def test_invalid_listeners(self
):
470 class MyIter(bt2
._UserMessageIterator
):
474 class MySource(bt2
._UserSourceComponent
,
475 message_iterator_class
=MyIter
):
476 def __init__(self
, params
):
477 self
._add
_output
_port
('out')
478 self
._add
_output
_port
('zero')
480 class MySink(bt2
._UserSinkComponent
):
481 def __init__(self
, params
):
482 self
._add
_input
_port
('in')
487 def _port_connected(self
, port
, other_port
):
488 self
._add
_input
_port
('taste')
490 with self
.assertRaises(TypeError):
491 self
._graph
.add_port_added_listener(1234)
492 with self
.assertRaises(TypeError):
493 self
._graph
.add_ports_connected_listener(1234)
495 def test_raise_in_component_init(self
):
496 class MySink(bt2
._UserSinkComponent
):
497 def __init__(self
, params
):
498 raise ValueError('oops!')
505 with self
.assertRaises(bt2
.Error
):
506 graph
.add_component(MySink
, 'comp')
508 def test_raise_in_port_added_listener(self
):
509 class MySink(bt2
._UserSinkComponent
):
510 def __init__(self
, params
):
511 self
._add
_input
_port
('in')
516 def port_added_listener(component
, port
):
517 raise ValueError('oh noes!')
520 graph
.add_port_added_listener(port_added_listener
)
522 with self
.assertRaises(bt2
.Error
):
523 graph
.add_component(MySink
, 'comp')
525 def test_raise_in_ports_connected_listener(self
):
526 class MyIter(bt2
._UserMessageIterator
):
530 class MySource(bt2
._UserSourceComponent
,
531 message_iterator_class
=MyIter
):
532 def __init__(self
, params
):
533 self
._add
_output
_port
('out')
535 class MySink(bt2
._UserSinkComponent
):
536 def __init__(self
, params
):
537 self
._add
_input
_port
('in')
542 def ports_connected_listener(upstream_component
, upstream_port
,
543 downstream_component
, downstream_port
):
544 raise ValueError('oh noes!')
547 graph
.add_ports_connected_listener(ports_connected_listener
)
548 up
= graph
.add_component(MySource
, 'down')
549 down
= graph
.add_component(MySink
, 'up')
551 with self
.assertRaises(bt2
.Error
):
552 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
This page took 0.041033 seconds and 5 git commands to generate.