blob: 53b2ddbd9b903200d044bf27c0a2ce822b34099e [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
Greg Edelston01ae5942023-01-30 16:26:54 -07008import pathlib
Greg Edelston9dcdc8a2023-01-11 17:07:10 -07009from typing import List, Optional
Mike Frysinger166fea02021-02-12 05:30:33 -050010from unittest import mock
11
Alex Klein231d2da2019-07-22 16:44:45 -060012from chromite.api import api_config
Greg Edelston9dcdc8a2023-01-11 17:07:10 -070013from chromite.api.controller import controller_util
Alex Klein19c4cc42019-02-27 14:47:57 -070014from chromite.api.controller import sdk as sdk_controller
Alex Klein7107bdd2019-03-14 17:14:31 -060015from chromite.api.gen.chromite.api import sdk_pb2
Greg Edelston9dcdc8a2023-01-11 17:07:10 -070016from chromite.api.gen.chromiumos import common_pb2
17from chromite.lib import constants
Alex Klein19c4cc42019-02-27 14:47:57 -070018from chromite.lib import cros_build_lib
Alex Klein231d2da2019-07-22 16:44:45 -060019from chromite.lib import cros_test_lib
Alex Klein19c4cc42019-02-27 14:47:57 -070020from chromite.service import sdk as sdk_service
21
22
Alex Klein231d2da2019-07-22 16:44:45 -060023class SdkCreateTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -060024 """Create tests."""
Alex Klein19c4cc42019-02-27 14:47:57 -070025
Alex Klein1699fab2022-09-08 08:46:06 -060026 def setUp(self):
27 """Setup method."""
28 # We need to run the command outside the chroot.
29 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
30 self.response = sdk_pb2.CreateResponse()
Alex Klein19c4cc42019-02-27 14:47:57 -070031
Alex Klein1699fab2022-09-08 08:46:06 -060032 def _GetRequest(
33 self,
34 no_replace=False,
Chris McDonald5dcdb892020-02-07 15:10:46 -070035 bootstrap=False,
Alex Klein1699fab2022-09-08 08:46:06 -060036 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
Alex Klein231d2da2019-07-22 16:44:45 -060045
Alex Klein1699fab2022-09-08 08:46:06 -060046 if cache_path:
47 request.chroot.cache_dir = cache_path
48 if chroot_path:
49 request.chroot.path = chroot_path
50 if sdk_version:
51 request.sdk_version = sdk_version
52 if skip_chroot_upgrade:
53 request.skip_chroot_upgrade = skip_chroot_upgrade
Alex Klein19c4cc42019-02-27 14:47:57 -070054
Alex Klein1699fab2022-09-08 08:46:06 -060055 return request
56
57 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -070058 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -060059 patch = self.PatchObject(sdk_service, "Create")
60
61 sdk_controller.Create(
62 self._GetRequest(), self.response, self.validate_only_config
63 )
64 patch.assert_not_called()
65
66 def testMockCall(self):
67 """Sanity check that a mock call does not execute any logic."""
68 patch = self.PatchObject(sdk_service, "Create")
69
70 rc = sdk_controller.Create(
71 self._GetRequest(), self.response, self.mock_call_config
72 )
73 patch.assert_not_called()
74 self.assertFalse(rc)
75 self.assertTrue(self.response.version.version)
76
77 def testSuccess(self):
78 """Test the successful call output handling."""
79 self.PatchObject(sdk_service, "Create", return_value=1)
80
81 request = self._GetRequest()
82
83 sdk_controller.Create(request, self.response, self.api_config)
84
85 self.assertEqual(1, self.response.version.version)
86
87 def testFalseArguments(self):
88 """Test False argument handling."""
89 # Create the patches.
90 self.PatchObject(sdk_service, "Create", return_value=1)
91 args_patch = self.PatchObject(sdk_service, "CreateArguments")
92
93 # Flag translation tests.
94 # Test all false values in the message.
95 request = self._GetRequest(
Brian Norris35a7ed02023-02-23 12:50:14 -080096 no_replace=False,
97 bootstrap=False,
Alex Klein1699fab2022-09-08 08:46:06 -060098 )
99 sdk_controller.Create(request, self.response, self.api_config)
100 args_patch.assert_called_with(
101 replace=True,
102 bootstrap=False,
Brian Norris67374d82023-05-01 12:31:12 -0700103 chroot=mock.ANY,
Alex Klein1699fab2022-09-08 08:46:06 -0600104 sdk_version=mock.ANY,
105 skip_chroot_upgrade=mock.ANY,
106 )
107
108 def testTrueArguments(self):
109 """Test True arguments handling."""
110 # Create the patches.
111 self.PatchObject(sdk_service, "Create", return_value=1)
112 args_patch = self.PatchObject(sdk_service, "CreateArguments")
113
114 # Test all True values in the message.
115 request = self._GetRequest(
116 no_replace=True,
117 bootstrap=True,
Alex Klein1699fab2022-09-08 08:46:06 -0600118 sdk_version="foo",
119 skip_chroot_upgrade=True,
120 )
121 sdk_controller.Create(request, self.response, self.api_config)
122 args_patch.assert_called_with(
123 replace=False,
124 bootstrap=True,
Brian Norris67374d82023-05-01 12:31:12 -0700125 chroot=mock.ANY,
Alex Klein1699fab2022-09-08 08:46:06 -0600126 sdk_version="foo",
127 skip_chroot_upgrade=True,
128 )
Mike Frysingercb8992a2020-02-11 05:13:13 +0000129
Alex Kleinaa5c4172019-02-27 17:12:20 -0700130
George Engelbrecht86cfae62023-04-05 10:57:41 -0600131class SdkCleanTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
132 """Clean tests."""
133
134 def setUp(self):
135 """Setup method."""
136 # We need to run the command outside the chroot.
137 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
138 self.response = sdk_pb2.CleanResponse()
139
140 def _GetRequest(self, chroot_path=None, incrementals=False):
141 """Helper to build a clean request message."""
142 request = sdk_pb2.CleanRequest()
143 if chroot_path:
144 request.chroot.path = chroot_path
145
146 request.incrementals = incrementals
147
148 return request
149
150 def testMockCall(self):
151 """Sanity check that a mock call does not execute any logic."""
152 patch = self.PatchObject(sdk_service, "Clean")
153
154 rc = sdk_controller.Clean(
155 self._GetRequest(), self.response, self.mock_call_config
156 )
157 patch.assert_not_called()
158 self.assertFalse(rc)
159
160 def testSuccess(self):
161 """Test the successful call by verifying service invocation."""
162 patch = self.PatchObject(sdk_service, "Clean", return_value=0)
163
164 request = self._GetRequest(incrementals=True)
165
166 sdk_controller.Clean(request, self.response, self.api_config)
167 patch.assert_called_once_with(
168 mock.ANY,
169 safe=False,
170 images=False,
171 sysroots=False,
172 tmp=False,
173 cache=False,
174 logs=False,
175 workdirs=False,
176 incrementals=True,
177 )
178
179 def testDefaults(self):
180 """Test the successful call by verifying service invocation."""
181 patch = self.PatchObject(sdk_service, "Clean", return_value=0)
182
183 request = self._GetRequest()
184
185 sdk_controller.Clean(request, self.response, self.api_config)
186 patch.assert_called_once_with(mock.ANY, safe=True, sysroots=True)
187
188
Michael Mortensene87d8a62020-07-06 11:44:35 -0600189class SdkDeleteTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
George Engelbrecht86cfae62023-04-05 10:57:41 -0600190 """Delete tests."""
Michael Mortensene87d8a62020-07-06 11:44:35 -0600191
Alex Klein1699fab2022-09-08 08:46:06 -0600192 def setUp(self):
193 """Setup method."""
194 # We need to run the command outside the chroot.
195 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
196 self.response = sdk_pb2.DeleteResponse()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600197
Alex Klein1699fab2022-09-08 08:46:06 -0600198 def _GetRequest(self, chroot_path=None):
199 """Helper to build a delete request message."""
200 request = sdk_pb2.DeleteRequest()
201 if chroot_path:
202 request.chroot.path = chroot_path
Michael Mortensene87d8a62020-07-06 11:44:35 -0600203
Alex Klein1699fab2022-09-08 08:46:06 -0600204 return request
Michael Mortensene87d8a62020-07-06 11:44:35 -0600205
Alex Klein1699fab2022-09-08 08:46:06 -0600206 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700207 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600208 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600209
Alex Klein1699fab2022-09-08 08:46:06 -0600210 sdk_controller.Delete(
211 self._GetRequest(), self.response, self.validate_only_config
212 )
213 patch.assert_not_called()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600214
Alex Klein1699fab2022-09-08 08:46:06 -0600215 def testMockCall(self):
216 """Sanity check that a mock call does not execute any logic."""
217 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600218
Alex Klein1699fab2022-09-08 08:46:06 -0600219 rc = sdk_controller.Delete(
220 self._GetRequest(), self.response, self.mock_call_config
221 )
222 patch.assert_not_called()
223 self.assertFalse(rc)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600224
Alex Klein1699fab2022-09-08 08:46:06 -0600225 def testSuccess(self):
226 """Test the successful call by verifying service invocation."""
227 patch = self.PatchObject(sdk_service, "Delete", return_value=1)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600228
Alex Klein1699fab2022-09-08 08:46:06 -0600229 request = self._GetRequest()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600230
Alex Klein1699fab2022-09-08 08:46:06 -0600231 sdk_controller.Delete(request, self.response, self.api_config)
232 # Verify that by default sdk_service.Delete is called with force=True.
233 patch.assert_called_once_with(mock.ANY, force=True)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600234
235
Brian Norrisf624bf42023-03-02 12:57:49 -0800236class SdkUnmountTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
237 """SDK Unmount tests."""
238
239 def testNoop(self):
240 """Unmount is a deprecated noop."""
241 request = sdk_pb2.UnmountRequest()
242 response = sdk_pb2.UnmountResponse()
243 rc = sdk_controller.Unmount(request, response, self.api_config)
244 self.assertFalse(rc)
245
246
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600247class SdkUnmountPathTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600248 """Update tests."""
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600249
Alex Klein1699fab2022-09-08 08:46:06 -0600250 def setUp(self):
251 """Setup method."""
252 self.response = sdk_pb2.UnmountPathResponse()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600253
Alex Klein1699fab2022-09-08 08:46:06 -0600254 def _UnmountPathRequest(self, path=None):
255 """Helper to build a delete request message."""
256 request = sdk_pb2.UnmountPathRequest()
257 if path:
258 request.path.path = path
259 return request
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600260
Alex Klein1699fab2022-09-08 08:46:06 -0600261 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700262 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600263 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 sdk_controller.UnmountPath(
266 self._UnmountPathRequest("/test/path"),
267 self.response,
268 self.validate_only_config,
269 )
270 patch.assert_not_called()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600271
Alex Klein1699fab2022-09-08 08:46:06 -0600272 def testMockCall(self):
273 """Sanity check that a mock call does not execute any logic."""
274 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600275
Alex Klein1699fab2022-09-08 08:46:06 -0600276 rc = sdk_controller.UnmountPath(
277 self._UnmountPathRequest(), self.response, self.mock_call_config
278 )
279 patch.assert_not_called()
280 self.assertFalse(rc)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600281
Alex Klein1699fab2022-09-08 08:46:06 -0600282 def testSuccess(self):
283 """Test the successful call by verifying service invocation."""
284 patch = self.PatchObject(sdk_service, "UnmountPath", return_value=1)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600285
Alex Klein1699fab2022-09-08 08:46:06 -0600286 request = self._UnmountPathRequest("/test/path")
287 sdk_controller.UnmountPath(request, self.response, self.api_config)
288 patch.assert_called_once_with("/test/path")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600289
290
Alex Klein231d2da2019-07-22 16:44:45 -0600291class SdkUpdateTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600292 """Update tests."""
Alex Kleinaa5c4172019-02-27 17:12:20 -0700293
Alex Klein1699fab2022-09-08 08:46:06 -0600294 def setUp(self):
295 """Setup method."""
296 # We need to run the command inside the chroot.
297 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700298
Alex Klein1699fab2022-09-08 08:46:06 -0600299 self.response = sdk_pb2.UpdateResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600300
Alex Klein1699fab2022-09-08 08:46:06 -0600301 def _GetRequest(self, build_source=False, targets=None):
302 """Helper to simplify building a request instance."""
303 request = sdk_pb2.UpdateRequest()
304 request.flags.build_source = build_source
Alex Kleinaa5c4172019-02-27 17:12:20 -0700305
Alex Klein1699fab2022-09-08 08:46:06 -0600306 for target in targets or []:
307 added = request.toolchain_targets.add()
308 added.name = target
Alex Kleinaa5c4172019-02-27 17:12:20 -0700309
Alex Klein1699fab2022-09-08 08:46:06 -0600310 return request
Alex Kleinaa5c4172019-02-27 17:12:20 -0700311
Alex Klein1699fab2022-09-08 08:46:06 -0600312 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700313 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600314 patch = self.PatchObject(sdk_service, "Update")
Alex Klein231d2da2019-07-22 16:44:45 -0600315
Alex Klein1699fab2022-09-08 08:46:06 -0600316 sdk_controller.Update(
317 self._GetRequest(), self.response, self.validate_only_config
318 )
319 patch.assert_not_called()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700320
Alex Klein1699fab2022-09-08 08:46:06 -0600321 def testMockCall(self):
322 """Sanity check that a mock call does not execute any logic."""
323 patch = self.PatchObject(sdk_service, "Update")
Alex Klein076841b2019-08-29 15:19:39 -0600324
Alex Klein1699fab2022-09-08 08:46:06 -0600325 rc = sdk_controller.Create(
326 self._GetRequest(), self.response, self.mock_call_config
327 )
328 patch.assert_not_called()
329 self.assertFalse(rc)
330 self.assertTrue(self.response.version.version)
Alex Klein076841b2019-08-29 15:19:39 -0600331
Alex Klein1699fab2022-09-08 08:46:06 -0600332 def testSuccess(self):
333 """Successful call output handling test."""
334 expected_version = 1
335 self.PatchObject(sdk_service, "Update", return_value=expected_version)
336 request = self._GetRequest()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700337
Alex Klein1699fab2022-09-08 08:46:06 -0600338 sdk_controller.Update(request, self.response, self.api_config)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700339
Alex Klein1699fab2022-09-08 08:46:06 -0600340 self.assertEqual(expected_version, self.response.version.version)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700341
Alex Klein1699fab2022-09-08 08:46:06 -0600342 def testArgumentHandling(self):
343 """Test the proto argument handling."""
344 args = sdk_service.UpdateArguments()
345 self.PatchObject(sdk_service, "Update", return_value=1)
346 args_patch = self.PatchObject(
347 sdk_service, "UpdateArguments", return_value=args
348 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700349
Alex Klein1699fab2022-09-08 08:46:06 -0600350 # No boards and flags False.
351 request = self._GetRequest(build_source=False)
352 sdk_controller.Update(request, self.response, self.api_config)
353 args_patch.assert_called_with(
354 build_source=False, toolchain_targets=[], toolchain_changed=False
355 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700356
Alex Klein1699fab2022-09-08 08:46:06 -0600357 # Multiple boards and flags True.
358 targets = ["board1", "board2"]
359 request = self._GetRequest(build_source=True, targets=targets)
360 sdk_controller.Update(request, self.response, self.api_config)
361 args_patch.assert_called_with(
362 build_source=True,
363 toolchain_targets=targets,
364 toolchain_changed=False,
365 )
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700366
367
Greg Edelston01ae5942023-01-30 16:26:54 -0700368class CreateManifestFromSdkTest(
369 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
370):
371 """Test the SdkService/CreateManifestFromSdk endpoint."""
372
373 _chroot_path = "/path/to/chroot"
374 _sdk_path_relative = "build/my_sdk"
375 _dest_dir = "/build"
376 _manifest_path = "/build/my_sdk.Manifest"
377
378 def _NewRequest(self, inside: bool) -> sdk_pb2.CreateManifestFromSdkRequest:
379 return sdk_pb2.CreateManifestFromSdkRequest(
380 chroot=common_pb2.Chroot(path=self._chroot_path),
381 sdk_path=common_pb2.Path(
382 path="/%s" % self._sdk_path_relative,
383 location=common_pb2.Path.Location.INSIDE
384 if inside
385 else common_pb2.Path.Location.OUTSIDE,
386 ),
387 dest_dir=common_pb2.Path(
388 path=self._dest_dir,
389 location=common_pb2.Path.Location.OUTSIDE,
390 ),
391 )
392
393 def _NewResponse(self) -> sdk_pb2.CreateManifestFromSdkResponse:
394 return sdk_pb2.CreateManifestFromSdkResponse()
395
396 def testValidateOnly(self):
397 """Check that a validate only call does not execute any logic."""
398 impl_patch = self.PatchObject(sdk_service, "CreateManifestFromSdk")
399 sdk_controller.BuildSdkToolchain(
400 self._NewRequest(False),
401 self._NewResponse(),
402 self.validate_only_config,
403 )
404 impl_patch.assert_not_called()
405
406 def testOutside(self):
407 """Check that a call with an outside path succeeds."""
408 impl_patch = self.PatchObject(
409 sdk_service,
410 "CreateManifestFromSdk",
411 return_value=pathlib.Path(self._manifest_path),
412 )
413 request = self._NewRequest(inside=False)
414 response = self._NewResponse()
415 sdk_controller.CreateManifestFromSdk(
416 request,
417 response,
418 self.api_config,
419 )
420 impl_patch.assert_called_with(
421 pathlib.Path("/", self._sdk_path_relative),
422 pathlib.Path(self._dest_dir),
423 )
424 self.assertEqual(
425 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
426 )
427 self.assertEqual(response.manifest_path.path, self._manifest_path)
428
429 def testInside(self):
430 """Check that an inside path parses correctly and the call succeeds."""
431 impl_patch = self.PatchObject(
432 sdk_service,
433 "CreateManifestFromSdk",
434 return_value=pathlib.Path(self._manifest_path),
435 )
436 request = self._NewRequest(inside=True)
437 response = self._NewResponse()
438 sdk_controller.CreateManifestFromSdk(
439 request,
440 response,
441 self.api_config,
442 )
443 impl_patch.assert_called_with(
444 pathlib.Path(self._chroot_path, self._sdk_path_relative),
445 pathlib.Path(self._dest_dir),
446 )
447 self.assertEqual(
448 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
449 )
450 self.assertEqual(response.manifest_path.path, self._manifest_path)
451
452
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700453class BuildSdkToolchainTest(
454 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
455):
456 """Test the SdkService/BuildSdkToolchain endpoint."""
457
458 def setUp(self):
459 """Set up the test case."""
460 self._chroot_path = "/path/to/chroot"
461 self._response = sdk_pb2.BuildSdkToolchainResponse()
462 self._generated_filenames = (
463 "armv7a-cros-linux-gnueabihf.tar.xz",
464 "x86_64-cros-linux-gnu.tar.xz",
465 )
466 self._paths_for_generated_files = [
467 common_pb2.Path(
468 path=os.path.join(constants.SDK_TOOLCHAINS_OUTPUT, fname),
469 location=common_pb2.Path.Location.INSIDE,
470 )
471 for fname in self._generated_filenames
472 ]
473
474 def _NewRequest(
475 self,
476 chroot_path: Optional[str] = None,
477 use_flags: Optional[List[str]] = None,
478 ) -> sdk_pb2.BuildSdkToolchainRequest:
479 """Return a new BuildSdkToolchainRequest message."""
480 request = sdk_pb2.BuildSdkToolchainRequest()
481 if chroot_path:
482 request.chroot.path = chroot_path
483 if use_flags:
484 request.use_flags.extend(
485 common_pb2.UseFlag(flag=flag) for flag in use_flags
486 )
487 return request
488
489 def _NewResponse(
490 self, generated_filenames: Optional[List[str]] = None
491 ) -> sdk_pb2.BuildSdkToolchainResponse:
492 """Return a new BuildSdkToolchainResponse message."""
493 response = sdk_pb2.BuildSdkToolchainResponse()
494 if generated_filenames:
495 response.generated_files.extend(
496 common_pb2.Path(
497 path=os.path.join(constants.SDK_TOOLCHAINS_OUTPUT, fname),
498 location=common_pb2.Path.Location.INSIDE,
499 )
500 for fname in generated_filenames
501 )
502 return response
503
504 def testValidateOnly(self):
505 """Check that a validate only call does not execute any logic."""
506 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
507 sdk_controller.BuildSdkToolchain(
508 self._NewRequest(), self._NewResponse(), self.validate_only_config
509 )
510 impl_patch.assert_not_called()
511
512 def testSuccess(self):
513 """Check that a normal call defers to the SDK service as expected."""
514 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
515 request = self._NewRequest(use_flags=[])
516 response = self._NewResponse()
517 sdk_controller.BuildSdkToolchain(
518 request,
519 response,
520 self.api_config,
521 )
522 # Can't use assert_called_with, since the chroot objects are equal but
523 # not identical.
524 impl_patch.assert_called_once()
525 self.assertEqual(
526 impl_patch.call_args.args[0],
527 controller_util.ParseChroot(request.chroot),
528 )
529 self.assertEqual(impl_patch.call_args.kwargs["extra_env"], {})
530
531 def testSuccessWithUseFlags(self):
532 """Check that a call with USE flags works as expected."""
533 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
534 request = self._NewRequest(use_flags=["llvm-next", "another-flag"])
535 response = self._NewResponse()
536 sdk_controller.BuildSdkToolchain(
537 request,
538 response,
539 self.api_config,
540 )
541 # Can't use assert_called_with, since the chroot objects are equal but
542 # not identical.
543 impl_patch.assert_called_once()
544 self.assertEqual(
545 impl_patch.call_args.args[0],
546 controller_util.ParseChroot(request.chroot),
547 )
548 self.assertEqual(
549 impl_patch.call_args.kwargs["extra_env"],
550 {"USE": "llvm-next another-flag"},
551 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700552
553
Greg Edelstond401e5a2023-04-28 15:29:11 -0600554class uprev_test(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Greg Edelston6733dc52023-02-15 15:20:07 -0700555 """Test case for SdkService/Uprev() endpoint."""
556
Greg Edelston6733dc52023-02-15 15:20:07 -0700557 _binhost_gs_bucket = "gs://chromiumos-prebuilts/"
Greg Edelston40aea812023-03-27 16:34:35 -0600558 _latest_uprev_target_version = "2023.02.19.112358"
Greg Edelston6733dc52023-02-15 15:20:07 -0700559
560 def setUp(self):
561 """Set up the test case."""
Greg Edelston6733dc52023-02-15 15:20:07 -0700562 self.PatchObject(
563 sdk_service,
Greg Edelstond401e5a2023-04-28 15:29:11 -0600564 "get_latest_uprev_target_version",
Greg Edelston40aea812023-03-27 16:34:35 -0600565 return_value=self._latest_uprev_target_version,
Greg Edelston6733dc52023-02-15 15:20:07 -0700566 )
567 self._uprev_patch = self.PatchObject(
568 sdk_service,
Greg Edelstond401e5a2023-04-28 15:29:11 -0600569 "uprev_sdk_and_prebuilts",
Greg Edelston6733dc52023-02-15 15:20:07 -0700570 )
571
Greg Edelston0382ca42023-05-04 14:00:15 -0600572 def NewRequest(
573 self, version: str = "", toolchain_tarball_template: str = ""
574 ):
Greg Edelston6733dc52023-02-15 15:20:07 -0700575 """Return a new UprevRequest with standard inputs."""
576 return sdk_pb2.UprevRequest(
Greg Edelston6733dc52023-02-15 15:20:07 -0700577 binhost_gs_bucket=self._binhost_gs_bucket,
578 version=version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600579 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700580 )
581
582 @staticmethod
583 def NewResponse() -> sdk_pb2.UprevResponse:
584 """Return a new empty UprevResponse."""
585 return sdk_pb2.UprevResponse()
586
587 def testWithVersion(self):
588 """Test the endpoint with `version` specified.
589
590 In this case, we expect that sdk_controller.Uprev is called with the
591 version specified in the UprevRequest.
592 """
593 specified_version = "1970.01.01.000000"
Greg Edelston0382ca42023-05-04 14:00:15 -0600594 toolchain_tarball_template = "path/to/%(version)s/toolchain"
595 request = self.NewRequest(
596 version=specified_version,
597 toolchain_tarball_template=toolchain_tarball_template,
598 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700599 response = self.NewResponse()
600 sdk_controller.Uprev(request, response, self.api_config)
601 self._uprev_patch.assert_called_with(
Greg Edelston6733dc52023-02-15 15:20:07 -0700602 binhost_gs_bucket=self._binhost_gs_bucket,
603 version=specified_version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600604 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700605 )
606
607 def testWithoutVersion(self):
608 """Test the endpoint with `version` not specified.
609
610 In this case, we expect that sdk_controller.Uprev is called with the
Greg Edelston40aea812023-03-27 16:34:35 -0600611 latest uprev target version, based on the remote file in gs://. This is
612 fetched via sdk_controller.GetLatestUprevTargetVersionVersion
613 (mocked here in setUp()).
Greg Edelston6733dc52023-02-15 15:20:07 -0700614 """
Greg Edelston0382ca42023-05-04 14:00:15 -0600615 toolchain_tarball_template = "path/to/%(version)s/toolchain"
616 request = self.NewRequest(
617 toolchain_tarball_template=toolchain_tarball_template
618 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700619 response = self.NewResponse()
620 sdk_controller.Uprev(request, response, self.api_config)
621 self._uprev_patch.assert_called_with(
Greg Edelston6733dc52023-02-15 15:20:07 -0700622 binhost_gs_bucket=self._binhost_gs_bucket,
Greg Edelston40aea812023-03-27 16:34:35 -0600623 version=self._latest_uprev_target_version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600624 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700625 )
Greg Edelston0382ca42023-05-04 14:00:15 -0600626
627 def testWithoutToolchainTarballTemplate(self):
628 """Test the endpoint with `toolchain_tarball_template` not specified."""
629 request = self.NewRequest(version="1234")
630 response = self.NewResponse()
631 with self.assertRaises(cros_build_lib.DieSystemExit):
632 sdk_controller.Uprev(request, response, self.api_config)