blob: 0cac8e12973a38bc1075dde7bb95f5132e56fa15 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
LaMont Jones8a1644f2019-04-16 14:30:17 -06002# 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 Android operations."""
6
Mike Frysinger166fea02021-02-12 05:30:33 -05007from unittest import mock
8
Alex Klein231d2da2019-07-22 16:44:45 -06009from chromite.api import api_config
LaMont Jones8a1644f2019-04-16 14:30:17 -060010from chromite.api.controller import android
11from chromite.api.gen.chromite.api import android_pb2
12from chromite.api.gen.chromiumos import common_pb2
Mike Frysinger40ffb532021-02-12 07:36:08 -050013from chromite.lib import build_target_lib
LaMont Jones8a1644f2019-04-16 14:30:17 -060014from chromite.lib import constants
15from chromite.lib import cros_build_lib
16from chromite.lib import cros_test_lib
17from chromite.lib import osutils
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090018from chromite.service import android as service_android
Alex Klein4de25e82019-08-05 15:58:39 -060019from chromite.service import packages
20
LaMont Jones8a1644f2019-04-16 14:30:17 -060021
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090022class GetLatestBuildTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -060023 """Unittests for GetLatestBuild."""
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090024
Alex Klein1699fab2022-09-08 08:46:06 -060025 def setUp(self):
26 self._mock = self.PatchObject(service_android, "GetLatestBuild")
27 self._mock.return_value = ("7123456", {})
28 self._mock_branch_for_package = self.PatchObject(
29 service_android,
30 "GetAndroidBranchForPackage",
31 return_value="android-branch-for-package",
32 )
33 self._output_proto = android_pb2.GetLatestBuildResponse()
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090034
Alex Klein1699fab2022-09-08 08:46:06 -060035 def _GetRequest(self, android_build_branch=None, android_package=None):
36 req = android_pb2.GetLatestBuildRequest()
37 if android_build_branch is not None:
38 req.android_build_branch = android_build_branch
39 if android_package is not None:
40 req.android_package = android_package
41 return req
Shao-Chuan Lee6e8784a2021-05-13 09:34:46 +090042
Alex Klein1699fab2022-09-08 08:46:06 -060043 def testValidateOnly(self):
44 """Test that a validate only call does not execute any logic."""
45 req = self._GetRequest(android_package="android-package")
46 android.GetLatestBuild(
47 req, self._output_proto, self.validate_only_config
48 )
49 self._mock.assert_not_called()
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090050
Alex Klein1699fab2022-09-08 08:46:06 -060051 def testMockCall(self):
52 """Test that a mock call does not execute logic, returns mocked value."""
53 req = self._GetRequest(android_package="android-package")
54 android.GetLatestBuild(req, self._output_proto, self.mock_call_config)
55 self._mock.assert_not_called()
56 self.assertEqual(self._output_proto.android_version, "7123456")
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090057
Alex Klein1699fab2022-09-08 08:46:06 -060058 def testFailsIfBranchAndPackageMissing(self):
59 """Fails if both android_build_branch and android_package are missing."""
60 req = self._GetRequest()
61 with self.assertRaises(cros_build_lib.DieSystemExit):
62 android.GetLatestBuild(req, self._output_proto, self.api_config)
63 self._mock.assert_not_called()
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090064
Alex Klein1699fab2022-09-08 08:46:06 -060065 def testBranchSpecified(self):
66 """Test calling with Android branch specified."""
67 req = self._GetRequest(android_build_branch="android-branch")
68 android.GetLatestBuild(req, self._output_proto, self.api_config)
69 self._mock.assert_called_once_with("android-branch")
70 self._mock_branch_for_package.assert_not_called()
71 self.assertEqual(self._output_proto.android_version, "7123456")
Shao-Chuan Lee6e8784a2021-05-13 09:34:46 +090072
Alex Klein1699fab2022-09-08 08:46:06 -060073 def testPackageSpecified(self):
74 """Test calling with Android package specified."""
75 req = self._GetRequest(android_package="android-package")
76 android.GetLatestBuild(req, self._output_proto, self.api_config)
77 self._mock.assert_called_once_with("android-branch-for-package")
78 self._mock_branch_for_package.assert_called_once_with("android-package")
79 self.assertEqual(self._output_proto.android_version, "7123456")
Shao-Chuan Lee6e8784a2021-05-13 09:34:46 +090080
Alex Klein1699fab2022-09-08 08:46:06 -060081 def testBranchAndPackageSpecified(self):
82 """Test calling with both Android branch and package specified."""
83 req = self._GetRequest(
84 android_build_branch="android-branch",
85 android_package="android-package",
86 )
87 android.GetLatestBuild(req, self._output_proto, self.api_config)
88 self._mock.assert_called_once_with("android-branch")
89 self._mock_branch_for_package.assert_not_called()
90 self.assertEqual(self._output_proto.android_version, "7123456")
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090091
92
Alex Klein231d2da2019-07-22 16:44:45 -060093class MarkStableTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -060094 """Unittests for MarkStable."""
LaMont Jones8a1644f2019-04-16 14:30:17 -060095
Alex Klein1699fab2022-09-08 08:46:06 -060096 def setUp(self):
97 self.uprev = self.PatchObject(packages, "uprev_android")
LaMont Jones8a1644f2019-04-16 14:30:17 -060098
Alex Klein1699fab2022-09-08 08:46:06 -060099 self.input_proto = android_pb2.MarkStableRequest()
100 self.input_proto.package_name = "android-package-name"
101 self.input_proto.android_build_branch = "android_build_branch"
102 self.input_proto.android_version = "android-version"
103 self.input_proto.build_targets.add().name = "foo"
104 self.input_proto.build_targets.add().name = "bar"
105 self.input_proto.skip_commit = True
Alex Klein4de25e82019-08-05 15:58:39 -0600106
Alex Klein1699fab2022-09-08 08:46:06 -0600107 self.build_targets = [
108 build_target_lib.BuildTarget("foo"),
109 build_target_lib.BuildTarget("bar"),
110 ]
LaMont Jones8a1644f2019-04-16 14:30:17 -0600111
Alex Klein1699fab2022-09-08 08:46:06 -0600112 self.response = android_pb2.MarkStableResponse()
Alex Klein231d2da2019-07-22 16:44:45 -0600113
Alex Klein1699fab2022-09-08 08:46:06 -0600114 def testValidateOnly(self):
115 """Sanity check that a validate only call does not execute any logic."""
116 android.MarkStable(
117 self.input_proto, self.response, self.validate_only_config
118 )
119 self.uprev.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -0600120
Alex Klein1699fab2022-09-08 08:46:06 -0600121 def testMockCall(self):
122 """Test that a mock call does not execute logic, returns mocked value."""
123 android.MarkStable(
124 self.input_proto, self.response, self.mock_call_config
125 )
126 self.uprev.assert_not_called()
127 self.assertEqual(
128 self.response.status, android_pb2.MARK_STABLE_STATUS_SUCCESS
129 )
130 self.assertEqual(self.response.android_atom.category, "category")
131 self.assertEqual(
132 self.response.android_atom.package_name, "android-package-name"
133 )
134 self.assertEqual(self.response.android_atom.version, "1.2")
Michael Mortensen25626442019-11-22 10:06:59 -0700135
Alex Klein1699fab2022-09-08 08:46:06 -0600136 def testFailsIfPackageNameMissing(self):
137 """Fails if package_name is missing."""
138 self.input_proto.package_name = ""
139 with self.assertRaises(cros_build_lib.DieSystemExit):
140 android.MarkStable(self.input_proto, self.response, self.api_config)
141 self.uprev.assert_not_called()
LaMont Jones8a1644f2019-04-16 14:30:17 -0600142
Alex Klein1699fab2022-09-08 08:46:06 -0600143 def testCallsCommandCorrectly(self):
144 """Test that commands.MarkAndroidAsStable is called correctly."""
145 self.uprev.return_value = packages.UprevAndroidResult(
146 revved=True, android_atom="cat/android-1.2.3"
147 )
148 atom = common_pb2.PackageInfo()
149 atom.category = "cat"
150 atom.package_name = "android"
151 atom.version = "1.2.3"
152 android.MarkStable(self.input_proto, self.response, self.api_config)
153 self.uprev.assert_called_once_with(
154 android_package=self.input_proto.package_name,
155 chroot=mock.ANY,
156 build_targets=self.build_targets,
157 android_build_branch=self.input_proto.android_build_branch,
158 android_version=self.input_proto.android_version,
159 skip_commit=self.input_proto.skip_commit,
160 )
161 self.assertEqual(self.response.android_atom, atom)
162 self.assertEqual(
163 self.response.status, android_pb2.MARK_STABLE_STATUS_SUCCESS
164 )
LaMont Jones8a1644f2019-04-16 14:30:17 -0600165
Alex Klein1699fab2022-09-08 08:46:06 -0600166 def testHandlesEarlyExit(self):
167 """Test that early exit is handled correctly."""
168 self.uprev.return_value = packages.UprevAndroidResult(revved=False)
169 android.MarkStable(self.input_proto, self.response, self.api_config)
170 self.uprev.assert_called_once_with(
171 android_package=self.input_proto.package_name,
172 chroot=mock.ANY,
173 build_targets=self.build_targets,
174 android_build_branch=self.input_proto.android_build_branch,
175 android_version=self.input_proto.android_version,
176 skip_commit=self.input_proto.skip_commit,
177 )
178 self.assertEqual(
179 self.response.status, android_pb2.MARK_STABLE_STATUS_EARLY_EXIT
180 )
LaMont Jones8a1644f2019-04-16 14:30:17 -0600181
Alex Klein1699fab2022-09-08 08:46:06 -0600182 def testHandlesPinnedUprevError(self):
183 """Test that pinned error is handled correctly."""
184 self.uprev.side_effect = packages.AndroidIsPinnedUprevError(
185 "pin/xx-1.1"
186 )
187 atom = common_pb2.PackageInfo()
188 atom.category = "pin"
189 atom.package_name = "xx"
190 atom.version = "1.1"
191 android.MarkStable(self.input_proto, self.response, self.api_config)
192 self.uprev.assert_called_once_with(
193 android_package=self.input_proto.package_name,
194 chroot=mock.ANY,
195 build_targets=self.build_targets,
196 android_build_branch=self.input_proto.android_build_branch,
197 android_version=self.input_proto.android_version,
198 skip_commit=self.input_proto.skip_commit,
199 )
200 self.assertEqual(self.response.android_atom, atom)
201 self.assertEqual(
202 self.response.status, android_pb2.MARK_STABLE_STATUS_PINNED
203 )
LaMont Jones8a1644f2019-04-16 14:30:17 -0600204
205
Alex Klein231d2da2019-07-22 16:44:45 -0600206class UnpinVersionTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600207 """Unittests for UnpinVersion."""
LaMont Jones8a1644f2019-04-16 14:30:17 -0600208
Alex Klein1699fab2022-09-08 08:46:06 -0600209 def testCallsUnlink(self):
210 """SetAndroid calls service with correct args."""
211 safeunlink = self.PatchObject(osutils, "SafeUnlink")
212 self.PatchObject(constants, "_FindSourceRoot", return_value="SRCROOT")
LaMont Jones8a1644f2019-04-16 14:30:17 -0600213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 # This has the side effect of making sure that input and output proto are
215 # not actually used.
216 android.UnpinVersion(None, None, self.api_config)
217 safeunlink.assert_called_once_with(android.ANDROIDPIN_MASK_PATH)
Alex Klein231d2da2019-07-22 16:44:45 -0600218
Alex Klein1699fab2022-09-08 08:46:06 -0600219 def testValidateOnly(self):
220 """Sanity check that a validate only call does not execute any logic."""
221 safeunlink = self.PatchObject(osutils, "SafeUnlink")
Alex Klein231d2da2019-07-22 16:44:45 -0600222
Alex Klein1699fab2022-09-08 08:46:06 -0600223 android.UnpinVersion(None, None, self.validate_only_config)
224 safeunlink.assert_not_called()
Michael Mortensen25626442019-11-22 10:06:59 -0700225
Alex Klein1699fab2022-09-08 08:46:06 -0600226 def testMockCall(self):
227 """Test that a mock call does not execute logic."""
228 safeunlink = self.PatchObject(osutils, "SafeUnlink")
Michael Mortensen25626442019-11-22 10:06:59 -0700229
Alex Klein1699fab2022-09-08 08:46:06 -0600230 android.UnpinVersion(None, None, self.mock_call_config)
231 safeunlink.assert_not_called()
232 # android.UnpinVersion does not modify the response.
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900233
234
235class WriteLKGBTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600236 """Unittests for WriteLKGB."""
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900237
Alex Klein1699fab2022-09-08 08:46:06 -0600238 def setUp(self):
239 self._output_proto = android_pb2.WriteLKGBResponse()
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900240
Alex Klein1699fab2022-09-08 08:46:06 -0600241 def testValidateOnly(self):
242 """Test that a validate only call does not execute any logic."""
243 mock_write_lkgb = self.PatchObject(service_android, "WriteLKGB")
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900244
Alex Klein1699fab2022-09-08 08:46:06 -0600245 req = android_pb2.WriteLKGBRequest(
246 android_package="android-package", android_version="android-version"
247 )
248 android.WriteLKGB(req, self._output_proto, self.validate_only_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900249
Alex Klein1699fab2022-09-08 08:46:06 -0600250 mock_write_lkgb.assert_not_called()
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900251
Alex Klein1699fab2022-09-08 08:46:06 -0600252 def testMockCall(self):
253 """Test that a mock call does not execute logic, returns mocked value."""
254 mock_write_lkgb = self.PatchObject(service_android, "WriteLKGB")
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900255
Alex Klein1699fab2022-09-08 08:46:06 -0600256 req = android_pb2.WriteLKGBRequest(
257 android_package="android-package", android_version="android-version"
258 )
259 android.WriteLKGB(req, self._output_proto, self.mock_call_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900260
Alex Klein1699fab2022-09-08 08:46:06 -0600261 mock_write_lkgb.assert_not_called()
262 self.assertSequenceEqual(
263 self._output_proto.modified_files, ["fake_file"]
264 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900265
Alex Klein1699fab2022-09-08 08:46:06 -0600266 def testFailsIfAndroidPackageMissing(self):
267 """Fails if android_package is missing."""
268 req = android_pb2.WriteLKGBRequest(android_version="android-version")
269 with self.assertRaises(cros_build_lib.DieSystemExit):
270 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900271
Alex Klein1699fab2022-09-08 08:46:06 -0600272 def testFailsIfAndroidVersionMissing(self):
273 """Fails if android_version is missing."""
274 req = android_pb2.WriteLKGBRequest(android_package="android-package")
275 with self.assertRaises(cros_build_lib.DieSystemExit):
276 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900277
Alex Klein1699fab2022-09-08 08:46:06 -0600278 def testSuccess(self):
279 """Successful request."""
280 mock_read_lkgb = self.PatchObject(
281 service_android, "ReadLKGB", return_value="old-version"
282 )
283 mock_write_lkgb = self.PatchObject(
284 service_android, "WriteLKGB", return_value="mock_file"
285 )
286 self.PatchObject(
287 service_android,
288 "GetAndroidPackageDir",
289 return_value="android-package-dir",
290 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900291
Alex Klein1699fab2022-09-08 08:46:06 -0600292 req = android_pb2.WriteLKGBRequest(
293 android_package="android-package", android_version="android-version"
294 )
295 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900296
Alex Klein1699fab2022-09-08 08:46:06 -0600297 mock_read_lkgb.assert_called_once_with("android-package-dir")
298 mock_write_lkgb.assert_called_once_with(
299 "android-package-dir", "android-version"
300 )
301 self.assertSequenceEqual(
302 self._output_proto.modified_files, ["mock_file"]
303 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900304
Alex Klein1699fab2022-09-08 08:46:06 -0600305 def testSameVersion(self):
306 """Nothing is modified if LKGB is already the same version."""
307 mock_read_lkgb = self.PatchObject(
308 service_android, "ReadLKGB", return_value="android-version"
309 )
310 mock_write_lkgb = self.PatchObject(service_android, "WriteLKGB")
311 self.PatchObject(
312 service_android,
313 "GetAndroidPackageDir",
314 return_value="android-package-dir",
315 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900316
Alex Klein1699fab2022-09-08 08:46:06 -0600317 req = android_pb2.WriteLKGBRequest(
318 android_package="android-package", android_version="android-version"
319 )
320 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900321
Alex Klein1699fab2022-09-08 08:46:06 -0600322 mock_read_lkgb.assert_called_once_with("android-package-dir")
323 mock_write_lkgb.assert_not_called()
324 self.assertSequenceEqual(self._output_proto.modified_files, [])
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900325
Alex Klein1699fab2022-09-08 08:46:06 -0600326 def testMissingLKGB(self):
327 """Proceed if LKGB file is currently missing."""
328 mock_read_lkgb = self.PatchObject(
329 service_android,
330 "ReadLKGB",
331 side_effect=service_android.MissingLKGBError(),
332 )
333 mock_write_lkgb = self.PatchObject(
334 service_android, "WriteLKGB", return_value="mock_file"
335 )
336 self.PatchObject(
337 service_android,
338 "GetAndroidPackageDir",
339 return_value="android-package-dir",
340 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900341
Alex Klein1699fab2022-09-08 08:46:06 -0600342 req = android_pb2.WriteLKGBRequest(
343 android_package="android-package", android_version="android-version"
344 )
345 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900346
Alex Klein1699fab2022-09-08 08:46:06 -0600347 mock_read_lkgb.assert_called_once_with("android-package-dir")
348 mock_write_lkgb.assert_called_once_with(
349 "android-package-dir", "android-version"
350 )
351 self.assertSequenceEqual(
352 self._output_proto.modified_files, ["mock_file"]
353 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900354
Alex Klein1699fab2022-09-08 08:46:06 -0600355 def testInvalidLKGB(self):
356 """Proceed if LKGB file currently contains invalid content."""
357 mock_read_lkgb = self.PatchObject(
358 service_android,
359 "ReadLKGB",
360 side_effect=service_android.InvalidLKGBError(),
361 )
362 mock_write_lkgb = self.PatchObject(
363 service_android, "WriteLKGB", return_value="mock_file"
364 )
365 self.PatchObject(
366 service_android,
367 "GetAndroidPackageDir",
368 return_value="android-package-dir",
369 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900370
Alex Klein1699fab2022-09-08 08:46:06 -0600371 req = android_pb2.WriteLKGBRequest(
372 android_package="android-package", android_version="android-version"
373 )
374 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900375
Alex Klein1699fab2022-09-08 08:46:06 -0600376 mock_read_lkgb.assert_called_once_with("android-package-dir")
377 mock_write_lkgb.assert_called_once_with(
378 "android-package-dir", "android-version"
379 )
380 self.assertSequenceEqual(
381 self._output_proto.modified_files, ["mock_file"]
382 )