b719d9ca133e7b6956e7bbdb72a0bfc257f4ae01
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.
23 class _MyIter(bt2
._UserMessageIterator
):
24 def __init__(self
, self_output_port
):
28 def _build_meta(self
):
29 self
._tc
= self
._component
._create
_trace
_class
()
31 self
._sc
= self
._tc
.create_stream_class(supports_packets
=True)
32 self
._ec
= self
._sc
.create_event_class(name
='salut')
33 self
._my
_int
_ft
= self
._tc
.create_signed_integer_field_class(32)
34 payload_ft
= self
._tc
.create_structure_field_class()
35 payload_ft
+= [('my_int', self
._my
_int
_ft
)]
36 self
._ec
.payload_field_type
= payload_ft
37 self
._stream
= self
._t
.create_stream(self
._sc
)
38 self
._packet
= self
._stream
.create_packet()
40 def _create_event(self
, value
):
42 ev
.payload_field
['my_int'] = value
43 ev
.packet
= self
._packet
47 class GraphTestCase(unittest
.TestCase
):
49 self
._graph
= bt2
.Graph()
54 def test_create_default(self
):
57 def test_create_known_mip_version(self
):
60 def test_create_invalid_mip_version_type(self
):
61 with self
.assertRaises(TypeError):
64 def test_create_unknown_mip_version(self
):
65 with self
.assertRaisesRegex(ValueError, 'unknown MIP version'):
68 def test_add_component_user_cls(self
):
69 class MySink(bt2
._UserSinkComponent
):
70 def _user_consume(self
):
73 comp
= self
._graph
.add_component(MySink
, 'salut')
74 self
.assertEqual(comp
.name
, 'salut')
76 def test_add_component_gen_cls(self
):
77 class MySink(bt2
._UserSinkComponent
):
78 def _user_consume(self
):
81 comp
= self
._graph
.add_component(MySink
, 'salut')
83 comp2
= self
._graph
.add_component(comp
.cls
, 'salut2')
84 self
.assertEqual(comp2
.name
, 'salut2')
86 def test_add_component_params(self
):
89 class MySink(bt2
._UserSinkComponent
):
90 def __init__(self
, params
, obj
):
94 def _user_consume(self
):
97 params
= {'hello': 23, 'path': '/path/to/stuff'}
98 comp
= self
._graph
.add_component(MySink
, 'salut', params
)
99 self
.assertEqual(params
, comp_params
)
102 def test_add_component_obj_python_comp_cls(self
):
105 class MySink(bt2
._UserSinkComponent
):
106 def __init__(self
, params
, obj
):
110 def _user_consume(self
):
114 comp
= self
._graph
.add_component(MySink
, 'salut', obj
=obj
)
115 self
.assertIs(comp_obj
, obj
)
118 def test_add_component_obj_none_python_comp_cls(self
):
121 class MySink(bt2
._UserSinkComponent
):
122 def __init__(self
, params
, obj
):
126 def _user_consume(self
):
129 comp
= self
._graph
.add_component(MySink
, 'salut')
130 self
.assertIsNone(comp_obj
)
133 def test_add_component_obj_non_python_comp_cls(self
):
136 plugin
= bt2
.find_plugin('text', find_in_user_dir
=False, find_in_sys_dir
=False)
137 assert plugin
is not None
138 cc
= plugin
.source_component_classes
['dmesg']
139 assert cc
is not None
141 with self
.assertRaises(ValueError):
142 comp
= self
._graph
.add_component(cc
, 'salut', obj
=57)
144 def test_add_component_invalid_cls_type(self
):
145 with self
.assertRaises(TypeError):
146 self
._graph
.add_component(int, 'salut')
148 def test_add_component_invalid_logging_level_type(self
):
149 class MySink(bt2
._UserSinkComponent
):
150 def _user_consume(self
):
153 with self
.assertRaises(TypeError):
154 self
._graph
.add_component(MySink
, 'salut', logging_level
='yo')
156 def test_add_component_invalid_logging_level_value(self
):
157 class MySink(bt2
._UserSinkComponent
):
158 def _user_consume(self
):
161 with self
.assertRaises(ValueError):
162 self
._graph
.add_component(MySink
, 'salut', logging_level
=12345)
164 def test_add_component_logging_level(self
):
165 class MySink(bt2
._UserSinkComponent
):
166 def _user_consume(self
):
169 comp
= self
._graph
.add_component(
170 MySink
, 'salut', logging_level
=bt2
.LoggingLevel
.DEBUG
172 self
.assertEqual(comp
.logging_level
, bt2
.LoggingLevel
.DEBUG
)
174 def test_connect_ports(self
):
175 class MyIter(bt2
._UserMessageIterator
):
179 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
180 def __init__(self
, params
, obj
):
181 self
._add
_output
_port
('out')
183 class MySink(bt2
._UserSinkComponent
):
184 def __init__(self
, params
, obj
):
185 self
._add
_input
_port
('in')
187 def _user_consume(self
):
190 src
= self
._graph
.add_component(MySource
, 'src')
191 sink
= self
._graph
.add_component(MySink
, 'sink')
193 conn
= self
._graph
.connect_ports(
194 src
.output_ports
['out'], sink
.input_ports
['in']
196 self
.assertTrue(src
.output_ports
['out'].is_connected
)
197 self
.assertTrue(sink
.input_ports
['in'].is_connected
)
198 self
.assertEqual(src
.output_ports
['out'].connection
.addr
, conn
.addr
)
199 self
.assertEqual(sink
.input_ports
['in'].connection
.addr
, conn
.addr
)
201 def test_connect_ports_invalid_direction(self
):
202 class MyIter(bt2
._UserMessageIterator
):
206 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
207 def __init__(self
, params
, obj
):
208 self
._add
_output
_port
('out')
210 class MySink(bt2
._UserSinkComponent
):
211 def __init__(self
, params
, obj
):
212 self
._add
_input
_port
('in')
214 def _user_consume(self
):
217 src
= self
._graph
.add_component(MySource
, 'src')
218 sink
= self
._graph
.add_component(MySink
, 'sink')
220 with self
.assertRaises(TypeError):
221 conn
= self
._graph
.connect_ports(
222 sink
.input_ports
['in'], src
.output_ports
['out']
225 def test_add_interrupter(self
):
226 class MyIter(bt2
._UserMessageIterator
):
230 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
231 def __init__(self
, params
, obj
):
232 self
._add
_output
_port
('out')
234 class MySink(bt2
._UserSinkComponent
):
235 def __init__(self
, params
, obj
):
236 self
._add
_input
_port
('in')
238 def _user_consume(self
):
241 def _user_graph_is_configured(self
):
242 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
243 self
._input
_ports
['in']
246 # add two interrupters, set one of them
247 interrupter1
= bt2
.Interrupter()
248 interrupter2
= bt2
.Interrupter()
249 self
._graph
.add_interrupter(interrupter1
)
250 src
= self
._graph
.add_component(MySource
, 'src')
251 sink
= self
._graph
.add_component(MySink
, 'sink')
252 self
._graph
.connect_ports(src
.output_ports
['out'], sink
.input_ports
['in'])
253 self
._graph
.add_interrupter(interrupter2
)
255 with self
.assertRaises(bt2
._Error
):
260 with self
.assertRaises(bt2
.TryAgain
):
265 with self
.assertRaises(bt2
._Error
):
268 # Test that Graph.run() raises bt2.Interrupted if the graph gets
269 # interrupted during execution.
270 def test_interrupt_while_running(self
):
271 class MyIter(_MyIter
):
273 return self
._create
_stream
_beginning
_message
(self
._stream
)
275 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
276 def __init__(self
, params
, obj
):
277 self
._add
_output
_port
('out')
279 class MySink(bt2
._UserSinkComponent
):
280 def __init__(self
, params
, obj
):
281 self
._add
_input
_port
('in')
283 def _user_consume(self
):
284 # Pretend that somebody asynchronously interrupted the graph.
287 return next(self
._msg
_iter
)
289 def _user_graph_is_configured(self
):
290 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
291 self
._input
_ports
['in']
295 up
= self
._graph
.add_component(MySource
, 'down')
296 down
= self
._graph
.add_component(MySink
, 'up')
297 self
._graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
299 with self
.assertRaises(bt2
.TryAgain
):
303 class MyIter(_MyIter
):
309 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
311 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
313 msg
= self
._create
_packet
_end
_message
(self
._packet
)
315 msg
= self
._create
_stream
_end
_message
(self
._stream
)
317 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
322 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
323 def __init__(self
, params
, obj
):
324 self
._add
_output
_port
('out')
326 class MySink(bt2
._UserSinkComponent
):
327 def __init__(self
, params
, obj
):
328 self
._input
_port
= self
._add
_input
_port
('in')
331 def _user_consume(comp_self
):
332 msg
= next(comp_self
._msg
_iter
)
334 if comp_self
._at
== 0:
335 self
.assertIsInstance(msg
, bt2
._StreamBeginningMessage
)
336 elif comp_self
._at
== 1:
337 self
.assertIsInstance(msg
, bt2
._PacketBeginningMessage
)
338 elif comp_self
._at
>= 2 and comp_self
._at
<= 6:
339 self
.assertIsInstance(msg
, bt2
._EventMessage
)
340 self
.assertEqual(msg
.event
.cls
.name
, 'salut')
341 elif comp_self
._at
== 7:
342 self
.assertIsInstance(msg
, bt2
._PacketEndMessage
)
343 elif comp_self
._at
== 8:
344 self
.assertIsInstance(msg
, bt2
._StreamEndMessage
)
348 def _user_graph_is_configured(self
):
349 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
353 src
= self
._graph
.add_component(MySource
, 'src')
354 sink
= self
._graph
.add_component(MySink
, 'sink')
355 conn
= self
._graph
.connect_ports(
356 src
.output_ports
['out'], sink
.input_ports
['in']
360 def test_run_once(self
):
361 class MyIter(_MyIter
):
364 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
365 def __init__(self
, params
, obj
):
366 self
._add
_output
_port
('out')
368 class MySink(bt2
._UserSinkComponent
):
369 def __init__(self
, params
, obj
):
370 self
._input
_port
= self
._add
_input
_port
('in')
372 def _user_consume(comp_self
):
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
):
385 self
._graph
.run_once()
387 self
.assertEqual(run_count
, 1)
389 def test_run_once_stops(self
):
390 class MyIter(_MyIter
):
393 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
394 def __init__(self
, params
, obj
):
395 self
._add
_output
_port
('out')
397 class MySink(bt2
._UserSinkComponent
):
398 def __init__(self
, params
, obj
):
399 self
._input
_port
= self
._add
_input
_port
('in')
401 def _user_consume(comp_self
):
404 src
= self
._graph
.add_component(MySource
, 'src')
405 sink
= self
._graph
.add_component(MySink
, 'sink')
406 conn
= self
._graph
.connect_ports(
407 src
.output_ports
['out'], sink
.input_ports
['in']
410 with self
.assertRaises(bt2
.Stop
):
411 self
._graph
.run_once()
413 def test_run_again(self
):
414 class MyIter(_MyIter
):
420 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
422 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
424 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
429 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
430 def __init__(self
, params
, obj
):
431 self
._add
_output
_port
('out')
433 class MySink(bt2
._UserSinkComponent
):
434 def __init__(self
, params
, obj
):
435 self
._input
_port
= self
._add
_input
_port
('in')
438 def _user_consume(comp_self
):
439 msg
= next(comp_self
._msg
_iter
)
440 if comp_self
._at
== 0:
441 self
.assertIsInstance(msg
, bt2
._StreamBeginningMessage
)
442 elif comp_self
._at
== 1:
443 self
.assertIsInstance(msg
, bt2
._PacketBeginningMessage
)
444 elif comp_self
._at
== 2:
445 self
.assertIsInstance(msg
, bt2
._EventMessage
)
452 def _user_graph_is_configured(self
):
453 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
457 src
= self
._graph
.add_component(MySource
, 'src')
458 sink
= self
._graph
.add_component(MySink
, 'sink')
459 conn
= self
._graph
.connect_ports(
460 src
.output_ports
['out'], sink
.input_ports
['in']
463 with self
.assertRaises(bt2
.TryAgain
):
466 def test_run_error(self
):
467 raised_in_sink
= False
469 class MyIter(_MyIter
):
471 # If this gets called after the sink raised an exception, it is
473 nonlocal raised_in_sink
474 assert raised_in_sink
is False
477 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
479 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
480 elif self
._at
== 2 or self
._at
== 3:
481 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
487 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
488 def __init__(self
, params
, obj
):
489 self
._add
_output
_port
('out')
491 class MySink(bt2
._UserSinkComponent
):
492 def __init__(self
, params
, obj
):
493 self
._input
_port
= self
._add
_input
_port
('in')
496 def _user_consume(comp_self
):
497 msg
= next(comp_self
._msg
_iter
)
498 if comp_self
._at
== 0:
499 self
.assertIsInstance(msg
, bt2
._StreamBeginningMessage
)
500 elif comp_self
._at
== 1:
501 self
.assertIsInstance(msg
, bt2
._PacketBeginningMessage
)
502 elif comp_self
._at
== 2:
503 self
.assertIsInstance(msg
, bt2
._EventMessage
)
504 elif comp_self
._at
== 3:
505 nonlocal raised_in_sink
506 raised_in_sink
= True
507 raise RuntimeError('error!')
511 def _user_graph_is_configured(self
):
512 self
._msg
_iter
= self
._create
_input
_port
_message
_iterator
(
516 src
= self
._graph
.add_component(MySource
, 'src')
517 sink
= self
._graph
.add_component(MySink
, 'sink')
518 conn
= self
._graph
.connect_ports(
519 src
.output_ports
['out'], sink
.input_ports
['in']
522 with self
.assertRaises(bt2
._Error
):
525 def test_listeners(self
):
526 class MyIter(bt2
._UserMessageIterator
):
530 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
531 def __init__(self
, params
, obj
):
532 self
._add
_output
_port
('out')
533 self
._add
_output
_port
('zero')
535 class MySink(bt2
._UserSinkComponent
):
536 def __init__(self
, params
, obj
):
537 self
._add
_input
_port
('in')
539 def _user_consume(self
):
542 def _user_port_connected(self
, port
, other_port
):
543 self
._add
_input
_port
('taste')
545 def port_added_listener(component
, port
):
547 calls
.append((port_added_listener
, component
, port
))
549 def ports_connected_listener(
550 upstream_component
, upstream_port
, downstream_component
, downstream_port
555 ports_connected_listener
,
558 downstream_component
,
564 self
._graph
.add_port_added_listener(port_added_listener
)
565 self
._graph
.add_ports_connected_listener(ports_connected_listener
)
566 src
= self
._graph
.add_component(MySource
, 'src')
567 sink
= self
._graph
.add_component(MySink
, 'sink')
568 self
._graph
.connect_ports(src
.output_ports
['out'], sink
.input_ports
['in'])
570 self
.assertEqual(len(calls
), 5)
572 self
.assertIs(calls
[0][0], port_added_listener
)
573 self
.assertEqual(calls
[0][1].name
, 'src')
574 self
.assertEqual(calls
[0][2].name
, 'out')
576 self
.assertIs(calls
[1][0], port_added_listener
)
577 self
.assertEqual(calls
[1][1].name
, 'src')
578 self
.assertEqual(calls
[1][2].name
, 'zero')
580 self
.assertIs(calls
[2][0], port_added_listener
)
581 self
.assertEqual(calls
[2][1].name
, 'sink')
582 self
.assertEqual(calls
[2][2].name
, 'in')
584 self
.assertIs(calls
[3][0], port_added_listener
)
585 self
.assertEqual(calls
[3][1].name
, 'sink')
586 self
.assertEqual(calls
[3][2].name
, 'taste')
588 self
.assertIs(calls
[4][0], ports_connected_listener
)
589 self
.assertEqual(calls
[4][1].name
, 'src')
590 self
.assertEqual(calls
[4][2].name
, 'out')
591 self
.assertEqual(calls
[4][3].name
, 'sink')
592 self
.assertEqual(calls
[4][4].name
, 'in')
594 def test_invalid_listeners(self
):
595 class MyIter(bt2
._UserMessageIterator
):
599 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
600 def __init__(self
, params
, obj
):
601 self
._add
_output
_port
('out')
602 self
._add
_output
_port
('zero')
604 class MySink(bt2
._UserSinkComponent
):
605 def __init__(self
, params
, obj
):
606 self
._add
_input
_port
('in')
608 def _user_consume(self
):
611 def _user_port_connected(self
, port
, other_port
):
612 self
._add
_input
_port
('taste')
614 with self
.assertRaises(TypeError):
615 self
._graph
.add_port_added_listener(1234)
616 with self
.assertRaises(TypeError):
617 self
._graph
.add_ports_connected_listener(1234)
619 def test_raise_in_component_init(self
):
620 class MySink(bt2
._UserSinkComponent
):
621 def __init__(self
, params
, obj
):
622 raise ValueError('oops!')
624 def _user_consume(self
):
629 with self
.assertRaises(bt2
._Error
):
630 graph
.add_component(MySink
, 'comp')
632 def test_raise_in_port_added_listener(self
):
633 class MySink(bt2
._UserSinkComponent
):
634 def __init__(self
, params
, obj
):
635 self
._add
_input
_port
('in')
637 def _user_consume(self
):
640 def port_added_listener(component
, port
):
641 raise ValueError('oh noes!')
644 graph
.add_port_added_listener(port_added_listener
)
646 with self
.assertRaises(bt2
._Error
):
647 graph
.add_component(MySink
, 'comp')
649 def test_raise_in_ports_connected_listener(self
):
650 class MyIter(bt2
._UserMessageIterator
):
654 class MySource(bt2
._UserSourceComponent
, message_iterator_class
=MyIter
):
655 def __init__(self
, params
, obj
):
656 self
._add
_output
_port
('out')
658 class MySink(bt2
._UserSinkComponent
):
659 def __init__(self
, params
, obj
):
660 self
._add
_input
_port
('in')
662 def _user_consume(self
):
665 def ports_connected_listener(
666 upstream_component
, upstream_port
, downstream_component
, downstream_port
668 raise ValueError('oh noes!')
671 graph
.add_ports_connected_listener(ports_connected_listener
)
672 up
= graph
.add_component(MySource
, 'down')
673 down
= graph
.add_component(MySink
, 'up')
675 with self
.assertRaises(bt2
._Error
):
676 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
This page took 0.045388 seconds and 3 git commands to generate.