blob: 014e28148c47192ce3f111db90e61e17cd64ef85 [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
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 cache_path=None,
36 chroot_path=None,
37 sdk_version=None,
38 skip_chroot_upgrade=False,
39 ):
40 """Helper to build a create request message."""
41 request = sdk_pb2.CreateRequest()
42 request.flags.no_replace = no_replace
43 request.flags.bootstrap = bootstrap
Alex Klein231d2da2019-07-22 16:44:45 -060044
Alex Klein1699fab2022-09-08 08:46:06 -060045 if cache_path:
46 request.chroot.cache_dir = cache_path
47 if chroot_path:
48 request.chroot.path = chroot_path
49 if sdk_version:
50 request.sdk_version = sdk_version
51 if skip_chroot_upgrade:
52 request.skip_chroot_upgrade = skip_chroot_upgrade
Alex Klein19c4cc42019-02-27 14:47:57 -070053
Alex Klein1699fab2022-09-08 08:46:06 -060054 return request
55
56 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -070057 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -060058 patch = self.PatchObject(sdk_service, "Create")
59
60 sdk_controller.Create(
61 self._GetRequest(), self.response, self.validate_only_config
62 )
63 patch.assert_not_called()
64
65 def testMockCall(self):
66 """Sanity check that a mock call does not execute any logic."""
67 patch = self.PatchObject(sdk_service, "Create")
68
69 rc = sdk_controller.Create(
70 self._GetRequest(), self.response, self.mock_call_config
71 )
72 patch.assert_not_called()
73 self.assertFalse(rc)
74 self.assertTrue(self.response.version.version)
75
76 def testSuccess(self):
77 """Test the successful call output handling."""
78 self.PatchObject(sdk_service, "Create", return_value=1)
79
80 request = self._GetRequest()
81
82 sdk_controller.Create(request, self.response, self.api_config)
83
84 self.assertEqual(1, self.response.version.version)
85
86 def testFalseArguments(self):
87 """Test False argument handling."""
88 # Create the patches.
89 self.PatchObject(sdk_service, "Create", return_value=1)
90 args_patch = self.PatchObject(sdk_service, "CreateArguments")
91
92 # Flag translation tests.
93 # Test all false values in the message.
94 request = self._GetRequest(
Brian Norris35a7ed02023-02-23 12:50:14 -080095 no_replace=False,
96 bootstrap=False,
Alex Klein1699fab2022-09-08 08:46:06 -060097 )
98 sdk_controller.Create(request, self.response, self.api_config)
99 args_patch.assert_called_with(
100 replace=True,
101 bootstrap=False,
Brian Norris67374d82023-05-01 12:31:12 -0700102 chroot=mock.ANY,
Alex Klein1699fab2022-09-08 08:46:06 -0600103 sdk_version=mock.ANY,
104 skip_chroot_upgrade=mock.ANY,
105 )
106
107 def testTrueArguments(self):
108 """Test True arguments handling."""
109 # Create the patches.
110 self.PatchObject(sdk_service, "Create", return_value=1)
111 args_patch = self.PatchObject(sdk_service, "CreateArguments")
112
113 # Test all True values in the message.
114 request = self._GetRequest(
115 no_replace=True,
116 bootstrap=True,
Alex Klein1699fab2022-09-08 08:46:06 -0600117 sdk_version="foo",
118 skip_chroot_upgrade=True,
119 )
120 sdk_controller.Create(request, self.response, self.api_config)
121 args_patch.assert_called_with(
122 replace=False,
123 bootstrap=True,
Brian Norris67374d82023-05-01 12:31:12 -0700124 chroot=mock.ANY,
Alex Klein1699fab2022-09-08 08:46:06 -0600125 sdk_version="foo",
126 skip_chroot_upgrade=True,
127 )
Mike Frysingercb8992a2020-02-11 05:13:13 +0000128
Alex Kleinaa5c4172019-02-27 17:12:20 -0700129
George Engelbrecht86cfae62023-04-05 10:57:41 -0600130class SdkCleanTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
131 """Clean tests."""
132
133 def setUp(self):
134 """Setup method."""
135 # We need to run the command outside the chroot.
136 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
137 self.response = sdk_pb2.CleanResponse()
138
139 def _GetRequest(self, chroot_path=None, incrementals=False):
140 """Helper to build a clean request message."""
141 request = sdk_pb2.CleanRequest()
142 if chroot_path:
143 request.chroot.path = chroot_path
144
145 request.incrementals = incrementals
146
147 return request
148
149 def testMockCall(self):
150 """Sanity check that a mock call does not execute any logic."""
151 patch = self.PatchObject(sdk_service, "Clean")
152
153 rc = sdk_controller.Clean(
154 self._GetRequest(), self.response, self.mock_call_config
155 )
156 patch.assert_not_called()
157 self.assertFalse(rc)
158
159 def testSuccess(self):
160 """Test the successful call by verifying service invocation."""
161 patch = self.PatchObject(sdk_service, "Clean", return_value=0)
162
163 request = self._GetRequest(incrementals=True)
164
165 sdk_controller.Clean(request, self.response, self.api_config)
166 patch.assert_called_once_with(
167 mock.ANY,
168 safe=False,
169 images=False,
170 sysroots=False,
171 tmp=False,
172 cache=False,
173 logs=False,
174 workdirs=False,
175 incrementals=True,
176 )
177
178 def testDefaults(self):
179 """Test the successful call by verifying service invocation."""
180 patch = self.PatchObject(sdk_service, "Clean", return_value=0)
181
182 request = self._GetRequest()
183
184 sdk_controller.Clean(request, self.response, self.api_config)
185 patch.assert_called_once_with(mock.ANY, safe=True, sysroots=True)
186
187
Michael Mortensene87d8a62020-07-06 11:44:35 -0600188class SdkDeleteTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
George Engelbrecht86cfae62023-04-05 10:57:41 -0600189 """Delete tests."""
Michael Mortensene87d8a62020-07-06 11:44:35 -0600190
Alex Klein1699fab2022-09-08 08:46:06 -0600191 def setUp(self):
192 """Setup method."""
193 # We need to run the command outside the chroot.
194 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
195 self.response = sdk_pb2.DeleteResponse()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600196
Alex Klein1699fab2022-09-08 08:46:06 -0600197 def _GetRequest(self, chroot_path=None):
198 """Helper to build a delete request message."""
199 request = sdk_pb2.DeleteRequest()
200 if chroot_path:
201 request.chroot.path = chroot_path
Michael Mortensene87d8a62020-07-06 11:44:35 -0600202
Alex Klein1699fab2022-09-08 08:46:06 -0600203 return request
Michael Mortensene87d8a62020-07-06 11:44:35 -0600204
Alex Klein1699fab2022-09-08 08:46:06 -0600205 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700206 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600207 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600208
Alex Klein1699fab2022-09-08 08:46:06 -0600209 sdk_controller.Delete(
210 self._GetRequest(), self.response, self.validate_only_config
211 )
212 patch.assert_not_called()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 def testMockCall(self):
215 """Sanity check that a mock call does not execute any logic."""
216 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600217
Alex Klein1699fab2022-09-08 08:46:06 -0600218 rc = sdk_controller.Delete(
219 self._GetRequest(), self.response, self.mock_call_config
220 )
221 patch.assert_not_called()
222 self.assertFalse(rc)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600223
Alex Klein1699fab2022-09-08 08:46:06 -0600224 def testSuccess(self):
225 """Test the successful call by verifying service invocation."""
226 patch = self.PatchObject(sdk_service, "Delete", return_value=1)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600227
Alex Klein1699fab2022-09-08 08:46:06 -0600228 request = self._GetRequest()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600229
Alex Klein1699fab2022-09-08 08:46:06 -0600230 sdk_controller.Delete(request, self.response, self.api_config)
231 # Verify that by default sdk_service.Delete is called with force=True.
232 patch.assert_called_once_with(mock.ANY, force=True)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600233
234
Brian Norrisf624bf42023-03-02 12:57:49 -0800235class SdkUnmountTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
236 """SDK Unmount tests."""
237
238 def testNoop(self):
239 """Unmount is a deprecated noop."""
240 request = sdk_pb2.UnmountRequest()
241 response = sdk_pb2.UnmountResponse()
242 rc = sdk_controller.Unmount(request, response, self.api_config)
243 self.assertFalse(rc)
244
245
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600246class SdkUnmountPathTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600247 """Update tests."""
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600248
Alex Klein1699fab2022-09-08 08:46:06 -0600249 def setUp(self):
250 """Setup method."""
251 self.response = sdk_pb2.UnmountPathResponse()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600252
Alex Klein1699fab2022-09-08 08:46:06 -0600253 def _UnmountPathRequest(self, path=None):
254 """Helper to build a delete request message."""
255 request = sdk_pb2.UnmountPathRequest()
256 if path:
257 request.path.path = path
258 return request
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600259
Alex Klein1699fab2022-09-08 08:46:06 -0600260 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700261 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600262 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600263
Alex Klein1699fab2022-09-08 08:46:06 -0600264 sdk_controller.UnmountPath(
265 self._UnmountPathRequest("/test/path"),
266 self.response,
267 self.validate_only_config,
268 )
269 patch.assert_not_called()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600270
Alex Klein1699fab2022-09-08 08:46:06 -0600271 def testMockCall(self):
272 """Sanity check that a mock call does not execute any logic."""
273 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600274
Alex Klein1699fab2022-09-08 08:46:06 -0600275 rc = sdk_controller.UnmountPath(
276 self._UnmountPathRequest(), self.response, self.mock_call_config
277 )
278 patch.assert_not_called()
279 self.assertFalse(rc)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600280
Alex Klein1699fab2022-09-08 08:46:06 -0600281 def testSuccess(self):
282 """Test the successful call by verifying service invocation."""
283 patch = self.PatchObject(sdk_service, "UnmountPath", return_value=1)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600284
Alex Klein1699fab2022-09-08 08:46:06 -0600285 request = self._UnmountPathRequest("/test/path")
286 sdk_controller.UnmountPath(request, self.response, self.api_config)
287 patch.assert_called_once_with("/test/path")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600288
289
Alex Klein231d2da2019-07-22 16:44:45 -0600290class SdkUpdateTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600291 """Update tests."""
Alex Kleinaa5c4172019-02-27 17:12:20 -0700292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 def setUp(self):
294 """Setup method."""
295 # We need to run the command inside the chroot.
296 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700297
Alex Klein1699fab2022-09-08 08:46:06 -0600298 self.response = sdk_pb2.UpdateResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600299
Alex Klein1699fab2022-09-08 08:46:06 -0600300 def _GetRequest(self, build_source=False, targets=None):
301 """Helper to simplify building a request instance."""
302 request = sdk_pb2.UpdateRequest()
303 request.flags.build_source = build_source
Alex Kleinaa5c4172019-02-27 17:12:20 -0700304
Alex Klein1699fab2022-09-08 08:46:06 -0600305 for target in targets or []:
306 added = request.toolchain_targets.add()
307 added.name = target
Alex Kleinaa5c4172019-02-27 17:12:20 -0700308
Alex Klein1699fab2022-09-08 08:46:06 -0600309 return request
Alex Kleinaa5c4172019-02-27 17:12:20 -0700310
Alex Klein1699fab2022-09-08 08:46:06 -0600311 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700312 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600313 patch = self.PatchObject(sdk_service, "Update")
Alex Klein231d2da2019-07-22 16:44:45 -0600314
Alex Klein1699fab2022-09-08 08:46:06 -0600315 sdk_controller.Update(
316 self._GetRequest(), self.response, self.validate_only_config
317 )
318 patch.assert_not_called()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700319
Alex Klein1699fab2022-09-08 08:46:06 -0600320 def testMockCall(self):
321 """Sanity check that a mock call does not execute any logic."""
322 patch = self.PatchObject(sdk_service, "Update")
Alex Klein076841b2019-08-29 15:19:39 -0600323
Alex Klein1699fab2022-09-08 08:46:06 -0600324 rc = sdk_controller.Create(
325 self._GetRequest(), self.response, self.mock_call_config
326 )
327 patch.assert_not_called()
328 self.assertFalse(rc)
329 self.assertTrue(self.response.version.version)
Alex Klein076841b2019-08-29 15:19:39 -0600330
Alex Klein1699fab2022-09-08 08:46:06 -0600331 def testSuccess(self):
332 """Successful call output handling test."""
333 expected_version = 1
334 self.PatchObject(sdk_service, "Update", return_value=expected_version)
335 request = self._GetRequest()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700336
Alex Klein1699fab2022-09-08 08:46:06 -0600337 sdk_controller.Update(request, self.response, self.api_config)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700338
Alex Klein1699fab2022-09-08 08:46:06 -0600339 self.assertEqual(expected_version, self.response.version.version)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700340
Alex Klein1699fab2022-09-08 08:46:06 -0600341 def testArgumentHandling(self):
342 """Test the proto argument handling."""
343 args = sdk_service.UpdateArguments()
344 self.PatchObject(sdk_service, "Update", return_value=1)
345 args_patch = self.PatchObject(
346 sdk_service, "UpdateArguments", return_value=args
347 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700348
Alex Klein1699fab2022-09-08 08:46:06 -0600349 # No boards and flags False.
350 request = self._GetRequest(build_source=False)
351 sdk_controller.Update(request, self.response, self.api_config)
352 args_patch.assert_called_with(
353 build_source=False, toolchain_targets=[], toolchain_changed=False
354 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700355
Alex Klein1699fab2022-09-08 08:46:06 -0600356 # Multiple boards and flags True.
357 targets = ["board1", "board2"]
358 request = self._GetRequest(build_source=True, targets=targets)
359 sdk_controller.Update(request, self.response, self.api_config)
360 args_patch.assert_called_with(
361 build_source=True,
362 toolchain_targets=targets,
363 toolchain_changed=False,
364 )
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700365
366
Greg Edelston01ae5942023-01-30 16:26:54 -0700367class CreateManifestFromSdkTest(
368 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
369):
370 """Test the SdkService/CreateManifestFromSdk endpoint."""
371
372 _chroot_path = "/path/to/chroot"
373 _sdk_path_relative = "build/my_sdk"
374 _dest_dir = "/build"
375 _manifest_path = "/build/my_sdk.Manifest"
376
377 def _NewRequest(self, inside: bool) -> sdk_pb2.CreateManifestFromSdkRequest:
378 return sdk_pb2.CreateManifestFromSdkRequest(
379 chroot=common_pb2.Chroot(path=self._chroot_path),
380 sdk_path=common_pb2.Path(
381 path="/%s" % self._sdk_path_relative,
382 location=common_pb2.Path.Location.INSIDE
383 if inside
384 else common_pb2.Path.Location.OUTSIDE,
385 ),
386 dest_dir=common_pb2.Path(
387 path=self._dest_dir,
388 location=common_pb2.Path.Location.OUTSIDE,
389 ),
390 )
391
392 def _NewResponse(self) -> sdk_pb2.CreateManifestFromSdkResponse:
393 return sdk_pb2.CreateManifestFromSdkResponse()
394
395 def testValidateOnly(self):
396 """Check that a validate only call does not execute any logic."""
397 impl_patch = self.PatchObject(sdk_service, "CreateManifestFromSdk")
Greg Edelstone265a172023-06-26 17:20:05 -0600398 sdk_controller.CreateManifestFromSdk(
Greg Edelston01ae5942023-01-30 16:26:54 -0700399 self._NewRequest(False),
400 self._NewResponse(),
401 self.validate_only_config,
402 )
403 impl_patch.assert_not_called()
404
405 def testOutside(self):
406 """Check that a call with an outside path succeeds."""
407 impl_patch = self.PatchObject(
408 sdk_service,
409 "CreateManifestFromSdk",
410 return_value=pathlib.Path(self._manifest_path),
411 )
412 request = self._NewRequest(inside=False)
413 response = self._NewResponse()
414 sdk_controller.CreateManifestFromSdk(
415 request,
416 response,
417 self.api_config,
418 )
419 impl_patch.assert_called_with(
420 pathlib.Path("/", self._sdk_path_relative),
421 pathlib.Path(self._dest_dir),
422 )
423 self.assertEqual(
424 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
425 )
426 self.assertEqual(response.manifest_path.path, self._manifest_path)
427
428 def testInside(self):
429 """Check that an inside path parses correctly and the call succeeds."""
430 impl_patch = self.PatchObject(
431 sdk_service,
432 "CreateManifestFromSdk",
433 return_value=pathlib.Path(self._manifest_path),
434 )
435 request = self._NewRequest(inside=True)
436 response = self._NewResponse()
437 sdk_controller.CreateManifestFromSdk(
438 request,
439 response,
440 self.api_config,
441 )
442 impl_patch.assert_called_with(
443 pathlib.Path(self._chroot_path, self._sdk_path_relative),
444 pathlib.Path(self._dest_dir),
445 )
446 self.assertEqual(
447 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
448 )
449 self.assertEqual(response.manifest_path.path, self._manifest_path)
450
451
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700452class BuildSdkToolchainTest(
453 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
454):
455 """Test the SdkService/BuildSdkToolchain endpoint."""
456
457 def setUp(self):
458 """Set up the test case."""
459 self._chroot_path = "/path/to/chroot"
Greg Edelstone265a172023-06-26 17:20:05 -0600460 self._result_dir = "/out/toolchain-pkgs/"
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700461 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."""
Greg Edelstone265a172023-06-26 17:20:05 -0600480 request = sdk_pb2.BuildSdkToolchainRequest(
481 result_path=common_pb2.ResultPath(
482 path=common_pb2.Path(
483 path=self._result_dir,
484 location=common_pb2.Path.Location.OUTSIDE,
485 )
486 )
487 )
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700488 if chroot_path:
489 request.chroot.path = chroot_path
490 if use_flags:
491 request.use_flags.extend(
492 common_pb2.UseFlag(flag=flag) for flag in use_flags
493 )
494 return request
495
496 def _NewResponse(
497 self, generated_filenames: Optional[List[str]] = None
498 ) -> sdk_pb2.BuildSdkToolchainResponse:
499 """Return a new BuildSdkToolchainResponse message."""
500 response = sdk_pb2.BuildSdkToolchainResponse()
501 if generated_filenames:
502 response.generated_files.extend(
503 common_pb2.Path(
Greg Edelstone265a172023-06-26 17:20:05 -0600504 path=os.path.join(self._result_dir, fname),
505 location=common_pb2.Path.Location.OUTSIDE,
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700506 )
507 for fname in generated_filenames
508 )
509 return response
510
511 def testValidateOnly(self):
512 """Check that a validate only call does not execute any logic."""
513 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
514 sdk_controller.BuildSdkToolchain(
515 self._NewRequest(), self._NewResponse(), self.validate_only_config
516 )
517 impl_patch.assert_not_called()
518
519 def testSuccess(self):
520 """Check that a normal call defers to the SDK service as expected."""
521 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
522 request = self._NewRequest(use_flags=[])
523 response = self._NewResponse()
524 sdk_controller.BuildSdkToolchain(
525 request,
526 response,
527 self.api_config,
528 )
529 # Can't use assert_called_with, since the chroot objects are equal but
530 # not identical.
531 impl_patch.assert_called_once()
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700532 self.assertEqual(impl_patch.call_args.kwargs["extra_env"], {})
533
534 def testSuccessWithUseFlags(self):
535 """Check that a call with USE flags works as expected."""
536 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
537 request = self._NewRequest(use_flags=["llvm-next", "another-flag"])
538 response = self._NewResponse()
539 sdk_controller.BuildSdkToolchain(
540 request,
541 response,
542 self.api_config,
543 )
544 # Can't use assert_called_with, since the chroot objects are equal but
545 # not identical.
546 impl_patch.assert_called_once()
547 self.assertEqual(
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700548 impl_patch.call_args.kwargs["extra_env"],
549 {"USE": "llvm-next another-flag"},
550 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700551
552
Greg Edelstond401e5a2023-04-28 15:29:11 -0600553class uprev_test(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Greg Edelston6733dc52023-02-15 15:20:07 -0700554 """Test case for SdkService/Uprev() endpoint."""
555
Greg Edelston6733dc52023-02-15 15:20:07 -0700556 _binhost_gs_bucket = "gs://chromiumos-prebuilts/"
Greg Edelston40aea812023-03-27 16:34:35 -0600557 _latest_uprev_target_version = "2023.02.19.112358"
Greg Edelston6733dc52023-02-15 15:20:07 -0700558
559 def setUp(self):
560 """Set up the test case."""
Greg Edelston6733dc52023-02-15 15:20:07 -0700561 self.PatchObject(
562 sdk_service,
Greg Edelstond401e5a2023-04-28 15:29:11 -0600563 "get_latest_uprev_target_version",
Greg Edelston40aea812023-03-27 16:34:35 -0600564 return_value=self._latest_uprev_target_version,
Greg Edelston6733dc52023-02-15 15:20:07 -0700565 )
566 self._uprev_patch = self.PatchObject(
567 sdk_service,
Greg Edelstond401e5a2023-04-28 15:29:11 -0600568 "uprev_sdk_and_prebuilts",
Greg Edelston6733dc52023-02-15 15:20:07 -0700569 )
570
Greg Edelston0382ca42023-05-04 14:00:15 -0600571 def NewRequest(
572 self, version: str = "", toolchain_tarball_template: str = ""
573 ):
Greg Edelston6733dc52023-02-15 15:20:07 -0700574 """Return a new UprevRequest with standard inputs."""
575 return sdk_pb2.UprevRequest(
Greg Edelston6733dc52023-02-15 15:20:07 -0700576 binhost_gs_bucket=self._binhost_gs_bucket,
577 version=version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600578 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700579 )
580
581 @staticmethod
582 def NewResponse() -> sdk_pb2.UprevResponse:
583 """Return a new empty UprevResponse."""
584 return sdk_pb2.UprevResponse()
585
586 def testWithVersion(self):
587 """Test the endpoint with `version` specified.
588
589 In this case, we expect that sdk_controller.Uprev is called with the
590 version specified in the UprevRequest.
591 """
592 specified_version = "1970.01.01.000000"
Greg Edelston0382ca42023-05-04 14:00:15 -0600593 toolchain_tarball_template = "path/to/%(version)s/toolchain"
594 request = self.NewRequest(
595 version=specified_version,
596 toolchain_tarball_template=toolchain_tarball_template,
597 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700598 response = self.NewResponse()
599 sdk_controller.Uprev(request, response, self.api_config)
600 self._uprev_patch.assert_called_with(
Greg Edelston6733dc52023-02-15 15:20:07 -0700601 binhost_gs_bucket=self._binhost_gs_bucket,
602 version=specified_version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600603 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700604 )
605
606 def testWithoutVersion(self):
607 """Test the endpoint with `version` not specified.
608
609 In this case, we expect that sdk_controller.Uprev is called with the
Greg Edelston40aea812023-03-27 16:34:35 -0600610 latest uprev target version, based on the remote file in gs://. This is
611 fetched via sdk_controller.GetLatestUprevTargetVersionVersion
612 (mocked here in setUp()).
Greg Edelston6733dc52023-02-15 15:20:07 -0700613 """
Greg Edelston0382ca42023-05-04 14:00:15 -0600614 toolchain_tarball_template = "path/to/%(version)s/toolchain"
615 request = self.NewRequest(
616 toolchain_tarball_template=toolchain_tarball_template
617 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700618 response = self.NewResponse()
619 sdk_controller.Uprev(request, response, self.api_config)
620 self._uprev_patch.assert_called_with(
Greg Edelston6733dc52023-02-15 15:20:07 -0700621 binhost_gs_bucket=self._binhost_gs_bucket,
Greg Edelston40aea812023-03-27 16:34:35 -0600622 version=self._latest_uprev_target_version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600623 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700624 )
Greg Edelston0382ca42023-05-04 14:00:15 -0600625
626 def testWithoutToolchainTarballTemplate(self):
627 """Test the endpoint with `toolchain_tarball_template` not specified."""
628 request = self.NewRequest(version="1234")
629 response = self.NewResponse()
630 with self.assertRaises(cros_build_lib.DieSystemExit):
631 sdk_controller.Uprev(request, response, self.api_config)