blob: 4a2606623865ef1c45323e04c1876f4e3f7fce34 [file] [log] [blame]
Alex Kleina9d500b2019-04-22 15:37:51 -06001# Copyright 2019 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"""controller_util unittests."""
6
Lizzy Preslandaa5cb932022-02-05 01:24:25 +00007import glob
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 Klein26e472b2020-03-10 14:35:01 -060013from chromite.lib import build_target_lib
Lizzy Presland29e62452022-01-05 21:58:21 +000014from chromite.lib import cros_build_lib
Alex Klein18a60af2020-06-11 12:08:47 -060015from chromite.lib import cros_test_lib
16from chromite.lib.parser import package_info
Alex Klein171da612019-08-06 14:00:42 -060017from chromite.lib.chroot_lib import Chroot
Lizzy Preslandaa5cb932022-02-05 01:24:25 +000018from chromite.lib import sysroot_lib
Alex Klein171da612019-08-06 14:00:42 -060019
20
Michael Mortensen9a73c322019-10-03 17:14:37 -060021class ParseChrootTest(cros_test_lib.MockTestCase):
Alex Klein171da612019-08-06 14:00:42 -060022 """ParseChroot tests."""
23
24 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 = {'USE': 'useflag1 useflag2',
Alex Kleinb7485bb2019-09-19 13:23:37 -060032 'FEATURES': 'feature1 feature2',
33 'CHROME_ORIGIN': 'LOCAL_SOURCE'}
Alex Klein171da612019-08-06 14:00:42 -060034
35 chroot_message = common_pb2.Chroot(path=path, cache_dir=cache_dir,
36 chrome_dir=chrome_root,
37 env={'use_flags': use_flags,
38 'features': features})
39
40 expected = Chroot(path=path, cache_dir=cache_dir, chrome_root=chrome_root,
41 env=expected_env)
42 result = controller_util.ParseChroot(chroot_message)
43
44 self.assertEqual(expected, result)
45
46 def testWrongMessage(self):
47 """Test invalid message type given."""
48 with self.assertRaises(AssertionError):
49 controller_util.ParseChroot(common_pb2.BuildTarget())
50
George Engelbrechtc9a8e812021-06-16 18:14:17 -060051class ParseSysrootTest(cros_test_lib.MockTestCase):
52 """ParseSysroot tests."""
53
54 def testSuccess(self):
55 """test successful handling case."""
56 path = '/build/rare_pokemon'
57 sysroot_message = sysroot_pb2.Sysroot(path=path)
Lizzy Preslandaa5cb932022-02-05 01:24:25 +000058 expected = sysroot_lib.Sysroot(path=path)
George Engelbrechtc9a8e812021-06-16 18:14:17 -060059 result = controller_util.ParseSysroot(sysroot_message)
60 self.assertEqual(expected, result)
61
62 def testWrongMessage(self):
63 with self.assertRaises(AssertionError):
64 controller_util.ParseSysroot(common_pb2.BuildTarget())
Alex Klein171da612019-08-06 14:00:42 -060065
66class ParseBuildTargetTest(cros_test_lib.TestCase):
67 """ParseBuildTarget tests."""
68
69 def testSuccess(self):
70 """Test successful handling case."""
71 name = 'board'
72 build_target_message = common_pb2.BuildTarget(name=name)
Alex Klein26e472b2020-03-10 14:35:01 -060073 expected = build_target_lib.BuildTarget(name)
Alex Klein171da612019-08-06 14:00:42 -060074 result = controller_util.ParseBuildTarget(build_target_message)
75
76 self.assertEqual(expected, result)
77
Alex Klein26e472b2020-03-10 14:35:01 -060078 def testParseProfile(self):
79 """Test the parsing of a profile."""
80 name = 'build-target-name'
81 profile = 'profile'
82 build_target_msg = common_pb2.BuildTarget(name=name)
83 profile_msg = sysroot_pb2.Profile(name=profile)
84
85 expected = build_target_lib.BuildTarget(name, profile=profile)
86 result = controller_util.ParseBuildTarget(
87 build_target_msg, profile_message=profile_msg)
88
89 self.assertEqual(expected, result)
90
91
Alex Klein171da612019-08-06 14:00:42 -060092 def testWrongMessage(self):
93 """Test invalid message type given."""
94 with self.assertRaises(AssertionError):
Alex Klein26e472b2020-03-10 14:35:01 -060095 controller_util.ParseBuildTarget(build_api_test_pb2.TestRequestMessage())
Alex Klein171da612019-08-06 14:00:42 -060096
97
98class ParseBuildTargetsTest(cros_test_lib.TestCase):
99 """ParseBuildTargets tests."""
100
101 def testSuccess(self):
102 """Test successful handling case."""
103 names = ['foo', 'bar', 'baz']
104 message = build_api_test_pb2.TestRequestMessage()
105 for name in names:
106 message.build_targets.add().name = name
107
108 result = controller_util.ParseBuildTargets(message.build_targets)
109
Alex Klein26e472b2020-03-10 14:35:01 -0600110 expected = [build_target_lib.BuildTarget(name) for name in names]
111 self.assertCountEqual(expected, result)
Alex Klein171da612019-08-06 14:00:42 -0600112
113 def testWrongMessage(self):
114 """Wrong message type handling."""
115 message = common_pb2.Chroot()
116 message.env.use_flags.add().flag = 'foo'
117 message.env.use_flags.add().flag = 'bar'
118
119 with self.assertRaises(AssertionError):
120 controller_util.ParseBuildTargets(message.env.use_flags)
Alex Kleina9d500b2019-04-22 15:37:51 -0600121
122
Alex Kleina9d500b2019-04-22 15:37:51 -0600123class PackageInfoToCPVTest(cros_test_lib.TestCase):
124 """PackageInfoToCPV tests."""
125
126 def testAllFields(self):
127 """Quick sanity check it's working properly."""
128 pi = common_pb2.PackageInfo()
129 pi.package_name = 'pkg'
130 pi.category = 'cat'
131 pi.version = '2.0.0'
132
133 cpv = controller_util.PackageInfoToCPV(pi)
134
135 self.assertEqual('pkg', cpv.package)
136 self.assertEqual('cat', cpv.category)
137 self.assertEqual('2.0.0', cpv.version)
138
139 def testNoPackageInfo(self):
140 """Test no package info given."""
141 self.assertIsNone(controller_util.PackageInfoToCPV(None))
142
143 def testNoPackageName(self):
144 """Test no package name given."""
145 pi = common_pb2.PackageInfo()
146 pi.category = 'cat'
147 pi.version = '2.0.0'
148
149 self.assertIsNone(controller_util.PackageInfoToCPV(pi))
150
151
152class PackageInfoToStringTest(cros_test_lib.TestCase):
153 """PackageInfoToString tests."""
154
155 def testAllFields(self):
156 """Test all fields present."""
157 pi = common_pb2.PackageInfo()
158 pi.package_name = 'pkg'
159 pi.category = 'cat'
160 pi.version = '2.0.0'
161
162 cpv_str = controller_util.PackageInfoToString(pi)
163
164 self.assertEqual('cat/pkg-2.0.0', cpv_str)
165
166 def testNoVersion(self):
167 """Test no version provided."""
168 pi = common_pb2.PackageInfo()
169 pi.package_name = 'pkg'
170 pi.category = 'cat'
171
172 cpv_str = controller_util.PackageInfoToString(pi)
173
174 self.assertEqual('cat/pkg', cpv_str)
175
176 def testPackageOnly(self):
177 """Test no version provided."""
178 pi = common_pb2.PackageInfo()
179 pi.package_name = 'pkg'
180
181 cpv_str = controller_util.PackageInfoToString(pi)
182
183 self.assertEqual('pkg', cpv_str)
184
185 def testNoPackageName(self):
186 """Test no package name given."""
187 pi = common_pb2.PackageInfo()
188
189 with self.assertRaises(ValueError):
190 controller_util.PackageInfoToString(pi)
191
192
193class CPVToStringTest(cros_test_lib.TestCase):
194 """CPVToString tests."""
195
196 def testTranslations(self):
197 """Test standard translations used."""
198 cases = [
199 'cat/pkg-2.0.0-r1',
200 'cat/pkg-2.0.0',
201 'cat/pkg',
202 'pkg',
203 ]
204
205 for case in cases:
Alex Klein18a60af2020-06-11 12:08:47 -0600206 cpv = package_info.SplitCPV(case, strict=False)
Alex Kleina9d500b2019-04-22 15:37:51 -0600207 # We should end up with as much info as is available, so we should see
208 # the original value in each case.
209 self.assertEqual(case, controller_util.CPVToString(cpv))
210
211 def testInvalidCPV(self):
212 """Test invalid CPV object."""
Alex Klein18a60af2020-06-11 12:08:47 -0600213 cpv = package_info.SplitCPV('', strict=False)
Alex Kleina9d500b2019-04-22 15:37:51 -0600214 with self.assertRaises(ValueError):
215 controller_util.CPVToString(cpv)
Alex Klein1e68a8e2020-10-06 17:25:11 -0600216
217
218def test_serialize_package_info():
219 pkg_info = package_info.parse('foo/bar-1.2.3-r4')
220 pkg_info_msg = common_pb2.PackageInfo()
221 controller_util.serialize_package_info(pkg_info, pkg_info_msg)
222 assert pkg_info_msg.category == 'foo'
223 assert pkg_info_msg.package_name == 'bar'
224 assert pkg_info_msg.version == '1.2.3-r4'
225
226
227def test_deserialize_package_info():
228 pkg_info_msg = common_pb2.PackageInfo()
229 pkg_info_msg.category = 'foo'
230 pkg_info_msg.package_name = 'bar'
231 pkg_info_msg.version = '1.2.3-r4'
232 pkg_info = controller_util.deserialize_package_info(pkg_info_msg)
233 assert pkg_info.cpvr == 'foo/bar-1.2.3-r4'
Lizzy Presland29e62452022-01-05 21:58:21 +0000234
235
Lizzy Preslandaa5cb932022-02-05 01:24:25 +0000236def test_retrieve_package_log_paths(monkeypatch):
237 class MockSysroot():
238 """Mock implementation of sysroot."""
239 def __init__(self, path):
240 pass
241 @property
242 def portage_logdir(self):
243 return '/path/to/sysroot/logdir'
244
245 old_time = '20210609-162000'
246 new_time = '20220420-131200'
247 def mock_glob(glob_path):
248 return [glob_path.replace('*', old_time),
249 glob_path.replace('*', new_time)]
250
251 monkeypatch.setattr(sysroot_lib, 'Sysroot', MockSysroot)
252 monkeypatch.setattr(glob, 'glob', mock_glob)
253 error = sysroot_lib.PackageInstallError(
Lizzy Presland29e62452022-01-05 21:58:21 +0000254 msg='Failed to install 3 packages',
255 result=cros_build_lib.CommandResult(),
256 packages=[package_info.parse('foo/bar%d-1.0-r1' % num)
257 for num in range(1, 4)])
258 output_proto = sysroot_pb2.InstallPackagesResponse()
Lizzy Presland29e62452022-01-05 21:58:21 +0000259 controller_util.retrieve_package_log_paths(error,
260 output_proto,
Lizzy Preslandaa5cb932022-02-05 01:24:25 +0000261 sysroot_lib.Sysroot('/'))
Lizzy Presland29e62452022-01-05 21:58:21 +0000262 assert len(output_proto.failed_package_data) == 3
Lizzy Preslandaa5cb932022-02-05 01:24:25 +0000263 for pd in output_proto.failed_package_data:
264 assert pd.log_path.path != ''
265 assert new_time in pd.log_path.path
266
267
268def test_retrieve_package_log_paths_not_found(monkeypatch):
269 class MockSysroot():
270 """Mock implementation of sysroot."""
271 def __init__(self, path):
272 pass
273 @property
274 def portage_logdir(self):
275 return '/path/to/sysroot/logdir'
276
277 monkeypatch.setattr(sysroot_lib, 'Sysroot', MockSysroot)
278 error = sysroot_lib.PackageInstallError(
279 msg='Failed to install 3 packages',
280 result=cros_build_lib.CommandResult(),
281 packages=[package_info.parse('foo/bar%d-1.0-r1' % num)
282 for num in range(1, 4)])
283 output_proto = sysroot_pb2.InstallPackagesResponse()
284 controller_util.retrieve_package_log_paths(error,
285 output_proto,
286 sysroot_lib.Sysroot('/'))
287 assert len(output_proto.failed_package_data) == 3
288 for pd in output_proto.failed_package_data:
289 assert pd.log_path.path == ''