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
._input
_ports
['in'].create_message_iterator()
230 up
= graph
.add_component(MySource
, 'down')
231 down
= graph
.add_component(MySink
, 'up')
232 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
233 with self
.assertRaises(bt2
.Canceled
):
237 class MyIter(_MyIter
):
243 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
245 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
247 msg
= self
._create
_packet
_end
_message
(self
._packet
)
249 msg
= self
._create
_stream
_end
_message
(self
._stream
)
251 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
256 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
257 def __init__(self
, params
):
258 self
._add
_output
_port
('out')
260 class MySink(bt2
._UserSinkComponent
):
261 def __init__(self
, params
):
262 self
._input
_port
= self
._add
_input
_port
('in')
265 def _consume(comp_self
):
266 msg
= next(comp_self
._msg
_iter
)
268 if comp_self
._at
== 0:
269 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
270 elif comp_self
._at
== 1:
271 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
272 elif comp_self
._at
>= 2 and comp_self
._at
<= 6:
273 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
274 self
.assertEqual(msg
.event
.cls
.name
, 'salut')
275 elif comp_self
._at
== 7:
276 self
.assertIsInstance(msg
, bt2
.message
._PacketEndMessage
)
277 elif comp_self
._at
== 8:
278 self
.assertIsInstance(msg
, bt2
.message
._StreamEndMessage
)
282 def _graph_is_configured(self
):
283 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
285 src
= self
._graph
.add_component(MySource
, 'src')
286 sink
= self
._graph
.add_component(MySink
, 'sink')
287 conn
= self
._graph
.connect_ports(
288 src
.output_ports
['out'], sink
.input_ports
['in']
292 def test_run_again(self
):
293 class MyIter(_MyIter
):
299 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
301 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
303 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
308 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
309 def __init__(self
, params
):
310 self
._add
_output
_port
('out')
312 class MySink(bt2
._UserSinkComponent
):
313 def __init__(self
, params
):
314 self
._input
_port
= self
._add
_input
_port
('in')
317 def _consume(comp_self
):
318 msg
= next(comp_self
._msg
_iter
)
319 if comp_self
._at
== 0:
320 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
321 elif comp_self
._at
== 1:
322 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
323 elif comp_self
._at
== 2:
324 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
331 def _graph_is_configured(self
):
332 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
334 src
= self
._graph
.add_component(MySource
, 'src')
335 sink
= self
._graph
.add_component(MySink
, 'sink')
336 conn
= self
._graph
.connect_ports(
337 src
.output_ports
['out'], sink
.input_ports
['in']
340 with self
.assertRaises(bt2
.TryAgain
):
343 def test_run_error(self
):
344 raised_in_sink
= False
346 class MyIter(_MyIter
):
348 # If this gets called after the sink raised an exception, it is
350 nonlocal raised_in_sink
351 assert raised_in_sink
is False
354 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
356 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
357 elif self
._at
== 2 or self
._at
== 3:
358 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
364 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
365 def __init__(self
, params
):
366 self
._add
_output
_port
('out')
368 class MySink(bt2
._UserSinkComponent
):
369 def __init__(self
, params
):
370 self
._input
_port
= self
._add
_input
_port
('in')
373 def _consume(comp_self
):
374 msg
= next(comp_self
._msg
_iter
)
375 if comp_self
._at
== 0:
376 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
377 elif comp_self
._at
== 1:
378 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
379 elif comp_self
._at
== 2:
380 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
381 elif comp_self
._at
== 3:
382 nonlocal raised_in_sink
383 raised_in_sink
= True
384 raise RuntimeError('error!')
388 def _graph_is_configured(self
):
389 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
391 src
= self
._graph
.add_component(MySource
, 'src')
392 sink
= self
._graph
.add_component(MySink
, 'sink')
393 conn
= self
._graph
.connect_ports(
394 src
.output_ports
['out'], sink
.input_ports
['in']
397 with self
.assertRaises(bt2
.Error
):
400 def test_listeners(self
):
401 class MyIter(bt2
._UserMessageIterator
):
405 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
406 def __init__(self
, params
):
407 self
._add
_output
_port
('out')
408 self
._add
_output
_port
('zero')
410 class MySink(bt2
._UserSinkComponent
):
411 def __init__(self
, params
):
412 self
._add
_input
_port
('in')
417 def _graph_is_configured(self
):
420 def _port_connected(self
, port
, other_port
):
421 self
._add
_input
_port
('taste')
423 def port_added_listener(component
, port
):
425 calls
.append((port_added_listener
, component
, port
))
427 def ports_connected_listener(
428 upstream_component
, upstream_port
, downstream_component
, downstream_port
433 ports_connected_listener
,
436 downstream_component
,
442 self
._graph
.add_port_added_listener(port_added_listener
)
443 self
._graph
.add_ports_connected_listener(ports_connected_listener
)
444 src
= self
._graph
.add_component(MySource
, 'src')
445 sink
= self
._graph
.add_component(MySink
, 'sink')
446 self
._graph
.connect_ports(src
.output_ports
['out'], sink
.input_ports
['in'])
448 self
.assertEqual(len(calls
), 5)
450 self
.assertIs(calls
[0][0], port_added_listener
)
451 self
.assertEqual(calls
[0][1].name
, 'src')
452 self
.assertEqual(calls
[0][2].name
, 'out')
454 self
.assertIs(calls
[1][0], port_added_listener
)
455 self
.assertEqual(calls
[1][1].name
, 'src')
456 self
.assertEqual(calls
[1][2].name
, 'zero')
458 self
.assertIs(calls
[2][0], port_added_listener
)
459 self
.assertEqual(calls
[2][1].name
, 'sink')
460 self
.assertEqual(calls
[2][2].name
, 'in')
462 self
.assertIs(calls
[3][0], port_added_listener
)
463 self
.assertEqual(calls
[3][1].name
, 'sink')
464 self
.assertEqual(calls
[3][2].name
, 'taste')
466 self
.assertIs(calls
[4][0], ports_connected_listener
)
467 self
.assertEqual(calls
[4][1].name
, 'src')
468 self
.assertEqual(calls
[4][2].name
, 'out')
469 self
.assertEqual(calls
[4][3].name
, 'sink')
470 self
.assertEqual(calls
[4][4].name
, 'in')
472 def test_invalid_listeners(self
):
473 class MyIter(bt2
._UserMessageIterator
):
477 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
478 def __init__(self
, params
):
479 self
._add
_output
_port
('out')
480 self
._add
_output
_port
('zero')
482 class MySink(bt2
._UserSinkComponent
):
483 def __init__(self
, params
):
484 self
._add
_input
_port
('in')
489 def _graph_is_configured(self
):
492 def _port_connected(self
, port
, other_port
):
493 self
._add
_input
_port
('taste')
495 with self
.assertRaises(TypeError):
496 self
._graph
.add_port_added_listener(1234)
497 with self
.assertRaises(TypeError):
498 self
._graph
.add_ports_connected_listener(1234)
500 def test_raise_in_component_init(self
):
501 class MySink(bt2
._UserSinkComponent
):
502 def __init__(self
, params
):
503 raise ValueError('oops!')
508 def _graph_is_configured(self
):
513 with self
.assertRaises(bt2
.Error
):
514 graph
.add_component(MySink
, 'comp')
516 def test_raise_in_port_added_listener(self
):
517 class MySink(bt2
._UserSinkComponent
):
518 def __init__(self
, params
):
519 self
._add
_input
_port
('in')
524 def _graph_is_configured(self
):
527 def port_added_listener(component
, port
):
528 raise ValueError('oh noes!')
531 graph
.add_port_added_listener(port_added_listener
)
533 with self
.assertRaises(bt2
.Error
):
534 graph
.add_component(MySink
, 'comp')
536 def test_raise_in_ports_connected_listener(self
):
537 class MyIter(bt2
._UserMessageIterator
):
541 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
542 def __init__(self
, params
):
543 self
._add
_output
_port
('out')
545 class MySink(bt2
._UserSinkComponent
):
546 def __init__(self
, params
):
547 self
._add
_input
_port
('in')
552 def _graph_is_configured(self
):
555 def ports_connected_listener(
556 upstream_component
, upstream_port
, downstream_component
, downstream_port
558 raise ValueError('oh noes!')
561 graph
.add_ports_connected_listener(ports_connected_listener
)
562 up
= graph
.add_component(MySource
, 'down')
563 down
= graph
.add_component(MySink
, 'up')
565 with self
.assertRaises(bt2
.Error
):
566 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
This page took 0.040681 seconds and 4 git commands to generate.