blob: 8ab8c3d4a5f6e1a5c526f4bb4487e65863c61cbd [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Tiancong Wangaf050172019-07-10 11:52:03 -07002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Unittests for Toolchain-related operations."""
6
Alex Kleincd03a5e2021-10-18 13:23:47 -06007import os
8
Alex Klein231d2da2019-07-22 16:44:45 -06009from chromite.api import api_config
LaMont Jones5d2edcb2019-12-23 11:32:03 -070010from chromite.api import controller
Tiancong Wangaf050172019-07-10 11:52:03 -070011from chromite.api.controller import toolchain
LaMont Jones5d2edcb2019-12-23 11:32:03 -070012from chromite.api.gen.chromite.api import artifacts_pb2
LaMont Jones4579e8c2019-12-06 14:20:37 -070013from chromite.api.gen.chromite.api import sysroot_pb2
Tiancong Wangaf050172019-07-10 11:52:03 -070014from chromite.api.gen.chromite.api import toolchain_pb2
LaMont Jones4579e8c2019-12-06 14:20:37 -070015from chromite.api.gen.chromiumos import common_pb2
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040016from chromite.api.gen.chromiumos.builder_config_pb2 import BuilderConfig
Tiancong Wang24a3df72019-08-20 15:48:51 -070017from chromite.lib import cros_build_lib
Tiancong Wangaf050172019-07-10 11:52:03 -070018from chromite.lib import cros_test_lib
Alex Kleincd03a5e2021-10-18 13:23:47 -060019from chromite.lib import osutils
Jack Neus4ee7b1d2022-06-27 19:54:18 +000020from chromite.lib import toolchain as toolchain_lib
Tiancong Wangaf050172019-07-10 11:52:03 -070021from chromite.lib import toolchain_util
22
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040023
LaMont Jones5d2edcb2019-12-23 11:32:03 -070024# pylint: disable=protected-access
Tiancong Wangaf050172019-07-10 11:52:03 -070025
Tiancong Wangba2a1c22021-01-19 10:45:06 -080026
Alex Klein1699fab2022-09-08 08:46:06 -060027class UpdateEbuildWithAFDOArtifactsTest(
28 cros_test_lib.MockTestCase, api_config.ApiConfigMixin
29):
30 """Unittests for UpdateEbuildWithAFDOArtifacts."""
Tiancong Wang24a3df72019-08-20 15:48:51 -070031
Alex Klein1699fab2022-09-08 08:46:06 -060032 @staticmethod
33 def mock_die(message, *args):
34 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangaf050172019-07-10 11:52:03 -070035
Alex Klein1699fab2022-09-08 08:46:06 -060036 def setUp(self):
37 self.board = "board"
38 self.response = toolchain_pb2.VerifyAFDOArtifactsResponse()
39 self.invalid_artifact_type = toolchain_pb2.BENCHMARK_AFDO
40 self.PatchObject(cros_build_lib, "Die", new=self.mock_die)
Tiancong Wang24a3df72019-08-20 15:48:51 -070041
Alex Klein1699fab2022-09-08 08:46:06 -060042 def _GetRequest(self, build_target=None, artifact_type=None):
43 return toolchain_pb2.VerifyAFDOArtifactsRequest(
44 build_target={"name": build_target},
45 artifact_type=artifact_type,
46 )
Tiancong Wangaf050172019-07-10 11:52:03 -070047
LaMont Jonesb20b3d92019-11-23 11:47:48 -070048
Alex Klein1699fab2022-09-08 08:46:06 -060049class PrepareForBuildTest(
50 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
51):
52 """Unittests for PrepareForBuild."""
LaMont Jonesb20b3d92019-11-23 11:47:48 -070053
Alex Klein1699fab2022-09-08 08:46:06 -060054 def setUp(self):
55 self.response = toolchain_pb2.PrepareForToolchainBuildResponse()
56 self.prep = self.PatchObject(
57 toolchain_util,
58 "PrepareForBuild",
59 return_value=toolchain_util.PrepareForBuildReturn.NEEDED,
60 )
61 self.bundle = self.PatchObject(
62 toolchain_util, "BundleArtifacts", return_value=[]
63 )
64 self.PatchObject(
65 toolchain,
66 "_TOOLCHAIN_ARTIFACT_HANDLERS",
67 {
Alex Kleinab87ceb2023-01-24 12:00:51 -070068 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE: (
69 toolchain._Handlers(
70 "UnverifiedChromeLlvmOrderfile", self.prep, self.bundle
71 )
Alex Klein1699fab2022-09-08 08:46:06 -060072 ),
73 },
74 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -070075
Alex Klein1699fab2022-09-08 08:46:06 -060076 def _GetRequest(
77 self, artifact_types=None, input_artifacts=None, additional_args=None
78 ):
79 chroot = common_pb2.Chroot(path=str(self.tempdir))
80 sysroot = sysroot_pb2.Sysroot(
81 path="/build/board",
82 build_target=common_pb2.BuildTarget(name="board"),
83 )
84 return toolchain_pb2.PrepareForToolchainBuildRequest(
85 artifact_types=artifact_types,
86 chroot=chroot,
87 sysroot=sysroot,
88 input_artifacts=input_artifacts,
89 additional_args=additional_args,
90 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -070091
Alex Klein1699fab2022-09-08 08:46:06 -060092 def testRaisesForUnknown(self):
93 request = self._GetRequest([BuilderConfig.Artifacts.IMAGE_ARCHIVES])
94 self.assertRaises(
95 KeyError,
96 toolchain.PrepareForBuild,
97 request,
98 self.response,
99 self.api_config,
100 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700101
Alex Klein1699fab2022-09-08 08:46:06 -0600102 def testAcceptsNone(self):
103 request = toolchain_pb2.PrepareForToolchainBuildRequest(
104 artifact_types=[
105 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
106 ],
107 chroot=None,
108 sysroot=None,
109 )
110 toolchain.PrepareForBuild(request, self.response, self.api_config)
111 self.prep.assert_called_once_with(
112 "UnverifiedChromeLlvmOrderfile", None, "", "", {}, {}
113 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700114
Alex Klein1699fab2022-09-08 08:46:06 -0600115 def testHandlesUnknownInputArtifacts(self):
116 request = toolchain_pb2.PrepareForToolchainBuildRequest(
117 artifact_types=[
118 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
119 ],
120 chroot=None,
121 sysroot=None,
122 input_artifacts=[
123 BuilderConfig.Artifacts.InputArtifactInfo(
124 input_artifact_type=BuilderConfig.Artifacts.IMAGE_ZIP,
125 input_artifact_gs_locations=["path1"],
126 ),
127 ],
128 )
129 toolchain.PrepareForBuild(request, self.response, self.api_config)
130 self.prep.assert_called_once_with(
131 "UnverifiedChromeLlvmOrderfile", None, "", "", {}, {}
132 )
LaMont Jones45ca6c42020-02-05 09:39:09 -0700133
Alex Klein1699fab2022-09-08 08:46:06 -0600134 def testPassesProfileInfo(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700135 # pylint: disable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600136 request = toolchain_pb2.PrepareForToolchainBuildRequest(
137 artifact_types=[
138 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
139 ],
140 chroot=None,
141 sysroot=None,
142 input_artifacts=[
143 BuilderConfig.Artifacts.InputArtifactInfo(
144 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
145 input_artifact_gs_locations=["path1", "path2"],
146 ),
147 BuilderConfig.Artifacts.InputArtifactInfo(
148 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
149 input_artifact_gs_locations=["path3"],
150 ),
151 ],
152 profile_info=common_pb2.ArtifactProfileInfo(
Denis Nikitin62e69862023-02-13 23:37:00 -0800153 chrome_cwp_profile="CWPVERSION",
154 arch="amd64",
Alex Klein1699fab2022-09-08 08:46:06 -0600155 ),
156 )
Alex Kleinab87ceb2023-01-24 12:00:51 -0700157 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600158 toolchain.PrepareForBuild(request, self.response, self.api_config)
159 self.prep.assert_called_once_with(
160 "UnverifiedChromeLlvmOrderfile",
161 None,
162 "",
163 "",
164 {
165 "UnverifiedChromeLlvmOrderfile": [
166 "gs://path1",
167 "gs://path2",
168 "gs://path3",
169 ],
170 },
Denis Nikitin62e69862023-02-13 23:37:00 -0800171 {
172 "chrome_cwp_profile": "CWPVERSION",
173 "arch": "amd64",
174 },
Alex Klein1699fab2022-09-08 08:46:06 -0600175 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700176
Alex Klein1699fab2022-09-08 08:46:06 -0600177 def testPassesProfileInfoAfdoRelease(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700178 # pylint: disable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600179 request = toolchain_pb2.PrepareForToolchainBuildRequest(
180 artifact_types=[
181 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
182 ],
183 chroot=None,
184 sysroot=None,
185 input_artifacts=[
186 BuilderConfig.Artifacts.InputArtifactInfo(
187 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
188 input_artifact_gs_locations=["path1", "path2"],
189 ),
190 BuilderConfig.Artifacts.InputArtifactInfo(
191 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
192 input_artifact_gs_locations=["path3"],
193 ),
194 ],
195 profile_info=common_pb2.ArtifactProfileInfo(
196 afdo_release=common_pb2.AfdoRelease(
Denis Nikitin62e69862023-02-13 23:37:00 -0800197 chrome_cwp_profile="CWPVERSION",
198 image_build_id=1234,
199 ),
200 arch="amd64",
Alex Klein1699fab2022-09-08 08:46:06 -0600201 ),
202 )
Alex Kleinab87ceb2023-01-24 12:00:51 -0700203 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600204 toolchain.PrepareForBuild(request, self.response, self.api_config)
205 self.prep.assert_called_once_with(
206 "UnverifiedChromeLlvmOrderfile",
207 None,
208 "",
209 "",
210 {
211 "UnverifiedChromeLlvmOrderfile": [
212 "gs://path1",
213 "gs://path2",
214 "gs://path3",
215 ],
216 },
Denis Nikitin62e69862023-02-13 23:37:00 -0800217 {
218 "chrome_cwp_profile": "CWPVERSION",
219 "image_build_id": 1234,
220 "arch": "amd64",
221 },
Alex Klein1699fab2022-09-08 08:46:06 -0600222 )
LaMont Jonese7821672020-04-09 08:56:26 -0600223
Alex Klein1699fab2022-09-08 08:46:06 -0600224 def testHandlesDuplicateInputArtifacts(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700225 # pylint: disable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600226 request = toolchain_pb2.PrepareForToolchainBuildRequest(
227 artifact_types=[
228 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
229 ],
230 chroot=None,
231 sysroot=None,
232 input_artifacts=[
233 BuilderConfig.Artifacts.InputArtifactInfo(
234 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
235 input_artifact_gs_locations=["path1", "path2"],
236 ),
237 BuilderConfig.Artifacts.InputArtifactInfo(
238 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
239 input_artifact_gs_locations=["path3"],
240 ),
241 ],
242 )
Alex Kleinab87ceb2023-01-24 12:00:51 -0700243 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600244 toolchain.PrepareForBuild(request, self.response, self.api_config)
245 self.prep.assert_called_once_with(
246 "UnverifiedChromeLlvmOrderfile",
247 None,
248 "",
249 "",
250 {
251 "UnverifiedChromeLlvmOrderfile": [
252 "gs://path1",
253 "gs://path2",
254 "gs://path3",
255 ],
256 },
257 {},
258 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700259
260
Alex Klein1699fab2022-09-08 08:46:06 -0600261class BundleToolchainTest(
262 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
263):
264 """Unittests for BundleToolchain."""
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700265
Alex Klein1699fab2022-09-08 08:46:06 -0600266 def setUp(self):
267 self.response = toolchain_pb2.BundleToolchainResponse()
268 self.prep = self.PatchObject(
269 toolchain_util,
270 "PrepareForBuild",
271 return_value=toolchain_util.PrepareForBuildReturn.NEEDED,
272 )
273 self.bundle = self.PatchObject(
274 toolchain_util, "BundleArtifacts", return_value=[]
275 )
276 self.PatchObject(
277 toolchain,
278 "_TOOLCHAIN_ARTIFACT_HANDLERS",
279 {
Alex Kleinab87ceb2023-01-24 12:00:51 -0700280 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE: (
281 toolchain._Handlers(
282 "UnverifiedChromeLlvmOrderfile", self.prep, self.bundle
283 )
Alex Klein1699fab2022-09-08 08:46:06 -0600284 ),
285 },
286 )
287 osutils.WriteFile(os.path.join(self.tempdir, "artifact.txt"), "test")
288 osutils.Touch(os.path.join(self.tempdir, "empty"))
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700289
Alex Klein1699fab2022-09-08 08:46:06 -0600290 def _GetRequest(self, artifact_types=None):
291 chroot = common_pb2.Chroot(path=str(self.tempdir))
292 sysroot = sysroot_pb2.Sysroot(
293 path="/build/board",
294 build_target=common_pb2.BuildTarget(name="board"),
295 )
296 return toolchain_pb2.BundleToolchainRequest(
297 chroot=chroot,
298 sysroot=sysroot,
299 output_dir=str(self.tempdir),
300 artifact_types=artifact_types,
301 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700302
Alex Klein1699fab2022-09-08 08:46:06 -0600303 def testRaisesForUnknown(self):
304 request = self._GetRequest([BuilderConfig.Artifacts.IMAGE_ARCHIVES])
305 self.assertEqual(
306 controller.RETURN_CODE_UNRECOVERABLE,
307 toolchain.BundleArtifacts(request, self.response, self.api_config),
308 )
Michael Mortensen3232ab32020-01-05 19:14:36 -0700309
Alex Klein1699fab2022-09-08 08:46:06 -0600310 def testValidateOnly(self):
311 """Sanity check that a validate only call does not execute any logic."""
312 request = self._GetRequest(
313 [BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE]
314 )
315 toolchain.BundleArtifacts(
316 request, self.response, self.validate_only_config
317 )
318 self.bundle.assert_not_called()
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700319
Alex Klein1699fab2022-09-08 08:46:06 -0600320 def testSetsArtifactsInfo(self):
321 request = self._GetRequest(
322 [BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE]
323 )
324 self.bundle.return_value = ["artifact.txt", "empty", "does_not_exist"]
325 toolchain.BundleArtifacts(request, self.response, self.api_config)
326 self.assertEqual(1, len(self.response.artifacts_info))
327 self.assertEqual(
328 self.response.artifacts_info[0],
329 toolchain_pb2.ArtifactInfo(
330 artifact_type=(
331 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
332 ),
333 artifacts=[
334 artifacts_pb2.Artifact(path=self.bundle.return_value[0])
335 ],
336 ),
337 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800338
339
Alex Klein1699fab2022-09-08 08:46:06 -0600340class GetUpdatedFilesTest(
341 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
342):
343 """Unittests for GetUpdatedFiles."""
Tiancong Wangd5214132021-01-12 10:43:57 -0800344
Alex Klein1699fab2022-09-08 08:46:06 -0600345 def setUp(self):
346 self.response = toolchain_pb2.GetUpdatedFilesResponse()
347 self.artifact_path = "/any/path/to/metadata"
Denis Nikitin62e69862023-02-13 23:37:00 -0800348 self.profile_info = common_pb2.ArtifactProfileInfo(
349 kernel_version="4.4", arch="amd64"
350 )
Alex Klein1699fab2022-09-08 08:46:06 -0600351 self.update = self.PatchObject(
352 toolchain_util, "GetUpdatedFiles", return_value=([], "")
353 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800354
Alex Klein1699fab2022-09-08 08:46:06 -0600355 def _GetRequest(self, uploaded_artifacts):
356 uploaded = []
357 for artifact_type, artifact_path, profile_info in uploaded_artifacts:
358 uploaded.append(
359 toolchain_pb2.GetUpdatedFilesRequest.UploadedArtifacts(
360 artifact_info=toolchain_pb2.ArtifactInfo(
361 artifact_type=artifact_type,
362 artifacts=[artifacts_pb2.Artifact(path=artifact_path)],
363 ),
364 profile_info=profile_info,
365 )
366 )
367 return toolchain_pb2.GetUpdatedFilesRequest(uploaded_artifacts=uploaded)
Tiancong Wangd5214132021-01-12 10:43:57 -0800368
Alex Klein1699fab2022-09-08 08:46:06 -0600369 def testRaisesForUnknown(self):
370 request = self._GetRequest(
371 [
372 (
373 BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE,
374 self.artifact_path,
375 self.profile_info,
376 )
377 ]
378 )
379 self.assertEqual(
380 controller.RETURN_CODE_UNRECOVERABLE,
381 toolchain.GetUpdatedFiles(request, self.response, self.api_config),
382 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800383
Alex Klein1699fab2022-09-08 08:46:06 -0600384 def testValidateOnly(self):
385 """Sanity check that a validate only call does not execute any logic."""
386 request = self._GetRequest(
387 [
388 (
389 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE,
390 self.artifact_path,
391 self.profile_info,
392 )
393 ]
394 )
395 toolchain.GetUpdatedFiles(
396 request, self.response, self.validate_only_config
397 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800398
Alex Klein1699fab2022-09-08 08:46:06 -0600399 def testUpdateSuccess(self):
400 updated_file = "/path/to/updated_file"
401 self.update.return_value = ([updated_file], "Commit Message")
402 request = self._GetRequest(
403 [
404 (
405 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE,
406 self.artifact_path,
407 self.profile_info,
408 )
409 ]
410 )
411 toolchain.GetUpdatedFiles(request, self.response, self.api_config)
412 print(self.response.updated_files)
413 self.assertEqual(len(self.response.updated_files), 1)
414 self.assertEqual(
415 self.response.updated_files[0],
416 toolchain_pb2.GetUpdatedFilesResponse.UpdatedFile(
417 path=updated_file
418 ),
419 )
420 self.assertIn("Commit Message", self.response.commit_message)
421 self.assertEqual(len(self.response.commit_footer), 0)
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000422
423
Alex Klein1699fab2022-09-08 08:46:06 -0600424class GetToolchainsForBoardTest(
425 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
426):
427 """Unittests for GetToolchainsForBoard."""
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000428
Alex Klein1699fab2022-09-08 08:46:06 -0600429 def setUp(self):
430 self.response = toolchain_pb2.ToolchainsResponse()
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000431
Alex Klein1699fab2022-09-08 08:46:06 -0600432 def _GetRequest(self, board="betty-pi-arc"):
433 return toolchain_pb2.ToolchainsRequest(board=board)
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000434
Alex Klein1699fab2022-09-08 08:46:06 -0600435 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700436 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600437 request = self._GetRequest()
438 toolchain.GetToolchainsForBoard(
439 request, self.response, self.validate_only_config
440 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000441
Alex Klein1699fab2022-09-08 08:46:06 -0600442 def testUpdateSuccess(self):
443 toolchain_info = {
444 "default-a": {"default": True},
445 "default-b": {"default": True},
446 "nondefault-a": {"default": False},
447 "nondefault-b": {"default": False},
448 }
449 self.PatchObject(
450 toolchain_lib, "GetToolchainsForBoard", return_value=toolchain_info
451 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000452
Alex Klein1699fab2022-09-08 08:46:06 -0600453 request = self._GetRequest()
454 toolchain.GetToolchainsForBoard(request, self.response, self.api_config)
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000455
Alex Klein1699fab2022-09-08 08:46:06 -0600456 self.assertEqual(
457 self.response.default_toolchains, ["default-a", "default-b"]
458 )
459 self.assertEqual(
460 self.response.nondefault_toolchains,
461 ["nondefault-a", "nondefault-b"],
462 )