blob: 17dc6779f1796983c28b223a41b8293b8fc8e7d2 [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(
153 chrome_cwp_profile="CWPVERSION"
154 ),
155 )
Alex Kleinab87ceb2023-01-24 12:00:51 -0700156 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600157 toolchain.PrepareForBuild(request, self.response, self.api_config)
158 self.prep.assert_called_once_with(
159 "UnverifiedChromeLlvmOrderfile",
160 None,
161 "",
162 "",
163 {
164 "UnverifiedChromeLlvmOrderfile": [
165 "gs://path1",
166 "gs://path2",
167 "gs://path3",
168 ],
169 },
170 {"chrome_cwp_profile": "CWPVERSION"},
171 )
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700172
Alex Klein1699fab2022-09-08 08:46:06 -0600173 def testPassesProfileInfoAfdoRelease(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700174 # pylint: disable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600175 request = toolchain_pb2.PrepareForToolchainBuildRequest(
176 artifact_types=[
177 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
178 ],
179 chroot=None,
180 sysroot=None,
181 input_artifacts=[
182 BuilderConfig.Artifacts.InputArtifactInfo(
183 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
184 input_artifact_gs_locations=["path1", "path2"],
185 ),
186 BuilderConfig.Artifacts.InputArtifactInfo(
187 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
188 input_artifact_gs_locations=["path3"],
189 ),
190 ],
191 profile_info=common_pb2.ArtifactProfileInfo(
192 afdo_release=common_pb2.AfdoRelease(
193 chrome_cwp_profile="CWPVERSION", image_build_id=1234
194 )
195 ),
196 )
Alex Kleinab87ceb2023-01-24 12:00:51 -0700197 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600198 toolchain.PrepareForBuild(request, self.response, self.api_config)
199 self.prep.assert_called_once_with(
200 "UnverifiedChromeLlvmOrderfile",
201 None,
202 "",
203 "",
204 {
205 "UnverifiedChromeLlvmOrderfile": [
206 "gs://path1",
207 "gs://path2",
208 "gs://path3",
209 ],
210 },
211 {"chrome_cwp_profile": "CWPVERSION", "image_build_id": 1234},
212 )
LaMont Jonese7821672020-04-09 08:56:26 -0600213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 def testHandlesDuplicateInputArtifacts(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700215 # pylint: disable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600216 request = toolchain_pb2.PrepareForToolchainBuildRequest(
217 artifact_types=[
218 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
219 ],
220 chroot=None,
221 sysroot=None,
222 input_artifacts=[
223 BuilderConfig.Artifacts.InputArtifactInfo(
224 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
225 input_artifact_gs_locations=["path1", "path2"],
226 ),
227 BuilderConfig.Artifacts.InputArtifactInfo(
228 input_artifact_type=BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE,
229 input_artifact_gs_locations=["path3"],
230 ),
231 ],
232 )
Alex Kleinab87ceb2023-01-24 12:00:51 -0700233 # pylint: enable=line-too-long
Alex Klein1699fab2022-09-08 08:46:06 -0600234 toolchain.PrepareForBuild(request, self.response, self.api_config)
235 self.prep.assert_called_once_with(
236 "UnverifiedChromeLlvmOrderfile",
237 None,
238 "",
239 "",
240 {
241 "UnverifiedChromeLlvmOrderfile": [
242 "gs://path1",
243 "gs://path2",
244 "gs://path3",
245 ],
246 },
247 {},
248 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700249
250
Alex Klein1699fab2022-09-08 08:46:06 -0600251class BundleToolchainTest(
252 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
253):
254 """Unittests for BundleToolchain."""
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 def setUp(self):
257 self.response = toolchain_pb2.BundleToolchainResponse()
258 self.prep = self.PatchObject(
259 toolchain_util,
260 "PrepareForBuild",
261 return_value=toolchain_util.PrepareForBuildReturn.NEEDED,
262 )
263 self.bundle = self.PatchObject(
264 toolchain_util, "BundleArtifacts", return_value=[]
265 )
266 self.PatchObject(
267 toolchain,
268 "_TOOLCHAIN_ARTIFACT_HANDLERS",
269 {
Alex Kleinab87ceb2023-01-24 12:00:51 -0700270 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE: (
271 toolchain._Handlers(
272 "UnverifiedChromeLlvmOrderfile", self.prep, self.bundle
273 )
Alex Klein1699fab2022-09-08 08:46:06 -0600274 ),
275 },
276 )
277 osutils.WriteFile(os.path.join(self.tempdir, "artifact.txt"), "test")
278 osutils.Touch(os.path.join(self.tempdir, "empty"))
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700279
Alex Klein1699fab2022-09-08 08:46:06 -0600280 def _GetRequest(self, artifact_types=None):
281 chroot = common_pb2.Chroot(path=str(self.tempdir))
282 sysroot = sysroot_pb2.Sysroot(
283 path="/build/board",
284 build_target=common_pb2.BuildTarget(name="board"),
285 )
286 return toolchain_pb2.BundleToolchainRequest(
287 chroot=chroot,
288 sysroot=sysroot,
289 output_dir=str(self.tempdir),
290 artifact_types=artifact_types,
291 )
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700292
Alex Klein1699fab2022-09-08 08:46:06 -0600293 def testRaisesForUnknown(self):
294 request = self._GetRequest([BuilderConfig.Artifacts.IMAGE_ARCHIVES])
295 self.assertEqual(
296 controller.RETURN_CODE_UNRECOVERABLE,
297 toolchain.BundleArtifacts(request, self.response, self.api_config),
298 )
Michael Mortensen3232ab32020-01-05 19:14:36 -0700299
Alex Klein1699fab2022-09-08 08:46:06 -0600300 def testValidateOnly(self):
301 """Sanity check that a validate only call does not execute any logic."""
302 request = self._GetRequest(
303 [BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE]
304 )
305 toolchain.BundleArtifacts(
306 request, self.response, self.validate_only_config
307 )
308 self.bundle.assert_not_called()
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700309
Alex Klein1699fab2022-09-08 08:46:06 -0600310 def testSetsArtifactsInfo(self):
311 request = self._GetRequest(
312 [BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE]
313 )
314 self.bundle.return_value = ["artifact.txt", "empty", "does_not_exist"]
315 toolchain.BundleArtifacts(request, self.response, self.api_config)
316 self.assertEqual(1, len(self.response.artifacts_info))
317 self.assertEqual(
318 self.response.artifacts_info[0],
319 toolchain_pb2.ArtifactInfo(
320 artifact_type=(
321 BuilderConfig.Artifacts.UNVERIFIED_CHROME_LLVM_ORDERFILE
322 ),
323 artifacts=[
324 artifacts_pb2.Artifact(path=self.bundle.return_value[0])
325 ],
326 ),
327 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800328
329
Alex Klein1699fab2022-09-08 08:46:06 -0600330class GetUpdatedFilesTest(
331 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
332):
333 """Unittests for GetUpdatedFiles."""
Tiancong Wangd5214132021-01-12 10:43:57 -0800334
Alex Klein1699fab2022-09-08 08:46:06 -0600335 def setUp(self):
336 self.response = toolchain_pb2.GetUpdatedFilesResponse()
337 self.artifact_path = "/any/path/to/metadata"
338 self.profile_info = common_pb2.ArtifactProfileInfo(kernel_version="4.4")
339 self.update = self.PatchObject(
340 toolchain_util, "GetUpdatedFiles", return_value=([], "")
341 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800342
Alex Klein1699fab2022-09-08 08:46:06 -0600343 def _GetRequest(self, uploaded_artifacts):
344 uploaded = []
345 for artifact_type, artifact_path, profile_info in uploaded_artifacts:
346 uploaded.append(
347 toolchain_pb2.GetUpdatedFilesRequest.UploadedArtifacts(
348 artifact_info=toolchain_pb2.ArtifactInfo(
349 artifact_type=artifact_type,
350 artifacts=[artifacts_pb2.Artifact(path=artifact_path)],
351 ),
352 profile_info=profile_info,
353 )
354 )
355 return toolchain_pb2.GetUpdatedFilesRequest(uploaded_artifacts=uploaded)
Tiancong Wangd5214132021-01-12 10:43:57 -0800356
Alex Klein1699fab2022-09-08 08:46:06 -0600357 def testRaisesForUnknown(self):
358 request = self._GetRequest(
359 [
360 (
361 BuilderConfig.Artifacts.UNVERIFIED_KERNEL_CWP_AFDO_FILE,
362 self.artifact_path,
363 self.profile_info,
364 )
365 ]
366 )
367 self.assertEqual(
368 controller.RETURN_CODE_UNRECOVERABLE,
369 toolchain.GetUpdatedFiles(request, self.response, self.api_config),
370 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800371
Alex Klein1699fab2022-09-08 08:46:06 -0600372 def testValidateOnly(self):
373 """Sanity check that a validate only call does not execute any logic."""
374 request = self._GetRequest(
375 [
376 (
377 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE,
378 self.artifact_path,
379 self.profile_info,
380 )
381 ]
382 )
383 toolchain.GetUpdatedFiles(
384 request, self.response, self.validate_only_config
385 )
Tiancong Wangd5214132021-01-12 10:43:57 -0800386
Alex Klein1699fab2022-09-08 08:46:06 -0600387 def testUpdateSuccess(self):
388 updated_file = "/path/to/updated_file"
389 self.update.return_value = ([updated_file], "Commit Message")
390 request = self._GetRequest(
391 [
392 (
393 BuilderConfig.Artifacts.VERIFIED_KERNEL_CWP_AFDO_FILE,
394 self.artifact_path,
395 self.profile_info,
396 )
397 ]
398 )
399 toolchain.GetUpdatedFiles(request, self.response, self.api_config)
400 print(self.response.updated_files)
401 self.assertEqual(len(self.response.updated_files), 1)
402 self.assertEqual(
403 self.response.updated_files[0],
404 toolchain_pb2.GetUpdatedFilesResponse.UpdatedFile(
405 path=updated_file
406 ),
407 )
408 self.assertIn("Commit Message", self.response.commit_message)
409 self.assertEqual(len(self.response.commit_footer), 0)
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000410
411
Alex Klein1699fab2022-09-08 08:46:06 -0600412class GetToolchainsForBoardTest(
413 cros_test_lib.MockTempDirTestCase, api_config.ApiConfigMixin
414):
415 """Unittests for GetToolchainsForBoard."""
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000416
Alex Klein1699fab2022-09-08 08:46:06 -0600417 def setUp(self):
418 self.response = toolchain_pb2.ToolchainsResponse()
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000419
Alex Klein1699fab2022-09-08 08:46:06 -0600420 def _GetRequest(self, board="betty-pi-arc"):
421 return toolchain_pb2.ToolchainsRequest(board=board)
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000422
Alex Klein1699fab2022-09-08 08:46:06 -0600423 def testValidateOnly(self):
Alex Kleinab87ceb2023-01-24 12:00:51 -0700424 """Verify a validate-only call does not execute any logic."""
Alex Klein1699fab2022-09-08 08:46:06 -0600425 request = self._GetRequest()
426 toolchain.GetToolchainsForBoard(
427 request, self.response, self.validate_only_config
428 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000429
Alex Klein1699fab2022-09-08 08:46:06 -0600430 def testUpdateSuccess(self):
431 toolchain_info = {
432 "default-a": {"default": True},
433 "default-b": {"default": True},
434 "nondefault-a": {"default": False},
435 "nondefault-b": {"default": False},
436 }
437 self.PatchObject(
438 toolchain_lib, "GetToolchainsForBoard", return_value=toolchain_info
439 )
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000440
Alex Klein1699fab2022-09-08 08:46:06 -0600441 request = self._GetRequest()
442 toolchain.GetToolchainsForBoard(request, self.response, self.api_config)
Jack Neus4ee7b1d2022-06-27 19:54:18 +0000443
Alex Klein1699fab2022-09-08 08:46:06 -0600444 self.assertEqual(
445 self.response.default_toolchains, ["default-a", "default-b"]
446 )
447 self.assertEqual(
448 self.response.nondefault_toolchains,
449 ["nondefault-a", "nondefault-b"],
450 )