blob: 2598130643d689383bbedfd5f3e92af4f6e1e450 [file] [log] [blame]
Alex Kleinda35fcf2019-03-07 16:01:15 -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"""Sysroot controller tests."""
7
8from __future__ import print_function
9
10import os
11
12from chromite.api.controller import sysroot as sysroot_controller
13from chromite.api.gen.chromite.api import sysroot_pb2
14from chromite.lib import build_target_util
15from chromite.lib import cros_build_lib
16from chromite.lib import cros_test_lib
17from chromite.lib import osutils
18from chromite.lib import portage_util
19from chromite.lib import sysroot_lib
20from chromite.service import sysroot as sysroot_service
21
22
23class CreateTest(cros_test_lib.MockTestCase):
24 """Create function tests."""
25
26 def _InputProto(self, build_target=None, profile=None, replace=False,
27 current=False):
28 """Helper to build and input proto instance."""
29 proto = sysroot_pb2.SysrootCreateRequest()
30 if build_target:
31 proto.build_target.name = build_target
32 if profile:
33 proto.profile.name = profile
34 if replace:
35 proto.flags.replace = replace
36 if current:
37 proto.flags.chroot_current = current
38
39 return proto
40
41 def _OutputProto(self):
42 """Helper to build output proto instance."""
43 return sysroot_pb2.SysrootCreateResponse()
44
45 def testArgumentValidation(self):
46 """Test the input argument validation."""
47 # Error when no name provided.
48 in_proto = self._InputProto()
49 out_proto = self._OutputProto()
50 with self.assertRaises(cros_build_lib.DieSystemExit):
51 sysroot_controller.Create(in_proto, out_proto)
52
53 # Valid when board passed.
54 result = sysroot_lib.Sysroot('/sysroot/path')
55 patch = self.PatchObject(sysroot_service, 'Create', return_value=result)
56 in_proto = self._InputProto('board')
57 out_proto = self._OutputProto()
58 sysroot_controller.Create(in_proto, out_proto)
59 patch.assert_called_once()
60
61 def testArgumentHandling(self):
62 """Test the arguments get processed and passed correctly."""
63 sysroot_path = '/sysroot/path'
64
65 sysroot = sysroot_lib.Sysroot(sysroot_path)
66 create_patch = self.PatchObject(sysroot_service, 'Create',
67 return_value=sysroot)
68 target_patch = self.PatchObject(build_target_util, 'BuildTarget')
69 rc_patch = self.PatchObject(sysroot_service, 'SetupBoardRunConfig')
70
71 # Default values.
72 board = 'board'
73 profile = None
74 force = False
75 upgrade_chroot = True
76 in_proto = self._InputProto(build_target=board, profile=profile,
77 replace=force, current=not upgrade_chroot)
78 out_proto = self._OutputProto()
79 sysroot_controller.Create(in_proto, out_proto)
80
81 # Default value checks.
82 target_patch.assert_called_with(name=board, profile=profile)
83 rc_patch.assert_called_with(force=force, upgrade_chroot=upgrade_chroot)
84 self.assertEqual(board, out_proto.sysroot.build_target.name)
85 self.assertEqual(sysroot_path, out_proto.sysroot.path)
86
87 # Not default values.
88 create_patch.reset_mock()
89 board = 'board'
90 profile = 'profile'
91 force = True
92 upgrade_chroot = False
93 in_proto = self._InputProto(build_target=board, profile=profile,
94 replace=force, current=not upgrade_chroot)
95 out_proto = self._OutputProto()
96 sysroot_controller.Create(in_proto, out_proto)
97
98 # Not default value checks.
99 target_patch.assert_called_with(name=board, profile=profile)
100 rc_patch.assert_called_with(force=force, upgrade_chroot=upgrade_chroot)
101 self.assertEqual(board, out_proto.sysroot.build_target.name)
102 self.assertEqual(sysroot_path, out_proto.sysroot.path)
103
104
105class InstallToolchainTest(cros_test_lib.MockTempDirTestCase):
106 """Install toolchain function tests."""
107
108 def setUp(self):
109 self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True)
110 self.board = 'board'
111 self.sysroot = os.path.join(self.tempdir, 'board')
112 self.invalid_sysroot = os.path.join(self.tempdir, 'invalid', 'sysroot')
113 osutils.SafeMakedirs(self.sysroot)
114
115 def _InputProto(self, build_target=None, sysroot_path=None,
116 compile_source=False):
Alex Kleind4e1e422019-03-18 16:00:41 -0600117 """Helper to build an input proto instance."""
Alex Kleinda35fcf2019-03-07 16:01:15 -0700118 proto = sysroot_pb2.InstallToolchainRequest()
119 if build_target:
120 proto.sysroot.build_target.name = build_target
121 if sysroot_path:
122 proto.sysroot.path = sysroot_path
123 if compile_source:
124 proto.flags.compile_source = compile_source
125
126 return proto
127
128 def _OutputProto(self):
129 """Helper to build output proto instance."""
130 return sysroot_pb2.InstallToolchainResponse()
131
132 def testArgumentValidation(self):
133 """Test the argument validation."""
134 # Test errors on missing inputs.
135 out_proto = self._OutputProto()
136 # Both missing.
137 in_proto = self._InputProto()
138 with self.assertRaises(cros_build_lib.DieSystemExit):
139 sysroot_controller.InstallToolchain(in_proto, out_proto)
140
141 # Sysroot path missing.
142 in_proto = self._InputProto(build_target=self.board)
143 with self.assertRaises(cros_build_lib.DieSystemExit):
144 sysroot_controller.InstallToolchain(in_proto, out_proto)
145
146 # Build target name missing.
147 in_proto = self._InputProto(sysroot_path=self.sysroot)
148 with self.assertRaises(cros_build_lib.DieSystemExit):
149 sysroot_controller.InstallToolchain(in_proto, out_proto)
150
151 # Both provided, but invalid sysroot path.
152 in_proto = self._InputProto(build_target=self.board,
153 sysroot_path=self.invalid_sysroot)
154 with self.assertRaises(cros_build_lib.DieSystemExit):
155 sysroot_controller.InstallToolchain(in_proto, out_proto)
156
157 def testSuccessOutputHandling(self):
158 """Test the output is processed and recorded correctly."""
159 self.PatchObject(sysroot_service, 'InstallToolchain')
160 out_proto = self._OutputProto()
161 in_proto = self._InputProto(build_target=self.board,
162 sysroot_path=self.sysroot)
163
164 rc = sysroot_controller.InstallToolchain(in_proto, out_proto)
165 self.assertFalse(rc)
166 self.assertFalse(out_proto.failed_packages)
167
168
169 def testErrorOutputHandling(self):
170 """Test the error output is processed and recorded correctly."""
171 out_proto = self._OutputProto()
172 in_proto = self._InputProto(build_target=self.board,
173 sysroot_path=self.sysroot)
174
175 err_pkgs = ['cat/pkg', 'cat2/pkg2']
176 err_cpvs = [portage_util.SplitCPV(pkg, strict=False) for pkg in err_pkgs]
177 expected = [('cat', 'pkg'), ('cat2', 'pkg2')]
178 err = sysroot_lib.ToolchainInstallError('Error',
179 cros_build_lib.CommandResult(),
180 tc_info=err_cpvs)
181 self.PatchObject(sysroot_service, 'InstallToolchain', side_effect=err)
182
183 rc = sysroot_controller.InstallToolchain(in_proto, out_proto)
184 self.assertTrue(rc)
185 self.assertTrue(out_proto.failed_packages)
186 for package in out_proto.failed_packages:
187 cat_pkg = (package.category, package.package_name)
188 self.assertIn(cat_pkg, expected)
Alex Kleind4e1e422019-03-18 16:00:41 -0600189
190
191class InstallPackagesTest(cros_test_lib.MockTempDirTestCase):
192 """InstallPackages tests."""
193
194 def setUp(self):
195 self.PatchObject(cros_build_lib, 'IsInsideChroot', return_value=True)
196 self.build_target = 'board'
197 self.sysroot = os.path.join(self.tempdir, 'build', 'board')
198 osutils.SafeMakedirs(self.sysroot)
199
200 def _InputProto(self, build_target=None, sysroot_path=None,
201 build_source=False):
202 """Helper to build an input proto instance."""
203 instance = sysroot_pb2.InstallPackagesRequest()
204
205 if build_target:
206 instance.sysroot.build_target.name = build_target
207 if sysroot_path:
208 instance.sysroot.path = sysroot_path
209 if build_source:
210 instance.flags.build_source = build_source
211
212 return instance
213
214 def _OutputProto(self):
215 """Helper to build an empty output proto instance."""
216 return sysroot_pb2.InstallPackagesResponse()
217
218 def testArgumentValidationAllMissing(self):
219 """Test missing all arguments."""
220 out_proto = self._OutputProto()
221 in_proto = self._InputProto()
222 with self.assertRaises(cros_build_lib.DieSystemExit):
223 sysroot_controller.InstallPackages(in_proto, out_proto)
224
225 def testArgumentValidationNoSysroot(self):
226 """Test missing sysroot path."""
227 out_proto = self._OutputProto()
228 in_proto = self._InputProto(build_target=self.build_target)
229 with self.assertRaises(cros_build_lib.DieSystemExit):
230 sysroot_controller.InstallPackages(in_proto, out_proto)
231
232 def testArgumentValidationNoBuildTarget(self):
233 """Test missing build target name."""
234 out_proto = self._OutputProto()
235 in_proto = self._InputProto(sysroot_path=self.sysroot)
236 with self.assertRaises(cros_build_lib.DieSystemExit):
237 sysroot_controller.InstallPackages(in_proto, out_proto)
238
239 def testArgumentValidationInvalidSysroot(self):
240 """Test sysroot that hasn't had the toolchain installed."""
241 out_proto = self._OutputProto()
242 in_proto = self._InputProto(build_target=self.build_target,
243 sysroot_path=self.sysroot)
244 self.PatchObject(sysroot_lib.Sysroot, 'IsToolchainInstalled',
245 return_value=False)
246 with self.assertRaises(cros_build_lib.DieSystemExit):
247 sysroot_controller.InstallPackages(in_proto, out_proto)
248
249 def testSuccessOutputHandling(self):
250 """Test successful call output handling."""
251 # Prevent argument validation error.
252 self.PatchObject(sysroot_lib.Sysroot, 'IsToolchainInstalled',
253 return_value=True)
254
255 in_proto = self._InputProto(build_target=self.build_target,
256 sysroot_path=self.sysroot)
257 out_proto = self._OutputProto()
258 self.PatchObject(sysroot_service, 'BuildPackages')
259
260 rc = sysroot_controller.InstallPackages(in_proto, out_proto)
261 self.assertFalse(rc)
262 self.assertFalse(out_proto.failed_packages)
263
264 def testFailureOutputHandling(self):
265 """Test failed package handling."""
266 # Prevent argument validation error.
267 self.PatchObject(sysroot_lib.Sysroot, 'IsToolchainInstalled',
268 return_value=True)
269
270 in_proto = self._InputProto(build_target=self.build_target,
271 sysroot_path=self.sysroot)
272 out_proto = self._OutputProto()
273
274 # Failed package info and expected list for verification.
275 err_pkgs = ['cat/pkg', 'cat2/pkg2']
276 err_cpvs = [portage_util.SplitCPV(cpv, strict=False) for cpv in err_pkgs]
277 expected = [('cat', 'pkg'), ('cat2', 'pkg2')]
278
279 # Force error to be raised with the packages.
280 error = sysroot_lib.PackageInstallError('Error',
281 cros_build_lib.CommandResult(),
282 packages=err_cpvs)
283 self.PatchObject(sysroot_service, 'BuildPackages', side_effect=error)
284
285 rc = sysroot_controller.InstallPackages(in_proto, out_proto)
286 self.assertTrue(rc)
287 for package in out_proto.failed_packages:
288 cat_pkg = (package.category, package.package_name)
289 self.assertIn(cat_pkg, expected)