blob: fe2adf1dbecc681d9aa130e03d3d41f27959ad52 [file] [log] [blame]
Mike Frysingerf1ba7ad2022-09-12 05:42:57 -04001# Copyright 2019 The ChromiumOS Authors
Alex Kleina9d500b2019-04-22 15:37:51 -06002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""controller_util unittests."""
6
Greg Edelston1f5deb62023-03-31 14:22:08 -06007from pathlib import Path
8
Alex Kleina9d500b2019-04-22 15:37:51 -06009from chromite.api.controller import controller_util
Alex Klein171da612019-08-06 14:00:42 -060010from chromite.api.gen.chromite.api import build_api_test_pb2
Alex Klein26e472b2020-03-10 14:35:01 -060011from chromite.api.gen.chromite.api import sysroot_pb2
Alex Kleina9d500b2019-04-22 15:37:51 -060012from chromite.api.gen.chromiumos import common_pb2
Alex Klein247d7922023-01-18 15:36:02 -070013from chromite.lib import binpkg
Alex Klein26e472b2020-03-10 14:35:01 -060014from chromite.lib import build_target_lib
Alex Klein7f768322023-01-18 15:34:01 -070015from chromite.lib import chroot_lib
Alex Klein18a60af2020-06-11 12:08:47 -060016from chromite.lib import cros_test_lib
Alex Klein7f768322023-01-18 15:34:01 -070017from chromite.lib import sysroot_lib
Mike Frysinger1cc8f1f2022-04-28 22:40:40 -040018from chromite.lib.parser import package_info
Alex Klein171da612019-08-06 14:00:42 -060019
20
Michael Mortensen9a73c322019-10-03 17:14:37 -060021class ParseChrootTest(cros_test_lib.MockTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -060022 """ParseChroot tests."""
Alex Klein171da612019-08-06 14:00:42 -060023
Alex Klein1699fab2022-09-08 08:46:06 -060024 def testSuccess(self):
25 """Test successful handling case."""
26 path = "/chroot/path"
27 cache_dir = "/cache/dir"
28 chrome_root = "/chrome/root"
29 use_flags = [{"flag": "useflag1"}, {"flag": "useflag2"}]
30 features = [{"feature": "feature1"}, {"feature": "feature2"}]
31 expected_env = {
32 "USE": "useflag1 useflag2",
33 "FEATURES": "feature1 feature2",
34 "CHROME_ORIGIN": "LOCAL_SOURCE",
35 }
Alex Klein171da612019-08-06 14:00:42 -060036
Alex Klein1699fab2022-09-08 08:46:06 -060037 chroot_message = common_pb2.Chroot(
38 path=path,
39 cache_dir=cache_dir,
40 chrome_dir=chrome_root,
41 env={"use_flags": use_flags, "features": features},
42 )
Alex Klein171da612019-08-06 14:00:42 -060043
Alex Klein7f768322023-01-18 15:34:01 -070044 expected = chroot_lib.Chroot(
Alex Klein1699fab2022-09-08 08:46:06 -060045 path=path,
46 cache_dir=cache_dir,
47 chrome_root=chrome_root,
48 env=expected_env,
49 )
50 result = controller_util.ParseChroot(chroot_message)
Alex Klein171da612019-08-06 14:00:42 -060051
Alex Klein1699fab2022-09-08 08:46:06 -060052 self.assertEqual(expected, result)
Alex Klein171da612019-08-06 14:00:42 -060053
Alex Klein1699fab2022-09-08 08:46:06 -060054 def testWrongMessage(self):
55 """Test invalid message type given."""
56 with self.assertRaises(AssertionError):
57 controller_util.ParseChroot(common_pb2.BuildTarget())
58
Alex Klein171da612019-08-06 14:00:42 -060059
George Engelbrechtc9a8e812021-06-16 18:14:17 -060060class ParseSysrootTest(cros_test_lib.MockTestCase):
Alex Klein1699fab2022-09-08 08:46:06 -060061 """ParseSysroot tests."""
George Engelbrechtc9a8e812021-06-16 18:14:17 -060062
Alex Klein1699fab2022-09-08 08:46:06 -060063 def testSuccess(self):
64 """test successful handling case."""
65 path = "/build/rare_pokemon"
66 sysroot_message = sysroot_pb2.Sysroot(path=path)
Alex Klein7f768322023-01-18 15:34:01 -070067 expected = sysroot_lib.Sysroot(path=path)
Alex Klein1699fab2022-09-08 08:46:06 -060068 result = controller_util.ParseSysroot(sysroot_message)
69 self.assertEqual(expected, result)
George Engelbrechtc9a8e812021-06-16 18:14:17 -060070
Alex Klein1699fab2022-09-08 08:46:06 -060071 def testWrongMessage(self):
72 with self.assertRaises(AssertionError):
73 controller_util.ParseSysroot(common_pb2.BuildTarget())
74
Alex Klein171da612019-08-06 14:00:42 -060075
76class ParseBuildTargetTest(cros_test_lib.TestCase):
Alex Klein1699fab2022-09-08 08:46:06 -060077 """ParseBuildTarget tests."""
Alex Klein171da612019-08-06 14:00:42 -060078
Alex Klein1699fab2022-09-08 08:46:06 -060079 def testSuccess(self):
80 """Test successful handling case."""
81 name = "board"
82 build_target_message = common_pb2.BuildTarget(name=name)
83 expected = build_target_lib.BuildTarget(name)
84 result = controller_util.ParseBuildTarget(build_target_message)
Alex Klein171da612019-08-06 14:00:42 -060085
Alex Klein1699fab2022-09-08 08:46:06 -060086 self.assertEqual(expected, result)
Alex Klein171da612019-08-06 14:00:42 -060087
Alex Klein1699fab2022-09-08 08:46:06 -060088 def testParseProfile(self):
89 """Test the parsing of a profile."""
90 name = "build-target-name"
91 profile = "profile"
92 build_target_msg = common_pb2.BuildTarget(name=name)
93 profile_msg = sysroot_pb2.Profile(name=profile)
Alex Klein26e472b2020-03-10 14:35:01 -060094
Alex Klein1699fab2022-09-08 08:46:06 -060095 expected = build_target_lib.BuildTarget(name, profile=profile)
96 result = controller_util.ParseBuildTarget(
97 build_target_msg, profile_message=profile_msg
98 )
Alex Klein26e472b2020-03-10 14:35:01 -060099
Alex Klein1699fab2022-09-08 08:46:06 -0600100 self.assertEqual(expected, result)
Alex Klein26e472b2020-03-10 14:35:01 -0600101
Alex Klein1699fab2022-09-08 08:46:06 -0600102 def testWrongMessage(self):
103 """Test invalid message type given."""
104 with self.assertRaises(AssertionError):
105 controller_util.ParseBuildTarget(
106 build_api_test_pb2.TestRequestMessage()
107 )
Alex Klein171da612019-08-06 14:00:42 -0600108
109
110class ParseBuildTargetsTest(cros_test_lib.TestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600111 """ParseBuildTargets tests."""
Alex Klein171da612019-08-06 14:00:42 -0600112
Alex Klein1699fab2022-09-08 08:46:06 -0600113 def testSuccess(self):
114 """Test successful handling case."""
115 names = ["foo", "bar", "baz"]
116 message = build_api_test_pb2.TestRequestMessage()
117 for name in names:
118 message.build_targets.add().name = name
Alex Klein171da612019-08-06 14:00:42 -0600119
Alex Klein1699fab2022-09-08 08:46:06 -0600120 result = controller_util.ParseBuildTargets(message.build_targets)
Alex Klein171da612019-08-06 14:00:42 -0600121
Alex Klein1699fab2022-09-08 08:46:06 -0600122 expected = [build_target_lib.BuildTarget(name) for name in names]
123 self.assertCountEqual(expected, result)
Alex Klein171da612019-08-06 14:00:42 -0600124
Alex Klein1699fab2022-09-08 08:46:06 -0600125 def testWrongMessage(self):
126 """Wrong message type handling."""
127 message = common_pb2.Chroot()
128 message.env.use_flags.add().flag = "foo"
129 message.env.use_flags.add().flag = "bar"
Alex Klein171da612019-08-06 14:00:42 -0600130
Alex Klein1699fab2022-09-08 08:46:06 -0600131 with self.assertRaises(AssertionError):
132 controller_util.ParseBuildTargets(message.env.use_flags)
Alex Kleina9d500b2019-04-22 15:37:51 -0600133
134
Alex Kleina9d500b2019-04-22 15:37:51 -0600135class PackageInfoToStringTest(cros_test_lib.TestCase):
Alex Klein1699fab2022-09-08 08:46:06 -0600136 """PackageInfoToString tests."""
Alex Kleina9d500b2019-04-22 15:37:51 -0600137
Alex Klein1699fab2022-09-08 08:46:06 -0600138 def testAllFields(self):
139 """Test all fields present."""
140 pi = common_pb2.PackageInfo()
141 pi.package_name = "pkg"
142 pi.category = "cat"
143 pi.version = "2.0.0"
Alex Kleina9d500b2019-04-22 15:37:51 -0600144
Alex Klein1699fab2022-09-08 08:46:06 -0600145 cpv_str = controller_util.PackageInfoToString(pi)
Alex Kleina9d500b2019-04-22 15:37:51 -0600146
Alex Klein1699fab2022-09-08 08:46:06 -0600147 self.assertEqual("cat/pkg-2.0.0", cpv_str)
Alex Kleina9d500b2019-04-22 15:37:51 -0600148
Alex Klein1699fab2022-09-08 08:46:06 -0600149 def testNoVersion(self):
150 """Test no version provided."""
151 pi = common_pb2.PackageInfo()
152 pi.package_name = "pkg"
153 pi.category = "cat"
Alex Kleina9d500b2019-04-22 15:37:51 -0600154
Alex Klein1699fab2022-09-08 08:46:06 -0600155 cpv_str = controller_util.PackageInfoToString(pi)
Alex Kleina9d500b2019-04-22 15:37:51 -0600156
Alex Klein1699fab2022-09-08 08:46:06 -0600157 self.assertEqual("cat/pkg", cpv_str)
Alex Kleina9d500b2019-04-22 15:37:51 -0600158
Alex Klein1699fab2022-09-08 08:46:06 -0600159 def testPackageOnly(self):
160 """Test no version provided."""
161 pi = common_pb2.PackageInfo()
162 pi.package_name = "pkg"
Alex Kleina9d500b2019-04-22 15:37:51 -0600163
Alex Klein1699fab2022-09-08 08:46:06 -0600164 cpv_str = controller_util.PackageInfoToString(pi)
Alex Kleina9d500b2019-04-22 15:37:51 -0600165
Alex Klein1699fab2022-09-08 08:46:06 -0600166 self.assertEqual("pkg", cpv_str)
Alex Kleina9d500b2019-04-22 15:37:51 -0600167
Alex Klein1699fab2022-09-08 08:46:06 -0600168 def testNoPackageName(self):
169 """Test no package name given."""
170 pi = common_pb2.PackageInfo()
Alex Kleina9d500b2019-04-22 15:37:51 -0600171
Alex Klein1699fab2022-09-08 08:46:06 -0600172 with self.assertRaises(ValueError):
173 controller_util.PackageInfoToString(pi)
Alex Kleina9d500b2019-04-22 15:37:51 -0600174
175
Alex Klein1e68a8e2020-10-06 17:25:11 -0600176def test_serialize_package_info():
Alex Klein1699fab2022-09-08 08:46:06 -0600177 pkg_info = package_info.parse("foo/bar-1.2.3-r4")
178 pkg_info_msg = common_pb2.PackageInfo()
179 controller_util.serialize_package_info(pkg_info, pkg_info_msg)
180 assert pkg_info_msg.category == "foo"
181 assert pkg_info_msg.package_name == "bar"
182 assert pkg_info_msg.version == "1.2.3-r4"
Alex Klein1e68a8e2020-10-06 17:25:11 -0600183
184
185def test_deserialize_package_info():
Alex Klein1699fab2022-09-08 08:46:06 -0600186 pkg_info_msg = common_pb2.PackageInfo()
187 pkg_info_msg.category = "foo"
188 pkg_info_msg.package_name = "bar"
189 pkg_info_msg.version = "1.2.3-r4"
190 pkg_info = controller_util.deserialize_package_info(pkg_info_msg)
191 assert pkg_info.cpvr == "foo/bar-1.2.3-r4"
Lizzy Presland29e62452022-01-05 21:58:21 +0000192
193
Lizzy Preslandfebffa72022-02-24 23:38:58 +0000194def test_retrieve_package_log_paths():
Alex Klein1699fab2022-09-08 08:46:06 -0600195 packages = [
196 package_info.parse("foo/bar%d-1.0-r1" % num) for num in range(1, 4)
197 ]
198 output_proto = sysroot_pb2.InstallPackagesResponse()
Alex Klein7f768322023-01-18 15:34:01 -0700199 target_sysroot = sysroot_lib.Sysroot(path="/path/to/sysroot")
Alex Klein1699fab2022-09-08 08:46:06 -0600200 controller_util.retrieve_package_log_paths(
201 packages, output_proto, target_sysroot
202 )
203 assert len(output_proto.failed_package_data) == 3
Alex Klein247d7922023-01-18 15:36:02 -0700204
205
206def test_package_index_info():
207 """Quick check converting to/from protobuf works."""
208 sha = "SHA"
209 number = 5
210 build_target_name = "build_target"
211 profile_name = "profile"
212 location = "location"
213
214 msg = common_pb2.PackageIndexInfo()
215 msg.snapshot_sha = sha
216 msg.snapshot_number = number
217 msg.build_target.name = build_target_name
218 msg.profile.name = profile_name
219 msg.location = location
220
221 obj = binpkg.PackageIndexInfo(
222 snapshot_sha=sha,
223 snapshot_number=number,
224 build_target=build_target_lib.BuildTarget(name=build_target_name),
225 profile=sysroot_lib.Profile(name=profile_name),
226 location=location,
227 )
228
229 assert obj == controller_util.deserialize_package_index_info(msg)
Greg Edelston1f5deb62023-03-31 14:22:08 -0600230
231
232class Pb2PathToPathlibPathTest(cros_test_lib.TestCase):
233 """Verify functionality for pb2_path_to_pathlib_path()."""
234
235 chroot = common_pb2.Chroot(path="/path/to/chroot")
236
237 @staticmethod
238 def create_pb2_path(path: str, inside: bool) -> common_pb2.Path:
239 """Helper function to create a common_pb2.Path."""
240 location = (
241 common_pb2.Path.Location.INSIDE
242 if inside
243 else common_pb2.Path.Location.OUTSIDE
244 )
245 return common_pb2.Path(path=path, location=location)
246
247 def test_relative_inside(self):
248 """Verify that passing in a relative path inside the chroot fails"""
249 pb2_path = self.create_pb2_path(path="usr/bin", inside=True)
250 with self.assertRaises(ValueError):
251 controller_util.pb2_path_to_pathlib_path(
252 pb2_path, chroot=self.chroot
253 )
254
255 def test_relative_outside(self):
256 """Verify that passing in a relative path outside the chroot fails"""
257 pb2_path = self.create_pb2_path(path="usr/bin", inside=False)
258 with self.assertRaises(ValueError):
259 controller_util.pb2_path_to_pathlib_path(
260 pb2_path, chroot=self.chroot
261 )
262
263 def test_inside_with_chroot(self):
264 """Verify that we can convert an inside path with a chroot."""
265 pb2_path = self.create_pb2_path(path="/usr/bin", inside=True)
266 pathlib_path = controller_util.pb2_path_to_pathlib_path(
267 pb2_path, chroot=self.chroot
268 )
269 self.assertEqual(pathlib_path, Path("/path/to/chroot/usr/bin"))
270
271 def test_outside_with_chroot(self):
272 """Verify that we can convert an outside path with a chroot."""
273 pb2_path = self.create_pb2_path(path="/usr/bin", inside=False)
274 pathlib_path = controller_util.pb2_path_to_pathlib_path(
275 pb2_path, chroot=self.chroot
276 )
277 self.assertEqual(pathlib_path, Path("/usr/bin"))
278
279 def test_inside_without_chroot(self):
280 """Verify that we cannot convert an inside path without a chroot."""
281 pb2_path = self.create_pb2_path(path="/usr/bin", inside=True)
282 with self.assertRaises(ValueError):
283 controller_util.pb2_path_to_pathlib_path(pb2_path)
284
285 def test_outside_without_chroot(self):
286 """Verify that we can convert an outside path without a chroot."""
287 pb2_path = self.create_pb2_path(path="/usr/bin", inside=False)
288 pathlib_path = controller_util.pb2_path_to_pathlib_path(pb2_path)
289 self.assertEqual(pathlib_path, Path("/usr/bin"))