blob: 4877941bdb6d00918de7ecfde3e244266f0c1df4 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2018 The ChromiumOS Authors
Alex Kleinf4dc4f52018-12-05 13:55:12 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Alex Klein2bfacb22019-02-04 11:42:17 -07005"""Tests for the build_api script covering the base Build API functionality."""
6
Alex Klein5bcb4d22019-03-21 13:51:54 -06007import os
Tomasz Tylendab4292302021-08-08 18:59:36 +09008from typing import Callable
Alex Klein5bcb4d22019-03-21 13:51:54 -06009
Mike Frysinger2c024062021-05-22 15:43:22 -040010from chromite.third_party.google.protobuf import json_format
Alex Kleinbd6edf82019-07-18 10:30:49 -060011
Alex Klein69339cc2019-07-22 14:08:35 -060012from chromite.api import api_config
Alex Kleine191ed62020-02-27 15:59:55 -070013from chromite.api import message_util
Alex Klein146d4772019-06-20 13:48:25 -060014from chromite.api import router
Alex Klein7107bdd2019-03-14 17:14:31 -060015from chromite.api.gen.chromite.api import build_api_test_pb2
Alex Kleinc7d647f2020-01-06 12:00:48 -070016from chromite.lib import chroot_lib
Alex Klein12fc7ca2023-04-26 18:23:18 -060017from chromite.lib import constants
Alex Klein2bfacb22019-02-04 11:42:17 -070018from chromite.lib import cros_build_lib
Alex Kleinf4dc4f52018-12-05 13:55:12 -070019from chromite.lib import cros_test_lib
Alex Klein5bcb4d22019-03-21 13:51:54 -060020from chromite.lib import osutils
Alex Kleinf4dc4f52018-12-05 13:55:12 -070021
22
Alex Klein1699fab2022-09-08 08:46:06 -060023class RouterTest(
24 cros_test_lib.RunCommandTempDirTestCase, api_config.ApiConfigMixin
25):
26 """Test Router functionality."""
Alex Kleinf4dc4f52018-12-05 13:55:12 -070027
Alex Klein1699fab2022-09-08 08:46:06 -060028 def setUp(self):
29 self.router = router.Router()
30 self.router.Register(build_api_test_pb2)
Alex Kleinf4dc4f52018-12-05 13:55:12 -070031
Alex Klein1699fab2022-09-08 08:46:06 -060032 self.chroot_dir = os.path.join(self.tempdir, "chroot")
33 chroot_tmp = os.path.join(self.chroot_dir, "tmp")
34 # Make the tmp dir for the re-exec inside chroot input/output files.
35 osutils.SafeMakedirs(chroot_tmp)
Alex Klein00aa8072019-04-15 16:36:00 -060036
Alex Klein1699fab2022-09-08 08:46:06 -060037 # Build the input/output/config paths we'll be using in the tests.
38 self.json_input_file = os.path.join(self.tempdir, "input.json")
39 self.json_output_file = os.path.join(self.tempdir, "output.json")
40 self.json_config_file = os.path.join(self.tempdir, "config.json")
41 self.binary_input_file = os.path.join(self.tempdir, "input.bin")
42 self.binary_output_file = os.path.join(self.tempdir, "output.bin")
43 self.binary_config_file = os.path.join(self.tempdir, "config.bin")
Alex Kleine191ed62020-02-27 15:59:55 -070044
Alex Klein1699fab2022-09-08 08:46:06 -060045 # The message handlers for the respective files.
46 self.json_input_handler = message_util.get_message_handler(
47 self.json_input_file, message_util.FORMAT_JSON
48 )
49 self.json_output_handler = message_util.get_message_handler(
50 self.json_output_file, message_util.FORMAT_JSON
51 )
52 self.json_config_handler = message_util.get_message_handler(
53 self.json_config_file, message_util.FORMAT_JSON
54 )
55 self.binary_input_handler = message_util.get_message_handler(
56 self.binary_input_file, message_util.FORMAT_BINARY
57 )
58 self.binary_output_handler = message_util.get_message_handler(
59 self.binary_output_file, message_util.FORMAT_BINARY
60 )
61 self.binary_config_handler = message_util.get_message_handler(
62 self.binary_config_file, message_util.FORMAT_BINARY
63 )
Alex Kleine191ed62020-02-27 15:59:55 -070064
Alex Klein1699fab2022-09-08 08:46:06 -060065 # Build an input message to use.
66 self.expected_id = "input id"
67 input_msg = build_api_test_pb2.TestRequestMessage()
68 input_msg.id = self.expected_id
69 input_msg.chroot.path = self.chroot_dir
Alex Kleine191ed62020-02-27 15:59:55 -070070
Alex Klein1699fab2022-09-08 08:46:06 -060071 # Write out base input and config messages.
72 osutils.WriteFile(
73 self.json_input_file, json_format.MessageToJson(input_msg)
74 )
75 osutils.WriteFile(
76 self.binary_input_file, input_msg.SerializeToString(), mode="wb"
77 )
Alex Kleine191ed62020-02-27 15:59:55 -070078
Alex Klein1699fab2022-09-08 08:46:06 -060079 config_msg = self.api_config.get_proto()
80 osutils.WriteFile(
81 self.json_config_file, json_format.MessageToJson(config_msg)
82 )
83 osutils.WriteFile(
84 self.binary_config_file, config_msg.SerializeToString(), mode="wb"
85 )
Alex Kleinbd6edf82019-07-18 10:30:49 -060086
Alex Klein1699fab2022-09-08 08:46:06 -060087 self.subprocess_tempdir = os.path.join(self.chroot_dir, "tempdir")
88 osutils.SafeMakedirs(self.subprocess_tempdir)
Alex Klein5bcb4d22019-03-21 13:51:54 -060089
Alex Klein1699fab2022-09-08 08:46:06 -060090 def testJsonInputOutputMethod(self):
91 """Test json input/output handling."""
Alex Kleinf4dc4f52018-12-05 13:55:12 -070092
Alex Klein1699fab2022-09-08 08:46:06 -060093 def impl(input_msg, output_msg, config):
94 self.assertIsInstance(
95 input_msg, build_api_test_pb2.TestRequestMessage
96 )
97 self.assertIsInstance(
98 output_msg, build_api_test_pb2.TestResultMessage
99 )
100 self.assertIsInstance(config, api_config.ApiConfig)
101 self.assertEqual(config, self.api_config)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700102
Alex Klein1699fab2022-09-08 08:46:06 -0600103 self.PatchObject(self.router, "_GetMethod", return_value=impl)
Alex Kleine191ed62020-02-27 15:59:55 -0700104
Alex Klein1699fab2022-09-08 08:46:06 -0600105 self.router.Route(
106 "chromite.api.TestApiService",
107 "InputOutputMethod",
108 self.api_config,
109 self.json_input_handler,
110 [self.json_output_handler],
111 self.json_config_handler,
112 )
Alex Kleine191ed62020-02-27 15:59:55 -0700113
Alex Klein1699fab2022-09-08 08:46:06 -0600114 def testBinaryInputOutputMethod(self):
115 """Test binary input/output handling."""
Alex Kleine191ed62020-02-27 15:59:55 -0700116
Alex Klein1699fab2022-09-08 08:46:06 -0600117 def impl(input_msg, output_msg, config):
118 self.assertIsInstance(
119 input_msg, build_api_test_pb2.TestRequestMessage
120 )
121 self.assertIsInstance(
122 output_msg, build_api_test_pb2.TestResultMessage
123 )
124 self.assertIsInstance(config, api_config.ApiConfig)
125 self.assertEqual(config, self.api_config)
Alex Kleine191ed62020-02-27 15:59:55 -0700126
Alex Klein1699fab2022-09-08 08:46:06 -0600127 self.PatchObject(self.router, "_GetMethod", return_value=impl)
Alex Kleine191ed62020-02-27 15:59:55 -0700128
Alex Klein1699fab2022-09-08 08:46:06 -0600129 self.router.Route(
130 "chromite.api.TestApiService",
131 "InputOutputMethod",
132 self.api_config,
133 self.binary_input_handler,
134 [self.binary_output_handler],
135 self.binary_config_handler,
136 )
Alex Kleine191ed62020-02-27 15:59:55 -0700137
Alex Klein1699fab2022-09-08 08:46:06 -0600138 def testMultipleOutputHandling(self):
139 """Test multiple output handling."""
140 expected_result = "Success!"
Alex Kleine191ed62020-02-27 15:59:55 -0700141
Alex Klein1699fab2022-09-08 08:46:06 -0600142 def impl(input_msg, output_msg, config):
143 self.assertIsInstance(
144 input_msg, build_api_test_pb2.TestRequestMessage
145 )
146 self.assertIsInstance(
147 output_msg, build_api_test_pb2.TestResultMessage
148 )
149 self.assertIsInstance(config, api_config.ApiConfig)
150 self.assertEqual(config, self.api_config)
151 # Set the property on the output to test against.
152 output_msg.result = expected_result
Alex Kleine191ed62020-02-27 15:59:55 -0700153
Alex Klein1699fab2022-09-08 08:46:06 -0600154 self.PatchObject(self.router, "_GetMethod", return_value=impl)
Alex Kleine191ed62020-02-27 15:59:55 -0700155
Alex Klein1699fab2022-09-08 08:46:06 -0600156 self.router.Route(
157 "chromite.api.TestApiService",
158 "InputOutputMethod",
159 self.api_config,
160 self.binary_input_handler,
161 [self.binary_output_handler, self.json_output_handler],
162 self.binary_config_handler,
163 )
Alex Kleine191ed62020-02-27 15:59:55 -0700164
Alex Klein1699fab2022-09-08 08:46:06 -0600165 # Make sure it did write out all the expected files.
166 self.assertExists(self.binary_output_file)
167 self.assertExists(self.json_output_file)
Alex Kleinf4dc4f52018-12-05 13:55:12 -0700168
Alex Klein1699fab2022-09-08 08:46:06 -0600169 # Parse the output files back into a message.
170 binary_msg = build_api_test_pb2.TestResultMessage()
171 json_msg = build_api_test_pb2.TestResultMessage()
172 self.binary_output_handler.read_into(binary_msg)
173 self.json_output_handler.read_into(json_msg)
Alex Klein2bfacb22019-02-04 11:42:17 -0700174
Alex Klein1699fab2022-09-08 08:46:06 -0600175 # Make sure the parsed messages have the expected content.
176 self.assertEqual(binary_msg.result, expected_result)
177 self.assertEqual(json_msg.result, expected_result)
Alex Klein2bfacb22019-02-04 11:42:17 -0700178
Alex Klein1699fab2022-09-08 08:46:06 -0600179 def testRenameMethod(self):
180 """Test implementation name config."""
Alex Klein2bfacb22019-02-04 11:42:17 -0700181
Alex Klein1699fab2022-09-08 08:46:06 -0600182 def _GetMethod(_, method_name):
183 self.assertEqual("CorrectName", method_name)
184 return lambda x, y, z: None
Alex Klein00aa8072019-04-15 16:36:00 -0600185
Alex Klein1699fab2022-09-08 08:46:06 -0600186 self.PatchObject(self.router, "_GetMethod", side_effect=_GetMethod)
Alex Klein00aa8072019-04-15 16:36:00 -0600187
Alex Klein1699fab2022-09-08 08:46:06 -0600188 self.router.Route(
189 "chromite.api.TestApiService",
190 "RenamedMethod",
191 self.api_config,
192 self.binary_input_handler,
193 [self.binary_output_handler],
194 self.binary_config_handler,
195 )
Alex Klein2bfacb22019-02-04 11:42:17 -0700196
Alex Klein1699fab2022-09-08 08:46:06 -0600197 def _mock_callable(self, expect_called: bool) -> Callable:
198 """Helper to create the implementation mock to test chroot assertions.
Alex Klein2bfacb22019-02-04 11:42:17 -0700199
Alex Klein1699fab2022-09-08 08:46:06 -0600200 Args:
Alex Kleina0442682022-10-10 13:47:38 -0600201 expect_called: Whether the implementation should be called.
202 When False, an assertion will fail if it is called.
Alex Kleinbd6edf82019-07-18 10:30:49 -0600203
Alex Klein1699fab2022-09-08 08:46:06 -0600204 Returns:
Alex Kleina0442682022-10-10 13:47:38 -0600205 The implementation.
Alex Klein1699fab2022-09-08 08:46:06 -0600206 """
Alex Kleinbd6edf82019-07-18 10:30:49 -0600207
Alex Klein1699fab2022-09-08 08:46:06 -0600208 def impl(_input_msg, _output_msg, _config):
209 self.assertTrue(
210 expect_called, "The implementation should not have been called."
211 )
Alex Klein2bfacb22019-02-04 11:42:17 -0700212
Alex Klein1699fab2022-09-08 08:46:06 -0600213 return impl
Alex Klein00aa8072019-04-15 16:36:00 -0600214
Alex Klein1699fab2022-09-08 08:46:06 -0600215 def _writeChrootCallOutput(self, content="{}", mode="w"):
216 def impl(*_args, **_kwargs):
217 """Side effect for inside-chroot calls to the API."""
218 osutils.WriteFile(
219 os.path.join(
220 self.subprocess_tempdir, router.Router.REEXEC_OUTPUT_FILE
221 ),
222 content,
223 mode=mode,
224 )
Alex Klein00aa8072019-04-15 16:36:00 -0600225
Alex Klein1699fab2022-09-08 08:46:06 -0600226 return impl
Alex Klein00aa8072019-04-15 16:36:00 -0600227
Alex Klein1699fab2022-09-08 08:46:06 -0600228 def testInsideServiceInsideMethodInsideChroot(self):
229 """Test inside/inside/inside works correctly."""
230 self.PatchObject(
231 self.router,
232 "_GetMethod",
233 return_value=self._mock_callable(expect_called=True),
234 )
235 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
236 self.router.Route(
237 "chromite.api.InsideChrootApiService",
238 "InsideServiceInsideMethod",
239 self.api_config,
240 self.binary_input_handler,
241 [self.binary_output_handler],
242 self.binary_config_handler,
243 )
Alex Klein00aa8072019-04-15 16:36:00 -0600244
Alex Klein1699fab2022-09-08 08:46:06 -0600245 def testInsideServiceOutsideMethodOutsideChroot(self):
246 """Test the outside method override works as expected."""
247 self.PatchObject(
248 self.router,
249 "_GetMethod",
250 return_value=self._mock_callable(expect_called=True),
251 )
252 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
253 self.router.Route(
254 "chromite.api.InsideChrootApiService",
255 "InsideServiceOutsideMethod",
256 self.api_config,
257 self.binary_input_handler,
258 [self.binary_output_handler],
259 self.binary_config_handler,
260 )
Alex Klein2bfacb22019-02-04 11:42:17 -0700261
Alex Klein1699fab2022-09-08 08:46:06 -0600262 def testInsideServiceInsideMethodOutsideChroot(self):
263 """Test calling an inside method from outside the chroot."""
264 self.PatchObject(
265 self.router,
266 "_GetMethod",
267 return_value=self._mock_callable(expect_called=False),
268 )
269 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
Alex Klein2bfacb22019-02-04 11:42:17 -0700270
Alex Klein1699fab2022-09-08 08:46:06 -0600271 service = "chromite.api.InsideChrootApiService"
272 method = "InsideServiceInsideMethod"
273 service_method = "%s/%s" % (service, method)
274 self.router.Route(
275 service,
276 method,
277 self.api_config,
278 self.binary_input_handler,
279 [self.binary_output_handler],
280 self.binary_config_handler,
281 )
Alex Klein00aa8072019-04-15 16:36:00 -0600282
Alex Klein1699fab2022-09-08 08:46:06 -0600283 self.assertCommandContains(
284 ["build_api", service_method], enter_chroot=True
285 )
Alex Klein00aa8072019-04-15 16:36:00 -0600286
Alex Klein1699fab2022-09-08 08:46:06 -0600287 def testInsideServiceOutsideMethodInsideChroot(self):
288 """Test inside chroot for outside method raises an error."""
289 self.PatchObject(
290 self.router,
291 "_GetMethod",
292 return_value=self._mock_callable(expect_called=False),
293 )
294 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
295 with self.assertRaises(cros_build_lib.DieSystemExit):
296 self.router.Route(
297 "chromite.api.InsideChrootApiService",
298 "InsideServiceOutsideMethod",
299 self.api_config,
300 self.binary_input_handler,
301 [self.binary_output_handler],
302 self.binary_config_handler,
303 )
Alex Klein00aa8072019-04-15 16:36:00 -0600304
Alex Klein1699fab2022-09-08 08:46:06 -0600305 def testOutsideServiceOutsideMethodOutsideChroot(self):
306 """Test outside/outside/outside works correctly."""
307 self.PatchObject(
308 self.router,
309 "_GetMethod",
310 return_value=self._mock_callable(expect_called=True),
311 )
312 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
313 self.router.Route(
314 "chromite.api.OutsideChrootApiService",
315 "OutsideServiceOutsideMethod",
316 self.api_config,
317 self.binary_input_handler,
318 [self.binary_output_handler],
319 self.binary_config_handler,
320 )
Alex Kleinbd6edf82019-07-18 10:30:49 -0600321
Alex Klein1699fab2022-09-08 08:46:06 -0600322 def testOutsideServiceInsideMethodInsideChroot(self):
323 """Test the inside method assertion override works properly."""
324 self.PatchObject(
325 self.router,
326 "_GetMethod",
327 return_value=self._mock_callable(expect_called=True),
328 )
329 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
330 self.router.Route(
331 "chromite.api.OutsideChrootApiService",
332 "OutsideServiceInsideMethod",
333 self.api_config,
334 self.binary_input_handler,
335 [self.binary_output_handler],
336 self.binary_config_handler,
337 )
Alex Kleinc7d647f2020-01-06 12:00:48 -0700338
Alex Klein1699fab2022-09-08 08:46:06 -0600339 def testOutsideServiceInsideMethodOutsideChroot(self):
340 """Test calling an inside override method from outside the chroot."""
341 self.PatchObject(
342 self.router,
343 "_GetMethod",
344 return_value=self._mock_callable(expect_called=False),
345 )
346 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
Alex Kleinc7d647f2020-01-06 12:00:48 -0700347
Alex Klein1699fab2022-09-08 08:46:06 -0600348 service = "chromite.api.OutsideChrootApiService"
349 method = "OutsideServiceInsideMethod"
350 service_method = "%s/%s" % (service, method)
351 self.router.Route(
352 service,
353 method,
354 self.api_config,
355 self.binary_input_handler,
356 [self.binary_output_handler],
357 self.binary_config_handler,
358 )
Alex Kleine191ed62020-02-27 15:59:55 -0700359
Alex Klein1699fab2022-09-08 08:46:06 -0600360 self.assertCommandContains(
361 ["build_api", service_method], enter_chroot=True
362 )
Alex Kleinbd6edf82019-07-18 10:30:49 -0600363
Alex Klein1699fab2022-09-08 08:46:06 -0600364 def testReexecNonemptyOutput(self):
365 """Test calling an inside chroot method that produced output."""
366 self.PatchObject(
367 self.router,
368 "_GetMethod",
369 return_value=self._mock_callable(expect_called=False),
370 )
371 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
Alex Kleinbd6edf82019-07-18 10:30:49 -0600372
Alex Klein54c891a2023-01-24 10:45:41 -0700373 # Patch the chroot tempdir method to return a tempdir with our
374 # subprocess tempdir so the output file will be in the expected
375 # location.
Alex Klein1699fab2022-09-08 08:46:06 -0600376 tempdir = osutils.TempDir()
377 original = tempdir.tempdir
378 tempdir.tempdir = self.subprocess_tempdir
379 self.PatchObject(chroot_lib.Chroot, "tempdir", return_value=tempdir)
Alex Kleinbd6edf82019-07-18 10:30:49 -0600380
Alex Klein1699fab2022-09-08 08:46:06 -0600381 expected_output_msg = build_api_test_pb2.TestResultMessage()
382 expected_output_msg.result = "foo"
Alex Kleinbd6edf82019-07-18 10:30:49 -0600383
Alex Klein1699fab2022-09-08 08:46:06 -0600384 # Set the command side effect to write out our expected output to the
385 # output file for the inside the chroot reexecution of the endpoint.
Alex Klein54c891a2023-01-24 10:45:41 -0700386 # This lets us make sure the logic moving everything out works as
387 # intended.
Alex Klein1699fab2022-09-08 08:46:06 -0600388 self.rc.SetDefaultCmdResult(
389 side_effect=self._writeChrootCallOutput(
390 content=expected_output_msg.SerializeToString(), mode="wb"
391 )
392 )
Alex Kleinc7d647f2020-01-06 12:00:48 -0700393
Alex Klein1699fab2022-09-08 08:46:06 -0600394 service = "chromite.api.OutsideChrootApiService"
395 method = "OutsideServiceInsideMethod"
396 service_method = "%s/%s" % (service, method)
397 self.router.Route(
398 service,
399 method,
400 self.api_config,
401 self.binary_input_handler,
402 [self.binary_output_handler],
403 self.binary_config_handler,
404 )
Alex Kleine191ed62020-02-27 15:59:55 -0700405
Alex Klein1699fab2022-09-08 08:46:06 -0600406 self.assertCommandContains(
407 ["build_api", service_method], enter_chroot=True
408 )
Alex Kleine191ed62020-02-27 15:59:55 -0700409
Alex Klein1699fab2022-09-08 08:46:06 -0600410 # It should be writing the result out to our output file.
411 output_msg = build_api_test_pb2.TestResultMessage()
412 self.binary_output_handler.read_into(output_msg)
413 self.assertEqual(expected_output_msg, output_msg)
Alex Kleine191ed62020-02-27 15:59:55 -0700414
Alex Klein1699fab2022-09-08 08:46:06 -0600415 tempdir.tempdir = original
416 del tempdir
Alex Kleine191ed62020-02-27 15:59:55 -0700417
Alex Klein1699fab2022-09-08 08:46:06 -0600418 def testReexecEmptyOutput(self):
419 """Test calling an inside chroot method that produced no output."""
420 self.PatchObject(
421 self.router,
422 "_GetMethod",
423 return_value=self._mock_callable(expect_called=False),
424 )
425 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
426 expected_output_msg = build_api_test_pb2.TestResultMessage()
Alex Kleine191ed62020-02-27 15:59:55 -0700427
Alex Klein1699fab2022-09-08 08:46:06 -0600428 # Set the command side effect to write out our expected output to the
429 # output file for the inside the chroot reexecution of the endpoint.
Alex Klein54c891a2023-01-24 10:45:41 -0700430 # This lets us make sure the logic moving everything out works as
431 # intended.
Alex Klein1699fab2022-09-08 08:46:06 -0600432 self.rc.SetDefaultCmdResult(
433 side_effect=self._writeChrootCallOutput(
434 content=expected_output_msg.SerializeToString(), mode="wb"
435 )
436 )
Alex Kleinbd6edf82019-07-18 10:30:49 -0600437
Alex Klein1699fab2022-09-08 08:46:06 -0600438 service = "chromite.api.OutsideChrootApiService"
439 method = "OutsideServiceInsideMethod"
440 service_method = "%s/%s" % (service, method)
441 self.router.Route(
442 service,
443 method,
444 self.api_config,
445 self.binary_input_handler,
446 [self.binary_output_handler],
447 self.binary_config_handler,
448 )
Alex Kleinbd6edf82019-07-18 10:30:49 -0600449
Alex Klein1699fab2022-09-08 08:46:06 -0600450 self.assertCommandContains(
451 ["build_api", service_method], enter_chroot=True
452 )
Alex Kleine191ed62020-02-27 15:59:55 -0700453
Alex Klein1699fab2022-09-08 08:46:06 -0600454 output_msg = build_api_test_pb2.TestResultMessage()
455 self.binary_output_handler.read_into(output_msg)
456 self.assertEqual(expected_output_msg, output_msg)
Alex Klein6431d3a2019-08-29 10:16:08 -0600457
Alex Klein1699fab2022-09-08 08:46:06 -0600458 def testReexecNoOutput(self):
459 """Test calling an inside chroot method that produced no output."""
460 self.PatchObject(
461 self.router,
462 "_GetMethod",
463 return_value=self._mock_callable(expect_called=False),
464 )
465 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
466 self.rc.SetDefaultCmdResult(returncode=1)
Alex Klein6431d3a2019-08-29 10:16:08 -0600467
Alex Klein1699fab2022-09-08 08:46:06 -0600468 service = "chromite.api.OutsideChrootApiService"
469 method = "OutsideServiceInsideMethod"
470 service_method = "%s/%s" % (service, method)
471 self.router.Route(
472 service,
473 method,
474 self.api_config,
475 self.binary_input_handler,
476 [self.binary_output_handler],
477 self.binary_config_handler,
478 )
Alex Klein6431d3a2019-08-29 10:16:08 -0600479
Alex Klein1699fab2022-09-08 08:46:06 -0600480 self.assertCommandContains(
481 ["build_api", service_method], enter_chroot=True
482 )
Alex Klein6431d3a2019-08-29 10:16:08 -0600483
Alex Klein1699fab2022-09-08 08:46:06 -0600484 output_msg = build_api_test_pb2.TestResultMessage()
485 empty_msg = build_api_test_pb2.TestResultMessage()
486 self.binary_output_handler.read_into(output_msg)
487 self.assertEqual(empty_msg, output_msg)
Alex Klein6cce6f62021-03-02 14:24:05 -0700488
Alex Klein12fc7ca2023-04-26 18:23:18 -0600489 def test_tot_service_tot_method(self):
490 """Test no re-exec for ToT->ToT."""
491 self.PatchObject(
492 self.router,
493 "_GetMethod",
494 return_value=self._mock_callable(expect_called=True),
495 )
496 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
497 self.PatchObject(constants, "IS_BRANCHED_CHROMITE", new=False)
498
499 self.router.Route(
500 "chromite.api.TotExecutionService",
501 "TotServiceTotMethod",
502 self.api_config,
503 self.binary_input_handler,
504 [self.binary_output_handler],
505 self.binary_config_handler,
506 )
507
508 def test_tot_service_tot_method_inside(self):
509 """Test error raised when method runs ToT & inside the SDK."""
510 self.PatchObject(
511 self.router,
512 "_GetMethod",
513 return_value=self._mock_callable(expect_called=False),
514 )
515 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
516 self.PatchObject(constants, "IS_BRANCHED_CHROMITE", new=False)
517
518 with self.assertRaises(router.TotSdkError):
519 self.router.Route(
520 "chromite.api.TotExecutionService",
521 "TotServiceTotMethodInside",
522 self.api_config,
523 self.binary_input_handler,
524 [self.binary_output_handler],
525 self.binary_config_handler,
526 )
527
528 def test_tot_service_branched_method(self):
529 """Re-execute branched BAPI."""
530 self.PatchObject(
531 self.router,
532 "_GetMethod",
533 return_value=self._mock_callable(expect_called=False),
534 )
535 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
536 self.PatchObject(constants, "IS_BRANCHED_CHROMITE", new=False)
537 self.PatchObject(constants, "BRANCHED_CHROMITE_DIR", new=self.tempdir)
538
539 service = "chromite.api.TotExecutionService"
540 method = "TotServiceBranchedMethod"
541 self.router.Route(
542 service,
543 method,
544 self.api_config,
545 self.binary_input_handler,
546 [self.binary_output_handler],
547 self.binary_config_handler,
548 )
549
550 self.assertCommandContains(
551 [self.tempdir / "bin" / "build_api", f"{service}/{method}"]
552 )
553
554 def test_tot_service_branched_method_inside(self):
555 """Re-execute branched BAPI.
556
557 Chroot handling delegated to the branched BAPI, so should be identical
558 to the branched method case above.
559 """
560 self.PatchObject(
561 self.router,
562 "_GetMethod",
563 return_value=self._mock_callable(expect_called=False),
564 )
565 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
566 self.PatchObject(constants, "IS_BRANCHED_CHROMITE", new=False)
567 self.PatchObject(constants, "BRANCHED_CHROMITE_DIR", new=self.tempdir)
568
569 service = "chromite.api.TotExecutionService"
570 method = "TotServiceBranchedMethodInside"
571 self.router.Route(
572 service,
573 method,
574 self.api_config,
575 self.binary_input_handler,
576 [self.binary_output_handler],
577 self.binary_config_handler,
578 )
579
580 self.assertCommandContains(
581 [self.tempdir / "bin" / "build_api", f"{service}/{method}"]
582 )
583
Alex Klein1699fab2022-09-08 08:46:06 -0600584 def testInvalidService(self):
585 """Test invalid service call."""
586 service = "chromite.api.DoesNotExist"
587 method = "OutsideServiceInsideMethod"
Alex Klein6cce6f62021-03-02 14:24:05 -0700588
Alex Klein1699fab2022-09-08 08:46:06 -0600589 with self.assertRaises(router.UnknownServiceError):
590 self.router.Route(
591 service,
592 method,
593 self.api_config,
594 self.binary_input_handler,
595 [self.binary_output_handler],
596 self.binary_config_handler,
597 )
598
599 def testInvalidMethod(self):
600 """Test invalid method call."""
601 service = "chromite.api.OutsideChrootApiService"
602 method = "DoesNotExist"
603
604 with self.assertRaises(router.UnknownMethodError):
605 self.router.Route(
606 service,
607 method,
608 self.api_config,
609 self.binary_input_handler,
610 [self.binary_output_handler],
611 self.binary_config_handler,
612 )
613
614 def testListVisibility(self):
615 """Test visibility options."""
616 service = "HiddenService"
617 method = "HiddenMethod"
618
619 for current in self.router.ListMethods():
620 self.assertNotIn(service, current)
621 self.assertNotIn(method, current)