blob: 60f091d014b198bb0a469fc592eada43f67f5675 [file] [log] [blame]
Tiancong Wangaf050172019-07-10 11:52:03 -07001# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unittests for Toolchain-related operations."""
7
8from __future__ import print_function
9
Mike Frysingeref94e4c2020-02-10 23:59:54 -050010import sys
11
Alex Klein231d2da2019-07-22 16:44:45 -060012from chromite.api import api_config
LaMont Jones5d2edcb2019-12-23 11:32:03 -070013from chromite.api import controller
Tiancong Wangaf050172019-07-10 11:52:03 -070014from chromite.api.controller import toolchain
LaMont Jones5d2edcb2019-12-23 11:32:03 -070015from chromite.api.gen.chromite.api import artifacts_pb2
LaMont Jones4579e8c2019-12-06 14:20:37 -070016from chromite.api.gen.chromite.api import sysroot_pb2
Tiancong Wangaf050172019-07-10 11:52:03 -070017from chromite.api.gen.chromite.api import toolchain_pb2
LaMont Jonesb20b3d92019-11-23 11:47:48 -070018from chromite.api.gen.chromiumos.builder_config_pb2 import BuilderConfig
LaMont Jones4579e8c2019-12-06 14:20:37 -070019from chromite.api.gen.chromiumos import common_pb2
Tiancong Wangaf050172019-07-10 11:52:03 -070020
Tiancong Wang24a3df72019-08-20 15:48:51 -070021from chromite.lib import cros_build_lib
Tiancong Wangaf050172019-07-10 11:52:03 -070022from chromite.lib import cros_test_lib
Tiancong Wangaf050172019-07-10 11:52:03 -070023from chromite.lib import toolchain_util
24
Mike Frysingeref94e4c2020-02-10 23:59:54 -050025
26assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'
27
28
LaMont Jones5d2edcb2019-12-23 11:32:03 -070029# pylint: disable=protected-access
Tiancong Wangaf050172019-07-10 11:52:03 -070030
Tiancong Wang24a3df72019-08-20 15:48:51 -070031class UpdateEbuildWithAFDOArtifactsTest(cros_test_lib.MockTestCase,
32 api_config.ApiConfigMixin):
33 """Unittests for UpdateEbuildWithAFDOArtifacts."""
34
35 @staticmethod
36 def mock_die(message, *args):
37 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangaf050172019-07-10 11:52:03 -070038
39 def setUp(self):
Tiancong Wangaf050172019-07-10 11:52:03 -070040 self.board = 'board'
Tiancong Wang24a3df72019-08-20 15:48:51 -070041 self.response = toolchain_pb2.VerifyAFDOArtifactsResponse()
42 self.invalid_artifact_type = toolchain_pb2.BENCHMARK_AFDO
43 self.orderfile_command = self.PatchObject(
44 toolchain_util, 'OrderfileUpdateChromeEbuild', return_value=True)
45 self.kernel_command = self.PatchObject(
46 toolchain_util, 'AFDOUpdateKernelEbuild', return_value=True)
Tiancong Wangf9c736c2019-08-26 13:54:38 -070047 self.chrome_command = self.PatchObject(
48 toolchain_util, 'AFDOUpdateChromeEbuild', return_value=True)
Tiancong Wang24a3df72019-08-20 15:48:51 -070049 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
50
51 def _GetRequest(self, build_target=None, artifact_type=None):
52 return toolchain_pb2.VerifyAFDOArtifactsRequest(
53 build_target={'name': build_target},
54 artifact_type=artifact_type,
55 )
Tiancong Wangaf050172019-07-10 11:52:03 -070056
Alex Klein231d2da2019-07-22 16:44:45 -060057 def testValidateOnly(self):
58 """Sanity check that a validate only call does not execute any logic."""
59 patch = self.PatchObject(toolchain_util, 'OrderfileUpdateChromeEbuild')
Tiancong Wang24a3df72019-08-20 15:48:51 -070060 request = self._GetRequest(
61 build_target=self.board, artifact_type=toolchain_pb2.ORDERFILE)
62 toolchain.UpdateEbuildWithAFDOArtifacts(request, self.response,
63 self.validate_only_config)
Alex Klein231d2da2019-07-22 16:44:45 -060064 patch.assert_not_called()
65
Michael Mortensen54bd70a2019-11-21 14:45:38 -070066 def testMockCall(self):
67 """Test that a mock call does not execute logic, returns mock value."""
68 patch = self.PatchObject(toolchain_util, 'OrderfileUpdateChromeEbuild')
69 request = self._GetRequest(
70 build_target=self.board, artifact_type=toolchain_pb2.ORDERFILE)
71 toolchain.UpdateEbuildWithAFDOArtifacts(request, self.response,
72 self.mock_call_config)
73 patch.assert_not_called()
74 self.assertEqual(self.response.status, True)
75
Tiancong Wang24a3df72019-08-20 15:48:51 -070076 def testWrongArtifactType(self):
77 """Test passing wrong artifact type."""
78 request = self._GetRequest(
79 build_target=self.board, artifact_type=self.invalid_artifact_type)
80 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
81 toolchain.UpdateEbuildWithAFDOArtifacts(request, self.response,
82 self.api_config)
83 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
84 str(context.exception))
85
86 def testOrderfileSuccess(self):
87 """Test the command is called correctly with orderfile."""
88 request = self._GetRequest(
89 build_target=self.board, artifact_type=toolchain_pb2.ORDERFILE)
90 toolchain.UpdateEbuildWithAFDOArtifacts(request, self.response,
91 self.api_config)
92 self.orderfile_command.assert_called_once_with(self.board)
93 self.kernel_command.assert_not_called()
Tiancong Wangf9c736c2019-08-26 13:54:38 -070094 self.chrome_command.assert_not_called()
Tiancong Wang24a3df72019-08-20 15:48:51 -070095
96 def testKernelAFDOSuccess(self):
97 """Test the command is called correctly with kernel afdo."""
98 request = self._GetRequest(
99 build_target=self.board, artifact_type=toolchain_pb2.KERNEL_AFDO)
100 toolchain.UpdateEbuildWithAFDOArtifacts(request, self.response,
101 self.api_config)
102 self.kernel_command.assert_called_once_with(self.board)
103 self.orderfile_command.assert_not_called()
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700104 self.chrome_command.assert_not_called()
105
106 def testChromeAFDOSuccess(self):
107 """Test the command is called correctly with Chrome afdo."""
108 request = self._GetRequest(
109 build_target=self.board, artifact_type=toolchain_pb2.CHROME_AFDO)
110 toolchain.UpdateEbuildWithAFDOArtifacts(request, self.response,
111 self.api_config)
112 self.chrome_command.assert_called_once_with(self.board)
113 self.orderfile_command.assert_not_called()
114 self.kernel_command.assert_not_called()
Tiancong Wangaf050172019-07-10 11:52:03 -0700115
116
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700117class UploadVettedFDOArtifactsTest(UpdateEbuildWithAFDOArtifactsTest):
Tiancong Wang24a3df72019-08-20 15:48:51 -0700118 """Unittests for UploadVettedAFDOArtifacts."""
119
120 @staticmethod
121 def mock_die(message, *args):
122 raise cros_build_lib.DieSystemExit(message % args)
Tiancong Wangaf050172019-07-10 11:52:03 -0700123
124 def setUp(self):
Tiancong Wang24a3df72019-08-20 15:48:51 -0700125 self.board = 'board'
126 self.response = toolchain_pb2.VerifyAFDOArtifactsResponse()
127 self.invalid_artifact_type = toolchain_pb2.BENCHMARK_AFDO
128 self.command = self.PatchObject(
Tiancong Wangaf050172019-07-10 11:52:03 -0700129 toolchain_util,
Tiancong Wang24a3df72019-08-20 15:48:51 -0700130 'UploadAndPublishVettedAFDOArtifacts',
131 return_value=True)
132 self.PatchObject(cros_build_lib, 'Die', new=self.mock_die)
Tiancong Wangaf050172019-07-10 11:52:03 -0700133
Alex Klein231d2da2019-07-22 16:44:45 -0600134 def testValidateOnly(self):
135 """Sanity check that a validate only call does not execute any logic."""
Tiancong Wang24a3df72019-08-20 15:48:51 -0700136 request = self._GetRequest(
137 build_target=self.board, artifact_type=toolchain_pb2.ORDERFILE)
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700138 toolchain.UploadVettedAFDOArtifacts(request, self.response,
139 self.validate_only_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -0700140 self.command.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600141
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700142 def testMockCall(self):
143 """Test that a mock call does not execute logic, returns mock value."""
144 request = self._GetRequest(
145 build_target=self.board, artifact_type=toolchain_pb2.ORDERFILE)
146 toolchain.UploadVettedAFDOArtifacts(request, self.response,
147 self.mock_call_config)
148 self.command.assert_not_called()
149 self.assertEqual(self.response.status, True)
150
Tiancong Wang24a3df72019-08-20 15:48:51 -0700151 def testWrongArtifactType(self):
152 """Test passing wrong artifact type."""
153 request = self._GetRequest(
154 build_target=self.board, artifact_type=self.invalid_artifact_type)
155 with self.assertRaises(cros_build_lib.DieSystemExit) as context:
Michael Mortensen54bd70a2019-11-21 14:45:38 -0700156 toolchain.UploadVettedAFDOArtifacts(request, self.response,
157 self.api_config)
Tiancong Wang24a3df72019-08-20 15:48:51 -0700158 self.assertIn('artifact_type (%d) must be in' % self.invalid_artifact_type,
159 str(context.exception))
Alex Klein231d2da2019-07-22 16:44:45 -0600160
Tiancong Wang24a3df72019-08-20 15:48:51 -0700161 def testOrderfileSuccess(self):
162 """Test the command is called correctly with orderfile."""
163 request = self._GetRequest(
164 build_target=self.board, artifact_type=toolchain_pb2.ORDERFILE)
165 toolchain.UploadVettedAFDOArtifacts(request, self.response, self.api_config)
166 self.command.assert_called_once_with('orderfile', self.board)
Tiancong Wangaf050172019-07-10 11:52:03 -0700167
Tiancong Wang24a3df72019-08-20 15:48:51 -0700168 def testKernelAFDOSuccess(self):
169 """Test the command is called correctly with kernel afdo."""
170 request = self._GetRequest(
171 build_target=self.board, artifact_type=toolchain_pb2.KERNEL_AFDO)
172 toolchain.UploadVettedAFDOArtifacts(request, self.response, self.api_config)
173 self.command.assert_called_once_with('kernel_afdo', self.board)
Tiancong Wangf9c736c2019-08-26 13:54:38 -0700174
175 def testChromeAFDOSuccess(self):
176 """Test the command is called correctly with Chrome afdo."""
177 request = self._GetRequest(
178 build_target=self.board, artifact_type=toolchain_pb2.CHROME_AFDO)
179 toolchain.UploadVettedAFDOArtifacts(request, self.response, self.api_config)
180 self.command.assert_called_once_with('chrome_afdo', self.board)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700181
182
LaMont Jones4579e8c2019-12-06 14:20:37 -0700183class PrepareForBuildTest(cros_test_lib.MockTempDirTestCase,
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700184 api_config.ApiConfigMixin):
185 """Unittests for PrepareForBuild."""
186
187 def setUp(self):
188 self.response = toolchain_pb2.PrepareForToolchainBuildResponse()
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700189 self.prep = self.PatchObject(
190 toolchain_util, 'PrepareForBuild',
191 return_value=toolchain_util.PrepareForBuildReturn.NEEDED)
192 self.bundle = self.PatchObject(
193 toolchain_util, 'BundleArtifacts', return_value=[])
194 self.PatchObject(toolchain, '_TOOLCHAIN_ARTIFACT_HANDLERS', {
195 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE:
196 toolchain._Handlers('UnverifiedOrderingFile',
197 self.prep, self.bundle),
198 })
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700199
LaMont Jones45ca6c42020-02-05 09:39:09 -0700200 def _GetRequest(
201 self, artifact_types=None, input_artifacts=None, additional_args=None):
LaMont Jones4579e8c2019-12-06 14:20:37 -0700202 chroot = common_pb2.Chroot(path=self.tempdir)
203 sysroot = sysroot_pb2.Sysroot(
204 path='/build/board', build_target=common_pb2.BuildTarget(name='board'))
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700205 return toolchain_pb2.PrepareForToolchainBuildRequest(
LaMont Jones45ca6c42020-02-05 09:39:09 -0700206 artifact_types=artifact_types, chroot=chroot, sysroot=sysroot,
207 input_artifacts=input_artifacts, additional_args=additional_args)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700208
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700209 def testRaisesForUnknown(self):
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700210 request = self._GetRequest([BuilderConfig.Artifacts.IMAGE_ARCHIVES])
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700211 self.assertRaises(
212 KeyError,
213 toolchain.PrepareForBuild, request, self.response, self.api_config)
214
215 def testAcceptsNone(self):
216 request = toolchain_pb2.PrepareForToolchainBuildRequest(
217 artifact_types=[BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE],
218 chroot=None, sysroot=None)
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700219 toolchain.PrepareForBuild(request, self.response, self.api_config)
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700220 self.prep.assert_called_once_with(
LaMont Jones45ca6c42020-02-05 09:39:09 -0700221 'UnverifiedOrderingFile', None, '', '', {}, {})
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700222
223 def testHandlesUnknownInputArtifacts(self):
224 request = toolchain_pb2.PrepareForToolchainBuildRequest(
225 artifact_types=[BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE],
226 chroot=None, sysroot=None, input_artifacts=[
227 BuilderConfig.Artifacts.InputArtifactInfo(
228 input_artifact_type=BuilderConfig.Artifacts.IMAGE_ZIP,
229 input_artifact_gs_locations=['path1']),
230 ])
231 toolchain.PrepareForBuild(request, self.response, self.api_config)
232 self.prep.assert_called_once_with(
LaMont Jones45ca6c42020-02-05 09:39:09 -0700233 'UnverifiedOrderingFile', None, '', '', {}, {})
234
235 def testPassesAdditionalArgs(self):
236 request = toolchain_pb2.PrepareForToolchainBuildRequest(
237 artifact_types=[BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE],
238 chroot=None, sysroot=None, input_artifacts=[
239 BuilderConfig.Artifacts.InputArtifactInfo(
240 input_artifact_type=\
241 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE,
242 input_artifact_gs_locations=['path1', 'path2']),
243 BuilderConfig.Artifacts.InputArtifactInfo(
244 input_artifact_type=\
245 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE,
246 input_artifact_gs_locations=['path3']),
247 ],
248 additional_args=common_pb2.PrepareForBuildAdditionalArgs(
249 chrome_cwp_profile='CWPVERSION'),
250 )
251 toolchain.PrepareForBuild(request, self.response, self.api_config)
252 self.prep.assert_called_once_with(
253 'UnverifiedOrderingFile', None, '', '', {
254 'UnverifiedOrderingFile': [
255 'gs://path1', 'gs://path2', 'gs://path3']},
256 {'chrome_cwp_profile': 'CWPVERSION'})
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700257
258 def testHandlesDuplicateInputArtifacts(self):
259 request = toolchain_pb2.PrepareForToolchainBuildRequest(
260 artifact_types=[BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE],
261 chroot=None, sysroot=None, input_artifacts=[
262 BuilderConfig.Artifacts.InputArtifactInfo(
263 input_artifact_type=\
264 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE,
265 input_artifact_gs_locations=['path1', 'path2']),
266 BuilderConfig.Artifacts.InputArtifactInfo(
267 input_artifact_type=\
268 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE,
269 input_artifact_gs_locations=['path3']),
270 ])
271 toolchain.PrepareForBuild(request, self.response, self.api_config)
272 self.prep.assert_called_once_with(
273 'UnverifiedOrderingFile', None, '', '', {
274 'UnverifiedOrderingFile': [
LaMont Jones45ca6c42020-02-05 09:39:09 -0700275 'gs://path1', 'gs://path2', 'gs://path3']}, {})
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700276
277
278class BundleToolchainTest(cros_test_lib.MockTempDirTestCase,
279 api_config.ApiConfigMixin):
280 """Unittests for BundleToolchain."""
281
282 def setUp(self):
283 self.response = toolchain_pb2.BundleToolchainResponse()
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700284 self.prep = self.PatchObject(
285 toolchain_util, 'PrepareForBuild',
286 return_value=toolchain_util.PrepareForBuildReturn.NEEDED)
287 self.bundle = self.PatchObject(
288 toolchain_util, 'BundleArtifacts', return_value=[])
289 self.PatchObject(toolchain, '_TOOLCHAIN_ARTIFACT_HANDLERS', {
290 BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE:
291 toolchain._Handlers('UnverifiedOrderingFile',
292 self.prep, self.bundle),
293 })
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700294
295 def _GetRequest(self, artifact_types=None):
LaMont Jones4579e8c2019-12-06 14:20:37 -0700296 chroot = common_pb2.Chroot(path=self.tempdir)
297 sysroot = sysroot_pb2.Sysroot(
298 path='/build/board', build_target=common_pb2.BuildTarget(name='board'))
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700299 return toolchain_pb2.BundleToolchainRequest(
LaMont Jones4579e8c2019-12-06 14:20:37 -0700300 chroot=chroot, sysroot=sysroot,
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700301 output_dir=self.tempdir,
LaMont Jones4579e8c2019-12-06 14:20:37 -0700302 artifact_types=artifact_types,
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700303 )
304
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700305 def testRaisesForUnknown(self):
LaMont Jonesb20b3d92019-11-23 11:47:48 -0700306 request = self._GetRequest([BuilderConfig.Artifacts.IMAGE_ARCHIVES])
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700307 self.assertEqual(
308 controller.RETURN_CODE_UNRECOVERABLE,
309 toolchain.BundleArtifacts(request, self.response, self.api_config))
Michael Mortensen3232ab32020-01-05 19:14:36 -0700310
311 def testValidateOnly(self):
312 """Sanity check that a validate only call does not execute any logic."""
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700313 request = self._GetRequest(
314 [BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE])
Michael Mortensen3232ab32020-01-05 19:14:36 -0700315 toolchain.BundleArtifacts(request, self.response,
316 self.validate_only_config)
LaMont Jones5d2edcb2019-12-23 11:32:03 -0700317 self.bundle.assert_not_called()
318
319 def testSetsArtifactsInfo(self):
320 request = self._GetRequest(
321 [BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE])
322 self.bundle.return_value = ['artifact.xz']
323 toolchain.BundleArtifacts(request, self.response, self.api_config)
324 self.assertEqual(1, len(self.response.artifacts_info))
325 self.assertEqual(
326 self.response.artifacts_info[0],
327 toolchain_pb2.ArtifactInfo(
328 artifact_type=BuilderConfig.Artifacts.UNVERIFIED_ORDERING_FILE,
329 artifacts=[
330 artifacts_pb2.Artifact(path=self.bundle.return_value[0])]))