Commit | Line | Data |
---|---|---|
0235b0db | 1 | # SPDX-License-Identifier: GPL-2.0-only |
d2d857a8 MJ |
2 | # |
3 | # Copyright (C) 2019 EfficiOS Inc. | |
4 | # | |
d2d857a8 | 5 | |
5995b304 | 6 | import re |
c7eee084 | 7 | import unittest |
5995b304 | 8 | |
c7eee084 PP |
9 | import bt2 |
10 | ||
11 | ||
12 | class QueryExecutorTestCase(unittest.TestCase): | |
88d1a0b7 SM |
13 | def test_default_interrupter(self): |
14 | class MySink(bt2._UserSinkComponent): | |
15 | def _user_consume(self): | |
16 | pass | |
17 | ||
f5567ea8 | 18 | query_exec = bt2.QueryExecutor(MySink, "obj") |
88d1a0b7 SM |
19 | interrupter = query_exec.default_interrupter |
20 | self.assertIs(type(interrupter), bt2.Interrupter) | |
21 | ||
c7eee084 PP |
22 | def test_query(self): |
23 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 24 | def _user_consume(self): |
a01b452b SM |
25 | pass |
26 | ||
c7eee084 | 27 | @classmethod |
7c14d641 | 28 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
c7eee084 PP |
29 | nonlocal query_params |
30 | query_params = params | |
f5567ea8 | 31 | return {"null": None, "bt2": "BT2"} |
c7eee084 PP |
32 | |
33 | query_params = None | |
34 | params = { | |
f5567ea8 FD |
35 | "array": ["coucou", 23, None], |
36 | "other_map": {"yes": "yeah", "19": 19, "minus 1.5": -1.5}, | |
37 | "null": None, | |
c7eee084 PP |
38 | } |
39 | ||
f5567ea8 | 40 | res = bt2.QueryExecutor(MySink, "obj", params).query() |
e42e1587 | 41 | self.assertIs(type(res), bt2._MapValueConst) |
f5567ea8 | 42 | self.assertIs(type(res["bt2"]), bt2._StringValueConst) |
c7eee084 | 43 | self.assertEqual(query_params, params) |
f5567ea8 | 44 | self.assertEqual(res, {"null": None, "bt2": "BT2"}) |
c7eee084 PP |
45 | del query_params |
46 | ||
47 | def test_query_params_none(self): | |
48 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 49 | def _user_consume(self): |
a01b452b SM |
50 | pass |
51 | ||
c7eee084 | 52 | @classmethod |
7c14d641 | 53 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
c7eee084 PP |
54 | nonlocal query_params |
55 | query_params = params | |
56 | ||
57 | query_params = 23 | |
f5567ea8 | 58 | bt2.QueryExecutor(MySink, "obj", None).query() |
3c729b9a PP |
59 | self.assertIs(query_params, None) |
60 | del query_params | |
61 | ||
62 | def test_query_no_params(self): | |
63 | class MySink(bt2._UserSinkComponent): | |
64 | def _user_consume(self): | |
65 | pass | |
66 | ||
67 | @classmethod | |
7c14d641 | 68 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
3c729b9a PP |
69 | nonlocal query_params |
70 | query_params = params | |
71 | ||
72 | query_params = 23 | |
f5567ea8 | 73 | bt2.QueryExecutor(MySink, "obj").query() |
3c729b9a | 74 | self.assertIs(query_params, None) |
c7eee084 PP |
75 | del query_params |
76 | ||
7c14d641 PP |
77 | def test_query_with_method_obj(self): |
78 | class MySink(bt2._UserSinkComponent): | |
79 | def _user_consume(self): | |
80 | pass | |
81 | ||
82 | @classmethod | |
83 | def _user_query(cls, priv_query_exec, obj, params, method_obj): | |
84 | nonlocal query_method_obj | |
85 | query_method_obj = method_obj | |
86 | ||
87 | query_method_obj = None | |
88 | method_obj = object() | |
f5567ea8 | 89 | bt2.QueryExecutor(MySink, "obj", method_obj=method_obj).query() |
7c14d641 PP |
90 | self.assertIs(query_method_obj, method_obj) |
91 | del query_method_obj | |
92 | ||
93 | def test_query_with_method_obj_del_ref(self): | |
94 | class MySink(bt2._UserSinkComponent): | |
95 | def _user_consume(self): | |
96 | pass | |
97 | ||
98 | @classmethod | |
99 | def _user_query(cls, priv_query_exec, obj, params, method_obj): | |
100 | nonlocal query_method_obj | |
101 | query_method_obj = method_obj | |
102 | ||
103 | class Custom: | |
104 | pass | |
105 | ||
106 | query_method_obj = None | |
107 | method_obj = Custom() | |
f5567ea8 FD |
108 | method_obj.hola = "hello" |
109 | query_exec = bt2.QueryExecutor(MySink, "obj", method_obj=method_obj) | |
7c14d641 PP |
110 | del method_obj |
111 | query_exec.query() | |
112 | self.assertIsInstance(query_method_obj, Custom) | |
f5567ea8 | 113 | self.assertEqual(query_method_obj.hola, "hello") |
7c14d641 PP |
114 | del query_method_obj |
115 | ||
116 | def test_query_with_none_method_obj(self): | |
117 | class MySink(bt2._UserSinkComponent): | |
118 | def _user_consume(self): | |
119 | pass | |
120 | ||
121 | @classmethod | |
122 | def _user_query(cls, priv_query_exec, obj, params, method_obj): | |
123 | nonlocal query_method_obj | |
124 | query_method_obj = method_obj | |
125 | ||
126 | query_method_obj = object() | |
f5567ea8 | 127 | bt2.QueryExecutor(MySink, "obj").query() |
7c14d641 PP |
128 | self.assertIsNone(query_method_obj) |
129 | del query_method_obj | |
130 | ||
131 | def test_query_with_method_obj_non_python_comp_cls(self): | |
f5567ea8 | 132 | plugin = bt2.find_plugin("text", find_in_user_dir=False, find_in_sys_dir=False) |
7c14d641 | 133 | assert plugin is not None |
f5567ea8 | 134 | cc = plugin.source_component_classes["dmesg"] |
7c14d641 PP |
135 | assert cc is not None |
136 | ||
137 | with self.assertRaisesRegex( | |
138 | ValueError, | |
f5567ea8 | 139 | re.escape(r"cannot pass a Python object to a non-Python component class"), |
7c14d641 | 140 | ): |
f5567ea8 | 141 | bt2.QueryExecutor(cc, "obj", method_obj=object()).query() |
7c14d641 | 142 | |
761e1890 PP |
143 | def test_query_logging_level(self): |
144 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 145 | def _user_consume(self): |
a01b452b SM |
146 | pass |
147 | ||
761e1890 | 148 | @classmethod |
7c14d641 | 149 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
761e1890 | 150 | nonlocal query_log_level |
3c729b9a | 151 | query_log_level = priv_query_exec.logging_level |
761e1890 PP |
152 | |
153 | query_log_level = None | |
f5567ea8 | 154 | query_exec = bt2.QueryExecutor(MySink, "obj", None) |
3c729b9a PP |
155 | query_exec.logging_level = bt2.LoggingLevel.INFO |
156 | query_exec.query() | |
761e1890 PP |
157 | self.assertEqual(query_log_level, bt2.LoggingLevel.INFO) |
158 | del query_log_level | |
159 | ||
c7eee084 PP |
160 | def test_query_gen_error(self): |
161 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 162 | def _user_consume(self): |
a01b452b SM |
163 | pass |
164 | ||
c7eee084 | 165 | @classmethod |
7c14d641 | 166 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
c7eee084 PP |
167 | raise ValueError |
168 | ||
694c792b | 169 | with self.assertRaises(bt2._Error) as ctx: |
f5567ea8 | 170 | bt2.QueryExecutor(MySink, "obj", [17, 23]).query() |
c7eee084 | 171 | |
ce4923b0 | 172 | exc = ctx.exception |
561e7049 | 173 | self.assertEqual(len(exc), 3) |
ce4923b0 | 174 | cause = exc[0] |
3fb99a22 | 175 | self.assertIsInstance(cause, bt2._ComponentClassErrorCause) |
f5567ea8 | 176 | self.assertIn("raise ValueError", cause.message) |
ce4923b0 | 177 | self.assertEqual(cause.component_class_type, bt2.ComponentClassType.SINK) |
f5567ea8 | 178 | self.assertEqual(cause.component_class_name, "MySink") |
ce4923b0 | 179 | |
76b6c2f7 | 180 | def test_query_unknown_object(self): |
c7eee084 | 181 | class MySink(bt2._UserSinkComponent): |
6a91742b | 182 | def _user_consume(self): |
a01b452b SM |
183 | pass |
184 | ||
c7eee084 | 185 | @classmethod |
7c14d641 | 186 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
76b6c2f7 | 187 | raise bt2.UnknownObject |
c7eee084 | 188 | |
76b6c2f7 | 189 | with self.assertRaises(bt2.UnknownObject): |
f5567ea8 | 190 | bt2.QueryExecutor(MySink, "obj", [17, 23]).query() |
c7eee084 | 191 | |
761e1890 PP |
192 | def test_query_logging_level_invalid_type(self): |
193 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 194 | def _user_consume(self): |
a01b452b SM |
195 | pass |
196 | ||
761e1890 | 197 | @classmethod |
7c14d641 | 198 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
761e1890 PP |
199 | pass |
200 | ||
f5567ea8 | 201 | query_exec = bt2.QueryExecutor(MySink, "obj", [17, 23]) |
3c729b9a | 202 | |
761e1890 | 203 | with self.assertRaises(TypeError): |
f5567ea8 | 204 | query_exec.logging_level = "yeah" |
761e1890 PP |
205 | |
206 | def test_query_logging_level_invalid_value(self): | |
207 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 208 | def _user_consume(self): |
a01b452b SM |
209 | pass |
210 | ||
761e1890 | 211 | @classmethod |
7c14d641 | 212 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
761e1890 PP |
213 | pass |
214 | ||
f5567ea8 | 215 | query_exec = bt2.QueryExecutor(MySink, "obj", [17, 23]) |
3c729b9a | 216 | |
761e1890 | 217 | with self.assertRaises(ValueError): |
3c729b9a | 218 | query_exec.logging_level = 12345 |
761e1890 | 219 | |
c7eee084 PP |
220 | def test_query_try_again(self): |
221 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 222 | def _user_consume(self): |
a01b452b SM |
223 | pass |
224 | ||
c7eee084 | 225 | @classmethod |
7c14d641 | 226 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
c7eee084 PP |
227 | raise bt2.TryAgain |
228 | ||
229 | with self.assertRaises(bt2.TryAgain): | |
f5567ea8 | 230 | bt2.QueryExecutor(MySink, "obj", [17, 23]).query() |
c7eee084 | 231 | |
9b4f9b42 PP |
232 | def test_query_add_interrupter(self): |
233 | class MySink(bt2._UserSinkComponent): | |
6a91742b | 234 | def _user_consume(self): |
9b4f9b42 PP |
235 | pass |
236 | ||
237 | @classmethod | |
7c14d641 | 238 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
9b4f9b42 PP |
239 | nonlocal interrupter2 |
240 | test_self.assertFalse(query_exec.is_interrupted) | |
241 | interrupter2.set() | |
242 | test_self.assertTrue(query_exec.is_interrupted) | |
243 | interrupter2.reset() | |
244 | test_self.assertFalse(query_exec.is_interrupted) | |
245 | ||
246 | interrupter1 = bt2.Interrupter() | |
247 | interrupter2 = bt2.Interrupter() | |
248 | test_self = self | |
f5567ea8 | 249 | query_exec = bt2.QueryExecutor(MySink, "obj", [17, 23]) |
9b4f9b42 PP |
250 | query_exec.add_interrupter(interrupter1) |
251 | query_exec.add_interrupter(interrupter2) | |
3c729b9a | 252 | query_exec.query() |
c7eee084 | 253 | |
9b4f9b42 | 254 | def test_query_interrupt(self): |
c7eee084 | 255 | class MySink(bt2._UserSinkComponent): |
6a91742b | 256 | def _user_consume(self): |
a01b452b SM |
257 | pass |
258 | ||
c7eee084 | 259 | @classmethod |
7c14d641 | 260 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
9b4f9b42 | 261 | test_self.assertFalse(query_exec.is_interrupted) |
88d1a0b7 | 262 | query_exec.default_interrupter.set() |
9b4f9b42 | 263 | test_self.assertTrue(query_exec.is_interrupted) |
c7eee084 | 264 | |
9b4f9b42 | 265 | test_self = self |
f5567ea8 | 266 | query_exec = bt2.QueryExecutor(MySink, "obj", [17, 23]) |
3c729b9a PP |
267 | query_exec.query() |
268 | ||
269 | def test_query_priv_executor_invalid_after(self): | |
270 | class MySink(bt2._UserSinkComponent): | |
271 | def _user_consume(self): | |
272 | pass | |
273 | ||
274 | @classmethod | |
7c14d641 | 275 | def _user_query(cls, priv_query_exec, obj, params, method_obj): |
3c729b9a PP |
276 | nonlocal test_priv_query_exec |
277 | test_priv_query_exec = priv_query_exec | |
278 | ||
279 | test_priv_query_exec = None | |
f5567ea8 | 280 | query_exec = bt2.QueryExecutor(MySink, "obj", [17, 23]) |
3c729b9a PP |
281 | query_exec.query() |
282 | assert test_priv_query_exec is not None | |
283 | ||
284 | with self.assertRaises(RuntimeError): | |
285 | test_priv_query_exec.logging_level | |
286 | ||
287 | del test_priv_query_exec | |
d14ddbba SM |
288 | |
289 | ||
f5567ea8 | 290 | if __name__ == "__main__": |
d14ddbba | 291 | unittest.main() |