blob: 8c37306177b939d873552553a6bef00339609516 [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", {})
Alex Klein1699fab2022-09-08 08:46:06 -060028 self._output_proto = android_pb2.GetLatestBuildResponse()
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090029
Shao-Chuan Leed66bc992022-10-26 22:35:50 +090030 def _GetRequest(self, android_package=None):
Alex Klein1699fab2022-09-08 08:46:06 -060031 req = android_pb2.GetLatestBuildRequest()
Alex Klein1699fab2022-09-08 08:46:06 -060032 if android_package is not None:
33 req.android_package = android_package
34 return req
Shao-Chuan Lee6e8784a2021-05-13 09:34:46 +090035
Alex Klein1699fab2022-09-08 08:46:06 -060036 def testValidateOnly(self):
37 """Test that a validate only call does not execute any logic."""
38 req = self._GetRequest(android_package="android-package")
39 android.GetLatestBuild(
40 req, self._output_proto, self.validate_only_config
41 )
42 self._mock.assert_not_called()
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090043
Alex Klein1699fab2022-09-08 08:46:06 -060044 def testMockCall(self):
45 """Test that a mock call does not execute logic, returns mocked value."""
46 req = self._GetRequest(android_package="android-package")
47 android.GetLatestBuild(req, self._output_proto, self.mock_call_config)
48 self._mock.assert_not_called()
49 self.assertEqual(self._output_proto.android_version, "7123456")
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090050
Shao-Chuan Leed66bc992022-10-26 22:35:50 +090051 def testFailsIfPackageMissing(self):
52 """Fails if android_package is missing."""
Alex Klein1699fab2022-09-08 08:46:06 -060053 req = self._GetRequest()
54 with self.assertRaises(cros_build_lib.DieSystemExit):
55 android.GetLatestBuild(req, self._output_proto, self.api_config)
56 self._mock.assert_not_called()
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090057
Shao-Chuan Leed66bc992022-10-26 22:35:50 +090058 def testSuccess(self):
59 """Test a successful call."""
Alex Klein1699fab2022-09-08 08:46:06 -060060 req = self._GetRequest(android_package="android-package")
61 android.GetLatestBuild(req, self._output_proto, self.api_config)
Shao-Chuan Leed66bc992022-10-26 22:35:50 +090062 self._mock.assert_called_once_with("android-package")
Alex Klein1699fab2022-09-08 08:46:06 -060063 self.assertEqual(self._output_proto.android_version, "7123456")
Shao-Chuan Lee01dee222021-04-09 15:28:08 +090064
65
Alex Klein231d2da2019-07-22 16:44:45 -060066class MarkStableTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -060067 """Unittests for MarkStable."""
LaMont Jones8a1644f2019-04-16 14:30:17 -060068
Alex Klein1699fab2022-09-08 08:46:06 -060069 def setUp(self):
70 self.uprev = self.PatchObject(packages, "uprev_android")
LaMont Jones8a1644f2019-04-16 14:30:17 -060071
Alex Klein1699fab2022-09-08 08:46:06 -060072 self.input_proto = android_pb2.MarkStableRequest()
73 self.input_proto.package_name = "android-package-name"
74 self.input_proto.android_build_branch = "android_build_branch"
75 self.input_proto.android_version = "android-version"
76 self.input_proto.build_targets.add().name = "foo"
77 self.input_proto.build_targets.add().name = "bar"
78 self.input_proto.skip_commit = True
Alex Klein4de25e82019-08-05 15:58:39 -060079
Alex Klein1699fab2022-09-08 08:46:06 -060080 self.build_targets = [
81 build_target_lib.BuildTarget("foo"),
82 build_target_lib.BuildTarget("bar"),
83 ]
LaMont Jones8a1644f2019-04-16 14:30:17 -060084
Alex Klein1699fab2022-09-08 08:46:06 -060085 self.response = android_pb2.MarkStableResponse()
Alex Klein231d2da2019-07-22 16:44:45 -060086
Alex Klein1699fab2022-09-08 08:46:06 -060087 def testValidateOnly(self):
88 """Sanity check that a validate only call does not execute any logic."""
89 android.MarkStable(
90 self.input_proto, self.response, self.validate_only_config
91 )
92 self.uprev.assert_not_called()
Alex Klein231d2da2019-07-22 16:44:45 -060093
Alex Klein1699fab2022-09-08 08:46:06 -060094 def testMockCall(self):
95 """Test that a mock call does not execute logic, returns mocked value."""
96 android.MarkStable(
97 self.input_proto, self.response, self.mock_call_config
98 )
99 self.uprev.assert_not_called()
100 self.assertEqual(
101 self.response.status, android_pb2.MARK_STABLE_STATUS_SUCCESS
102 )
103 self.assertEqual(self.response.android_atom.category, "category")
104 self.assertEqual(
105 self.response.android_atom.package_name, "android-package-name"
106 )
107 self.assertEqual(self.response.android_atom.version, "1.2")
Michael Mortensen25626442019-11-22 10:06:59 -0700108
Alex Klein1699fab2022-09-08 08:46:06 -0600109 def testFailsIfPackageNameMissing(self):
110 """Fails if package_name is missing."""
111 self.input_proto.package_name = ""
112 with self.assertRaises(cros_build_lib.DieSystemExit):
113 android.MarkStable(self.input_proto, self.response, self.api_config)
114 self.uprev.assert_not_called()
LaMont Jones8a1644f2019-04-16 14:30:17 -0600115
Alex Klein1699fab2022-09-08 08:46:06 -0600116 def testCallsCommandCorrectly(self):
117 """Test that commands.MarkAndroidAsStable is called correctly."""
118 self.uprev.return_value = packages.UprevAndroidResult(
119 revved=True, android_atom="cat/android-1.2.3"
120 )
121 atom = common_pb2.PackageInfo()
122 atom.category = "cat"
123 atom.package_name = "android"
124 atom.version = "1.2.3"
125 android.MarkStable(self.input_proto, self.response, self.api_config)
126 self.uprev.assert_called_once_with(
127 android_package=self.input_proto.package_name,
128 chroot=mock.ANY,
129 build_targets=self.build_targets,
130 android_build_branch=self.input_proto.android_build_branch,
131 android_version=self.input_proto.android_version,
132 skip_commit=self.input_proto.skip_commit,
133 )
134 self.assertEqual(self.response.android_atom, atom)
135 self.assertEqual(
136 self.response.status, android_pb2.MARK_STABLE_STATUS_SUCCESS
137 )
LaMont Jones8a1644f2019-04-16 14:30:17 -0600138
Alex Klein1699fab2022-09-08 08:46:06 -0600139 def testHandlesEarlyExit(self):
140 """Test that early exit is handled correctly."""
141 self.uprev.return_value = packages.UprevAndroidResult(revved=False)
142 android.MarkStable(self.input_proto, self.response, self.api_config)
143 self.uprev.assert_called_once_with(
144 android_package=self.input_proto.package_name,
145 chroot=mock.ANY,
146 build_targets=self.build_targets,
147 android_build_branch=self.input_proto.android_build_branch,
148 android_version=self.input_proto.android_version,
149 skip_commit=self.input_proto.skip_commit,
150 )
151 self.assertEqual(
152 self.response.status, android_pb2.MARK_STABLE_STATUS_EARLY_EXIT
153 )
LaMont Jones8a1644f2019-04-16 14:30:17 -0600154
Alex Klein1699fab2022-09-08 08:46:06 -0600155 def testHandlesPinnedUprevError(self):
156 """Test that pinned error is handled correctly."""
157 self.uprev.side_effect = packages.AndroidIsPinnedUprevError(
158 "pin/xx-1.1"
159 )
160 atom = common_pb2.PackageInfo()
161 atom.category = "pin"
162 atom.package_name = "xx"
163 atom.version = "1.1"
164 android.MarkStable(self.input_proto, self.response, self.api_config)
165 self.uprev.assert_called_once_with(
166 android_package=self.input_proto.package_name,
167 chroot=mock.ANY,
168 build_targets=self.build_targets,
169 android_build_branch=self.input_proto.android_build_branch,
170 android_version=self.input_proto.android_version,
171 skip_commit=self.input_proto.skip_commit,
172 )
173 self.assertEqual(self.response.android_atom, atom)
174 self.assertEqual(
175 self.response.status, android_pb2.MARK_STABLE_STATUS_PINNED
176 )
LaMont Jones8a1644f2019-04-16 14:30:17 -0600177
178
Alex Klein231d2da2019-07-22 16:44:45 -0600179class UnpinVersionTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600180 """Unittests for UnpinVersion."""
LaMont Jones8a1644f2019-04-16 14:30:17 -0600181
Alex Klein1699fab2022-09-08 08:46:06 -0600182 def testCallsUnlink(self):
183 """SetAndroid calls service with correct args."""
184 safeunlink = self.PatchObject(osutils, "SafeUnlink")
185 self.PatchObject(constants, "_FindSourceRoot", return_value="SRCROOT")
LaMont Jones8a1644f2019-04-16 14:30:17 -0600186
Alex Klein1699fab2022-09-08 08:46:06 -0600187 # This has the side effect of making sure that input and output proto are
188 # not actually used.
189 android.UnpinVersion(None, None, self.api_config)
190 safeunlink.assert_called_once_with(android.ANDROIDPIN_MASK_PATH)
Alex Klein231d2da2019-07-22 16:44:45 -0600191
Alex Klein1699fab2022-09-08 08:46:06 -0600192 def testValidateOnly(self):
193 """Sanity check that a validate only call does not execute any logic."""
194 safeunlink = self.PatchObject(osutils, "SafeUnlink")
Alex Klein231d2da2019-07-22 16:44:45 -0600195
Alex Klein1699fab2022-09-08 08:46:06 -0600196 android.UnpinVersion(None, None, self.validate_only_config)
197 safeunlink.assert_not_called()
Michael Mortensen25626442019-11-22 10:06:59 -0700198
Alex Klein1699fab2022-09-08 08:46:06 -0600199 def testMockCall(self):
200 """Test that a mock call does not execute logic."""
201 safeunlink = self.PatchObject(osutils, "SafeUnlink")
Michael Mortensen25626442019-11-22 10:06:59 -0700202
Alex Klein1699fab2022-09-08 08:46:06 -0600203 android.UnpinVersion(None, None, self.mock_call_config)
204 safeunlink.assert_not_called()
205 # android.UnpinVersion does not modify the response.
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900206
207
208class WriteLKGBTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Alex Klein1699fab2022-09-08 08:46:06 -0600209 """Unittests for WriteLKGB."""
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900210
Alex Klein1699fab2022-09-08 08:46:06 -0600211 def setUp(self):
212 self._output_proto = android_pb2.WriteLKGBResponse()
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900213
Alex Klein1699fab2022-09-08 08:46:06 -0600214 def testValidateOnly(self):
215 """Test that a validate only call does not execute any logic."""
216 mock_write_lkgb = self.PatchObject(service_android, "WriteLKGB")
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900217
Alex Klein1699fab2022-09-08 08:46:06 -0600218 req = android_pb2.WriteLKGBRequest(
219 android_package="android-package", android_version="android-version"
220 )
221 android.WriteLKGB(req, self._output_proto, self.validate_only_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900222
Alex Klein1699fab2022-09-08 08:46:06 -0600223 mock_write_lkgb.assert_not_called()
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900224
Alex Klein1699fab2022-09-08 08:46:06 -0600225 def testMockCall(self):
226 """Test that a mock call does not execute logic, returns mocked value."""
227 mock_write_lkgb = self.PatchObject(service_android, "WriteLKGB")
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900228
Alex Klein1699fab2022-09-08 08:46:06 -0600229 req = android_pb2.WriteLKGBRequest(
230 android_package="android-package", android_version="android-version"
231 )
232 android.WriteLKGB(req, self._output_proto, self.mock_call_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900233
Alex Klein1699fab2022-09-08 08:46:06 -0600234 mock_write_lkgb.assert_not_called()
235 self.assertSequenceEqual(
236 self._output_proto.modified_files, ["fake_file"]
237 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900238
Alex Klein1699fab2022-09-08 08:46:06 -0600239 def testFailsIfAndroidPackageMissing(self):
240 """Fails if android_package is missing."""
241 req = android_pb2.WriteLKGBRequest(android_version="android-version")
242 with self.assertRaises(cros_build_lib.DieSystemExit):
243 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900244
Alex Klein1699fab2022-09-08 08:46:06 -0600245 def testFailsIfAndroidVersionMissing(self):
246 """Fails if android_version is missing."""
247 req = android_pb2.WriteLKGBRequest(android_package="android-package")
248 with self.assertRaises(cros_build_lib.DieSystemExit):
249 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900250
Alex Klein1699fab2022-09-08 08:46:06 -0600251 def testSuccess(self):
252 """Successful request."""
253 mock_read_lkgb = self.PatchObject(
254 service_android, "ReadLKGB", return_value="old-version"
255 )
256 mock_write_lkgb = self.PatchObject(
257 service_android, "WriteLKGB", return_value="mock_file"
258 )
259 self.PatchObject(
260 service_android,
261 "GetAndroidPackageDir",
262 return_value="android-package-dir",
263 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900264
Alex Klein1699fab2022-09-08 08:46:06 -0600265 req = android_pb2.WriteLKGBRequest(
266 android_package="android-package", android_version="android-version"
267 )
268 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900269
Alex Klein1699fab2022-09-08 08:46:06 -0600270 mock_read_lkgb.assert_called_once_with("android-package-dir")
271 mock_write_lkgb.assert_called_once_with(
272 "android-package-dir", "android-version"
273 )
274 self.assertSequenceEqual(
275 self._output_proto.modified_files, ["mock_file"]
276 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900277
Alex Klein1699fab2022-09-08 08:46:06 -0600278 def testSameVersion(self):
279 """Nothing is modified if LKGB is already the same version."""
280 mock_read_lkgb = self.PatchObject(
281 service_android, "ReadLKGB", return_value="android-version"
282 )
283 mock_write_lkgb = self.PatchObject(service_android, "WriteLKGB")
284 self.PatchObject(
285 service_android,
286 "GetAndroidPackageDir",
287 return_value="android-package-dir",
288 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900289
Alex Klein1699fab2022-09-08 08:46:06 -0600290 req = android_pb2.WriteLKGBRequest(
291 android_package="android-package", android_version="android-version"
292 )
293 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900294
Alex Klein1699fab2022-09-08 08:46:06 -0600295 mock_read_lkgb.assert_called_once_with("android-package-dir")
296 mock_write_lkgb.assert_not_called()
297 self.assertSequenceEqual(self._output_proto.modified_files, [])
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900298
Alex Klein1699fab2022-09-08 08:46:06 -0600299 def testMissingLKGB(self):
300 """Proceed if LKGB file is currently missing."""
301 mock_read_lkgb = self.PatchObject(
302 service_android,
303 "ReadLKGB",
304 side_effect=service_android.MissingLKGBError(),
305 )
306 mock_write_lkgb = self.PatchObject(
307 service_android, "WriteLKGB", return_value="mock_file"
308 )
309 self.PatchObject(
310 service_android,
311 "GetAndroidPackageDir",
312 return_value="android-package-dir",
313 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900314
Alex Klein1699fab2022-09-08 08:46:06 -0600315 req = android_pb2.WriteLKGBRequest(
316 android_package="android-package", android_version="android-version"
317 )
318 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900319
Alex Klein1699fab2022-09-08 08:46:06 -0600320 mock_read_lkgb.assert_called_once_with("android-package-dir")
321 mock_write_lkgb.assert_called_once_with(
322 "android-package-dir", "android-version"
323 )
324 self.assertSequenceEqual(
325 self._output_proto.modified_files, ["mock_file"]
326 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900327
Alex Klein1699fab2022-09-08 08:46:06 -0600328 def testInvalidLKGB(self):
329 """Proceed if LKGB file currently contains invalid content."""
330 mock_read_lkgb = self.PatchObject(
331 service_android,
332 "ReadLKGB",
333 side_effect=service_android.InvalidLKGBError(),
334 )
335 mock_write_lkgb = self.PatchObject(
336 service_android, "WriteLKGB", return_value="mock_file"
337 )
338 self.PatchObject(
339 service_android,
340 "GetAndroidPackageDir",
341 return_value="android-package-dir",
342 )
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900343
Alex Klein1699fab2022-09-08 08:46:06 -0600344 req = android_pb2.WriteLKGBRequest(
345 android_package="android-package", android_version="android-version"
346 )
347 android.WriteLKGB(req, self._output_proto, self.api_config)
Shao-Chuan Leeddcca812021-12-10 15:11:16 +0900348
Alex Klein1699fab2022-09-08 08:46:06 -0600349 mock_read_lkgb.assert_called_once_with("android-package-dir")
350 mock_write_lkgb.assert_called_once_with(
351 "android-package-dir", "android-version"
352 )
353 self.assertSequenceEqual(
354 self._output_proto.modified_files, ["mock_file"]
355 )