blob: fbc08f2f02ccf31b783b833ee07ebf642e7bb061 [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
7from __future__ import print_function
8
9import json
10import os
11
12from chromite.cli import deploy
13from chromite.lib import cros_build_lib
14from chromite.lib import cros_test_lib
15try:
16 import portage
17except ImportError:
18 if cros_build_lib.IsInsideChroot():
19 raise
20
21
22# pylint: disable=protected-access
23
24
25class ChromiumOSDeviceHandlerFake(object):
26 """Fake for chromite.lib.remote_access.ChomiumOSDeviceHandler."""
27
28 class RemoteAccessFake(object):
29 """Fake for chromite.lib.remote_access.RemoteAccess."""
30
31 def __init__(self):
32 self.remote_sh_output = None
33
34 def RemoteSh(self, *_args, **_kwargs):
35 return cros_build_lib.CommandResult(output=self.remote_sh_output)
36
37 def __init__(self):
David Pursell67a82762015-04-30 17:26:59 -070038 self._agent = self.RemoteAccessFake()
39
40 def GetAgent(self):
41 return self._agent
David Pursell9476bf42015-03-30 13:34:27 -070042
43
44class DbApiFake(object):
45 """Fake for Portage dbapi."""
46
47 def __init__(self, pkgs):
48 self.pkg_db = {}
49 for cpv, slot, rdeps_raw, build_time in pkgs:
50 self.pkg_db[cpv] = {
51 'SLOT': slot, 'RDEPEND': rdeps_raw, 'BUILD_TIME': build_time}
52
53 def cpv_all(self):
54 return self.pkg_db.keys()
55
56 def aux_get(self, cpv, keys):
57 pkg_info = self.pkg_db[cpv]
58 return [pkg_info[key] for key in keys]
59
60
61class PortageTreeFake(object):
62 """Fake for Portage tree."""
63
64 def __init__(self, dbapi):
65 self.dbapi = dbapi
66
67
68class TestInstallPackageScanner(cros_test_lib.MockTestCase):
69 """Test the update package scanner."""
70 _BOARD = 'foo_board'
71 _BUILD_ROOT = '/build/%s' % _BOARD
72 _VARTREE = [
73 ('foo/app1-1.2.3-r4', '0', 'foo/app2 !foo/app3', '1413309336'),
74 ('foo/app2-4.5.6-r7', '0', '', '1413309336'),
75 ('foo/app4-2.0.0-r1', '0', 'foo/app1 foo/app5', '1413309336'),
76 ('foo/app5-3.0.7-r3', '0', '', '1413309336'),
77 ]
78
79 def setUp(self):
80 """Patch imported modules."""
81 self.PatchObject(cros_build_lib, 'GetChoice', return_value=0)
82 self.device = ChromiumOSDeviceHandlerFake()
83 self.scanner = deploy._InstallPackageScanner(self._BUILD_ROOT)
84
85 def SetupVartree(self, vartree_pkgs):
David Pursell67a82762015-04-30 17:26:59 -070086 self.device.GetAgent().remote_sh_output = json.dumps(vartree_pkgs)
David Pursell9476bf42015-03-30 13:34:27 -070087
88 def SetupBintree(self, bintree_pkgs):
89 bintree = PortageTreeFake(DbApiFake(bintree_pkgs))
90 build_root = os.path.join(self._BUILD_ROOT, '')
91 portage_db = {build_root: {'bintree': bintree}}
92 self.PatchObject(portage, 'create_trees', return_value=portage_db)
93
94 def ValidatePkgs(self, actual, expected, constraints=None):
95 # Containing exactly the same packages.
96 self.assertEquals(sorted(expected), sorted(actual))
97 # Packages appear in the right order.
98 if constraints is not None:
99 for needs, needed in constraints:
100 self.assertGreater(actual.index(needs), actual.index(needed))
101
102 def testRunUpdatedVersion(self):
103 self.SetupVartree(self._VARTREE)
104 app1 = 'foo/app1-1.2.5-r4'
105 self.SetupBintree([
106 (app1, '0', 'foo/app2 !foo/app3', '1413309336'),
107 ('foo/app2-4.5.6-r7', '0', '', '1413309336'),
108 ])
109 installs, listed, num_updates = self.scanner.Run(
110 self.device, '/', ['app1'], True, True, True)
111 self.ValidatePkgs(installs, [app1])
112 self.ValidatePkgs(listed, [app1])
113 self.assertEquals(num_updates, 1)
114
115 def testRunUpdatedBuildTime(self):
116 self.SetupVartree(self._VARTREE)
117 app1 = 'foo/app1-1.2.3-r4'
118 self.SetupBintree([
119 (app1, '0', 'foo/app2 !foo/app3', '1413309350'),
120 ('foo/app2-4.5.6-r7', '0', '', '1413309336'),
121 ])
122 installs, listed, num_updates = self.scanner.Run(
123 self.device, '/', ['app1'], True, True, True)
124 self.ValidatePkgs(installs, [app1])
125 self.ValidatePkgs(listed, [app1])
126 self.assertEquals(num_updates, 1)
127
128 def testRunExistingDepUpdated(self):
129 self.SetupVartree(self._VARTREE)
130 app1 = 'foo/app1-1.2.5-r2'
131 app2 = 'foo/app2-4.5.8-r3'
132 self.SetupBintree([
133 (app1, '0', 'foo/app2 !foo/app3', '1413309350'),
134 (app2, '0', '', '1413309350'),
135 ])
136 installs, listed, num_updates = self.scanner.Run(
137 self.device, '/', ['app1'], True, True, True)
138 self.ValidatePkgs(installs, [app1, app2], constraints=[(app1, app2)])
139 self.ValidatePkgs(listed, [app1])
140 self.assertEquals(num_updates, 2)
141
142 def testRunMissingDepUpdated(self):
143 self.SetupVartree(self._VARTREE)
144 app1 = 'foo/app1-1.2.5-r2'
145 app6 = 'foo/app6-1.0.0-r1'
146 self.SetupBintree([
147 (app1, '0', 'foo/app2 !foo/app3 foo/app6', '1413309350'),
148 ('foo/app2-4.5.6-r7', '0', '', '1413309336'),
149 (app6, '0', '', '1413309350'),
150 ])
151 installs, listed, num_updates = self.scanner.Run(
152 self.device, '/', ['app1'], True, True, True)
153 self.ValidatePkgs(installs, [app1, app6], constraints=[(app1, app6)])
154 self.ValidatePkgs(listed, [app1])
155 self.assertEquals(num_updates, 1)
156
157 def testRunExistingRevDepUpdated(self):
158 self.SetupVartree(self._VARTREE)
159 app1 = 'foo/app1-1.2.5-r2'
160 app4 = 'foo/app4-2.0.1-r3'
161 self.SetupBintree([
162 (app1, '0', 'foo/app2 !foo/app3', '1413309350'),
163 (app4, '0', 'foo/app1 foo/app5', '1413309350'),
164 ('foo/app5-3.0.7-r3', '0', '', '1413309336'),
165 ])
166 installs, listed, num_updates = self.scanner.Run(
167 self.device, '/', ['app1'], True, True, True)
168 self.ValidatePkgs(installs, [app1, app4], constraints=[(app4, app1)])
169 self.ValidatePkgs(listed, [app1])
170 self.assertEquals(num_updates, 2)
171
172 def testRunMissingRevDepNotUpdated(self):
173 self.SetupVartree(self._VARTREE)
174 app1 = 'foo/app1-1.2.5-r2'
175 app6 = 'foo/app6-1.0.0-r1'
176 self.SetupBintree([
177 (app1, '0', 'foo/app2 !foo/app3', '1413309350'),
178 (app6, '0', 'foo/app1', '1413309350'),
179 ])
180 installs, listed, num_updates = self.scanner.Run(
181 self.device, '/', ['app1'], True, True, True)
182 self.ValidatePkgs(installs, [app1])
183 self.ValidatePkgs(listed, [app1])
184 self.assertEquals(num_updates, 1)
185
186 def testRunTransitiveDepsUpdated(self):
187 self.SetupVartree(self._VARTREE)
188 app1 = 'foo/app1-1.2.5-r2'
189 app2 = 'foo/app2-4.5.8-r3'
190 app4 = 'foo/app4-2.0.0-r1'
191 app5 = 'foo/app5-3.0.8-r2'
192 self.SetupBintree([
193 (app1, '0', 'foo/app2 !foo/app3', '1413309350'),
194 (app2, '0', '', '1413309350'),
195 (app4, '0', 'foo/app1 foo/app5', '1413309350'),
196 (app5, '0', '', '1413309350'),
197 ])
198 installs, listed, num_updates = self.scanner.Run(
199 self.device, '/', ['app1'], True, True, True)
200 self.ValidatePkgs(installs, [app1, app2, app4, app5],
201 constraints=[(app1, app2), (app4, app1), (app4, app5)])
202 self.ValidatePkgs(listed, [app1])
203 self.assertEquals(num_updates, 4)
204
205 def testRunDisjunctiveDepsExistingUpdated(self):
206 self.SetupVartree(self._VARTREE)
207 app1 = 'foo/app1-1.2.5-r2'
208 self.SetupBintree([
209 (app1, '0', '|| ( foo/app6 foo/app2 ) !foo/app3', '1413309350'),
210 ('foo/app2-4.5.6-r7', '0', '', '1413309336'),
211 ])
212 installs, listed, num_updates = self.scanner.Run(
213 self.device, '/', ['app1'], True, True, True)
214 self.ValidatePkgs(installs, [app1])
215 self.ValidatePkgs(listed, [app1])
216 self.assertEquals(num_updates, 1)
217
218 def testRunDisjunctiveDepsDefaultUpdated(self):
219 self.SetupVartree(self._VARTREE)
220 app1 = 'foo/app1-1.2.5-r2'
221 app7 = 'foo/app7-1.0.0-r1'
222 self.SetupBintree([
223 (app1, '0', '|| ( foo/app6 foo/app7 ) !foo/app3', '1413309350'),
224 (app7, '0', '', '1413309350'),
225 ])
226 installs, listed, num_updates = self.scanner.Run(
227 self.device, '/', ['app1'], True, True, True)
228 self.ValidatePkgs(installs, [app1, app7], constraints=[(app1, app7)])
229 self.ValidatePkgs(listed, [app1])
230 self.assertEquals(num_updates, 1)