bt2c::Logger: remove unused cLevel() method
[babeltrace.git] / tests / bindings / python / bt2 / test_error.py
CommitLineData
0235b0db 1# SPDX-License-Identifier: GPL-2.0-only
ce4923b0
SM
2#
3# Copyright (C) 2019 EfficiOS Inc.
4#
ce4923b0 5
ce4923b0
SM
6import unittest
7
5995b304
SM
8import bt2
9from bt2 import native_bt
10
ce4923b0
SM
11
12class FailingIter(bt2._UserMessageIterator):
13 def __next__(self):
f5567ea8 14 raise ValueError("User message iterator is failing")
ce4923b0
SM
15
16
17class SourceWithFailingIter(
18 bt2._UserSourceComponent, message_iterator_class=FailingIter
19):
59225a3e 20 def __init__(self, config, params, obj):
f5567ea8 21 self._add_output_port("out")
ce4923b0
SM
22
23
24class SourceWithFailingInit(
25 bt2._UserSourceComponent, message_iterator_class=FailingIter
26):
59225a3e 27 def __init__(self, config, params, obj):
f5567ea8 28 raise ValueError("Source is failing")
ce4923b0
SM
29
30
31class WorkingSink(bt2._UserSinkComponent):
59225a3e 32 def __init__(self, config, params, obj):
f5567ea8 33 self._in = self._add_input_port("in")
ce4923b0 34
6a91742b 35 def _user_graph_is_configured(self):
9a2c8b8e 36 self._iter = self._create_message_iterator(self._in)
ce4923b0 37
6a91742b 38 def _user_consume(self):
ce4923b0
SM
39 next(self._iter)
40
41
42class SinkWithExceptionChaining(bt2._UserSinkComponent):
59225a3e 43 def __init__(self, config, params, obj):
f5567ea8 44 self._in = self._add_input_port("in")
ce4923b0 45
6a91742b 46 def _user_graph_is_configured(self):
9a2c8b8e 47 self._iter = self._create_message_iterator(self._in)
ce4923b0 48
6a91742b 49 def _user_consume(self):
ce4923b0 50 try:
ce4923b0 51 next(self._iter)
694c792b 52 except bt2._Error as e:
f5567ea8 53 raise ValueError("oops") from e
ce4923b0
SM
54
55
56class SinkWithFailingQuery(bt2._UserSinkComponent):
6a91742b 57 def _user_consume(self):
ce4923b0
SM
58 pass
59
60 @staticmethod
7c14d641 61 def _user_query(priv_executor, obj, params, method_obj):
f5567ea8 62 raise ValueError("Query is failing")
ce4923b0
SM
63
64
65class ErrorTestCase(unittest.TestCase):
66 def _run_failing_graph(self, source_cc, sink_cc):
694c792b 67 with self.assertRaises(bt2._Error) as ctx:
ce4923b0 68 graph = bt2.Graph()
f5567ea8
FD
69 src = graph.add_component(source_cc, "src")
70 snk = graph.add_component(sink_cc, "snk")
71 graph.connect_ports(src.output_ports["out"], snk.input_ports["in"])
ce4923b0
SM
72 graph.run()
73
74 return ctx.exception
75
76 def test_current_thread_error_none(self):
694c792b 77 # When a bt2._Error is raised, it steals the current thread's error.
ce4923b0 78 # Verify that it is now NULL.
082db648 79 self._run_failing_graph(SourceWithFailingInit, WorkingSink)
ce4923b0
SM
80 self.assertIsNone(native_bt.current_thread_take_error())
81
82 def test_len(self):
83 exc = self._run_failing_graph(SourceWithFailingIter, WorkingSink)
84
85 # The exact number of causes is not too important (it can change if we
86 # append more or less causes along the way), but the idea is to verify is
87 # has a value that makes sense.
88 self.assertEqual(len(exc), 4)
89
90 def test_iter(self):
91 exc = self._run_failing_graph(SourceWithFailingIter, WorkingSink)
92
93 for c in exc:
94 # Each cause is an instance of _ErrorCause (including subclasses).
3fb99a22 95 self.assertIsInstance(c, bt2._ErrorCause)
ce4923b0
SM
96
97 def test_getitem(self):
98 exc = self._run_failing_graph(SourceWithFailingIter, WorkingSink)
99
100 for i in range(len(exc)):
101 c = exc[i]
102 # Each cause is an instance of _ErrorCause (including subclasses).
3fb99a22 103 self.assertIsInstance(c, bt2._ErrorCause)
ce4923b0
SM
104
105 def test_getitem_indexerror(self):
106 exc = self._run_failing_graph(SourceWithFailingIter, WorkingSink)
107
108 with self.assertRaises(IndexError):
109 exc[len(exc)]
110
111 def test_exception_chaining(self):
112 # Test that if we do:
113 #
114 # try:
115 # ...
694c792b 116 # except bt2._Error as exc:
ce4923b0
SM
117 # raise ValueError('oh noes') from exc
118 #
694c792b 119 # We are able to fetch the causes of the original bt2._Error in the
ce4923b0
SM
120 # exception chain. Also, each exception in the chain should become one
121 # cause once caught.
122 exc = self._run_failing_graph(SourceWithFailingIter, SinkWithExceptionChaining)
123
124 self.assertEqual(len(exc), 5)
125
3fb99a22 126 self.assertIsInstance(exc[0], bt2._MessageIteratorErrorCause)
f5567ea8
FD
127 self.assertEqual(exc[0].component_class_name, "SourceWithFailingIter")
128 self.assertIn("ValueError: User message iterator is failing", exc[0].message)
ce4923b0 129
3fb99a22 130 self.assertIsInstance(exc[1], bt2._ErrorCause)
ce4923b0 131
3fb99a22 132 self.assertIsInstance(exc[2], bt2._ComponentErrorCause)
f5567ea8 133 self.assertEqual(exc[2].component_class_name, "SinkWithExceptionChaining")
ce4923b0 134 self.assertIn(
f5567ea8 135 "unexpected error: cannot advance the message iterator", exc[2].message
ce4923b0
SM
136 )
137
3fb99a22 138 self.assertIsInstance(exc[3], bt2._ComponentErrorCause)
f5567ea8
FD
139 self.assertEqual(exc[3].component_class_name, "SinkWithExceptionChaining")
140 self.assertIn("ValueError: oops", exc[3].message)
ce4923b0 141
3fb99a22 142 self.assertIsInstance(exc[4], bt2._ErrorCause)
ce4923b0
SM
143
144 def _common_cause_tests(self, cause):
145 self.assertIsInstance(cause.module_name, str)
146 self.assertIsInstance(cause.file_name, str)
147 self.assertIsInstance(cause.line_number, int)
148
149 def test_unknown_error_cause(self):
150 exc = self._run_failing_graph(SourceWithFailingIter, SinkWithExceptionChaining)
151 cause = exc[-1]
3fb99a22 152 self.assertIs(type(cause), bt2._ErrorCause)
ce4923b0
SM
153 self._common_cause_tests(cause)
154
155 def test_component_error_cause(self):
156 exc = self._run_failing_graph(SourceWithFailingInit, SinkWithExceptionChaining)
157 cause = exc[0]
3fb99a22 158 self.assertIs(type(cause), bt2._ComponentErrorCause)
ce4923b0
SM
159 self._common_cause_tests(cause)
160
f5567ea8
FD
161 self.assertIn("Source is failing", cause.message)
162 self.assertEqual(cause.component_name, "src")
ce4923b0 163 self.assertEqual(cause.component_class_type, bt2.ComponentClassType.SOURCE)
f5567ea8 164 self.assertEqual(cause.component_class_name, "SourceWithFailingInit")
ce4923b0
SM
165 self.assertIsNone(cause.plugin_name)
166
167 def test_component_class_error_cause(self):
f5567ea8 168 q = bt2.QueryExecutor(SinkWithFailingQuery, "hello")
ce4923b0 169
694c792b 170 with self.assertRaises(bt2._Error) as ctx:
3c729b9a 171 q.query()
ce4923b0
SM
172
173 cause = ctx.exception[0]
3fb99a22 174 self.assertIs(type(cause), bt2._ComponentClassErrorCause)
ce4923b0
SM
175 self._common_cause_tests(cause)
176
f5567ea8 177 self.assertIn("Query is failing", cause.message)
ce4923b0
SM
178
179 self.assertEqual(cause.component_class_type, bt2.ComponentClassType.SINK)
f5567ea8 180 self.assertEqual(cause.component_class_name, "SinkWithFailingQuery")
ce4923b0
SM
181 self.assertIsNone(cause.plugin_name)
182
183 def test_message_iterator_error_cause(self):
184 exc = self._run_failing_graph(SourceWithFailingIter, SinkWithExceptionChaining)
185 cause = exc[0]
3fb99a22 186 self.assertIs(type(cause), bt2._MessageIteratorErrorCause)
ce4923b0
SM
187 self._common_cause_tests(cause)
188
f5567ea8
FD
189 self.assertIn("User message iterator is failing", cause.message)
190 self.assertEqual(cause.component_name, "src")
191 self.assertEqual(cause.component_output_port_name, "out")
ce4923b0 192 self.assertEqual(cause.component_class_type, bt2.ComponentClassType.SOURCE)
f5567ea8 193 self.assertEqual(cause.component_class_name, "SourceWithFailingIter")
ce4923b0 194 self.assertIsNone(cause.plugin_name)
d14ddbba 195
8258c4bd
SM
196 def test_str(self):
197 # Test __str__. We don't need to test the precise format used, but
198 # just that it doesn't miserably crash and that it contains some
199 # expected bits.
200 exc = self._run_failing_graph(SourceWithFailingIter, SinkWithExceptionChaining)
201 s = str(exc)
5038e256 202 self.assertIn("[src (out): 'source.SourceWithFailingIter']", s)
f5567ea8 203 self.assertIn("ValueError: oops", s)
8258c4bd 204
d14ddbba 205
f5567ea8 206if __name__ == "__main__":
d14ddbba 207 unittest.main()
This page took 0.069566 seconds and 5 git commands to generate.