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_add_interrupter(self
):
200 class MyIter(bt2
._UserMessageIterator
):
204 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
205 def __init__(self
, params
):
206 self
._add
_output
_port
('out')
208 class MySink(bt2
._UserSinkComponent
):
209 def __init__(self
, params
):
210 self
._add
_input
_port
('in')
215 def _graph_is_configured(self
):
216 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
217 self
._input
_ports
['in']
220 # add two interrupters, set one of them
221 interrupter1
= bt2
.Interrupter()
222 interrupter2
= bt2
.Interrupter()
223 self
._graph
.add_interrupter(interrupter1
)
224 src
= self
._graph
.add_component(MySource
, 'src')
225 sink
= self
._graph
.add_component(MySink
, 'sink')
226 self
._graph
.connect_ports(src
.output_ports
['out'], sink
.input_ports
['in'])
227 self
._graph
.add_interrupter(interrupter2
)
229 with self
.assertRaises(bt2
._Error
):
234 with self
.assertRaises(bt2
.TryAgain
):
239 with self
.assertRaises(bt2
._Error
):
242 # Test that Graph.run() raises bt2.Interrupted if the graph gets
243 # interrupted during execution.
244 def test_interrupt_while_running(self
):
245 class MyIter(_MyIter
):
247 return self
._create
_stream
_beginning
_message
(self
._stream
)
249 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
250 def __init__(self
, params
):
251 self
._add
_output
_port
('out')
253 class MySink(bt2
._UserSinkComponent
):
254 def __init__(self
, params
):
255 self
._add
_input
_port
('in')
258 # Pretend that somebody asynchronously interrupted the graph.
261 return next(self
._msg
_iter
)
263 def _graph_is_configured(self
):
264 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
265 self
._input
_ports
['in']
269 up
= self
._graph
.add_component(MySource
, 'down')
270 down
= self
._graph
.add_component(MySink
, 'up')
271 self
._graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
273 with self
.assertRaises(bt2
.TryAgain
):
277 class MyIter(_MyIter
):
283 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
285 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
287 msg
= self
._create
_packet
_end
_message
(self
._packet
)
289 msg
= self
._create
_stream
_end
_message
(self
._stream
)
291 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
296 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
297 def __init__(self
, params
):
298 self
._add
_output
_port
('out')
300 class MySink(bt2
._UserSinkComponent
):
301 def __init__(self
, params
):
302 self
._input
_port
= self
._add
_input
_port
('in')
305 def _consume(comp_self
):
306 msg
= next(comp_self
._msg
_iter
)
308 if comp_self
._at
== 0:
309 self
.assertIsInstance(msg
, bt2
._StreamBeginningMessage
)
310 elif comp_self
._at
== 1:
311 self
.assertIsInstance(msg
, bt2
._PacketBeginningMessage
)
312 elif comp_self
._at
>= 2 and comp_self
._at
<= 6:
313 self
.assertIsInstance(msg
, bt2
._EventMessage
)
314 self
.assertEqual(msg
.event
.cls
.name
, 'salut')
315 elif comp_self
._at
== 7:
316 self
.assertIsInstance(msg
, bt2
._PacketEndMessage
)
317 elif comp_self
._at
== 8:
318 self
.assertIsInstance(msg
, bt2
._StreamEndMessage
)
322 def _graph_is_configured(self
):
323 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
327 src
= self
._graph
.add_component(MySource
, 'src')
328 sink
= self
._graph
.add_component(MySink
, 'sink')
329 conn
= self
._graph
.connect_ports(
330 src
.output_ports
['out'], sink
.input_ports
['in']
334 def test_run_again(self
):
335 class MyIter(_MyIter
):
341 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
343 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
345 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
350 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
351 def __init__(self
, params
):
352 self
._add
_output
_port
('out')
354 class MySink(bt2
._UserSinkComponent
):
355 def __init__(self
, params
):
356 self
._input
_port
= self
._add
_input
_port
('in')
359 def _consume(comp_self
):
360 msg
= next(comp_self
._msg
_iter
)
361 if comp_self
._at
== 0:
362 self
.assertIsInstance(msg
, bt2
._StreamBeginningMessage
)
363 elif comp_self
._at
== 1:
364 self
.assertIsInstance(msg
, bt2
._PacketBeginningMessage
)
365 elif comp_self
._at
== 2:
366 self
.assertIsInstance(msg
, bt2
._EventMessage
)
373 def _graph_is_configured(self
):
374 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
378 src
= self
._graph
.add_component(MySource
, 'src')
379 sink
= self
._graph
.add_component(MySink
, 'sink')
380 conn
= self
._graph
.connect_ports(
381 src
.output_ports
['out'], sink
.input_ports
['in']
384 with self
.assertRaises(bt2
.TryAgain
):
387 def test_run_error(self
):
388 raised_in_sink
= False
390 class MyIter(_MyIter
):
392 # If this gets called after the sink raised an exception, it is
394 nonlocal raised_in_sink
395 assert raised_in_sink
is False
398 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
400 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
401 elif self
._at
== 2 or self
._at
== 3:
402 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
408 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
409 def __init__(self
, params
):
410 self
._add
_output
_port
('out')
412 class MySink(bt2
._UserSinkComponent
):
413 def __init__(self
, params
):
414 self
._input
_port
= self
._add
_input
_port
('in')
417 def _consume(comp_self
):
418 msg
= next(comp_self
._msg
_iter
)
419 if comp_self
._at
== 0:
420 self
.assertIsInstance(msg
, bt2
._StreamBeginningMessage
)
421 elif comp_self
._at
== 1:
422 self
.assertIsInstance(msg
, bt2
._PacketBeginningMessage
)
423 elif comp_self
._at
== 2:
424 self
.assertIsInstance(msg
, bt2
._EventMessage
)
425 elif comp_self
._at
== 3:
426 nonlocal raised_in_sink
427 raised_in_sink
= True
428 raise RuntimeError('error!')
432 def _graph_is_configured(self
):
433 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
437 src
= self
._graph
.add_component(MySource
, 'src')
438 sink
= self
._graph
.add_component(MySink
, 'sink')
439 conn
= self
._graph
.connect_ports(
440 src
.output_ports
['out'], sink
.input_ports
['in']
443 with self
.assertRaises(bt2
._Error
):
446 def test_listeners(self
):
447 class MyIter(bt2
._UserMessageIterator
):
451 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
452 def __init__(self
, params
):
453 self
._add
_output
_port
('out')
454 self
._add
_output
_port
('zero')
456 class MySink(bt2
._UserSinkComponent
):
457 def __init__(self
, params
):
458 self
._add
_input
_port
('in')
463 def _graph_is_configured(self
):
466 def _port_connected(self
, port
, other_port
):
467 self
._add
_input
_port
('taste')
469 def port_added_listener(component
, port
):
471 calls
.append((port_added_listener
, component
, port
))
473 def ports_connected_listener(
474 upstream_component
, upstream_port
, downstream_component
, downstream_port
479 ports_connected_listener
,
482 downstream_component
,
488 self
._graph
.add_port_added_listener(port_added_listener
)
489 self
._graph
.add_ports_connected_listener(ports_connected_listener
)
490 src
= self
._graph
.add_component(MySource
, 'src')
491 sink
= self
._graph
.add_component(MySink
, 'sink')
492 self
._graph
.connect_ports(src
.output_ports
['out'], sink
.input_ports
['in'])
494 self
.assertEqual(len(calls
), 5)
496 self
.assertIs(calls
[0][0], port_added_listener
)
497 self
.assertEqual(calls
[0][1].name
, 'src')
498 self
.assertEqual(calls
[0][2].name
, 'out')
500 self
.assertIs(calls
[1][0], port_added_listener
)
501 self
.assertEqual(calls
[1][1].name
, 'src')
502 self
.assertEqual(calls
[1][2].name
, 'zero')
504 self
.assertIs(calls
[2][0], port_added_listener
)
505 self
.assertEqual(calls
[2][1].name
, 'sink')
506 self
.assertEqual(calls
[2][2].name
, 'in')
508 self
.assertIs(calls
[3][0], port_added_listener
)
509 self
.assertEqual(calls
[3][1].name
, 'sink')
510 self
.assertEqual(calls
[3][2].name
, 'taste')
512 self
.assertIs(calls
[4][0], ports_connected_listener
)
513 self
.assertEqual(calls
[4][1].name
, 'src')
514 self
.assertEqual(calls
[4][2].name
, 'out')
515 self
.assertEqual(calls
[4][3].name
, 'sink')
516 self
.assertEqual(calls
[4][4].name
, 'in')
518 def test_invalid_listeners(self
):
519 class MyIter(bt2
._UserMessageIterator
):
523 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
524 def __init__(self
, params
):
525 self
._add
_output
_port
('out')
526 self
._add
_output
_port
('zero')
528 class MySink(bt2
._UserSinkComponent
):
529 def __init__(self
, params
):
530 self
._add
_input
_port
('in')
535 def _graph_is_configured(self
):
538 def _port_connected(self
, port
, other_port
):
539 self
._add
_input
_port
('taste')
541 with self
.assertRaises(TypeError):
542 self
._graph
.add_port_added_listener(1234)
543 with self
.assertRaises(TypeError):
544 self
._graph
.add_ports_connected_listener(1234)
546 def test_raise_in_component_init(self
):
547 class MySink(bt2
._UserSinkComponent
):
548 def __init__(self
, params
):
549 raise ValueError('oops!')
554 def _graph_is_configured(self
):
559 with self
.assertRaises(bt2
._Error
):
560 graph
.add_component(MySink
, 'comp')
562 def test_raise_in_port_added_listener(self
):
563 class MySink(bt2
._UserSinkComponent
):
564 def __init__(self
, params
):
565 self
._add
_input
_port
('in')
570 def _graph_is_configured(self
):
573 def port_added_listener(component
, port
):
574 raise ValueError('oh noes!')
577 graph
.add_port_added_listener(port_added_listener
)
579 with self
.assertRaises(bt2
._Error
):
580 graph
.add_component(MySink
, 'comp')
582 def test_raise_in_ports_connected_listener(self
):
583 class MyIter(bt2
._UserMessageIterator
):
587 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
588 def __init__(self
, params
):
589 self
._add
_output
_port
('out')
591 class MySink(bt2
._UserSinkComponent
):
592 def __init__(self
, params
):
593 self
._add
_input
_port
('in')
598 def _graph_is_configured(self
):
601 def ports_connected_listener(
602 upstream_component
, upstream_port
, downstream_component
, downstream_port
604 raise ValueError('oh noes!')
607 graph
.add_ports_connected_listener(ports_connected_listener
)
608 up
= graph
.add_component(MySource
, 'down')
609 down
= graph
.add_component(MySink
, 'up')
611 with self
.assertRaises(bt2
._Error
):
612 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
This page took 0.043419 seconds and 5 git commands to generate.