blob: 3ccae46353d9e16593f7f1bebe7b3798ff434ea8 [file] [log] [blame]
Evan Hernandezd437b4e2019-03-25 13:48:30 -06001# -*- coding: utf-8 -*-
2# Copyright 2019 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unittests for Binhost operations."""
7
8from __future__ import print_function
9
Michael Mortensenfc823882019-08-27 14:38:07 -060010import os
Alex Klein82c85d42019-08-14 15:47:51 -060011import mock
12
Alex Klein231d2da2019-07-22 16:44:45 -060013from chromite.api import api_config
Evan Hernandezd437b4e2019-03-25 13:48:30 -060014from chromite.api.controller import binhost
15from chromite.api.gen.chromite.api import binhost_pb2
LaMont Jonesc64ae212019-04-15 15:41:28 -060016from chromite.lib import cros_build_lib
Evan Hernandezd437b4e2019-03-25 13:48:30 -060017from chromite.lib import cros_test_lib
Michael Mortensenfc823882019-08-27 14:38:07 -060018from chromite.lib import osutils
Evan Hernandezd437b4e2019-03-25 13:48:30 -060019from chromite.service import binhost as binhost_service
20
Alex Klein231d2da2019-07-22 16:44:45 -060021
Michael Mortensena0af77b2019-11-13 11:15:15 -070022class GetBinhostsTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
23 """Unittests for GetBinhosts."""
24
25 def setUp(self):
26 self.response = binhost_pb2.BinhostGetResponse()
27
28 def testValidateOnly(self):
29 """Sanity check that a validate only call does not execute any logic."""
30 patch = self.PatchObject(binhost_service, 'GetBinhosts')
31
32 request = binhost_pb2.PrepareBinhostUploadsRequest()
33 request.build_target.name = 'target'
34 binhost.GetBinhosts(request, self.response, self.validate_only_config)
35 patch.assert_not_called()
36
37 def testMockCall(self):
38 """Test that a mock call does not execute logic, returns mocked value."""
39 patch = self.PatchObject(binhost_service, 'GetBinhosts')
40
41 input_proto = binhost_pb2.BinhostGetRequest()
42 input_proto.build_target.name = 'target'
43
44 binhost.GetBinhosts(input_proto, self.response, self.mock_call_config)
45
46 self.assertEqual(len(self.response.binhosts), 1)
47 self.assertEqual(self.response.binhosts[0].package_index, 'Packages')
48 patch.assert_not_called()
49
50 def testGetBinhosts(self):
51 """GetBinhosts calls service with correct args."""
52 binhost_list = [
53 'gs://cr-prebuilt/board/amd64-generic/paladin-R66-17.0.0-rc2/packages/',
54 'gs://cr-prebuilt/board/eve/paladin-R66-17.0.0-rc2/packages/']
55 get_binhost = self.PatchObject(binhost_service, 'GetBinhosts',
56 return_value=binhost_list)
57
58 input_proto = binhost_pb2.BinhostGetRequest()
59 input_proto.build_target.name = 'target'
60
61 binhost.GetBinhosts(input_proto, self.response, self.api_config)
62
63 self.assertEqual(len(self.response.binhosts), 2)
64 self.assertEqual(self.response.binhosts[0].package_index, 'Packages')
65 get_binhost.assert_called_once_with(mock.ANY)
66
67
Alex Klein231d2da2019-07-22 16:44:45 -060068class PrepareBinhostUploadsTest(cros_test_lib.MockTestCase,
69 api_config.ApiConfigMixin):
Evan Hernandezd437b4e2019-03-25 13:48:30 -060070 """Unittests for PrepareBinhostUploads."""
71
72 def setUp(self):
73 self.PatchObject(binhost_service, 'GetPrebuiltsRoot',
74 return_value='/build/target/packages')
75 self.PatchObject(binhost_service, 'GetPrebuiltsFiles',
76 return_value=['foo.tbz2', 'bar.tbz2'])
77 self.PatchObject(binhost_service, 'UpdatePackageIndex',
78 return_value='/build/target/packages/Packages')
79
Alex Klein231d2da2019-07-22 16:44:45 -060080 self.response = binhost_pb2.PrepareBinhostUploadsResponse()
81
82 def testValidateOnly(self):
83 """Sanity check that a validate only call does not execute any logic."""
84 patch = self.PatchObject(binhost_service, 'GetPrebuiltsRoot')
85
86 request = binhost_pb2.PrepareBinhostUploadsRequest()
87 request.build_target.name = 'target'
88 request.uri = 'gs://chromeos-prebuilt/target'
89 rc = binhost.PrepareBinhostUploads(request, self.response,
90 self.validate_only_config)
91 patch.assert_not_called()
92 self.assertEqual(rc, 0)
93
Evan Hernandezd437b4e2019-03-25 13:48:30 -060094 def testPrepareBinhostUploads(self):
95 """PrepareBinhostUploads returns Packages and tar files."""
96 input_proto = binhost_pb2.PrepareBinhostUploadsRequest()
97 input_proto.build_target.name = 'target'
98 input_proto.uri = 'gs://chromeos-prebuilt/target'
Alex Klein231d2da2019-07-22 16:44:45 -060099 binhost.PrepareBinhostUploads(input_proto, self.response, self.api_config)
100 self.assertEqual(self.response.uploads_dir, '/build/target/packages')
Mike Frysinger678735c2019-09-28 18:23:28 -0400101 self.assertCountEqual(
Alex Klein231d2da2019-07-22 16:44:45 -0600102 [ut.path for ut in self.response.upload_targets],
Evan Hernandezd437b4e2019-03-25 13:48:30 -0600103 ['Packages', 'foo.tbz2', 'bar.tbz2'])
104
105 def testPrepareBinhostUploadsNonGsUri(self):
106 """PrepareBinhostUploads dies when URI does not point to GS."""
107 input_proto = binhost_pb2.PrepareBinhostUploadsRequest()
108 input_proto.build_target.name = 'target'
109 input_proto.uri = 'https://foo.bar'
Evan Hernandezd437b4e2019-03-25 13:48:30 -0600110 with self.assertRaises(ValueError):
Alex Klein231d2da2019-07-22 16:44:45 -0600111 binhost.PrepareBinhostUploads(input_proto, self.response, self.api_config)
Evan Hernandezd437b4e2019-03-25 13:48:30 -0600112
113
Alex Klein231d2da2019-07-22 16:44:45 -0600114class SetBinhostTest(cros_test_lib.MockTestCase, api_config.ApiConfigMixin):
Evan Hernandezd437b4e2019-03-25 13:48:30 -0600115 """Unittests for SetBinhost."""
116
Alex Klein231d2da2019-07-22 16:44:45 -0600117 def setUp(self):
118 self.response = binhost_pb2.SetBinhostResponse()
119
120 def testValidateOnly(self):
121 """Sanity check that a validate only call does not execute any logic."""
122 patch = self.PatchObject(binhost_service, 'GetPrebuiltsRoot')
123
124 request = binhost_pb2.PrepareBinhostUploadsRequest()
125 request.build_target.name = 'target'
126 request.uri = 'gs://chromeos-prebuilt/target'
127 binhost.PrepareBinhostUploads(request, self.response,
128 self.validate_only_config)
129 patch.assert_not_called()
130
Evan Hernandezd437b4e2019-03-25 13:48:30 -0600131 def testSetBinhost(self):
132 """SetBinhost calls service with correct args."""
133 set_binhost = self.PatchObject(binhost_service, 'SetBinhost',
134 return_value='/path/to/BINHOST.conf')
135
136 input_proto = binhost_pb2.SetBinhostRequest()
137 input_proto.build_target.name = 'target'
138 input_proto.private = True
139 input_proto.key = binhost_pb2.POSTSUBMIT_BINHOST
140 input_proto.uri = 'gs://chromeos-prebuilt/target'
141
Alex Klein231d2da2019-07-22 16:44:45 -0600142 binhost.SetBinhost(input_proto, self.response, self.api_config)
Evan Hernandezd437b4e2019-03-25 13:48:30 -0600143
Alex Klein231d2da2019-07-22 16:44:45 -0600144 self.assertEqual(self.response.output_file, '/path/to/BINHOST.conf')
LaMont Jonesc64ae212019-04-15 15:41:28 -0600145 set_binhost.assert_called_once_with(
Alex Kleinc010de02019-10-11 15:44:04 -0600146 'target',
147 'POSTSUBMIT_BINHOST',
148 'gs://chromeos-prebuilt/target',
149 private=True)
LaMont Jonesc64ae212019-04-15 15:41:28 -0600150
Alex Klein231d2da2019-07-22 16:44:45 -0600151
152class RegenBuildCacheTest(cros_test_lib.MockTestCase,
153 api_config.ApiConfigMixin):
LaMont Jonesc64ae212019-04-15 15:41:28 -0600154 """Unittests for RegenBuildCache."""
155
Alex Klein231d2da2019-07-22 16:44:45 -0600156 def setUp(self):
157 self.response = binhost_pb2.RegenBuildCacheResponse()
158
159 def testValidateOnly(self):
160 """Sanity check that a validate only call does not execute any logic."""
161 patch = self.PatchObject(binhost_service, 'RegenBuildCache')
162
163 request = binhost_pb2.RegenBuildCacheRequest()
164 request.overlay_type = binhost_pb2.OVERLAYTYPE_BOTH
165 binhost.RegenBuildCache(request, self.response, self.validate_only_config)
166 patch.assert_not_called()
167
LaMont Jonesc64ae212019-04-15 15:41:28 -0600168 def testRegenBuildCache(self):
169 """RegenBuildCache calls service with the correct args."""
170 regen_cache = self.PatchObject(binhost_service, 'RegenBuildCache')
171
172 input_proto = binhost_pb2.RegenBuildCacheRequest()
173 input_proto.overlay_type = binhost_pb2.OVERLAYTYPE_BOTH
LaMont Jonesc64ae212019-04-15 15:41:28 -0600174
Alex Klein231d2da2019-07-22 16:44:45 -0600175 binhost.RegenBuildCache(input_proto, self.response, self.api_config)
Alex Klein82c85d42019-08-14 15:47:51 -0600176 regen_cache.assert_called_once_with(mock.ANY, 'both')
LaMont Jonesc64ae212019-04-15 15:41:28 -0600177
178 def testRequiresOverlayType(self):
179 """RegenBuildCache dies if overlay_type not specified."""
180 regen_cache = self.PatchObject(binhost_service, 'RegenBuildCache')
LaMont Jonesc64ae212019-04-15 15:41:28 -0600181
182 input_proto = binhost_pb2.RegenBuildCacheRequest()
183 input_proto.overlay_type = binhost_pb2.OVERLAYTYPE_UNSPECIFIED
LaMont Jonesc64ae212019-04-15 15:41:28 -0600184
Alex Klein231d2da2019-07-22 16:44:45 -0600185 with self.assertRaises(cros_build_lib.DieSystemExit):
186 binhost.RegenBuildCache(input_proto, self.response, self.api_config)
LaMont Jonesc64ae212019-04-15 15:41:28 -0600187 regen_cache.assert_not_called()
Michael Mortensenfc823882019-08-27 14:38:07 -0600188
189
190class PrepareDevInstallerBinhostUploadsTest(cros_test_lib.MockTempDirTestCase,
191 api_config.ApiConfigMixin):
192 """Tests for the UploadDevInstallerPrebuilts stage."""
193 def setUp(self):
194 # target packages dir
195 self.chroot_path = os.path.join(self.tempdir, 'chroot')
196 self.sysroot_path = '/build/target'
197 self.chroot_path = os.path.join(self.tempdir, 'chroot')
198 full_sysroot_path = os.path.join(self.chroot_path,
199 self.sysroot_path.lstrip(os.sep))
200 self.full_sysroot_package_path = os.path.join(full_sysroot_path,
201 'packages')
202 osutils.SafeMakedirs(self.full_sysroot_package_path)
203 self.uploads_dir = os.path.join(self.tempdir, 'uploads_dir')
204 osutils.SafeMakedirs(self.uploads_dir)
205 # Create packages/Packages file
206 packages_file = os.path.join(self.full_sysroot_package_path, 'Packages')
207 packages_content = """\
208USE: test
209
210CPV: app-arch/brotli-1.0.6
211
212CPV: app-arch/zip-3.0-r3
213
214CPV: chromeos-base/shill-0.0.1-r1
215
216CPV: chromeos-base/test-0.0.1-r1
217
218CPV: virtual/chromium-os-printing-1-r4
219
220CPV: virtual/python-enum34-1
221
222"""
223 osutils.WriteFile(packages_file, packages_content)
224
225
226 # Create package.installable file
227 self.dev_install_packages = ['app-arch/zip-3.0-r3',
228 'virtual/chromium-os-printing-1-r4',
229 'virtual/python-enum34-1']
230 package_installable_dir = os.path.join(full_sysroot_path,
231 'build/dev-install')
232 osutils.SafeMakedirs(package_installable_dir)
233 package_installable_filename = os.path.join(package_installable_dir,
234 'package.installable')
235
236 # Create path to the dev_install_packages
237 packages_dir = os.path.join(full_sysroot_path, 'packages')
238 osutils.SafeMakedirs(packages_dir)
239 for package in self.dev_install_packages:
240 # Since a package has a category, such as app-arch/zip-3.0-r3, we need
241 # to create the packages_dir / category dir as needed.
242 category = package.split(os.sep)[0]
243 osutils.SafeMakedirs(os.path.join(packages_dir, category))
244 package_tbz2_file = os.path.join(packages_dir, package) + '.tbz2'
245 osutils.Touch(package_tbz2_file)
246 package_installable_file = open(package_installable_filename, 'w')
247 for package in self.dev_install_packages:
248 package_installable_file.write(package + '\n')
249 package_installable_file.close()
250 self.response = binhost_pb2.PrepareDevInstallBinhostUploadsResponse()
251
252 def testDevInstallerUpload(self):
253 """Basic sanity test testing uploads of dev installer prebuilts."""
254 # self.RunStage()
255 input_proto = binhost_pb2.PrepareDevInstallBinhostUploadsRequest()
256 input_proto.uri = 'gs://chromeos-prebuilt/target'
257 input_proto.chroot.path = self.chroot_path
258 input_proto.sysroot.path = self.sysroot_path
259 input_proto.uploads_dir = self.uploads_dir
260 # Call method under test
261 binhost.PrepareDevInstallBinhostUploads(input_proto, self.response,
262 self.api_config)
263 # Verify results
264 expected_upload_targets = ['app-arch/zip-3.0-r3.tbz2',
265 'virtual/chromium-os-printing-1-r4.tbz2',
266 'virtual/python-enum34-1.tbz2',
267 'Packages']
Mike Frysinger678735c2019-09-28 18:23:28 -0400268 self.assertCountEqual(
Michael Mortensenfc823882019-08-27 14:38:07 -0600269 [ut.path for ut in self.response.upload_targets],
270 expected_upload_targets)
271 # All of the upload_targets should also be in the uploads_directory
272 for target in self.response.upload_targets:
273 self.assertExists(os.path.join(input_proto.uploads_dir, target.path))
274
275 def testPrepareBinhostUploadsNonGsUri(self):
276 """PrepareBinhostUploads dies when URI does not point to GS."""
277 input_proto = binhost_pb2.PrepareDevInstallBinhostUploadsRequest()
278 input_proto.chroot.path = self.chroot_path
279 input_proto.sysroot.path = self.sysroot_path
280 input_proto.uploads_dir = self.uploads_dir
281 input_proto.uri = 'https://foo.bar'
282 with self.assertRaises(ValueError):
283 binhost.PrepareDevInstallBinhostUploads(input_proto, self.response,
284 self.api_config)