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_cancel(self
):
177 self
.assertFalse(self
._graph
.is_canceled
)
179 self
.assertTrue(self
._graph
.is_canceled
)
181 # Test that Graph.run() raises bt2.Canceled if the graph gets canceled
183 def test_cancel_while_running(self
):
184 class MyIter(_MyIter
):
186 return self
._create
_stream
_beginning
_message
(self
._stream
)
188 class MySource(bt2
._UserSourceComponent
,
189 message_iterator_class
=MyIter
):
190 def __init__(self
, params
):
191 self
._add
_output
_port
('out')
193 class MySink(bt2
._UserSinkComponent
):
194 def __init__(self
, params
):
195 self
._add
_input
_port
('in')
198 # Pretend that somebody asynchronously cancelled the graph.
202 return next(self
._msg
_iter
)
204 def _graph_is_configured(self
):
205 self
._msg
_iter
= self
._input
_ports
['in'].create_message_iterator()
208 up
= graph
.add_component(MySource
, 'down')
209 down
= graph
.add_component(MySink
, 'up')
210 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
211 with self
.assertRaises(bt2
.Canceled
):
215 class MyIter(_MyIter
):
221 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
223 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
225 msg
= self
._create
_packet
_end
_message
(self
._packet
)
227 msg
= self
._create
_stream
_end
_message
(self
._stream
)
229 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
234 class MySource(bt2
._UserSourceComponent
,
235 message_iterator_class
=MyIter
):
236 def __init__(self
, params
):
237 self
._add
_output
_port
('out')
239 class MySink(bt2
._UserSinkComponent
):
240 def __init__(self
, params
):
241 self
._input
_port
= self
._add
_input
_port
('in')
244 def _consume(comp_self
):
245 msg
= next(comp_self
._msg
_iter
)
247 if comp_self
._at
== 0:
248 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
249 elif comp_self
._at
== 1:
250 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
251 elif comp_self
._at
>= 2 and comp_self
._at
<= 6:
252 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
253 self
.assertEqual(msg
.event
.cls
.name
, 'salut')
254 elif comp_self
._at
== 7:
255 self
.assertIsInstance(msg
, bt2
.message
._PacketEndMessage
)
256 elif comp_self
._at
== 8:
257 self
.assertIsInstance(msg
, bt2
.message
._StreamEndMessage
)
261 def _graph_is_configured(self
):
262 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
264 src
= self
._graph
.add_component(MySource
, 'src')
265 sink
= self
._graph
.add_component(MySink
, 'sink')
266 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
267 sink
.input_ports
['in'])
270 def test_run_again(self
):
271 class MyIter(_MyIter
):
277 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
279 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
281 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
286 class MySource(bt2
._UserSourceComponent
,
287 message_iterator_class
=MyIter
):
288 def __init__(self
, params
):
289 self
._add
_output
_port
('out')
291 class MySink(bt2
._UserSinkComponent
):
292 def __init__(self
, params
):
293 self
._input
_port
= self
._add
_input
_port
('in')
296 def _consume(comp_self
):
297 msg
= next(comp_self
._msg
_iter
)
298 if comp_self
._at
== 0:
299 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
300 elif comp_self
._at
== 1:
301 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
302 elif comp_self
._at
== 2:
303 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
310 def _graph_is_configured(self
):
311 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
313 src
= self
._graph
.add_component(MySource
, 'src')
314 sink
= self
._graph
.add_component(MySink
, 'sink')
315 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
316 sink
.input_ports
['in'])
318 with self
.assertRaises(bt2
.TryAgain
):
321 def test_run_error(self
):
322 raised_in_sink
= False
324 class MyIter(_MyIter
):
326 # If this gets called after the sink raised an exception, it is
328 nonlocal raised_in_sink
329 assert raised_in_sink
is False
332 msg
= self
._create
_stream
_beginning
_message
(self
._stream
)
334 msg
= self
._create
_packet
_beginning
_message
(self
._packet
)
335 elif self
._at
== 2 or self
._at
== 3:
336 msg
= self
._create
_event
_message
(self
._ec
, self
._packet
)
342 class MySource(bt2
._UserSourceComponent
,
343 message_iterator_class
=MyIter
):
344 def __init__(self
, params
):
345 self
._add
_output
_port
('out')
347 class MySink(bt2
._UserSinkComponent
):
348 def __init__(self
, params
):
349 self
._input
_port
= self
._add
_input
_port
('in')
352 def _consume(comp_self
):
353 msg
= next(comp_self
._msg
_iter
)
354 if comp_self
._at
== 0:
355 self
.assertIsInstance(msg
, bt2
.message
._StreamBeginningMessage
)
356 elif comp_self
._at
== 1:
357 self
.assertIsInstance(msg
, bt2
.message
._PacketBeginningMessage
)
358 elif comp_self
._at
== 2:
359 self
.assertIsInstance(msg
, bt2
.message
._EventMessage
)
360 elif comp_self
._at
== 3:
361 nonlocal raised_in_sink
362 raised_in_sink
= True
363 raise RuntimeError('error!')
367 def _graph_is_configured(self
):
368 self
._msg
_iter
= self
._input
_port
.create_message_iterator()
370 src
= self
._graph
.add_component(MySource
, 'src')
371 sink
= self
._graph
.add_component(MySink
, 'sink')
372 conn
= self
._graph
.connect_ports(src
.output_ports
['out'],
373 sink
.input_ports
['in'])
375 with self
.assertRaises(bt2
.Error
):
378 def test_listeners(self
):
379 class MyIter(bt2
._UserMessageIterator
):
383 class MySource(bt2
._UserSourceComponent
,
384 message_iterator_class
=MyIter
):
385 def __init__(self
, params
):
386 self
._add
_output
_port
('out')
387 self
._add
_output
_port
('zero')
389 class MySink(bt2
._UserSinkComponent
):
390 def __init__(self
, params
):
391 self
._add
_input
_port
('in')
396 def _port_connected(self
, port
, other_port
):
397 self
._add
_input
_port
('taste')
399 def port_added_listener(component
, port
):
401 calls
.append((port_added_listener
, component
, port
))
403 def ports_connected_listener(upstream_component
, upstream_port
,
404 downstream_component
, downstream_port
):
406 calls
.append((ports_connected_listener
,
407 upstream_component
, upstream_port
,
408 downstream_component
, downstream_port
))
411 self
._graph
.add_port_added_listener(port_added_listener
)
412 self
._graph
.add_ports_connected_listener(ports_connected_listener
)
413 src
= self
._graph
.add_component(MySource
, 'src')
414 sink
= self
._graph
.add_component(MySink
, 'sink')
415 self
._graph
.connect_ports(src
.output_ports
['out'],
416 sink
.input_ports
['in'])
418 self
.assertEqual(len(calls
), 5)
420 self
.assertIs(calls
[0][0], port_added_listener
)
421 self
.assertEqual(calls
[0][1].name
, 'src')
422 self
.assertEqual(calls
[0][2].name
, 'out')
424 self
.assertIs(calls
[1][0], port_added_listener
)
425 self
.assertEqual(calls
[1][1].name
, 'src')
426 self
.assertEqual(calls
[1][2].name
, 'zero')
428 self
.assertIs(calls
[2][0], port_added_listener
)
429 self
.assertEqual(calls
[2][1].name
, 'sink')
430 self
.assertEqual(calls
[2][2].name
, 'in')
432 self
.assertIs(calls
[3][0], port_added_listener
)
433 self
.assertEqual(calls
[3][1].name
, 'sink')
434 self
.assertEqual(calls
[3][2].name
, 'taste')
436 self
.assertIs(calls
[4][0], ports_connected_listener
)
437 self
.assertEqual(calls
[4][1].name
, 'src')
438 self
.assertEqual(calls
[4][2].name
, 'out')
439 self
.assertEqual(calls
[4][3].name
, 'sink')
440 self
.assertEqual(calls
[4][4].name
, 'in')
442 def test_invalid_listeners(self
):
443 class MyIter(bt2
._UserMessageIterator
):
447 class MySource(bt2
._UserSourceComponent
,
448 message_iterator_class
=MyIter
):
449 def __init__(self
, params
):
450 self
._add
_output
_port
('out')
451 self
._add
_output
_port
('zero')
453 class MySink(bt2
._UserSinkComponent
):
454 def __init__(self
, params
):
455 self
._add
_input
_port
('in')
460 def _port_connected(self
, port
, other_port
):
461 self
._add
_input
_port
('taste')
463 with self
.assertRaises(TypeError):
464 self
._graph
.add_port_added_listener(1234)
465 with self
.assertRaises(TypeError):
466 self
._graph
.add_ports_connected_listener(1234)
468 def test_raise_in_component_init(self
):
469 class MySink(bt2
._UserSinkComponent
):
470 def __init__(self
, params
):
471 raise ValueError('oops!')
478 with self
.assertRaises(bt2
.Error
):
479 graph
.add_component(MySink
, 'comp')
481 def test_raise_in_port_added_listener(self
):
482 class MySink(bt2
._UserSinkComponent
):
483 def __init__(self
, params
):
484 self
._add
_input
_port
('in')
489 def port_added_listener(component
, port
):
490 raise ValueError('oh noes!')
493 graph
.add_port_added_listener(port_added_listener
)
495 with self
.assertRaises(bt2
.Error
):
496 graph
.add_component(MySink
, 'comp')
498 def test_raise_in_ports_connected_listener(self
):
499 class MyIter(bt2
._UserMessageIterator
):
503 class MySource(bt2
._UserSourceComponent
,
504 message_iterator_class
=MyIter
):
505 def __init__(self
, params
):
506 self
._add
_output
_port
('out')
508 class MySink(bt2
._UserSinkComponent
):
509 def __init__(self
, params
):
510 self
._add
_input
_port
('in')
515 def ports_connected_listener(upstream_component
, upstream_port
,
516 downstream_component
, downstream_port
):
517 raise ValueError('oh noes!')
520 graph
.add_ports_connected_listener(ports_connected_listener
)
521 up
= graph
.add_component(MySource
, 'down')
522 down
= graph
.add_component(MySink
, 'up')
524 with self
.assertRaises(bt2
.Error
):
525 graph
.connect_ports(up
.output_ports
['out'], down
.input_ports
['in'])
This page took 0.041401 seconds and 4 git commands to generate.