blob: 009a1bfcfbf3e96aa153464e77d414a60afcb24c [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,
Alex Klein1699fab2022-09-08 08:46:06 -0600103 chroot_path=mock.ANY,
104 cache_dir=mock.ANY,
105 sdk_version=mock.ANY,
106 skip_chroot_upgrade=mock.ANY,
107 )
108
109 def testTrueArguments(self):
110 """Test True arguments handling."""
111 # Create the patches.
112 self.PatchObject(sdk_service, "Create", return_value=1)
113 args_patch = self.PatchObject(sdk_service, "CreateArguments")
114
115 # Test all True values in the message.
116 request = self._GetRequest(
117 no_replace=True,
118 bootstrap=True,
Alex Klein1699fab2022-09-08 08:46:06 -0600119 sdk_version="foo",
120 skip_chroot_upgrade=True,
121 )
122 sdk_controller.Create(request, self.response, self.api_config)
123 args_patch.assert_called_with(
124 replace=False,
125 bootstrap=True,
Alex Klein1699fab2022-09-08 08:46:06 -0600126 chroot_path=mock.ANY,
127 cache_dir=mock.ANY,
128 sdk_version="foo",
129 skip_chroot_upgrade=True,
130 )
Mike Frysingercb8992a2020-02-11 05:13:13 +0000131
Alex Kleinaa5c4172019-02-27 17:12:20 -0700132
George Engelbrecht86cfae62023-04-05 10:57:41 -0600133class SdkCleanTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
134 """Clean tests."""
135
136 def setUp(self):
137 """Setup method."""
138 # We need to run the command outside the chroot.
139 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
140 self.response = sdk_pb2.CleanResponse()
141
142 def _GetRequest(self, chroot_path=None, incrementals=False):
143 """Helper to build a clean request message."""
144 request = sdk_pb2.CleanRequest()
145 if chroot_path:
146 request.chroot.path = chroot_path
147
148 request.incrementals = incrementals
149
150 return request
151
152 def testMockCall(self):
153 """Sanity check that a mock call does not execute any logic."""
154 patch = self.PatchObject(sdk_service, "Clean")
155
156 rc = sdk_controller.Clean(
157 self._GetRequest(), self.response, self.mock_call_config
158 )
159 patch.assert_not_called()
160 self.assertFalse(rc)
161
162 def testSuccess(self):
163 """Test the successful call by verifying service invocation."""
164 patch = self.PatchObject(sdk_service, "Clean", return_value=0)
165
166 request = self._GetRequest(incrementals=True)
167
168 sdk_controller.Clean(request, self.response, self.api_config)
169 patch.assert_called_once_with(
170 mock.ANY,
171 safe=False,
172 images=False,
173 sysroots=False,
174 tmp=False,
175 cache=False,
176 logs=False,
177 workdirs=False,
178 incrementals=True,
179 )
180
181 def testDefaults(self):
182 """Test the successful call by verifying service invocation."""
183 patch = self.PatchObject(sdk_service, "Clean", return_value=0)
184
185 request = self._GetRequest()
186
187 sdk_controller.Clean(request, self.response, self.api_config)
188 patch.assert_called_once_with(mock.ANY, safe=True, sysroots=True)
189
190
Michael Mortensene87d8a62020-07-06 11:44:35 -0600191class SdkDeleteTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
George Engelbrecht86cfae62023-04-05 10:57:41 -0600192 """Delete tests."""
Michael Mortensene87d8a62020-07-06 11:44:35 -0600193
Alex Klein1699fab2022-09-08 08:46:06 -0600194 def setUp(self):
195 """Setup method."""
196 # We need to run the command outside the chroot.
197 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
198 self.response = sdk_pb2.DeleteResponse()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600199
Alex Klein1699fab2022-09-08 08:46:06 -0600200 def _GetRequest(self, chroot_path=None):
201 """Helper to build a delete request message."""
202 request = sdk_pb2.DeleteRequest()
203 if chroot_path:
204 request.chroot.path = chroot_path
Michael Mortensene87d8a62020-07-06 11:44:35 -0600205
Alex Klein1699fab2022-09-08 08:46:06 -0600206 return request
Michael Mortensene87d8a62020-07-06 11:44:35 -0600207
Alex Klein1699fab2022-09-08 08:46:06 -0600208 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700209 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600210 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600211
Alex Klein1699fab2022-09-08 08:46:06 -0600212 sdk_controller.Delete(
213 self._GetRequest(), self.response, self.validate_only_config
214 )
215 patch.assert_not_called()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600216
Alex Klein1699fab2022-09-08 08:46:06 -0600217 def testMockCall(self):
218 """Sanity check that a mock call does not execute any logic."""
219 patch = self.PatchObject(sdk_service, "Delete")
Michael Mortensene87d8a62020-07-06 11:44:35 -0600220
Alex Klein1699fab2022-09-08 08:46:06 -0600221 rc = sdk_controller.Delete(
222 self._GetRequest(), self.response, self.mock_call_config
223 )
224 patch.assert_not_called()
225 self.assertFalse(rc)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600226
Alex Klein1699fab2022-09-08 08:46:06 -0600227 def testSuccess(self):
228 """Test the successful call by verifying service invocation."""
229 patch = self.PatchObject(sdk_service, "Delete", return_value=1)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600230
Alex Klein1699fab2022-09-08 08:46:06 -0600231 request = self._GetRequest()
Michael Mortensene87d8a62020-07-06 11:44:35 -0600232
Alex Klein1699fab2022-09-08 08:46:06 -0600233 sdk_controller.Delete(request, self.response, self.api_config)
234 # Verify that by default sdk_service.Delete is called with force=True.
235 patch.assert_called_once_with(mock.ANY, force=True)
Michael Mortensene87d8a62020-07-06 11:44:35 -0600236
237
Brian Norrisf624bf42023-03-02 12:57:49 -0800238class SdkUnmountTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
239 """SDK Unmount tests."""
240
241 def testNoop(self):
242 """Unmount is a deprecated noop."""
243 request = sdk_pb2.UnmountRequest()
244 response = sdk_pb2.UnmountResponse()
245 rc = sdk_controller.Unmount(request, response, self.api_config)
246 self.assertFalse(rc)
247
248
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600249class SdkUnmountPathTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600250 """Update tests."""
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 def setUp(self):
253 """Setup method."""
254 self.response = sdk_pb2.UnmountPathResponse()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 def _UnmountPathRequest(self, path=None):
257 """Helper to build a delete request message."""
258 request = sdk_pb2.UnmountPathRequest()
259 if path:
260 request.path.path = path
261 return request
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600262
Alex Klein1699fab2022-09-08 08:46:06 -0600263 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700264 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600265 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600266
Alex Klein1699fab2022-09-08 08:46:06 -0600267 sdk_controller.UnmountPath(
268 self._UnmountPathRequest("/test/path"),
269 self.response,
270 self.validate_only_config,
271 )
272 patch.assert_not_called()
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600273
Alex Klein1699fab2022-09-08 08:46:06 -0600274 def testMockCall(self):
275 """Sanity check that a mock call does not execute any logic."""
276 patch = self.PatchObject(sdk_service, "UnmountPath")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600277
Alex Klein1699fab2022-09-08 08:46:06 -0600278 rc = sdk_controller.UnmountPath(
279 self._UnmountPathRequest(), self.response, self.mock_call_config
280 )
281 patch.assert_not_called()
282 self.assertFalse(rc)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600283
Alex Klein1699fab2022-09-08 08:46:06 -0600284 def testSuccess(self):
285 """Test the successful call by verifying service invocation."""
286 patch = self.PatchObject(sdk_service, "UnmountPath", return_value=1)
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600287
Alex Klein1699fab2022-09-08 08:46:06 -0600288 request = self._UnmountPathRequest("/test/path")
289 sdk_controller.UnmountPath(request, self.response, self.api_config)
290 patch.assert_called_once_with("/test/path")
Michael Mortensen52a98ac2020-07-28 16:00:18 -0600291
292
Alex Klein231d2da2019-07-22 16:44:45 -0600293class SdkUpdateTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600294 """Update tests."""
Alex Kleinaa5c4172019-02-27 17:12:20 -0700295
Alex Klein1699fab2022-09-08 08:46:06 -0600296 def setUp(self):
297 """Setup method."""
298 # We need to run the command inside the chroot.
299 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700300
Alex Klein1699fab2022-09-08 08:46:06 -0600301 self.response = sdk_pb2.UpdateResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600302
Alex Klein1699fab2022-09-08 08:46:06 -0600303 def _GetRequest(self, build_source=False, targets=None):
304 """Helper to simplify building a request instance."""
305 request = sdk_pb2.UpdateRequest()
306 request.flags.build_source = build_source
Alex Kleinaa5c4172019-02-27 17:12:20 -0700307
Alex Klein1699fab2022-09-08 08:46:06 -0600308 for target in targets or []:
309 added = request.toolchain_targets.add()
310 added.name = target
Alex Kleinaa5c4172019-02-27 17:12:20 -0700311
Alex Klein1699fab2022-09-08 08:46:06 -0600312 return request
Alex Kleinaa5c4172019-02-27 17:12:20 -0700313
Alex Klein1699fab2022-09-08 08:46:06 -0600314 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700315 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600316 patch = self.PatchObject(sdk_service, "Update")
Alex Klein231d2da2019-07-22 16:44:45 -0600317
Alex Klein1699fab2022-09-08 08:46:06 -0600318 sdk_controller.Update(
319 self._GetRequest(), self.response, self.validate_only_config
320 )
321 patch.assert_not_called()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700322
Alex Klein1699fab2022-09-08 08:46:06 -0600323 def testMockCall(self):
324 """Sanity check that a mock call does not execute any logic."""
325 patch = self.PatchObject(sdk_service, "Update")
Alex Klein076841b2019-08-29 15:19:39 -0600326
Alex Klein1699fab2022-09-08 08:46:06 -0600327 rc = sdk_controller.Create(
328 self._GetRequest(), self.response, self.mock_call_config
329 )
330 patch.assert_not_called()
331 self.assertFalse(rc)
332 self.assertTrue(self.response.version.version)
Alex Klein076841b2019-08-29 15:19:39 -0600333
Alex Klein1699fab2022-09-08 08:46:06 -0600334 def testSuccess(self):
335 """Successful call output handling test."""
336 expected_version = 1
337 self.PatchObject(sdk_service, "Update", return_value=expected_version)
338 request = self._GetRequest()
Alex Kleinaa5c4172019-02-27 17:12:20 -0700339
Alex Klein1699fab2022-09-08 08:46:06 -0600340 sdk_controller.Update(request, self.response, self.api_config)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700341
Alex Klein1699fab2022-09-08 08:46:06 -0600342 self.assertEqual(expected_version, self.response.version.version)
Alex Kleinaa5c4172019-02-27 17:12:20 -0700343
Alex Klein1699fab2022-09-08 08:46:06 -0600344 def testArgumentHandling(self):
345 """Test the proto argument handling."""
346 args = sdk_service.UpdateArguments()
347 self.PatchObject(sdk_service, "Update", return_value=1)
348 args_patch = self.PatchObject(
349 sdk_service, "UpdateArguments", return_value=args
350 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700351
Alex Klein1699fab2022-09-08 08:46:06 -0600352 # No boards and flags False.
353 request = self._GetRequest(build_source=False)
354 sdk_controller.Update(request, self.response, self.api_config)
355 args_patch.assert_called_with(
356 build_source=False, toolchain_targets=[], toolchain_changed=False
357 )
Alex Kleinaa5c4172019-02-27 17:12:20 -0700358
Alex Klein1699fab2022-09-08 08:46:06 -0600359 # Multiple boards and flags True.
360 targets = ["board1", "board2"]
361 request = self._GetRequest(build_source=True, targets=targets)
362 sdk_controller.Update(request, self.response, self.api_config)
363 args_patch.assert_called_with(
364 build_source=True,
365 toolchain_targets=targets,
366 toolchain_changed=False,
367 )
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700368
369
Greg Edelston01ae5942023-01-30 16:26:54 -0700370class CreateManifestFromSdkTest(
371 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
372):
373 """Test the SdkService/CreateManifestFromSdk endpoint."""
374
375 _chroot_path = "/path/to/chroot"
376 _sdk_path_relative = "build/my_sdk"
377 _dest_dir = "/build"
378 _manifest_path = "/build/my_sdk.Manifest"
379
380 def _NewRequest(self, inside: bool) -> sdk_pb2.CreateManifestFromSdkRequest:
381 return sdk_pb2.CreateManifestFromSdkRequest(
382 chroot=common_pb2.Chroot(path=self._chroot_path),
383 sdk_path=common_pb2.Path(
384 path="/%s" % self._sdk_path_relative,
385 location=common_pb2.Path.Location.INSIDE
386 if inside
387 else common_pb2.Path.Location.OUTSIDE,
388 ),
389 dest_dir=common_pb2.Path(
390 path=self._dest_dir,
391 location=common_pb2.Path.Location.OUTSIDE,
392 ),
393 )
394
395 def _NewResponse(self) -> sdk_pb2.CreateManifestFromSdkResponse:
396 return sdk_pb2.CreateManifestFromSdkResponse()
397
398 def testValidateOnly(self):
399 """Check that a validate only call does not execute any logic."""
400 impl_patch = self.PatchObject(sdk_service, "CreateManifestFromSdk")
401 sdk_controller.BuildSdkToolchain(
402 self._NewRequest(False),
403 self._NewResponse(),
404 self.validate_only_config,
405 )
406 impl_patch.assert_not_called()
407
408 def testOutside(self):
409 """Check that a call with an outside path succeeds."""
410 impl_patch = self.PatchObject(
411 sdk_service,
412 "CreateManifestFromSdk",
413 return_value=pathlib.Path(self._manifest_path),
414 )
415 request = self._NewRequest(inside=False)
416 response = self._NewResponse()
417 sdk_controller.CreateManifestFromSdk(
418 request,
419 response,
420 self.api_config,
421 )
422 impl_patch.assert_called_with(
423 pathlib.Path("/", self._sdk_path_relative),
424 pathlib.Path(self._dest_dir),
425 )
426 self.assertEqual(
427 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
428 )
429 self.assertEqual(response.manifest_path.path, self._manifest_path)
430
431 def testInside(self):
432 """Check that an inside path parses correctly and the call succeeds."""
433 impl_patch = self.PatchObject(
434 sdk_service,
435 "CreateManifestFromSdk",
436 return_value=pathlib.Path(self._manifest_path),
437 )
438 request = self._NewRequest(inside=True)
439 response = self._NewResponse()
440 sdk_controller.CreateManifestFromSdk(
441 request,
442 response,
443 self.api_config,
444 )
445 impl_patch.assert_called_with(
446 pathlib.Path(self._chroot_path, self._sdk_path_relative),
447 pathlib.Path(self._dest_dir),
448 )
449 self.assertEqual(
450 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
451 )
452 self.assertEqual(response.manifest_path.path, self._manifest_path)
453
454
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700455class BuildSdkToolchainTest(
456 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
457):
458 """Test the SdkService/BuildSdkToolchain endpoint."""
459
460 def setUp(self):
461 """Set up the test case."""
462 self._chroot_path = "/path/to/chroot"
463 self._response = sdk_pb2.BuildSdkToolchainResponse()
464 self._generated_filenames = (
465 "armv7a-cros-linux-gnueabihf.tar.xz",
466 "x86_64-cros-linux-gnu.tar.xz",
467 )
468 self._paths_for_generated_files = [
469 common_pb2.Path(
470 path=os.path.join(constants.SDK_TOOLCHAINS_OUTPUT, fname),
471 location=common_pb2.Path.Location.INSIDE,
472 )
473 for fname in self._generated_filenames
474 ]
475
476 def _NewRequest(
477 self,
478 chroot_path: Optional[str] = None,
479 use_flags: Optional[List[str]] = None,
480 ) -> sdk_pb2.BuildSdkToolchainRequest:
481 """Return a new BuildSdkToolchainRequest message."""
482 request = sdk_pb2.BuildSdkToolchainRequest()
483 if chroot_path:
484 request.chroot.path = chroot_path
485 if use_flags:
486 request.use_flags.extend(
487 common_pb2.UseFlag(flag=flag) for flag in use_flags
488 )
489 return request
490
491 def _NewResponse(
492 self, generated_filenames: Optional[List[str]] = None
493 ) -> sdk_pb2.BuildSdkToolchainResponse:
494 """Return a new BuildSdkToolchainResponse message."""
495 response = sdk_pb2.BuildSdkToolchainResponse()
496 if generated_filenames:
497 response.generated_files.extend(
498 common_pb2.Path(
499 path=os.path.join(constants.SDK_TOOLCHAINS_OUTPUT, fname),
500 location=common_pb2.Path.Location.INSIDE,
501 )
502 for fname in generated_filenames
503 )
504 return response
505
506 def testValidateOnly(self):
507 """Check that a validate only call does not execute any logic."""
508 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
509 sdk_controller.BuildSdkToolchain(
510 self._NewRequest(), self._NewResponse(), self.validate_only_config
511 )
512 impl_patch.assert_not_called()
513
514 def testSuccess(self):
515 """Check that a normal call defers to the SDK service as expected."""
516 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
517 request = self._NewRequest(use_flags=[])
518 response = self._NewResponse()
519 sdk_controller.BuildSdkToolchain(
520 request,
521 response,
522 self.api_config,
523 )
524 # Can't use assert_called_with, since the chroot objects are equal but
525 # not identical.
526 impl_patch.assert_called_once()
527 self.assertEqual(
528 impl_patch.call_args.args[0],
529 controller_util.ParseChroot(request.chroot),
530 )
531 self.assertEqual(impl_patch.call_args.kwargs["extra_env"], {})
532
533 def testSuccessWithUseFlags(self):
534 """Check that a call with USE flags works as expected."""
535 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
536 request = self._NewRequest(use_flags=["llvm-next", "another-flag"])
537 response = self._NewResponse()
538 sdk_controller.BuildSdkToolchain(
539 request,
540 response,
541 self.api_config,
542 )
543 # Can't use assert_called_with, since the chroot objects are equal but
544 # not identical.
545 impl_patch.assert_called_once()
546 self.assertEqual(
547 impl_patch.call_args.args[0],
548 controller_util.ParseChroot(request.chroot),
549 )
550 self.assertEqual(
551 impl_patch.call_args.kwargs["extra_env"],
552 {"USE": "llvm-next another-flag"},
553 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700554
555
556class UprevTestCase(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
557 """Test case for SdkService/Uprev() endpoint."""
558
Greg Edelston4907c8c2023-03-27 14:53:31 -0600559 _source_root = pathlib.Path("/path/to/checkout/")
Greg Edelston6733dc52023-02-15 15:20:07 -0700560 _binhost_gs_bucket = "gs://chromiumos-prebuilts/"
Greg Edelston40aea812023-03-27 16:34:35 -0600561 _latest_uprev_target_version = "2023.02.19.112358"
Greg Edelston6733dc52023-02-15 15:20:07 -0700562
563 def setUp(self):
564 """Set up the test case."""
Greg Edelston4907c8c2023-03-27 14:53:31 -0600565 self._source_root_pb2 = common_pb2.Path(
566 path=str(self._source_root),
567 location=common_pb2.Path.Location.OUTSIDE,
568 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700569 self.PatchObject(
570 sdk_service,
Greg Edelston40aea812023-03-27 16:34:35 -0600571 "GetLatestUprevTargetVersion",
572 return_value=self._latest_uprev_target_version,
Greg Edelston6733dc52023-02-15 15:20:07 -0700573 )
574 self._uprev_patch = self.PatchObject(
575 sdk_service,
576 "UprevSdkAndPrebuilts",
577 )
578
579 def NewRequest(self, version: str = ""):
580 """Return a new UprevRequest with standard inputs."""
581 return sdk_pb2.UprevRequest(
Greg Edelston4907c8c2023-03-27 14:53:31 -0600582 source_root=self._source_root_pb2,
Greg Edelston6733dc52023-02-15 15:20:07 -0700583 binhost_gs_bucket=self._binhost_gs_bucket,
584 version=version,
585 )
586
587 @staticmethod
588 def NewResponse() -> sdk_pb2.UprevResponse:
589 """Return a new empty UprevResponse."""
590 return sdk_pb2.UprevResponse()
591
592 def testWithVersion(self):
593 """Test the endpoint with `version` specified.
594
595 In this case, we expect that sdk_controller.Uprev is called with the
596 version specified in the UprevRequest.
597 """
598 specified_version = "1970.01.01.000000"
599 request = self.NewRequest(version=specified_version)
600 response = self.NewResponse()
601 sdk_controller.Uprev(request, response, self.api_config)
602 self._uprev_patch.assert_called_with(
Greg Edelston4907c8c2023-03-27 14:53:31 -0600603 self._source_root,
Greg Edelston6733dc52023-02-15 15:20:07 -0700604 binhost_gs_bucket=self._binhost_gs_bucket,
605 version=specified_version,
606 )
607
608 def testWithoutVersion(self):
609 """Test the endpoint with `version` not specified.
610
611 In this case, we expect that sdk_controller.Uprev is called with the
Greg Edelston40aea812023-03-27 16:34:35 -0600612 latest uprev target version, based on the remote file in gs://. This is
613 fetched via sdk_controller.GetLatestUprevTargetVersionVersion
614 (mocked here in setUp()).
Greg Edelston6733dc52023-02-15 15:20:07 -0700615 """
616 request = self.NewRequest()
617 response = self.NewResponse()
618 sdk_controller.Uprev(request, response, self.api_config)
619 self._uprev_patch.assert_called_with(
Greg Edelston4907c8c2023-03-27 14:53:31 -0600620 self._source_root,
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 Edelston6733dc52023-02-15 15:20:07 -0700623 )