blob: 4e13d411f31d8696bc48e20ceb069be9c3e2eda2 [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
Brian Norris41f247b2023-06-30 11:09:40 -07008from pathlib import Path
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
Brian Norris41f247b2023-06-30 11:09:40 -070016from chromite.lib import chroot_lib
Greg Edelston9dcdc8a2023-01-11 17:07:10 -070017from 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
Brian Norris41f247b2023-06-30 11:09:40 -0700373 _sdk_path = "/build/my_sdk"
Greg Edelston01ae5942023-01-30 16:26:54 -0700374 _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(
Brian Norris41f247b2023-06-30 11:09:40 -0700379 chroot=common_pb2.Chroot(
380 path=self.chroot.path, out_path=str(self.chroot.out_path)
381 ),
Greg Edelston01ae5942023-01-30 16:26:54 -0700382 sdk_path=common_pb2.Path(
Brian Norris41f247b2023-06-30 11:09:40 -0700383 path=self._sdk_path,
Greg Edelston01ae5942023-01-30 16:26:54 -0700384 location=common_pb2.Path.Location.INSIDE
385 if inside
386 else common_pb2.Path.Location.OUTSIDE,
387 ),
388 dest_dir=common_pb2.Path(
389 path=self._dest_dir,
390 location=common_pb2.Path.Location.OUTSIDE,
391 ),
392 )
393
394 def _NewResponse(self) -> sdk_pb2.CreateManifestFromSdkResponse:
395 return sdk_pb2.CreateManifestFromSdkResponse()
396
Brian Norris41f247b2023-06-30 11:09:40 -0700397 def setUp(self):
398 self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
399
400 self.chroot = chroot_lib.Chroot(
401 path=Path("/path/to/chroot"),
402 out_path=Path("/path/to/out"),
403 )
404
Greg Edelston01ae5942023-01-30 16:26:54 -0700405 def testValidateOnly(self):
406 """Check that a validate only call does not execute any logic."""
407 impl_patch = self.PatchObject(sdk_service, "CreateManifestFromSdk")
Greg Edelstone265a172023-06-26 17:20:05 -0600408 sdk_controller.CreateManifestFromSdk(
Greg Edelston01ae5942023-01-30 16:26:54 -0700409 self._NewRequest(False),
410 self._NewResponse(),
411 self.validate_only_config,
412 )
413 impl_patch.assert_not_called()
414
415 def testOutside(self):
416 """Check that a call with an outside path succeeds."""
417 impl_patch = self.PatchObject(
418 sdk_service,
419 "CreateManifestFromSdk",
Brian Norris41f247b2023-06-30 11:09:40 -0700420 return_value=Path(self._manifest_path),
Greg Edelston01ae5942023-01-30 16:26:54 -0700421 )
422 request = self._NewRequest(inside=False)
423 response = self._NewResponse()
424 sdk_controller.CreateManifestFromSdk(
425 request,
426 response,
427 self.api_config,
428 )
429 impl_patch.assert_called_with(
Brian Norris41f247b2023-06-30 11:09:40 -0700430 Path(self._sdk_path),
431 Path(self._dest_dir),
Greg Edelston01ae5942023-01-30 16:26:54 -0700432 )
433 self.assertEqual(
434 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
435 )
436 self.assertEqual(response.manifest_path.path, self._manifest_path)
437
438 def testInside(self):
439 """Check that an inside path parses correctly and the call succeeds."""
440 impl_patch = self.PatchObject(
441 sdk_service,
442 "CreateManifestFromSdk",
Brian Norris41f247b2023-06-30 11:09:40 -0700443 return_value=Path(self._manifest_path),
Greg Edelston01ae5942023-01-30 16:26:54 -0700444 )
445 request = self._NewRequest(inside=True)
446 response = self._NewResponse()
447 sdk_controller.CreateManifestFromSdk(
448 request,
449 response,
450 self.api_config,
451 )
452 impl_patch.assert_called_with(
Brian Norris41f247b2023-06-30 11:09:40 -0700453 Path(self.chroot.full_path(self._sdk_path)),
454 Path(self._dest_dir),
Greg Edelston01ae5942023-01-30 16:26:54 -0700455 )
456 self.assertEqual(
457 response.manifest_path.location, common_pb2.Path.Location.OUTSIDE
458 )
459 self.assertEqual(response.manifest_path.path, self._manifest_path)
460
461
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700462class BuildSdkToolchainTest(
463 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
464):
465 """Test the SdkService/BuildSdkToolchain endpoint."""
466
467 def setUp(self):
468 """Set up the test case."""
469 self._chroot_path = "/path/to/chroot"
Greg Edelstone265a172023-06-26 17:20:05 -0600470 self._result_dir = "/out/toolchain-pkgs/"
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700471 self._response = sdk_pb2.BuildSdkToolchainResponse()
472 self._generated_filenames = (
473 "armv7a-cros-linux-gnueabihf.tar.xz",
474 "x86_64-cros-linux-gnu.tar.xz",
475 )
476 self._paths_for_generated_files = [
477 common_pb2.Path(
478 path=os.path.join(constants.SDK_TOOLCHAINS_OUTPUT, fname),
479 location=common_pb2.Path.Location.INSIDE,
480 )
481 for fname in self._generated_filenames
482 ]
483
484 def _NewRequest(
485 self,
486 chroot_path: Optional[str] = None,
487 use_flags: Optional[List[str]] = None,
488 ) -> sdk_pb2.BuildSdkToolchainRequest:
489 """Return a new BuildSdkToolchainRequest message."""
Greg Edelstone265a172023-06-26 17:20:05 -0600490 request = sdk_pb2.BuildSdkToolchainRequest(
491 result_path=common_pb2.ResultPath(
492 path=common_pb2.Path(
493 path=self._result_dir,
494 location=common_pb2.Path.Location.OUTSIDE,
495 )
496 )
497 )
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700498 if chroot_path:
499 request.chroot.path = chroot_path
500 if use_flags:
501 request.use_flags.extend(
502 common_pb2.UseFlag(flag=flag) for flag in use_flags
503 )
504 return request
505
506 def _NewResponse(
507 self, generated_filenames: Optional[List[str]] = None
508 ) -> sdk_pb2.BuildSdkToolchainResponse:
509 """Return a new BuildSdkToolchainResponse message."""
510 response = sdk_pb2.BuildSdkToolchainResponse()
511 if generated_filenames:
512 response.generated_files.extend(
513 common_pb2.Path(
Greg Edelstone265a172023-06-26 17:20:05 -0600514 path=os.path.join(self._result_dir, fname),
515 location=common_pb2.Path.Location.OUTSIDE,
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700516 )
517 for fname in generated_filenames
518 )
519 return response
520
521 def testValidateOnly(self):
522 """Check that a validate only call does not execute any logic."""
523 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
524 sdk_controller.BuildSdkToolchain(
525 self._NewRequest(), self._NewResponse(), self.validate_only_config
526 )
527 impl_patch.assert_not_called()
528
529 def testSuccess(self):
530 """Check that a normal call defers to the SDK service as expected."""
531 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
532 request = self._NewRequest(use_flags=[])
533 response = self._NewResponse()
534 sdk_controller.BuildSdkToolchain(
535 request,
536 response,
537 self.api_config,
538 )
539 # Can't use assert_called_with, since the chroot objects are equal but
540 # not identical.
541 impl_patch.assert_called_once()
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700542 self.assertEqual(impl_patch.call_args.kwargs["extra_env"], {})
543
544 def testSuccessWithUseFlags(self):
545 """Check that a call with USE flags works as expected."""
546 impl_patch = self.PatchObject(sdk_service, "BuildSdkToolchain")
547 request = self._NewRequest(use_flags=["llvm-next", "another-flag"])
548 response = self._NewResponse()
549 sdk_controller.BuildSdkToolchain(
550 request,
551 response,
552 self.api_config,
553 )
554 # Can't use assert_called_with, since the chroot objects are equal but
555 # not identical.
556 impl_patch.assert_called_once()
557 self.assertEqual(
Greg Edelston9dcdc8a2023-01-11 17:07:10 -0700558 impl_patch.call_args.kwargs["extra_env"],
559 {"USE": "llvm-next another-flag"},
560 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700561
562
Greg Edelstond401e5a2023-04-28 15:29:11 -0600563class uprev_test(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Greg Edelston6733dc52023-02-15 15:20:07 -0700564 """Test case for SdkService/Uprev() endpoint."""
565
Greg Edelston6733dc52023-02-15 15:20:07 -0700566 _binhost_gs_bucket = "gs://chromiumos-prebuilts/"
Greg Edelston40aea812023-03-27 16:34:35 -0600567 _latest_uprev_target_version = "2023.02.19.112358"
Greg Edelston6733dc52023-02-15 15:20:07 -0700568
569 def setUp(self):
570 """Set up the test case."""
Greg Edelston6733dc52023-02-15 15:20:07 -0700571 self.PatchObject(
572 sdk_service,
Greg Edelstond401e5a2023-04-28 15:29:11 -0600573 "get_latest_uprev_target_version",
Greg Edelston40aea812023-03-27 16:34:35 -0600574 return_value=self._latest_uprev_target_version,
Greg Edelston6733dc52023-02-15 15:20:07 -0700575 )
576 self._uprev_patch = self.PatchObject(
577 sdk_service,
Greg Edelstond401e5a2023-04-28 15:29:11 -0600578 "uprev_sdk_and_prebuilts",
Greg Edelston6733dc52023-02-15 15:20:07 -0700579 )
580
Greg Edelston0382ca42023-05-04 14:00:15 -0600581 def NewRequest(
582 self, version: str = "", toolchain_tarball_template: str = ""
583 ):
Greg Edelston6733dc52023-02-15 15:20:07 -0700584 """Return a new UprevRequest with standard inputs."""
585 return sdk_pb2.UprevRequest(
Greg Edelston6733dc52023-02-15 15:20:07 -0700586 binhost_gs_bucket=self._binhost_gs_bucket,
587 version=version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600588 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700589 )
590
591 @staticmethod
592 def NewResponse() -> sdk_pb2.UprevResponse:
593 """Return a new empty UprevResponse."""
594 return sdk_pb2.UprevResponse()
595
596 def testWithVersion(self):
597 """Test the endpoint with `version` specified.
598
599 In this case, we expect that sdk_controller.Uprev is called with the
600 version specified in the UprevRequest.
601 """
602 specified_version = "1970.01.01.000000"
Greg Edelston0382ca42023-05-04 14:00:15 -0600603 toolchain_tarball_template = "path/to/%(version)s/toolchain"
604 request = self.NewRequest(
605 version=specified_version,
606 toolchain_tarball_template=toolchain_tarball_template,
607 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700608 response = self.NewResponse()
609 sdk_controller.Uprev(request, response, self.api_config)
610 self._uprev_patch.assert_called_with(
Greg Edelston6733dc52023-02-15 15:20:07 -0700611 binhost_gs_bucket=self._binhost_gs_bucket,
Greg Edelston8bf6d4c2023-06-30 17:14:39 -0600612 sdk_version=specified_version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600613 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700614 )
615
616 def testWithoutVersion(self):
617 """Test the endpoint with `version` not specified.
618
619 In this case, we expect that sdk_controller.Uprev is called with the
Greg Edelston40aea812023-03-27 16:34:35 -0600620 latest uprev target version, based on the remote file in gs://. This is
621 fetched via sdk_controller.GetLatestUprevTargetVersionVersion
622 (mocked here in setUp()).
Greg Edelston6733dc52023-02-15 15:20:07 -0700623 """
Greg Edelston0382ca42023-05-04 14:00:15 -0600624 toolchain_tarball_template = "path/to/%(version)s/toolchain"
625 request = self.NewRequest(
626 toolchain_tarball_template=toolchain_tarball_template
627 )
Greg Edelston6733dc52023-02-15 15:20:07 -0700628 response = self.NewResponse()
629 sdk_controller.Uprev(request, response, self.api_config)
630 self._uprev_patch.assert_called_with(
Greg Edelston6733dc52023-02-15 15:20:07 -0700631 binhost_gs_bucket=self._binhost_gs_bucket,
Greg Edelston8bf6d4c2023-06-30 17:14:39 -0600632 sdk_version=self._latest_uprev_target_version,
Greg Edelston0382ca42023-05-04 14:00:15 -0600633 toolchain_tarball_template=toolchain_tarball_template,
Greg Edelston6733dc52023-02-15 15:20:07 -0700634 )
Greg Edelston0382ca42023-05-04 14:00:15 -0600635
636 def testWithoutToolchainTarballTemplate(self):
637 """Test the endpoint with `toolchain_tarball_template` not specified."""
638 request = self.NewRequest(version="1234")
639 response = self.NewResponse()
640 with self.assertRaises(cros_build_lib.DieSystemExit):
641 sdk_controller.Uprev(request, response, self.api_config)