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(supports_packets
=True)
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
+= [('my_int', self
._my
_int
_ft
)]
39 self
._ec
.payload_field_type
= payload_ft
40 self
._stream
= self
._t
.create_stream(self
._sc
)
41 self
._packet
= self
._stream
.create_packet()
43 def _create_event(self
, value
):
45 ev
.payload_field
['my_int'] = value
46 ev
.packet
= self
._packet
50 class GraphTestCase(unittest
.TestCase
):
52 self
._graph
= bt2
.Graph()
57 def test_create_empty(self
):
60 def test_add_component_user_cls(self
):
61 class MySink(bt2
._UserSinkComponent
):
65 def _graph_is_configured(self
):
68 comp
= self
._graph
.add_component(MySink
, 'salut')
69 self
.assertEqual(comp
.name
, 'salut')
71 def test_add_component_gen_cls(self
):
72 class MySink(bt2
._UserSinkComponent
):
76 def _graph_is_configured(self
):
79 comp
= self
._graph
.add_component(MySink
, 'salut')
81 comp2
= self
._graph
.add_component(comp
.cls
, 'salut2')
82 self
.assertEqual(comp2
.name
, 'salut2')
84 def test_add_component_params(self
):
87 class MySink(bt2
._UserSinkComponent
):
88 def __init__(self
, params
):
95 def _graph_is_configured(self
):
98 params
= {'hello': 23, 'path': '/path/to/stuff'}
99 comp
= self
._graph
.add_component(MySink
, 'salut', params
)
100 self
.assertEqual(params
, comp_params
)
103 def test_add_component_invalid_cls_type(self
):
104 with self
.assertRaises(TypeError):
105 self
._graph
.add_component(int, 'salut')
107 def test_add_component_invalid_logging_level_type(self
):
108 class MySink(bt2
._UserSinkComponent
):
112 def _graph_is_configured(self
):
115 with self
.assertRaises(TypeError):
116 self
._graph
.add_component(MySink
, 'salut', logging_level
='yo')
118 def test_add_component_invalid_logging_level_value(self
):
119 class MySink(bt2
._UserSinkComponent
):
123 def _graph_is_configured(self
):
126 with self
.assertRaises(ValueError):
127 self
._graph
.add_component(MySink
, 'salut', logging_level
=12345)
129 def test_add_component_logging_level(self
):
130 class MySink(bt2
._UserSinkComponent
):
134 def _graph_is_configured(self
):
137 comp
= self
._graph
.add_component(
138 MySink
, 'salut', logging_level
=bt2
.LoggingLevel
.DEBUG
140 self
.assertEqual(comp
.logging_level
, bt2
.LoggingLevel
.DEBUG
)
142 def test_connect_ports(self
):
143 class MyIter(bt2
._UserMessageIterator
):
147 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
148 def __init__(self
, params
):
149 self
._add
_output
_port
('out')
151 class MySink(bt2
._UserSinkComponent
):
152 def __init__(self
, params
):
153 self
._add
_input
_port
('in')
158 def _graph_is_configured(self
):
161 src
= self
._graph
.add_component(MySource
, 'src')
162 sink
= self
._graph
.add_component(MySink
, 'sink')
164 conn
= self
._graph
.connect_ports(
165 src
.output_ports
['out'], sink
.input_ports
['in']
167 self
.assertTrue(src
.output_ports
['out'].is_connected
)
168 self
.assertTrue(sink
.input_ports
['in'].is_connected
)
169 self
.assertEqual(src
.output_ports
['out'].connection
.addr
, conn
.addr
)
170 self
.assertEqual(sink
.input_ports
['in'].connection
.addr
, conn
.addr
)
172 def test_connect_ports_invalid_direction(self
):
173 class MyIter(bt2
._UserMessageIterator
):
177 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
178 def __init__(self
, params
):
179 self
._add
_output
_port
('out')
181 class MySink(bt2
._UserSinkComponent
):
182 def __init__(self
, params
):
183 self
._add
_input
_port
('in')
188 def _graph_is_configured(self
):
191 src
= self
._graph
.add_component(MySource
, 'src')
192 sink
= self
._graph
.add_component(MySink
, 'sink')
194 with self
.assertRaises(TypeError):
195 conn
= self
._graph
.connect_ports(
196 sink
.input_ports
['in'], src
.output_ports
['out']
199 def test_cancel(self
):
200 self
.assertFalse(self
._graph
.is_canceled
)
202 self
.assertTrue(self
._graph
.is_canceled
)
204 # Test that Graph.run() raises bt2.Canceled if the graph gets canceled
206 def test_cancel_while_running(self
):
207 class MyIter(_MyIter
):
209 return self
._create
_stream
_beginning
_message
(self
._stream
)
211 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
212 def __init__(self
, params
):
213 self
._add
_output
_port
('out')
215 class MySink(bt2
._UserSinkComponent
):
216 def __init__(self
, params
):
217 self
._add
_input
_port
('in')
220 # Pretend that somebody asynchronously cancelled the graph.
224 return next(self
._msg
_iter
)
226 def _graph_is_configured(self
):
227 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
228 self
._input
_ports
['in']
232 up
= graph
.add_component(MySource
, 'down')
233 down
= graph
.add_component(MySink
, 'up')
234 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
235 with self
.assertRaises(bt2
.Canceled
):
239 class MyIter(_MyIter
):
245 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
247 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
249 msg
= self
._create
_packet
_end
_message
(self
._packet
)
251 msg
= self
._create
_stream
_end
_message
(self
._stream
)
253 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
258 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
259 def __init__(self
, params
):
260 self
._add
_output
_port
('out')
262 class MySink(bt2
._UserSinkComponent
):
263 def __init__(self
, params
):
264 self
._input
_port
= self
._add
_input
_port
('in')
267 def _consume(comp_self
):
268 msg
= next(comp_self
._msg
_iter
)
270 if comp_self
._at
== 0:
271 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
272 elif comp_self
._at
== 1:
273 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
274 elif comp_self
._at
>= 2 and comp_self
._at
<= 6:
275 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
276 self
.assertEqual(msg
.event
.cls
.name
, 'salut')
277 elif comp_self
._at
== 7:
278 self
.assertIsInstance(msg
, bt2
.message
._PacketEndMessage
)
279 elif comp_self
._at
== 8:
280 self
.assertIsInstance(msg
, bt2
.message
._StreamEndMessage
)
284 def _graph_is_configured(self
):
285 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
289 src
= self
._graph
.add_component(MySource
, 'src')
290 sink
= self
._graph
.add_component(MySink
, 'sink')
291 conn
= self
._graph
.connect_ports(
292 src
.output_ports
['out'], sink
.input_ports
['in']
296 def test_run_again(self
):
297 class MyIter(_MyIter
):
303 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
305 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
307 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
312 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
313 def __init__(self
, params
):
314 self
._add
_output
_port
('out')
316 class MySink(bt2
._UserSinkComponent
):
317 def __init__(self
, params
):
318 self
._input
_port
= self
._add
_input
_port
('in')
321 def _consume(comp_self
):
322 msg
= next(comp_self
._msg
_iter
)
323 if comp_self
._at
== 0:
324 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
325 elif comp_self
._at
== 1:
326 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
327 elif comp_self
._at
== 2:
328 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
335 def _graph_is_configured(self
):
336 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
340 src
= self
._graph
.add_component(MySource
, 'src')
341 sink
= self
._graph
.add_component(MySink
, 'sink')
342 conn
= self
._graph
.connect_ports(
343 src
.output_ports
['out'], sink
.input_ports
['in']
346 with self
.assertRaises(bt2
.TryAgain
):
349 def test_run_error(self
):
350 raised_in_sink
= False
352 class MyIter(_MyIter
):
354 # If this gets called after the sink raised an exception, it is
356 nonlocal raised_in_sink
357 assert raised_in_sink
is False
360 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
362 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
363 elif self
._at
== 2 or self
._at
== 3:
364 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
370 class MySource(bt2
._UserSourceComponent
, 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
._create
_input
_port
_message
_iterator
(
399 src
= self
._graph
.add_component(MySource
, 'src')
400 sink
= self
._graph
.add_component(MySink
, 'sink')
401 conn
= self
._graph
.connect_ports(
402 src
.output_ports
['out'], sink
.input_ports
['in']
405 with self
.assertRaises(bt2
._Error
):
408 def test_listeners(self
):
409 class MyIter(bt2
._UserMessageIterator
):
413 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
414 def __init__(self
, params
):
415 self
._add
_output
_port
('out')
416 self
._add
_output
_port
('zero')
418 class MySink(bt2
._UserSinkComponent
):
419 def __init__(self
, params
):
420 self
._add
_input
_port
('in')
425 def _graph_is_configured(self
):
428 def _port_connected(self
, port
, other_port
):
429 self
._add
_input
_port
('taste')
431 def port_added_listener(component
, port
):
433 calls
.append((port_added_listener
, component
, port
))
435 def ports_connected_listener(
436 upstream_component
, upstream_port
, downstream_component
, downstream_port
441 ports_connected_listener
,
444 downstream_component
,
450 self
._graph
.add_port_added_listener(port_added_listener
)
451 self
._graph
.add_ports_connected_listener(ports_connected_listener
)
452 src
= self
._graph
.add_component(MySource
, 'src')
453 sink
= self
._graph
.add_component(MySink
, 'sink')
454 self
._graph
.connect_ports(src
.output_ports
['out'], sink
.input_ports
['in'])
456 self
.assertEqual(len(calls
), 5)
458 self
.assertIs(calls
[0][0], port_added_listener
)
459 self
.assertEqual(calls
[0][1].name
, 'src')
460 self
.assertEqual(calls
[0][2].name
, 'out')
462 self
.assertIs(calls
[1][0], port_added_listener
)
463 self
.assertEqual(calls
[1][1].name
, 'src')
464 self
.assertEqual(calls
[1][2].name
, 'zero')
466 self
.assertIs(calls
[2][0], port_added_listener
)
467 self
.assertEqual(calls
[2][1].name
, 'sink')
468 self
.assertEqual(calls
[2][2].name
, 'in')
470 self
.assertIs(calls
[3][0], port_added_listener
)
471 self
.assertEqual(calls
[3][1].name
, 'sink')
472 self
.assertEqual(calls
[3][2].name
, 'taste')
474 self
.assertIs(calls
[4][0], ports_connected_listener
)
475 self
.assertEqual(calls
[4][1].name
, 'src')
476 self
.assertEqual(calls
[4][2].name
, 'out')
477 self
.assertEqual(calls
[4][3].name
, 'sink')
478 self
.assertEqual(calls
[4][4].name
, 'in')
480 def test_invalid_listeners(self
):
481 class MyIter(bt2
._UserMessageIterator
):
485 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
486 def __init__(self
, params
):
487 self
._add
_output
_port
('out')
488 self
._add
_output
_port
('zero')
490 class MySink(bt2
._UserSinkComponent
):
491 def __init__(self
, params
):
492 self
._add
_input
_port
('in')
497 def _graph_is_configured(self
):
500 def _port_connected(self
, port
, other_port
):
501 self
._add
_input
_port
('taste')
503 with self
.assertRaises(TypeError):
504 self
._graph
.add_port_added_listener(1234)
505 with self
.assertRaises(TypeError):
506 self
._graph
.add_ports_connected_listener(1234)
508 def test_raise_in_component_init(self
):
509 class MySink(bt2
._UserSinkComponent
):
510 def __init__(self
, params
):
511 raise ValueError('oops!')
516 def _graph_is_configured(self
):
521 with self
.assertRaises(bt2
._Error
):
522 graph
.add_component(MySink
, 'comp')
524 def test_raise_in_port_added_listener(self
):
525 class MySink(bt2
._UserSinkComponent
):
526 def __init__(self
, params
):
527 self
._add
_input
_port
('in')
532 def _graph_is_configured(self
):
535 def port_added_listener(component
, port
):
536 raise ValueError('oh noes!')
539 graph
.add_port_added_listener(port_added_listener
)
541 with self
.assertRaises(bt2
._Error
):
542 graph
.add_component(MySink
, 'comp')
544 def test_raise_in_ports_connected_listener(self
):
545 class MyIter(bt2
._UserMessageIterator
):
549 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
550 def __init__(self
, params
):
551 self
._add
_output
_port
('out')
553 class MySink(bt2
._UserSinkComponent
):
554 def __init__(self
, params
):
555 self
._add
_input
_port
('in')
560 def _graph_is_configured(self
):
563 def ports_connected_listener(
564 upstream_component
, upstream_port
, downstream_component
, downstream_port
566 raise ValueError('oh noes!')
569 graph
.add_ports_connected_listener(ports_connected_listener
)
570 up
= graph
.add_component(MySource
, 'down')
571 down
= graph
.add_component(MySink
, 'up')
573 with self
.assertRaises(bt2
._Error
):
574 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
This page took 0.04184 seconds and 4 git commands to generate.