blob: b7d3c323101f901ac9ba09773b0e5cff315f8170 [file] [log] [blame]
David Pursell9476bf42015-03-30 13:34:27 -07001# Copyright 2015 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""Unit tests for the deploy module."""
6
David Pursell9476bf42015-03-30 13:34:27 -07007import json
Ralph Nathane01ccf12015-04-16 10:40:32 -07008import multiprocessing
David Pursell9476bf42015-03-30 13:34:27 -07009import os
Mike Frysinger050fa5a2019-12-01 16:16:29 -050010import sys
Mike Frysinger166fea02021-02-12 05:30:33 -050011from unittest import mock
David Pursell9476bf42015-03-30 13:34:27 -070012
Ralph Nathane01ccf12015-04-16 10:40:32 -070013from chromite.cli import command
David Pursell9476bf42015-03-30 13:34:27 -070014from chromite.cli import deploy
Mike Frysinger06a51c82021-04-06 11:39:17 -040015from chromite.lib import build_target_lib
David Pursell9476bf42015-03-30 13:34:27 -070016from chromite.lib import cros_build_lib
17from chromite.lib import cros_test_lib
Brian Norris2eee8892021-04-06 16:23:23 -070018from chromite.lib import osutils
Ralph Nathane01ccf12015-04-16 10:40:32 -070019from chromite.lib import remote_access
Brian Norris2eee8892021-04-06 16:23:23 -070020from chromite.lib import sysroot_lib
Sloan Johnsona85640f2021-10-01 22:32:40 +000021from chromite.lib import unittest_lib
Alex Klein18a60af2020-06-11 12:08:47 -060022from chromite.lib.parser import package_info
Mike Frysinger40ffb532021-02-12 07:36:08 -050023
Greg Edelstona4c9b3b2020-01-07 17:51:13 -070024
Chris McDonald186b9ee2020-04-16 05:56:49 -060025pytestmark = [cros_test_lib.pytestmark_inside_only]
Greg Edelstona4c9b3b2020-01-07 17:51:13 -070026
27
28if cros_build_lib.IsInsideChroot():
Alex Klein1699fab2022-09-08 08:46:06 -060029 import portage # pylint: disable=import-error
David Pursell9476bf42015-03-30 13:34:27 -070030
31
32# pylint: disable=protected-access
33
34
Ralph Nathane01ccf12015-04-16 10:40:32 -070035class ChromiumOSDeviceFake(object):
Alex Klein1699fab2022-09-08 08:46:06 -060036 """Fake for device."""
Ralph Nathane01ccf12015-04-16 10:40:32 -070037
Alex Klein1699fab2022-09-08 08:46:06 -060038 def __init__(self):
39 self.board = "board"
40 self.hostname = None
41 self.username = None
42 self.port = None
43 self.lsb_release = None
44 self.cmds = []
45 self.work_dir = "/testdir/"
46 self.selinux_available = False
Ralph Nathane01ccf12015-04-16 10:40:32 -070047
Alex Klein1699fab2022-09-08 08:46:06 -060048 def MountRootfsReadWrite(self):
49 return True
Ralph Nathane01ccf12015-04-16 10:40:32 -070050
Alex Klein1699fab2022-09-08 08:46:06 -060051 def IsSELinuxAvailable(self):
52 return self.selinux_available
Ben Pastene5f03b052019-08-12 18:03:24 -070053
Alex Klein1699fab2022-09-08 08:46:06 -060054 def IsSELinuxEnforced(self):
55 return True
Ben Pastene5f03b052019-08-12 18:03:24 -070056
Alex Klein1699fab2022-09-08 08:46:06 -060057 def run(self, cmd, **_kwargs):
58 self.cmds.append(cmd)
Andrewc7e1c6b2020-02-27 16:03:53 -080059
Alex Klein1699fab2022-09-08 08:46:06 -060060 def CopyToDevice(self, _src, _dest, _mode="rsync", **_kwargs):
61 return True
Andrewc7e1c6b2020-02-27 16:03:53 -080062
Ralph Nathane01ccf12015-04-16 10:40:32 -070063
David Pursell9476bf42015-03-30 13:34:27 -070064class ChromiumOSDeviceHandlerFake(object):
Alex Klein1699fab2022-09-08 08:46:06 -060065 """Fake for chromite.lib.remote_access.ChomiumOSDeviceHandler."""
David Pursell9476bf42015-03-30 13:34:27 -070066
Alex Klein1699fab2022-09-08 08:46:06 -060067 class RemoteAccessFake(object):
68 """Fake for chromite.lib.remote_access.RemoteAccess."""
David Pursell9476bf42015-03-30 13:34:27 -070069
Alex Klein1699fab2022-09-08 08:46:06 -060070 def __init__(self):
71 self.remote_sh_output = None
David Pursell9476bf42015-03-30 13:34:27 -070072
Alex Klein1699fab2022-09-08 08:46:06 -060073 def RemoteSh(self, *_args, **_kwargs):
74 return cros_build_lib.CompletedProcess(stdout=self.remote_sh_output)
David Pursell9476bf42015-03-30 13:34:27 -070075
Alex Klein1699fab2022-09-08 08:46:06 -060076 def __init__(self, *_args, **_kwargs):
77 self._agent = self.RemoteAccessFake()
78 self.device = ChromiumOSDeviceFake()
David Pursell67a82762015-04-30 17:26:59 -070079
Alex Klein1699fab2022-09-08 08:46:06 -060080 # TODO(dpursell): Mock remote access object in cros_test_lib (brbug.com/986).
81 def GetAgent(self):
82 return self._agent
David Pursell9476bf42015-03-30 13:34:27 -070083
Alex Klein1699fab2022-09-08 08:46:06 -060084 def __exit__(self, _type, _value, _traceback):
85 pass
Ralph Nathane01ccf12015-04-16 10:40:32 -070086
Alex Klein1699fab2022-09-08 08:46:06 -060087 def __enter__(self):
88 return self.device
Ralph Nathane01ccf12015-04-16 10:40:32 -070089
90
91class BrilloDeployOperationFake(deploy.BrilloDeployOperation):
Alex Klein1699fab2022-09-08 08:46:06 -060092 """Fake for deploy.BrilloDeployOperation."""
Ralph Nathane01ccf12015-04-16 10:40:32 -070093
Alex Klein1699fab2022-09-08 08:46:06 -060094 def __init__(self, emerge, queue):
95 super().__init__(emerge)
96 self._queue = queue
97
98 def ParseOutput(self, output=None):
99 super().ParseOutput(output)
100 self._queue.put("advance")
Ralph Nathane01ccf12015-04-16 10:40:32 -0700101
David Pursell9476bf42015-03-30 13:34:27 -0700102
103class DbApiFake(object):
Alex Klein1699fab2022-09-08 08:46:06 -0600104 """Fake for Portage dbapi."""
David Pursell9476bf42015-03-30 13:34:27 -0700105
Alex Klein1699fab2022-09-08 08:46:06 -0600106 def __init__(self, pkgs):
107 self.pkg_db = {}
108 for cpv, slot, rdeps_raw, build_time in pkgs:
109 self.pkg_db[cpv] = {
110 "SLOT": slot,
111 "RDEPEND": rdeps_raw,
112 "BUILD_TIME": build_time,
113 }
David Pursell9476bf42015-03-30 13:34:27 -0700114
Alex Klein1699fab2022-09-08 08:46:06 -0600115 def cpv_all(self):
116 return list(self.pkg_db)
David Pursell9476bf42015-03-30 13:34:27 -0700117
Alex Klein1699fab2022-09-08 08:46:06 -0600118 def aux_get(self, cpv, keys):
119 pkg_info = self.pkg_db[cpv]
120 return [pkg_info[key] for key in keys]
David Pursell9476bf42015-03-30 13:34:27 -0700121
122
Ralph Nathane01ccf12015-04-16 10:40:32 -0700123class PackageScannerFake(object):
Alex Klein1699fab2022-09-08 08:46:06 -0600124 """Fake for PackageScanner."""
Ralph Nathane01ccf12015-04-16 10:40:32 -0700125
Alex Klein1699fab2022-09-08 08:46:06 -0600126 def __init__(self, packages, pkgs_attrs, packages_cpvs=None):
127 self.pkgs = packages
128 self.cpvs = packages_cpvs or packages
129 self.listed = []
130 self.num_updates = 0
131 self.pkgs_attrs = pkgs_attrs
Ralph Nathane01ccf12015-04-16 10:40:32 -0700132
Alex Klein1699fab2022-09-08 08:46:06 -0600133 def Run(self, _device, _root, _packages, _update, _deep, _deep_rev):
134 return self.cpvs, self.listed, self.num_updates, self.pkgs_attrs
Ralph Nathane01ccf12015-04-16 10:40:32 -0700135
136
David Pursell9476bf42015-03-30 13:34:27 -0700137class PortageTreeFake(object):
Alex Klein1699fab2022-09-08 08:46:06 -0600138 """Fake for Portage tree."""
David Pursell9476bf42015-03-30 13:34:27 -0700139
Alex Klein1699fab2022-09-08 08:46:06 -0600140 def __init__(self, dbapi):
141 self.dbapi = dbapi
David Pursell9476bf42015-03-30 13:34:27 -0700142
143
Ralph Nathane01ccf12015-04-16 10:40:32 -0700144class TestInstallPackageScanner(cros_test_lib.MockOutputTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600145 """Test the update package scanner."""
David Pursell9476bf42015-03-30 13:34:27 -0700146
Alex Klein1699fab2022-09-08 08:46:06 -0600147 _BOARD = "foo_board"
148 _BUILD_ROOT = "/build/%s" % _BOARD
149 _VARTREE = [
150 ("foo/app1-1.2.3-r4", "0", "foo/app2 !foo/app3", "1413309336"),
151 ("foo/app2-4.5.6-r7", "0", "", "1413309336"),
152 ("foo/app4-2.0.0-r1", "0", "foo/app1 foo/app5", "1413309336"),
153 ("foo/app5-3.0.7-r3", "0", "", "1413309336"),
154 ]
David Pursell9476bf42015-03-30 13:34:27 -0700155
Alex Klein1699fab2022-09-08 08:46:06 -0600156 def setUp(self):
157 """Patch imported modules."""
158 self.PatchObject(cros_build_lib, "GetChoice", return_value=0)
159 self.device = ChromiumOSDeviceHandlerFake()
160 self.scanner = deploy._InstallPackageScanner(self._BUILD_ROOT)
161 self.PatchObject(deploy, "_GetDLCInfo", return_value=(None, None))
David Pursell9476bf42015-03-30 13:34:27 -0700162
Alex Klein1699fab2022-09-08 08:46:06 -0600163 def SetupVartree(self, vartree_pkgs):
164 self.device.GetAgent().remote_sh_output = json.dumps(vartree_pkgs)
David Pursell9476bf42015-03-30 13:34:27 -0700165
Alex Klein1699fab2022-09-08 08:46:06 -0600166 def SetupBintree(self, bintree_pkgs):
167 bintree = PortageTreeFake(DbApiFake(bintree_pkgs))
168 build_root = os.path.join(self._BUILD_ROOT, "")
169 portage_db = {build_root: {"bintree": bintree}}
170 self.PatchObject(portage, "create_trees", return_value=portage_db)
David Pursell9476bf42015-03-30 13:34:27 -0700171
Alex Klein1699fab2022-09-08 08:46:06 -0600172 def ValidatePkgs(self, actual, expected, constraints=None):
173 # Containing exactly the same packages.
174 self.assertEqual(sorted(expected), sorted(actual))
175 # Packages appear in the right order.
176 if constraints is not None:
177 for needs, needed in constraints:
178 self.assertGreater(actual.index(needs), actual.index(needed))
David Pursell9476bf42015-03-30 13:34:27 -0700179
Alex Klein1699fab2022-09-08 08:46:06 -0600180 def testRunUpdatedVersion(self):
181 self.SetupVartree(self._VARTREE)
182 app1 = "foo/app1-1.2.5-r4"
183 self.SetupBintree(
184 [
185 (app1, "0", "foo/app2 !foo/app3", "1413309336"),
186 ("foo/app2-4.5.6-r7", "0", "", "1413309336"),
187 ]
188 )
189 installs, listed, num_updates, _ = self.scanner.Run(
190 self.device, "/", ["app1"], True, True, True
191 )
192 self.ValidatePkgs(installs, [app1])
193 self.ValidatePkgs(listed, [app1])
194 self.assertEqual(num_updates, 1)
David Pursell9476bf42015-03-30 13:34:27 -0700195
Alex Klein1699fab2022-09-08 08:46:06 -0600196 def testRunUpdatedBuildTime(self):
197 self.SetupVartree(self._VARTREE)
198 app1 = "foo/app1-1.2.3-r4"
199 self.SetupBintree(
200 [
201 (app1, "0", "foo/app2 !foo/app3", "1413309350"),
202 ("foo/app2-4.5.6-r7", "0", "", "1413309336"),
203 ]
204 )
205 installs, listed, num_updates, _ = self.scanner.Run(
206 self.device, "/", ["app1"], True, True, True
207 )
208 self.ValidatePkgs(installs, [app1])
209 self.ValidatePkgs(listed, [app1])
210 self.assertEqual(num_updates, 1)
David Pursell9476bf42015-03-30 13:34:27 -0700211
Alex Klein1699fab2022-09-08 08:46:06 -0600212 def testRunExistingDepUpdated(self):
213 self.SetupVartree(self._VARTREE)
214 app1 = "foo/app1-1.2.5-r2"
215 app2 = "foo/app2-4.5.8-r3"
216 self.SetupBintree(
217 [
218 (app1, "0", "foo/app2 !foo/app3", "1413309350"),
219 (app2, "0", "", "1413309350"),
220 ]
221 )
222 installs, listed, num_updates, _ = self.scanner.Run(
223 self.device, "/", ["app1"], True, True, True
224 )
225 self.ValidatePkgs(installs, [app1, app2], constraints=[(app1, app2)])
226 self.ValidatePkgs(listed, [app1])
227 self.assertEqual(num_updates, 2)
David Pursell9476bf42015-03-30 13:34:27 -0700228
Alex Klein1699fab2022-09-08 08:46:06 -0600229 def testRunMissingDepUpdated(self):
230 self.SetupVartree(self._VARTREE)
231 app1 = "foo/app1-1.2.5-r2"
232 app6 = "foo/app6-1.0.0-r1"
233 self.SetupBintree(
234 [
235 (app1, "0", "foo/app2 !foo/app3 foo/app6", "1413309350"),
236 ("foo/app2-4.5.6-r7", "0", "", "1413309336"),
237 (app6, "0", "", "1413309350"),
238 ]
239 )
240 installs, listed, num_updates, _ = self.scanner.Run(
241 self.device, "/", ["app1"], True, True, True
242 )
243 self.ValidatePkgs(installs, [app1, app6], constraints=[(app1, app6)])
244 self.ValidatePkgs(listed, [app1])
245 self.assertEqual(num_updates, 1)
David Pursell9476bf42015-03-30 13:34:27 -0700246
Alex Klein1699fab2022-09-08 08:46:06 -0600247 def testRunExistingRevDepUpdated(self):
248 self.SetupVartree(self._VARTREE)
249 app1 = "foo/app1-1.2.5-r2"
250 app4 = "foo/app4-2.0.1-r3"
251 self.SetupBintree(
252 [
253 (app1, "0", "foo/app2 !foo/app3", "1413309350"),
254 (app4, "0", "foo/app1 foo/app5", "1413309350"),
255 ("foo/app5-3.0.7-r3", "0", "", "1413309336"),
256 ]
257 )
258 installs, listed, num_updates, _ = self.scanner.Run(
259 self.device, "/", ["app1"], True, True, True
260 )
261 self.ValidatePkgs(installs, [app1, app4], constraints=[(app4, app1)])
262 self.ValidatePkgs(listed, [app1])
263 self.assertEqual(num_updates, 2)
David Pursell9476bf42015-03-30 13:34:27 -0700264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 def testRunMissingRevDepNotUpdated(self):
266 self.SetupVartree(self._VARTREE)
267 app1 = "foo/app1-1.2.5-r2"
268 app6 = "foo/app6-1.0.0-r1"
269 self.SetupBintree(
270 [
271 (app1, "0", "foo/app2 !foo/app3", "1413309350"),
272 (app6, "0", "foo/app1", "1413309350"),
273 ]
274 )
275 installs, listed, num_updates, _ = self.scanner.Run(
276 self.device, "/", ["app1"], True, True, True
277 )
278 self.ValidatePkgs(installs, [app1])
279 self.ValidatePkgs(listed, [app1])
280 self.assertEqual(num_updates, 1)
David Pursell9476bf42015-03-30 13:34:27 -0700281
Alex Klein1699fab2022-09-08 08:46:06 -0600282 def testRunTransitiveDepsUpdated(self):
283 self.SetupVartree(self._VARTREE)
284 app1 = "foo/app1-1.2.5-r2"
285 app2 = "foo/app2-4.5.8-r3"
286 app4 = "foo/app4-2.0.0-r1"
287 app5 = "foo/app5-3.0.8-r2"
288 self.SetupBintree(
289 [
290 (app1, "0", "foo/app2 !foo/app3", "1413309350"),
291 (app2, "0", "", "1413309350"),
292 (app4, "0", "foo/app1 foo/app5", "1413309350"),
293 (app5, "0", "", "1413309350"),
294 ]
295 )
296 installs, listed, num_updates, _ = self.scanner.Run(
297 self.device, "/", ["app1"], True, True, True
298 )
299 self.ValidatePkgs(
300 installs,
301 [app1, app2, app4, app5],
302 constraints=[(app1, app2), (app4, app1), (app4, app5)],
303 )
304 self.ValidatePkgs(listed, [app1])
305 self.assertEqual(num_updates, 4)
David Pursell9476bf42015-03-30 13:34:27 -0700306
Alex Klein1699fab2022-09-08 08:46:06 -0600307 def testRunDisjunctiveDepsExistingUpdated(self):
308 self.SetupVartree(self._VARTREE)
309 app1 = "foo/app1-1.2.5-r2"
310 self.SetupBintree(
311 [
312 (app1, "0", "|| ( foo/app6 foo/app2 ) !foo/app3", "1413309350"),
313 ("foo/app2-4.5.6-r7", "0", "", "1413309336"),
314 ]
315 )
316 installs, listed, num_updates, _ = self.scanner.Run(
317 self.device, "/", ["app1"], True, True, True
318 )
319 self.ValidatePkgs(installs, [app1])
320 self.ValidatePkgs(listed, [app1])
321 self.assertEqual(num_updates, 1)
322
323 def testRunDisjunctiveDepsDefaultUpdated(self):
324 self.SetupVartree(self._VARTREE)
325 app1 = "foo/app1-1.2.5-r2"
326 app7 = "foo/app7-1.0.0-r1"
327 self.SetupBintree(
328 [
329 (app1, "0", "|| ( foo/app6 foo/app7 ) !foo/app3", "1413309350"),
330 (app7, "0", "", "1413309350"),
331 ]
332 )
333 installs, listed, num_updates, _ = self.scanner.Run(
334 self.device, "/", ["app1"], True, True, True
335 )
336 self.ValidatePkgs(installs, [app1, app7], constraints=[(app1, app7)])
337 self.ValidatePkgs(listed, [app1])
338 self.assertEqual(num_updates, 1)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700339
340
Alex Klein1699fab2022-09-08 08:46:06 -0600341class TestDeploy(
342 cros_test_lib.ProgressBarTestCase, cros_test_lib.MockTempDirTestCase
343):
344 """Test deploy.Deploy."""
Ralph Nathane01ccf12015-04-16 10:40:32 -0700345
Alex Klein1699fab2022-09-08 08:46:06 -0600346 @staticmethod
347 def FakeGetPackagesByCPV(cpvs, _strip, _sysroot):
348 return ["/path/to/%s.tbz2" % cpv.pv for cpv in cpvs]
Gilad Arnold0e1b1da2015-06-10 06:41:05 -0700349
Alex Klein1699fab2022-09-08 08:46:06 -0600350 def setUp(self):
351 # Fake being root to avoid running filesystem commands with sudo_run.
352 self.PatchObject(osutils, "IsRootUser", return_value=True)
353 self._sysroot = os.path.join(self.tempdir, "sysroot")
354 osutils.SafeMakedirs(self._sysroot)
355 self.device = ChromiumOSDeviceHandlerFake()
356 self.PatchObject(
357 remote_access, "ChromiumOSDeviceHandler", return_value=self.device
358 )
359 self.PatchObject(cros_build_lib, "GetBoard", return_value=None)
360 self.PatchObject(
361 build_target_lib,
362 "get_default_sysroot_path",
363 return_value=self._sysroot,
364 )
365 self.package_scanner = self.PatchObject(
366 deploy, "_InstallPackageScanner"
367 )
368 self.get_packages_paths = self.PatchObject(
369 deploy, "_GetPackagesByCPV", side_effect=self.FakeGetPackagesByCPV
370 )
371 self.emerge = self.PatchObject(deploy, "_Emerge", return_value=None)
372 self.unmerge = self.PatchObject(deploy, "_Unmerge", return_value=None)
373 self.PatchObject(deploy, "_GetDLCInfo", return_value=(None, None))
374 # Avoid running the portageq command.
375 sysroot_lib.Sysroot(self._sysroot).WriteConfig(
376 'ARCH="amd64"\nPORTDIR_OVERLAY="%s"' % "/nothing/here"
377 )
378 # make.conf needs to exist to correctly read back config.
379 unittest_lib.create_stub_make_conf(self._sysroot)
Brian Norris2eee8892021-04-06 16:23:23 -0700380
Alex Klein1699fab2022-09-08 08:46:06 -0600381 def testDeployEmerge(self):
382 """Test that deploy._Emerge is called for each package."""
Ralph Nathane01ccf12015-04-16 10:40:32 -0700383
Alex Klein1699fab2022-09-08 08:46:06 -0600384 _BINPKG = "/path/to/bar-1.2.5.tbz2"
Gilad Arnold0e1b1da2015-06-10 06:41:05 -0700385
Alex Klein1699fab2022-09-08 08:46:06 -0600386 def FakeIsFile(fname):
387 return fname == _BINPKG
Gilad Arnold0e1b1da2015-06-10 06:41:05 -0700388
Alex Klein1699fab2022-09-08 08:46:06 -0600389 packages = ["some/foo-1.2.3", _BINPKG, "some/foobar-2.0"]
390 cpvs = ["some/foo-1.2.3", "to/bar-1.2.5", "some/foobar-2.0"]
391 self.package_scanner.return_value = PackageScannerFake(
392 packages,
393 {"some/foo-1.2.3": {}, _BINPKG: {}, "some/foobar-2.0": {}},
394 cpvs,
395 )
396 self.PatchObject(os.path, "isfile", side_effect=FakeIsFile)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700397
Alex Klein1699fab2022-09-08 08:46:06 -0600398 deploy.Deploy(None, ["package"], force=True, clean_binpkg=False)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700399
Alex Klein1699fab2022-09-08 08:46:06 -0600400 # Check that package names were correctly resolved into binary packages.
401 self.get_packages_paths.assert_called_once_with(
402 [package_info.SplitCPV(p) for p in cpvs], True, self._sysroot
403 )
404 # Check that deploy._Emerge is called the right number of times.
405 self.emerge.assert_called_once_with(
406 mock.ANY,
407 [
408 "/path/to/foo-1.2.3.tbz2",
409 "/path/to/bar-1.2.5.tbz2",
410 "/path/to/foobar-2.0.tbz2",
411 ],
412 "/",
413 extra_args=None,
414 )
415 self.assertEqual(self.unmerge.call_count, 0)
Qijiang Fan8a945032019-04-25 20:53:29 +0900416
Alex Klein1699fab2022-09-08 08:46:06 -0600417 def testDeployEmergeDLC(self):
418 """Test that deploy._Emerge installs images for DLC packages."""
419 packages = ["some/foodlc-1.0", "some/bardlc-2.0"]
420 cpvs = ["some/foodlc-1.0", "some/bardlc-2.0"]
421 self.package_scanner.return_value = PackageScannerFake(
422 packages, {"some/foodlc-1.0": {}, "some/bardlc-2.0": {}}, cpvs
423 )
424 self.PatchObject(
425 deploy, "_GetDLCInfo", return_value=("foo_id", "foo_package")
426 )
Xiaochu Liu2726e7c2019-07-18 10:28:10 -0700427
Alex Klein1699fab2022-09-08 08:46:06 -0600428 deploy.Deploy(None, ["package"], force=True, clean_binpkg=False)
429 # Check that dlcservice is restarted (DLC modules are deployed).
430 self.assertTrue(["restart", "dlcservice"] in self.device.device.cmds)
Xiaochu Liu2726e7c2019-07-18 10:28:10 -0700431
Alex Klein1699fab2022-09-08 08:46:06 -0600432 def testDeployEmergeSELinux(self):
433 """Test deploy progress when the device has SELinux"""
Qijiang Fan8a945032019-04-25 20:53:29 +0900434
Alex Klein1699fab2022-09-08 08:46:06 -0600435 _BINPKG = "/path/to/bar-1.2.5.tbz2"
Qijiang Fan8a945032019-04-25 20:53:29 +0900436
Alex Klein1699fab2022-09-08 08:46:06 -0600437 def FakeIsFile(fname):
438 return fname == _BINPKG
Qijiang Fan8a945032019-04-25 20:53:29 +0900439
Alex Klein1699fab2022-09-08 08:46:06 -0600440 def GetRestoreconCommand(pkgfile):
441 remote_path = os.path.join("/testdir/packages/to/", pkgfile)
442 return [
443 [
444 "cd",
445 "/",
446 "&&",
447 "tar",
448 "tf",
449 remote_path,
450 "|",
451 "restorecon",
452 "-i",
453 "-f",
454 "-",
455 ]
456 ]
Qijiang Fan8a945032019-04-25 20:53:29 +0900457
Alex Klein1699fab2022-09-08 08:46:06 -0600458 self.device.device.selinux_available = True
459 packages = ["some/foo-1.2.3", _BINPKG, "some/foobar-2.0"]
460 cpvs = ["some/foo-1.2.3", "to/bar-1.2.5", "some/foobar-2.0"]
461 self.package_scanner.return_value = PackageScannerFake(
462 packages,
463 {"some/foo-1.2.3": {}, _BINPKG: {}, "some/foobar-2.0": {}},
464 cpvs,
465 )
466 self.PatchObject(os.path, "isfile", side_effect=FakeIsFile)
Qijiang Fan8a945032019-04-25 20:53:29 +0900467
Alex Klein1699fab2022-09-08 08:46:06 -0600468 deploy.Deploy(None, ["package"], force=True, clean_binpkg=False)
Qijiang Fan8a945032019-04-25 20:53:29 +0900469
Alex Klein1699fab2022-09-08 08:46:06 -0600470 # Check that package names were correctly resolved into binary packages.
471 self.get_packages_paths.assert_called_once_with(
472 [package_info.SplitCPV(p) for p in cpvs], True, self._sysroot
473 )
474 # Check that deploy._Emerge is called the right number of times.
475 self.assertEqual(self.emerge.call_count, 1)
476 self.assertEqual(self.unmerge.call_count, 0)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700477
Alex Klein1699fab2022-09-08 08:46:06 -0600478 self.assertEqual(
479 self.device.device.cmds,
480 [["setenforce", "0"]]
481 + GetRestoreconCommand("foo-1.2.3.tbz2")
482 + GetRestoreconCommand("bar-1.2.5.tbz2")
483 + GetRestoreconCommand("foobar-2.0.tbz2")
484 + [["setenforce", "1"]],
485 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700486
Alex Klein1699fab2022-09-08 08:46:06 -0600487 def testDeployUnmerge(self):
488 """Test that deploy._Unmerge is called for each package."""
489 packages = ["foo", "bar", "foobar", "foodlc"]
490 self.package_scanner.return_value = PackageScannerFake(
491 packages,
492 {
493 "foo": {},
494 "bar": {},
495 "foobar": {},
496 "foodlc": {
497 deploy._DLC_ID: "foodlc",
498 deploy._DLC_PACKAGE: "foopackage",
499 },
500 },
501 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700502
Alex Klein1699fab2022-09-08 08:46:06 -0600503 deploy.Deploy(
504 None, ["package"], force=True, clean_binpkg=False, emerge=False
505 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700506
Alex Klein1699fab2022-09-08 08:46:06 -0600507 # Check that deploy._Unmerge is called the right number of times.
508 self.assertEqual(self.emerge.call_count, 0)
509 self.unmerge.assert_called_once_with(mock.ANY, packages, "/")
Xiaochu Liu2726e7c2019-07-18 10:28:10 -0700510
Alex Klein1699fab2022-09-08 08:46:06 -0600511 self.assertEqual(
512 self.device.device.cmds,
513 [
514 ["dlcservice_util", "--uninstall", "--id=foodlc"],
515 ["restart", "dlcservice"],
516 ],
517 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700518
Alex Klein1699fab2022-09-08 08:46:06 -0600519 def testDeployMergeWithProgressBar(self):
520 """Test that BrilloDeployOperation.Run() is called for merge."""
521 packages = ["foo", "bar", "foobar"]
522 self.package_scanner.return_value = PackageScannerFake(
523 packages, {"foo": {}, "bar": {}, "foobar": {}}
524 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700525
Alex Klein1699fab2022-09-08 08:46:06 -0600526 run = self.PatchObject(
527 deploy.BrilloDeployOperation, "Run", return_value=None
528 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700529
Alex Klein1699fab2022-09-08 08:46:06 -0600530 self.PatchObject(command, "UseProgressBar", return_value=True)
531 deploy.Deploy(None, ["package"], force=True, clean_binpkg=False)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700532
Alex Klein1699fab2022-09-08 08:46:06 -0600533 # Check that BrilloDeployOperation.Run was called.
534 self.assertTrue(run.called)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700535
Alex Klein1699fab2022-09-08 08:46:06 -0600536 def testDeployUnmergeWithProgressBar(self):
537 """Test that BrilloDeployOperation.Run() is called for unmerge."""
538 packages = ["foo", "bar", "foobar"]
539 self.package_scanner.return_value = PackageScannerFake(
540 packages, {"foo": {}, "bar": {}, "foobar": {}}
541 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700542
Alex Klein1699fab2022-09-08 08:46:06 -0600543 run = self.PatchObject(
544 deploy.BrilloDeployOperation, "Run", return_value=None
545 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700546
Alex Klein1699fab2022-09-08 08:46:06 -0600547 self.PatchObject(command, "UseProgressBar", return_value=True)
548 deploy.Deploy(
549 None, ["package"], force=True, clean_binpkg=False, emerge=False
550 )
Ralph Nathane01ccf12015-04-16 10:40:32 -0700551
Alex Klein1699fab2022-09-08 08:46:06 -0600552 # Check that BrilloDeployOperation.Run was called.
553 self.assertTrue(run.called)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700554
Alex Klein1699fab2022-09-08 08:46:06 -0600555 def testBrilloDeployMergeOperation(self):
556 """Test that BrilloDeployOperation works for merge."""
Ralph Nathane01ccf12015-04-16 10:40:32 -0700557
Alex Klein1699fab2022-09-08 08:46:06 -0600558 def func(queue):
559 for event in op.MERGE_EVENTS:
560 queue.get()
561 print(event)
562 sys.stdout.flush()
Ralph Nathane01ccf12015-04-16 10:40:32 -0700563
Alex Klein1699fab2022-09-08 08:46:06 -0600564 queue = multiprocessing.Queue()
565 # Emerge one package.
566 op = BrilloDeployOperationFake(True, queue)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700567
Alex Klein1699fab2022-09-08 08:46:06 -0600568 with self.OutputCapturer():
569 op.Run(func, queue)
Ralph Nathane01ccf12015-04-16 10:40:32 -0700570
Alex Klein1699fab2022-09-08 08:46:06 -0600571 # Check that the progress bar prints correctly.
572 self.AssertProgressBarAllEvents(len(op.MERGE_EVENTS))
Ralph Nathane01ccf12015-04-16 10:40:32 -0700573
Alex Klein1699fab2022-09-08 08:46:06 -0600574 def testBrilloDeployUnmergeOperation(self):
575 """Test that BrilloDeployOperation works for unmerge."""
Ralph Nathane01ccf12015-04-16 10:40:32 -0700576
Alex Klein1699fab2022-09-08 08:46:06 -0600577 def func(queue):
578 for event in op.UNMERGE_EVENTS:
579 queue.get()
580 print(event)
581 sys.stdout.flush()
582
583 queue = multiprocessing.Queue()
584 # Unmerge one package.
585 op = BrilloDeployOperationFake(False, queue)
586
587 with self.OutputCapturer():
588 op.Run(func, queue)
589
590 # Check that the progress bar prints correctly.
591 self.AssertProgressBarAllEvents(len(op.UNMERGE_EVENTS))