blob: 4bc397c3dc753ee39ef1ab16d8d9eb01dc5c0454 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Alex Klein19c4cc42019-02-27 14:47:57 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""SDK tests."""
6
Greg Edelston9dcdc8a2023-01-11 17:07:10 -07007import os
8from typing import List, Optional
Mike Frysinger166fea02021-02-12 05:30:33 -05009from unittest import mock
10
Alex Klein231d2da2019-07-22 16:44:45 -060011from chromite.api import api_config
Greg Edelston9dcdc8a2023-01-11 17:07:10 -070012from chromite.api.controller import controller_util
Alex Klein19c4cc42019-02-27 14:47:57 -070013from chromite.api.controller import sdk as sdk_controller
Alex Klein7107bdd2019-03-14 17:14:31 -060014from chromite.api.gen.chromite.api import sdk_pb2
Greg Edelston9dcdc8a2023-01-11 17:07:10 -070015from chromite.api.gen.chromiumos import common_pb2
16from chromite.lib import constants
Alex Klein19c4cc42019-02-27 14:47:57 -070017from chromite.lib import cros_build_lib
Alex Klein231d2da2019-07-22 16:44:45 -060018from chromite.lib import cros_test_lib
Alex Klein19c4cc42019-02-27 14:47:57 -070019from chromite.service import sdk as sdk_service
20
21
Alex Klein231d2da2019-07-22 16:44:45 -060022class SdkCreateTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -060023 """Create tests."""
Alex Klein19c4cc42019-02-27 14:47:57 -070024
Alex Klein1699fab2022-09-08 08:46:06 -060025 def setUp(self):
26 """Setup method."""
27 # We need to run the command outside the chroot.
28 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
29 self.response = sdk_pb2.CreateResponse()
Alex Klein19c4cc42019-02-27 14:47:57 -070030
Alex Klein1699fab2022-09-08 08:46:06 -060031 def _GetRequest(
32 self,
33 no_replace=False,
Chris McDonald5dcdb892020-02-07 15:10:46 -070034 bootstrap=False,
Alex Klein1699fab2022-09-08 08:46:06 -060035 no_use_image=False,
36 cache_path=None,
37 chroot_path=None,
38 sdk_version=None,
39 skip_chroot_upgrade=False,
40 ):
41 """Helper to build a create request message."""
42 request = sdk_pb2.CreateRequest()
43 request.flags.no_replace = no_replace
44 request.flags.bootstrap = bootstrap
45 request.flags.no_use_image = no_use_image
Alex Klein231d2da2019-07-22 16:44:45 -060046
Alex Klein1699fab2022-09-08 08:46:06 -060047 if cache_path:
48 request.chroot.cache_dir = cache_path
49 if chroot_path:
50 request.chroot.path = chroot_path
51 if sdk_version:
52 request.sdk_version = sdk_version
53 if skip_chroot_upgrade:
54 request.skip_chroot_upgrade = skip_chroot_upgrade
Alex Klein19c4cc42019-02-27 14:47:57 -070055
Alex Klein1699fab2022-09-08 08:46:06 -060056 return request
57
58 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -070059 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -060060 patch = self.PatchObject(sdk_service, "Create")
61
62 sdk_controller.Create(
63 self._GetRequest(), self.response, self.validate_only_config
64 )
65 patch.assert_not_called()
66
67 def testMockCall(self):
68 """Sanity check that a mock call does not execute any logic."""
69 patch = self.PatchObject(sdk_service, "Create")
70
71 rc = sdk_controller.Create(
72 self._GetRequest(), self.response, self.mock_call_config
73 )
74 patch.assert_not_called()
75 self.assertFalse(rc)
76 self.assertTrue(self.response.version.version)
77
78 def testSuccess(self):
79 """Test the successful call output handling."""
80 self.PatchObject(sdk_service, "Create", return_value=1)
81
82 request = self._GetRequest()
83
84 sdk_controller.Create(request, self.response, self.api_config)
85
86 self.assertEqual(1, self.response.version.version)
87
88 def testFalseArguments(self):
89 """Test False argument handling."""
90 # Create the patches.
91 self.PatchObject(sdk_service, "Create", return_value=1)
92 args_patch = self.PatchObject(sdk_service, "CreateArguments")
93
94 # Flag translation tests.
95 # Test all false values in the message.
96 request = self._GetRequest(
97 no_replace=False, bootstrap=False, no_use_image=False
98 )
99 sdk_controller.Create(request, self.response, self.api_config)
100 args_patch.assert_called_with(
101 replace=True,
102 bootstrap=False,
103 use_image=True,
104 chroot_path=mock.ANY,
105 cache_dir=mock.ANY,
106 sdk_version=mock.ANY,
107 skip_chroot_upgrade=mock.ANY,
108 )
109
110 def testTrueArguments(self):
111 """Test True arguments handling."""
112 # Create the patches.
113 self.PatchObject(sdk_service, "Create", return_value=1)
114 args_patch = self.PatchObject(sdk_service, "CreateArguments")
115
116 # Test all True values in the message.
117 request = self._GetRequest(
118 no_replace=True,
119 bootstrap=True,
120 no_use_image=True,
121 sdk_version="foo",
122 skip_chroot_upgrade=True,
123 )
124 sdk_controller.Create(request, self.response, self.api_config)
125 args_patch.assert_called_with(
126 replace=False,
127 bootstrap=True,
128 use_image=False,
129 chroot_path=mock.ANY,
130 cache_dir=mock.ANY,
131 sdk_version="foo",
132 skip_chroot_upgrade=True,
133 )
Mike Frysingercb8992a2020-02-11 05:13:13 +0000134
Alex Kleinaa5c4172019-02-27 17:12:20 -0700135
Michael Mortensene87d8a62020-07-06 11:44:35 -0600136class SdkDeleteTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600137 """Create tests."""
Michael Mortensene87d8a62020-07-06 11:44:35 -0600138
Alex Klein1699fab2022-09-08 08:46:06 -0600139 def setUp(self):
140 """Setup method."""
141 # We need to run the command outside the chroot.
142 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
143 self.response = sdk_pb2.DeleteResponse()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600144
Alex Klein1699fab2022-09-08 08:46:06 -0600145 def _GetRequest(self, chroot_path=None):
146 """Helper to build a delete request message."""
147 request = sdk_pb2.DeleteRequest()
148 if chroot_path:
149 request.chroot.path = chroot_path
Michael Mortensene87d8a62020-07-06 11:44:35 -0600150
Alex Klein1699fab2022-09-08 08:46:06 -0600151 return request
Michael Mortensene87d8a62020-07-06 11:44:35 -0600152
Alex Klein1699fab2022-09-08 08:46:06 -0600153 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700154 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600155 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600156
Alex Klein1699fab2022-09-08 08:46:06 -0600157 sdk_controller.Delete(
158 self._GetRequest(), self.response, self.validate_only_config
159 )
160 patch.assert_not_called()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600161
Alex Klein1699fab2022-09-08 08:46:06 -0600162 def testMockCall(self):
163 """Sanity check that a mock call does not execute any logic."""
164 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600165
Alex Klein1699fab2022-09-08 08:46:06 -0600166 rc = sdk_controller.Delete(
167 self._GetRequest(), self.response, self.mock_call_config
168 )
169 patch.assert_not_called()
170 self.assertFalse(rc)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600171
Alex Klein1699fab2022-09-08 08:46:06 -0600172 def testSuccess(self):
173 """Test the successful call by verifying service invocation."""
174 patch = self.PatchObject(sdk_service, "Delete", return_value=1)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600175
Alex Klein1699fab2022-09-08 08:46:06 -0600176 request = self._GetRequest()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600177
Alex Klein1699fab2022-09-08 08:46:06 -0600178 sdk_controller.Delete(request, self.response, self.api_config)
179 # Verify that by default sdk_service.Delete is called with force=True.
180 patch.assert_called_once_with(mock.ANY, force=True)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600181
182
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600183class SdkUnmountPathTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600184 """Update tests."""
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600185
Alex Klein1699fab2022-09-08 08:46:06 -0600186 def setUp(self):
187 """Setup method."""
188 self.response = sdk_pb2.UnmountPathResponse()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600189
Alex Klein1699fab2022-09-08 08:46:06 -0600190 def _UnmountPathRequest(self, path=None):
191 """Helper to build a delete request message."""
192 request = sdk_pb2.UnmountPathRequest()
193 if path:
194 request.path.path = path
195 return request
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600196
Alex Klein1699fab2022-09-08 08:46:06 -0600197 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700198 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600199 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600200
Alex Klein1699fab2022-09-08 08:46:06 -0600201 sdk_controller.UnmountPath(
202 self._UnmountPathRequest("/test/path"),
203 self.response,
204 self.validate_only_config,
205 )
206 patch.assert_not_called()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600207
Alex Klein1699fab2022-09-08 08:46:06 -0600208 def testMockCall(self):
209 """Sanity check that a mock call does not execute any logic."""
210 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600211
Alex Klein1699fab2022-09-08 08:46:06 -0600212 rc = sdk_controller.UnmountPath(
213 self._UnmountPathRequest(), self.response, self.mock_call_config
214 )
215 patch.assert_not_called()
216 self.assertFalse(rc)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600217
Alex Klein1699fab2022-09-08 08:46:06 -0600218 def testSuccess(self):
219 """Test the successful call by verifying service invocation."""
220 patch = self.PatchObject(sdk_service, "UnmountPath", return_value=1)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600221
Alex Klein1699fab2022-09-08 08:46:06 -0600222 request = self._UnmountPathRequest("/test/path")
223 sdk_controller.UnmountPath(request, self.response, self.api_config)
224 patch.assert_called_once_with("/test/path")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600225
226
Alex Klein231d2da2019-07-22 16:44:45 -0600227class SdkUpdateTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600228 """Update tests."""
Alex Kleinaa5c4172019-02-27 17:12:20 -0700229
Alex Klein1699fab2022-09-08 08:46:06 -0600230 def setUp(self):
231 """Setup method."""
232 # We need to run the command inside the chroot.
233 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700234
Alex Klein1699fab2022-09-08 08:46:06 -0600235 self.response = sdk_pb2.UpdateResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600236
Alex Klein1699fab2022-09-08 08:46:06 -0600237 def _GetRequest(self, build_source=False, targets=None):
238 """Helper to simplify building a request instance."""
239 request = sdk_pb2.UpdateRequest()
240 request.flags.build_source = build_source
Alex Kleinaa5c4172019-02-27 17:12:20 -0700241
Alex Klein1699fab2022-09-08 08:46:06 -0600242 for target in targets or []:
243 added = request.toolchain_targets.add()
244 added.name = target
Alex Kleinaa5c4172019-02-27 17:12:20 -0700245
Alex Klein1699fab2022-09-08 08:46:06 -0600246 return request
Alex Kleinaa5c4172019-02-27 17:12:20 -0700247
Alex Klein1699fab2022-09-08 08:46:06 -0600248 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700249 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600250 patch = self.PatchObject(sdk_service, "Update")
Alex Klein231d2da2019-07-22 16:44:45 -0600251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 sdk_controller.Update(
253 self._GetRequest(), self.response, self.validate_only_config
254 )
255 patch.assert_not_called()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700256
Alex Klein1699fab2022-09-08 08:46:06 -0600257 def testMockCall(self):
258 """Sanity check that a mock call does not execute any logic."""
259 patch = self.PatchObject(sdk_service, "Update")
Alex Klein076841b2019-08-29 15:19:39 -0600260
Alex Klein1699fab2022-09-08 08:46:06 -0600261 rc = sdk_controller.Create(
262 self._GetRequest(), self.response, self.mock_call_config
263 )
264 patch.assert_not_called()
265 self.assertFalse(rc)
266 self.assertTrue(self.response.version.version)
Alex Klein076841b2019-08-29 15:19:39 -0600267
Alex Klein1699fab2022-09-08 08:46:06 -0600268 def testSuccess(self):
269 """Successful call output handling test."""
270 expected_version = 1
271 self.PatchObject(sdk_service, "Update", return_value=expected_version)
272 request = self._GetRequest()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700273
Alex Klein1699fab2022-09-08 08:46:06 -0600274 sdk_controller.Update(request, self.response, self.api_config)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700275
Alex Klein1699fab2022-09-08 08:46:06 -0600276 self.assertEqual(expected_version, self.response.version.version)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700277
Alex Klein1699fab2022-09-08 08:46:06 -0600278 def testArgumentHandling(self):
279 """Test the proto argument handling."""
280 args = sdk_service.UpdateArguments()
281 self.PatchObject(sdk_service, "Update", return_value=1)
282 args_patch = self.PatchObject(
283 sdk_service, "UpdateArguments", return_value=args
284 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700285
Alex Klein1699fab2022-09-08 08:46:06 -0600286 # No boards and flags False.
287 request = self._GetRequest(build_source=False)
288 sdk_controller.Update(request, self.response, self.api_config)
289 args_patch.assert_called_with(
290 build_source=False, toolchain_targets=[], toolchain_changed=False
291 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 # Multiple boards and flags True.
294 targets = ["board1", "board2"]
295 request = self._GetRequest(build_source=True, targets=targets)
296 sdk_controller.Update(request, self.response, self.api_config)
297 args_patch.assert_called_with(
298 build_source=True,
299 toolchain_targets=targets,
300 toolchain_changed=False,
301 )
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700302
303
304class BuildSdkToolchainTest(
305 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
306):
307 """Test the SdkService/BuildSdkToolchain endpoint."""
308
309 def setUp(self):
310 """Set up the test case."""
311 self._chroot_path = "/path/to/chroot"
312 self._response = sdk_pb2.BuildSdkToolchainResponse()
313 self._generated_filenames = (
314 "armv7a-cros-linux-gnueabihf.tar.xz",
315 "x86_64-cros-linux-gnu.tar.xz",
316 )
317 self._paths_for_generated_files = [
318 common_pb2.Path(
319 path=os.path.join(constants.SDK_TOOLCHAINS_OUTPUT, fname),
320 location=common_pb2.Path.Location.INSIDE,
321 )
322 for fname in self._generated_filenames
323 ]
324
325 def _NewRequest(
326 self,
327 chroot_path: Optional[str] = None,
328 use_flags: Optional[List[str]] = None,
329 ) -> sdk_pb2.BuildSdkToolchainRequest:
330 """Return a new BuildSdkToolchainRequest message."""
331 request = sdk_pb2.BuildSdkToolchainRequest()
332 if chroot_path:
333 request.chroot.path = chroot_path
334 if use_flags:
335 request.use_flags.extend(
336 common_pb2.UseFlag(flag=flag) for flag in use_flags
337 )
338 return request
339
340 def _NewResponse(
341 self, generated_filenames: Optional[List[str]] = None
342 ) -> sdk_pb2.BuildSdkToolchainResponse:
343 """Return a new BuildSdkToolchainResponse message."""
344 response = sdk_pb2.BuildSdkToolchainResponse()
345 if generated_filenames:
346 response.generated_files.extend(
347 common_pb2.Path(
348 path=os.path.join(constants.SDK_TOOLCHAINS_OUTPUT, fname),
349 location=common_pb2.Path.Location.INSIDE,
350 )
351 for fname in generated_filenames
352 )
353 return response
354
355 def testValidateOnly(self):
356 """Check that a validate only call does not execute any logic."""
357 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
358 sdk_controller.BuildSdkToolchain(
359 self._NewRequest(), self._NewResponse(), self.validate_only_config
360 )
361 impl_patch.assert_not_called()
362
363 def testSuccess(self):
364 """Check that a normal call defers to the SDK service as expected."""
365 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
366 request = self._NewRequest(use_flags=[])
367 response = self._NewResponse()
368 sdk_controller.BuildSdkToolchain(
369 request,
370 response,
371 self.api_config,
372 )
373 # Can't use assert_called_with, since the chroot objects are equal but
374 # not identical.
375 impl_patch.assert_called_once()
376 self.assertEqual(
377 impl_patch.call_args.args[0],
378 controller_util.ParseChroot(request.chroot),
379 )
380 self.assertEqual(impl_patch.call_args.kwargs["extra_env"], {})
381
382 def testSuccessWithUseFlags(self):
383 """Check that a call with USE flags works as expected."""
384 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
385 request = self._NewRequest(use_flags=["llvm-next", "another-flag"])
386 response = self._NewResponse()
387 sdk_controller.BuildSdkToolchain(
388 request,
389 response,
390 self.api_config,
391 )
392 # Can't use assert_called_with, since the chroot objects are equal but
393 # not identical.
394 impl_patch.assert_called_once()
395 self.assertEqual(
396 impl_patch.call_args.args[0],
397 controller_util.ParseChroot(request.chroot),
398 )
399 self.assertEqual(
400 impl_patch.call_args.kwargs["extra_env"],
401 {"USE": "llvm-next another-flag"},
402 )