blob: 79f115584782b873b16d971ee55d9d8e0becfc21 [file] [log] [blame]
David Jamesbb20ac82012-07-18 10:59:16 -07001# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
David James8c846492011-01-25 17:07:29 -08002# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Mike Frysingerc6824f62014-02-03 11:09:44 -05005"""Unittests for upload_prebuilts.py."""
6
David James8c846492011-01-25 17:07:29 -08007import copy
David James8fa34ea2011-04-15 13:00:20 -07008import multiprocessing
Mike Frysinger40ffb532021-02-12 07:36:08 -05009import os
David James8c846492011-01-25 17:07:29 -080010import tempfile
Mike Frysinger166fea02021-02-12 05:30:33 -050011from unittest import mock
Chris Sosa471532a2011-02-01 15:10:06 -080012
Mike Frysinger40ffb532021-02-12 07:36:08 -050013from chromite.lib import binpkg
Brian Harringc92788f2012-09-21 18:07:15 -070014from chromite.lib import cros_test_lib
David James2c7ccb42012-11-04 15:34:28 -080015from chromite.lib import gs
Zdenek Behanc0e18762012-09-22 04:06:17 +020016from chromite.lib import osutils
Mike Frysinger36870f92015-04-12 02:59:55 -040017from chromite.lib import parallel_unittest
Prathmesh Prabhu421eef22014-10-16 17:13:19 -070018from chromite.lib import portage_util
Mike Frysinger40ffb532021-02-12 07:36:08 -050019from chromite.scripts import upload_prebuilts as prebuilt
David James8c846492011-01-25 17:07:29 -080020
Mike Frysinger68182472014-11-05 22:38:39 -050021
Mike Frysinger27e21b72018-07-12 14:20:21 -040022# pylint: disable=protected-access
23
24
David James615e5b52011-06-03 11:10:15 -070025PUBLIC_PACKAGES = [{'CPV': 'gtk+/public1', 'SHA1': '1', 'MTIME': '1'},
David James8c846492011-01-25 17:07:29 -080026 {'CPV': 'gtk+/public2', 'SHA1': '2',
David James615e5b52011-06-03 11:10:15 -070027 'PATH': 'gtk+/foo.tgz', 'MTIME': '2'}]
28PRIVATE_PACKAGES = [{'CPV': 'private', 'SHA1': '3', 'MTIME': '3'}]
David James8c846492011-01-25 17:07:29 -080029
30
31def SimplePackageIndex(header=True, packages=True):
Chris Sosa58669192011-06-30 12:45:03 -070032 pkgindex = binpkg.PackageIndex()
33 if header:
David James2c7ccb42012-11-04 15:34:28 -080034 pkgindex.header['URI'] = 'gs://example'
Chris Sosa58669192011-06-30 12:45:03 -070035 if packages:
36 pkgindex.packages = copy.deepcopy(PUBLIC_PACKAGES + PRIVATE_PACKAGES)
37 return pkgindex
David James8c846492011-01-25 17:07:29 -080038
39
Brian Harringc92788f2012-09-21 18:07:15 -070040class TestUpdateFile(cros_test_lib.TempDirTestCase):
Mike Frysingerc6824f62014-02-03 11:09:44 -050041 """Tests for the UpdateLocalFile function."""
David James8c846492011-01-25 17:07:29 -080042
43 def setUp(self):
Mike Frysingerd6e2df02014-11-26 02:55:04 -050044 self.contents_str = [
45 '# comment that should be skipped',
46 'PKGDIR="/var/lib/portage/pkgs"',
47 'PORTAGE_BINHOST="http://no.thanks.com"',
48 'portage portage-20100310.tar.bz2',
49 'COMPILE_FLAGS="some_value=some_other"',
50 ]
Zdenek Behanc0e18762012-09-22 04:06:17 +020051 self.version_file = os.path.join(self.tempdir, 'version')
52 osutils.WriteFile(self.version_file, '\n'.join(self.contents_str))
David James8c846492011-01-25 17:07:29 -080053
David James8c846492011-01-25 17:07:29 -080054 def _read_version_file(self, version_file=None):
55 """Read the contents of self.version_file and return as a list."""
56 if not version_file:
57 version_file = self.version_file
58
Sergey Frolov89d28242022-06-06 17:49:20 -060059 with open(version_file) as version_fh:
David James8c846492011-01-25 17:07:29 -080060 return [line.strip() for line in version_fh.readlines()]
Sergey Frolov89d28242022-06-06 17:49:20 -060061
David James8c846492011-01-25 17:07:29 -080062
63 def _verify_key_pair(self, key, val):
64 file_contents = self._read_version_file()
65 # ensure key for verify is wrapped on quotes
66 if '"' not in val:
67 val = '"%s"' % val
68 for entry in file_contents:
69 if '=' not in entry:
70 continue
71 file_key, file_val = entry.split('=')
72 if file_key == key:
73 if val == file_val:
74 break
75 else:
76 self.fail('Could not find "%s=%s" in version file' % (key, val))
77
78 def testAddVariableThatDoesNotExist(self):
79 """Add in a new variable that was no present in the file."""
80 key = 'PORTAGE_BINHOST'
81 value = '1234567'
82 prebuilt.UpdateLocalFile(self.version_file, value)
Mike Frysinger383367e2014-09-16 15:06:17 -040083 print(self.version_file)
Chris Sosa58669192011-06-30 12:45:03 -070084 self._read_version_file()
David James8c846492011-01-25 17:07:29 -080085 self._verify_key_pair(key, value)
Mike Frysinger383367e2014-09-16 15:06:17 -040086 print(self.version_file)
David James8c846492011-01-25 17:07:29 -080087
88 def testUpdateVariable(self):
89 """Test updating a variable that already exists."""
90 key, val = self.contents_str[2].split('=')
91 new_val = 'test_update'
92 self._verify_key_pair(key, val)
93 prebuilt.UpdateLocalFile(self.version_file, new_val)
94 self._verify_key_pair(key, new_val)
95
96 def testUpdateNonExistentFile(self):
97 key = 'PORTAGE_BINHOST'
98 value = '1234567'
99 non_existent_file = tempfile.mktemp()
100 try:
101 prebuilt.UpdateLocalFile(non_existent_file, value)
102 file_contents = self._read_version_file(non_existent_file)
Chris Sosa739c8752012-05-16 19:30:35 -0700103 self.assertEqual(file_contents, ['%s="%s"' % (key, value)])
David James8c846492011-01-25 17:07:29 -0800104 finally:
105 if os.path.exists(non_existent_file):
106 os.remove(non_existent_file)
107
108
Mike Frysinger68182472014-11-05 22:38:39 -0500109class TestPrebuilt(cros_test_lib.MockTestCase):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500110 """Tests for Prebuilt logic."""
David James8c846492011-01-25 17:07:29 -0800111
Bertrand SIMONNET811bcde2014-11-20 15:21:25 -0800112 def setUp(self):
Mike Nicholsd0acc7f2021-05-21 17:18:24 +0000113 self._base_local_path = '/b/cbuild/build/chroot/build/x86-dogfood/'
Bertrand SIMONNET811bcde2014-11-20 15:21:25 -0800114 self._gs_bucket_path = 'gs://chromeos-prebuilt/host/version'
115 self._local_path = os.path.join(self._base_local_path, 'public1.tbz2')
116
David James8c846492011-01-25 17:07:29 -0800117 def testGenerateUploadDict(self):
Mike Frysinger68182472014-11-05 22:38:39 -0500118 self.PatchObject(prebuilt.os.path, 'exists', return_true=True)
Mike Frysingerd6e2df02014-11-26 02:55:04 -0500119 pkgs = [{'CPV': 'public1'}]
Bertrand SIMONNET811bcde2014-11-20 15:21:25 -0800120 result = prebuilt.GenerateUploadDict(self._base_local_path,
121 self._gs_bucket_path, pkgs)
122 expected = {self._local_path: self._gs_bucket_path + '/public1.tbz2', }
123 self.assertEqual(result, expected)
124
125 def testGenerateUploadDictWithDebug(self):
126 self.PatchObject(prebuilt.os.path, 'exists', return_true=True)
127 pkgs = [{'CPV': 'public1', 'DEBUG_SYMBOLS': 'yes'}]
128 result = prebuilt.GenerateUploadDict(self._base_local_path,
129 self._gs_bucket_path, pkgs)
130 expected = {self._local_path: self._gs_bucket_path + '/public1.tbz2',
131 self._local_path.replace('.tbz2', '.debug.tbz2'):
132 self._gs_bucket_path + '/public1.debug.tbz2'}
David James8c846492011-01-25 17:07:29 -0800133 self.assertEqual(result, expected)
134
David James8c846492011-01-25 17:07:29 -0800135 def testDeterminePrebuiltConfHost(self):
136 """Test that the host prebuilt path comes back properly."""
137 expected_path = os.path.join(prebuilt._PREBUILT_MAKE_CONF['amd64'])
138 self.assertEqual(prebuilt.DeterminePrebuiltConfFile('fake_path', 'amd64'),
139 expected_path)
140
David James8c846492011-01-25 17:07:29 -0800141
David James2c7ccb42012-11-04 15:34:28 -0800142class TestPkgIndex(cros_test_lib.TestCase):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500143 """Helper for tests that update the Packages index file."""
David James2c7ccb42012-11-04 15:34:28 -0800144
145 def setUp(self):
146 self.db = {}
147 self.pkgindex = SimplePackageIndex()
148 self.empty = SimplePackageIndex(packages=False)
149
150 def assertURIs(self, uris):
151 """Verify that the duplicate DB has the specified URLs."""
152 expected = [v.uri for _, v in sorted(self.db.items())]
153 self.assertEqual(expected, uris)
154
155
156class TestPackagesFileFiltering(TestPkgIndex):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500157 """Tests for Packages filtering behavior."""
David James8c846492011-01-25 17:07:29 -0800158
159 def testFilterPkgIndex(self):
David James2c7ccb42012-11-04 15:34:28 -0800160 """Test filtering out of private packages."""
161 self.pkgindex.RemoveFilteredPackages(lambda pkg: pkg in PRIVATE_PACKAGES)
162 self.assertEqual(self.pkgindex.packages, PUBLIC_PACKAGES)
163 self.assertEqual(self.pkgindex.modified, True)
David James8c846492011-01-25 17:07:29 -0800164
165
David James2c7ccb42012-11-04 15:34:28 -0800166class TestPopulateDuplicateDB(TestPkgIndex):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500167 """Tests for the _PopulateDuplicateDB function."""
David James8c846492011-01-25 17:07:29 -0800168
169 def testEmptyIndex(self):
David James2c7ccb42012-11-04 15:34:28 -0800170 """Test population of the duplicate DB with an empty index."""
171 self.empty._PopulateDuplicateDB(self.db, 0)
172 self.assertEqual(self.db, {})
David James8c846492011-01-25 17:07:29 -0800173
174 def testNormalIndex(self):
David James2c7ccb42012-11-04 15:34:28 -0800175 """Test population of the duplicate DB with a full index."""
176 self.pkgindex._PopulateDuplicateDB(self.db, 0)
177 self.assertURIs(['gs://example/gtk+/public1.tbz2',
178 'gs://example/gtk+/foo.tgz',
179 'gs://example/private.tbz2'])
David James8c846492011-01-25 17:07:29 -0800180
181 def testMissingSHA1(self):
David James2c7ccb42012-11-04 15:34:28 -0800182 """Test population of the duplicate DB with a missing SHA1."""
183 del self.pkgindex.packages[0]['SHA1']
184 self.pkgindex._PopulateDuplicateDB(self.db, 0)
185 self.assertURIs(['gs://example/gtk+/foo.tgz',
186 'gs://example/private.tbz2'])
David James8c846492011-01-25 17:07:29 -0800187
188 def testFailedPopulate(self):
David James2c7ccb42012-11-04 15:34:28 -0800189 """Test failure conditions for the populate method."""
190 headerless = SimplePackageIndex(header=False)
191 self.assertRaises(KeyError, headerless._PopulateDuplicateDB, self.db, 0)
192 del self.pkgindex.packages[0]['CPV']
193 self.assertRaises(KeyError, self.pkgindex._PopulateDuplicateDB, self.db, 0)
David James8c846492011-01-25 17:07:29 -0800194
195
Mike Frysinger68182472014-11-05 22:38:39 -0500196class TestResolveDuplicateUploads(cros_test_lib.MockTestCase, TestPkgIndex):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500197 """Tests for the ResolveDuplicateUploads function."""
David James8c846492011-01-25 17:07:29 -0800198
David James615e5b52011-06-03 11:10:15 -0700199 def setUp(self):
Mike Frysinger68182472014-11-05 22:38:39 -0500200 self.PatchObject(binpkg.time, 'time', return_value=binpkg.TWO_WEEKS)
David James2c7ccb42012-11-04 15:34:28 -0800201 self.db = {}
202 self.dup = SimplePackageIndex()
203 self.expected_pkgindex = SimplePackageIndex()
204
205 def assertNoDuplicates(self, candidates):
206 """Verify no duplicates are found with the specified candidates."""
207 uploads = self.pkgindex.ResolveDuplicateUploads(candidates)
208 self.assertEqual(uploads, self.pkgindex.packages)
209 self.assertEqual(len(self.pkgindex.packages),
210 len(self.expected_pkgindex.packages))
211 for pkg1, pkg2 in zip(self.pkgindex.packages,
212 self.expected_pkgindex.packages):
213 self.assertNotEqual(pkg1['MTIME'], pkg2['MTIME'])
214 del pkg1['MTIME']
215 del pkg2['MTIME']
216 self.assertEqual(self.pkgindex.modified, False)
217 self.assertEqual(self.pkgindex.packages, self.expected_pkgindex.packages)
218
219 def assertAllDuplicates(self, candidates):
220 """Verify every package is a duplicate in the specified list."""
221 for pkg in self.expected_pkgindex.packages:
222 pkg.setdefault('PATH', pkg['CPV'] + '.tbz2')
223 self.pkgindex.ResolveDuplicateUploads(candidates)
224 self.assertEqual(self.pkgindex.packages, self.expected_pkgindex.packages)
David James615e5b52011-06-03 11:10:15 -0700225
David James8c846492011-01-25 17:07:29 -0800226 def testEmptyList(self):
David James2c7ccb42012-11-04 15:34:28 -0800227 """If no candidates are supplied, no duplicates should be found."""
228 self.assertNoDuplicates([])
David James8c846492011-01-25 17:07:29 -0800229
230 def testEmptyIndex(self):
David James2c7ccb42012-11-04 15:34:28 -0800231 """If no packages are supplied, no duplicates should be found."""
232 self.assertNoDuplicates([self.empty])
David James8c846492011-01-25 17:07:29 -0800233
David James2c7ccb42012-11-04 15:34:28 -0800234 def testDifferentURI(self):
235 """If the URI differs, no duplicates should be found."""
236 self.dup.header['URI'] = 'gs://example2'
237 self.assertNoDuplicates([self.dup])
238
239 def testUpdateModificationTime(self):
240 """When duplicates are found, we should use the latest mtime."""
241 for pkg in self.expected_pkgindex.packages:
242 pkg['MTIME'] = '10'
243 for pkg in self.dup.packages:
244 pkg['MTIME'] = '4'
245 self.assertAllDuplicates([self.expected_pkgindex, self.dup])
246
247 def testCanonicalUrl(self):
248 """If the URL is in a different format, we should still find duplicates."""
249 self.dup.header['URI'] = gs.PUBLIC_BASE_HTTPS_URL + 'example'
250 self.assertAllDuplicates([self.dup])
David James8c846492011-01-25 17:07:29 -0800251
252 def testMissingSHA1(self):
David James2c7ccb42012-11-04 15:34:28 -0800253 """We should not find duplicates if there is no SHA1."""
254 del self.pkgindex.packages[0]['SHA1']
255 del self.expected_pkgindex.packages[0]['SHA1']
256 for pkg in self.expected_pkgindex.packages[1:]:
David James8c846492011-01-25 17:07:29 -0800257 pkg.setdefault('PATH', pkg['CPV'] + '.tbz2')
David James2c7ccb42012-11-04 15:34:28 -0800258 self.pkgindex.ResolveDuplicateUploads([self.dup])
259 self.assertNotEqual(self.pkgindex.packages[0]['MTIME'],
260 self.expected_pkgindex.packages[0]['MTIME'])
261 del self.pkgindex.packages[0]['MTIME']
262 del self.expected_pkgindex.packages[0]['MTIME']
263 self.assertEqual(self.pkgindex.packages, self.expected_pkgindex.packages)
David James8c846492011-01-25 17:07:29 -0800264
Bertrand SIMONNET811bcde2014-11-20 15:21:25 -0800265 def testSymbolsAvailable(self):
266 """If symbols are available remotely, re-use them and set DEBUG_SYMBOLS."""
267 self.dup.packages[0]['DEBUG_SYMBOLS'] = 'yes'
268
269 uploads = self.pkgindex.ResolveDuplicateUploads([self.dup])
270 self.assertEqual(uploads, [])
271 self.assertEqual(self.pkgindex.packages[0].get('DEBUG_SYMBOLS'), 'yes')
272
273 def testSymbolsAvailableLocallyOnly(self):
274 """If the symbols are only available locally, reupload them."""
275 self.pkgindex.packages[0]['DEBUG_SYMBOLS'] = 'yes'
276
277 uploads = self.pkgindex.ResolveDuplicateUploads([self.dup])
278 self.assertEqual(uploads, [self.pkgindex.packages[0]])
279
David James8c846492011-01-25 17:07:29 -0800280
Mike Frysinger68182472014-11-05 22:38:39 -0500281class TestWritePackageIndex(cros_test_lib.MockTestCase, TestPkgIndex):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500282 """Tests for the WriteToNamedTemporaryFile function."""
David James8c846492011-01-25 17:07:29 -0800283
284 def testSimple(self):
David James2c7ccb42012-11-04 15:34:28 -0800285 """Test simple call of WriteToNamedTemporaryFile()"""
Mike Frysinger68182472014-11-05 22:38:39 -0500286 self.PatchObject(self.pkgindex, 'Write')
David James2c7ccb42012-11-04 15:34:28 -0800287 f = self.pkgindex.WriteToNamedTemporaryFile()
Mike Frysinger652057c2019-12-09 23:59:07 -0500288 self.assertEqual(f.read(), '')
David James8c846492011-01-25 17:07:29 -0800289
290
Mike Frysinger36870f92015-04-12 02:59:55 -0400291class TestUploadPrebuilt(cros_test_lib.MockTempDirTestCase):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500292 """Tests for the _UploadPrebuilt function."""
David James05bcb2b2011-02-09 09:25:47 -0800293
294 def setUp(self):
295 class MockTemporaryFile(object):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500296 """Mock out the temporary file logic."""
David James05bcb2b2011-02-09 09:25:47 -0800297 def __init__(self, name):
298 self.name = name
David James05bcb2b2011-02-09 09:25:47 -0800299 self.pkgindex = SimplePackageIndex()
Mike Frysinger36870f92015-04-12 02:59:55 -0400300 self.PatchObject(binpkg, 'GrabLocalPackageIndex',
301 return_value=self.pkgindex)
302 self.PatchObject(self.pkgindex, 'ResolveDuplicateUploads',
303 return_value=PRIVATE_PACKAGES)
304 self.PatchObject(self.pkgindex, 'WriteToNamedTemporaryFile',
305 return_value=MockTemporaryFile('fake'))
306 self.remote_up_mock = self.PatchObject(prebuilt, 'RemoteUpload')
307 self.gs_up_mock = self.PatchObject(prebuilt, '_GsUpload')
David James05bcb2b2011-02-09 09:25:47 -0800308
David James05bcb2b2011-02-09 09:25:47 -0800309 def testSuccessfulGsUpload(self):
Alex Deymo541ea6f2014-12-23 01:18:14 -0800310 uploads = {
311 os.path.join(self.tempdir, 'private.tbz2'): 'gs://foo/private.tbz2'}
Mike Frysinger9bb6cd82020-08-20 03:02:23 -0400312 dev_extras = os.path.join(self.tempdir, 'dev-only-extras.tar.xz')
313 osutils.Touch(dev_extras)
Mike Frysinger36870f92015-04-12 02:59:55 -0400314 self.PatchObject(prebuilt, 'GenerateUploadDict',
315 return_value=uploads)
David James05bcb2b2011-02-09 09:25:47 -0800316 uploads = uploads.copy()
317 uploads['fake'] = 'gs://foo/suffix/Packages'
Mike Frysinger9bb6cd82020-08-20 03:02:23 -0400318 uploads[dev_extras] = 'gs://foo/suffix/dev-only-extras.tar.xz'
David Jamesfd0b0852011-02-23 11:15:36 -0800319 acl = 'public-read'
David Jamesc0f158a2011-02-22 16:07:29 -0800320 uri = self.pkgindex.header['URI']
David James8ece7ee2011-06-29 16:02:30 -0700321 uploader = prebuilt.PrebuiltUploader('gs://foo', acl, uri, [], '/', [],
Mike Frysinger8092a632014-05-24 13:25:46 -0400322 False, 'foo', False, 'x86-foo', [], '')
Alex Deymo541ea6f2014-12-23 01:18:14 -0800323 uploader._UploadPrebuilt(self.tempdir, 'suffix')
Mike Frysinger36870f92015-04-12 02:59:55 -0400324 self.remote_up_mock.assert_called_once_with(mock.ANY, acl, uploads)
325 self.assertTrue(self.gs_up_mock.called)
David James05bcb2b2011-02-09 09:25:47 -0800326
David James05bcb2b2011-02-09 09:25:47 -0800327
Mike Frysinger36870f92015-04-12 02:59:55 -0400328class TestSyncPrebuilts(cros_test_lib.MockTestCase):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500329 """Tests for the SyncHostPrebuilts function."""
David James05bcb2b2011-02-09 09:25:47 -0800330
331 def setUp(self):
Mike Frysinger36870f92015-04-12 02:59:55 -0400332 self.rev_mock = self.PatchObject(prebuilt, 'RevGitFile', return_value=None)
333 self.update_binhost_mock = self.PatchObject(
334 prebuilt, 'UpdateBinhostConfFile', return_value=None)
David James05bcb2b2011-02-09 09:25:47 -0800335 self.build_path = '/trunk'
336 self.upload_location = 'gs://upload/'
337 self.version = '1'
338 self.binhost = 'http://prebuilt/'
339 self.key = 'PORTAGE_BINHOST'
Mike Frysinger36870f92015-04-12 02:59:55 -0400340 self.upload_mock = self.PatchObject(prebuilt.PrebuiltUploader,
341 '_UploadPrebuilt', return_value=True)
David James05bcb2b2011-02-09 09:25:47 -0800342
Bob Haarmand1225ea2022-01-19 22:01:42 +0000343 def _testSyncHostPrebuilts(self, chroot):
David Jamese2488642011-11-14 16:15:20 -0800344 board = 'x86-foo'
David James4058b0d2011-12-08 21:24:50 -0800345 target = prebuilt.BuildTarget(board, 'aura')
346 slave_targets = [prebuilt.BuildTarget('x86-bar', 'aura')]
Bob Haarmand1225ea2022-01-19 22:01:42 +0000347 if chroot is None:
348 package_path = os.path.join(self.build_path,
349 'chroot',
350 prebuilt._HOST_PACKAGES_PATH)
351 else:
352 package_path = os.path.join(chroot, prebuilt._HOST_PACKAGES_PATH)
Mike Frysingerd6e2df02014-11-26 02:55:04 -0500353 url_suffix = prebuilt._REL_HOST_PATH % {
354 'version': self.version,
355 'host_arch': prebuilt._HOST_ARCH,
356 'target': target,
357 }
David James8fa34ea2011-04-15 13:00:20 -0700358 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David Jamesf0e6fd72011-04-15 15:58:07 -0700359 url_value = '%s/%s/' % (self.binhost.rstrip('/'),
360 packages_url_suffix.rstrip('/'))
David Jamese2488642011-11-14 16:15:20 -0800361 urls = [url_value.replace('foo', 'bar'), url_value]
David James20b2b6f2011-11-18 15:11:58 -0800362 binhost = ' '.join(urls)
David James615e5b52011-06-03 11:10:15 -0700363 uploader = prebuilt.PrebuiltUploader(
364 self.upload_location, 'public-read', self.binhost, [],
Mike Frysinger8092a632014-05-24 13:25:46 -0400365 self.build_path, [], False, 'foo', False, target, slave_targets,
Bob Haarmand1225ea2022-01-19 22:01:42 +0000366 self.version, chroot=chroot)
Mike Frysinger8092a632014-05-24 13:25:46 -0400367 uploader.SyncHostPrebuilts(self.key, True, True)
Mike Frysinger36870f92015-04-12 02:59:55 -0400368 self.upload_mock.assert_called_once_with(package_path, packages_url_suffix)
369 self.rev_mock.assert_called_once_with(
370 mock.ANY, {self.key: binhost}, dryrun=False)
371 self.update_binhost_mock.assert_called_once_with(
372 mock.ANY, self.key, binhost)
David James05bcb2b2011-02-09 09:25:47 -0800373
Bob Haarmand1225ea2022-01-19 22:01:42 +0000374 def testSyncHostPrebuilts(self):
375 self._testSyncHostPrebuilts(chroot=None)
376
377 def testSyncHostPrebuiltsWithChroot(self):
378 self._testSyncHostPrebuilts('/test/chroot')
379
David James05bcb2b2011-02-09 09:25:47 -0800380 def testSyncBoardPrebuilts(self):
David Jamese2488642011-11-14 16:15:20 -0800381 board = 'x86-foo'
David James4058b0d2011-12-08 21:24:50 -0800382 target = prebuilt.BuildTarget(board, 'aura')
383 slave_targets = [prebuilt.BuildTarget('x86-bar', 'aura')]
Mike Frysinger8092a632014-05-24 13:25:46 -0400384 board_path = os.path.join(
385 self.build_path, prebuilt._BOARD_PATH % {'board': board})
David James05bcb2b2011-02-09 09:25:47 -0800386 package_path = os.path.join(board_path, 'packages')
Mike Frysingerd6e2df02014-11-26 02:55:04 -0500387 url_suffix = prebuilt._REL_BOARD_PATH % {
388 'version': self.version,
389 'target': target,
390 }
David James8fa34ea2011-04-15 13:00:20 -0700391 packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')
David Jamesf0e6fd72011-04-15 15:58:07 -0700392 url_value = '%s/%s/' % (self.binhost.rstrip('/'),
393 packages_url_suffix.rstrip('/'))
David Jamese2488642011-11-14 16:15:20 -0800394 bar_binhost = url_value.replace('foo', 'bar')
Mike Frysinger36870f92015-04-12 02:59:55 -0400395 determine_mock = self.PatchObject(prebuilt, 'DeterminePrebuiltConfFile',
396 side_effect=('bar', 'foo'))
397 self.PatchObject(prebuilt.PrebuiltUploader, '_UploadSdkTarball')
398 with parallel_unittest.ParallelMock():
399 multiprocessing.Process.exitcode = 0
400 uploader = prebuilt.PrebuiltUploader(
401 self.upload_location, 'public-read', self.binhost, [],
402 self.build_path, [], False, 'foo', False, target, slave_targets,
403 self.version)
Gilad Arnoldad333182015-05-27 15:50:41 -0700404 uploader.SyncBoardPrebuilts(self.key, True, True, True, None, None, None,
405 None, None)
Mike Frysinger36870f92015-04-12 02:59:55 -0400406 determine_mock.assert_has_calls([
407 mock.call(self.build_path, slave_targets[0]),
408 mock.call(self.build_path, target),
409 ])
410 self.upload_mock.assert_called_once_with(package_path, packages_url_suffix)
411 self.rev_mock.assert_has_calls([
412 mock.call('bar', {self.key: bar_binhost}, dryrun=False),
413 mock.call('foo', {self.key: url_value}, dryrun=False),
414 ])
415 self.update_binhost_mock.assert_has_calls([
416 mock.call(mock.ANY, self.key, bar_binhost),
417 mock.call(mock.ANY, self.key, url_value),
418 ])
David James05bcb2b2011-02-09 09:25:47 -0800419
420
Mike Frysinger36870f92015-04-12 02:59:55 -0400421class TestMain(cros_test_lib.MockTestCase):
Mike Frysingerc6824f62014-02-03 11:09:44 -0500422 """Tests for the main() function."""
David Jamesc0f158a2011-02-22 16:07:29 -0800423
424 def testMain(self):
425 """Test that the main function works."""
Mike Frysinger36870f92015-04-12 02:59:55 -0400426 options = mock.MagicMock()
David Jamesc0f158a2011-02-22 16:07:29 -0800427 old_binhost = 'http://prebuilt/1'
428 options.previous_binhost_url = [old_binhost]
David Jamese2488642011-11-14 16:15:20 -0800429 options.board = 'x86-foo'
David James4058b0d2011-12-08 21:24:50 -0800430 options.profile = None
Chris Sosa6a5dceb2012-05-14 13:48:56 -0700431 target = prebuilt.BuildTarget(options.board, options.profile)
David Jamesc0f158a2011-02-22 16:07:29 -0800432 options.build_path = '/trunk'
Bob Haarmand1225ea2022-01-19 22:01:42 +0000433 options.chroot = None
Mike Frysinger86509232014-05-24 13:18:37 -0400434 options.dryrun = False
David Jamesfd0b0852011-02-23 11:15:36 -0800435 options.private = True
David James615e5b52011-06-03 11:10:15 -0700436 options.packages = []
David Jamesc0f158a2011-02-22 16:07:29 -0800437 options.sync_host = True
438 options.git_sync = True
David James8fa34ea2011-04-15 13:00:20 -0700439 options.upload_board_tarball = True
Zdenek Behan62a57792012-08-31 15:09:08 +0200440 options.prepackaged_tarball = None
Gilad Arnold2b79e2d2015-06-02 11:26:07 -0700441 options.toolchains_overlay_tarballs = []
442 options.toolchains_overlay_upload_path = ''
Mike Frysinger9e979b92012-11-29 02:55:09 -0500443 options.toolchain_tarballs = []
444 options.toolchain_upload_path = ''
David Jamesc0f158a2011-02-22 16:07:29 -0800445 options.upload = 'gs://upload/'
David Jamesfd0b0852011-02-23 11:15:36 -0800446 options.binhost_base_url = options.upload
David Jamesc0f158a2011-02-22 16:07:29 -0800447 options.prepend_version = True
David James8ece7ee2011-06-29 16:02:30 -0700448 options.set_version = None
449 options.skip_upload = False
David Jamesc0f158a2011-02-22 16:07:29 -0800450 options.filters = True
451 options.key = 'PORTAGE_BINHOST'
David Jamesb26b9312014-12-15 11:26:46 -0800452 options.binhost_conf_dir = None
David Jamesc0f158a2011-02-22 16:07:29 -0800453 options.sync_binhost_conf = True
David James4058b0d2011-12-08 21:24:50 -0800454 options.slave_targets = [prebuilt.BuildTarget('x86-bar', 'aura')]
Mike Frysinger36870f92015-04-12 02:59:55 -0400455 self.PatchObject(prebuilt, 'ParseOptions',
456 return_value=tuple([options, target]))
457 self.PatchObject(binpkg, 'GrabRemotePackageIndex', return_value=True)
458 init_mock = self.PatchObject(prebuilt.PrebuiltUploader, '__init__',
459 return_value=None)
460 expected_gs_acl_path = os.path.join('/fake_path',
Prathmesh Prabhu5f14da02014-10-17 15:13:56 -0700461 prebuilt._GOOGLESTORAGE_GSUTIL_FILE)
Mike Frysinger36870f92015-04-12 02:59:55 -0400462 self.PatchObject(portage_util, 'FindOverlayFile',
463 return_value=expected_gs_acl_path)
464 host_mock = self.PatchObject(
465 prebuilt.PrebuiltUploader, 'SyncHostPrebuilts', return_value=None)
466 board_mock = self.PatchObject(
467 prebuilt.PrebuiltUploader, 'SyncBoardPrebuilts', return_value=None)
468
469 prebuilt.main([])
470
471 init_mock.assert_called_once_with(options.upload, expected_gs_acl_path,
472 options.upload, mock.ANY,
473 options.build_path, options.packages,
474 False, None, False,
475 target, options.slave_targets,
Bob Haarmand1225ea2022-01-19 22:01:42 +0000476 mock.ANY, None)
Mike Frysinger36870f92015-04-12 02:59:55 -0400477 board_mock.assert_called_once_with(
Mike Frysinger8092a632014-05-24 13:25:46 -0400478 options.key, options.git_sync,
Gilad Arnoldad333182015-05-27 15:50:41 -0700479 options.sync_binhost_conf, options.upload_board_tarball, None,
480 [], '', [], '')
Mike Frysinger36870f92015-04-12 02:59:55 -0400481 host_mock.assert_called_once_with(
482 options.key, options.git_sync, options.sync_binhost_conf)
David Jamesc0f158a2011-02-22 16:07:29 -0800483
Mike Frysinger9e979b92012-11-29 02:55:09 -0500484
Mike Frysinger68182472014-11-05 22:38:39 -0500485class TestSdk(cros_test_lib.MockTestCase):
Mike Frysinger9e979b92012-11-29 02:55:09 -0500486 """Test logic related to uploading SDK binaries"""
487
488 def setUp(self):
Mike Frysinger68182472014-11-05 22:38:39 -0500489 self.PatchObject(prebuilt, '_GsUpload',
490 side_effect=Exception('should not get called'))
491 self.PatchObject(prebuilt, 'UpdateBinhostConfFile',
492 side_effect=Exception('should not get called'))
493 self.upload_mock = self.PatchObject(prebuilt.PrebuiltUploader, '_Upload')
Mike Frysinger9e979b92012-11-29 02:55:09 -0500494
495 self.acl = 'magic-acl'
496
497 # All these args pretty much get ignored. Whee.
498 self.uploader = prebuilt.PrebuiltUploader(
499 'gs://foo', self.acl, 'prebuilt', [], '/', [],
Mike Frysinger8092a632014-05-24 13:25:46 -0400500 False, 'foo', False, 'x86-foo', [], 'chroot-1234')
Mike Frysinger9e979b92012-11-29 02:55:09 -0500501
Gilad Arnold2b79e2d2015-06-02 11:26:07 -0700502 def testSdkUpload(self, to_tarballs=(), to_upload_path=None,
Gilad Arnoldad333182015-05-27 15:50:41 -0700503 tc_tarballs=(), tc_upload_path=None):
Mike Frysinger9e979b92012-11-29 02:55:09 -0500504 """Make sure we can upload just an SDK tarball"""
505 tar = 'sdk.tar.xz'
506 ver = '1234'
507 vtar = 'cros-sdk-%s.tar.xz' % ver
508
Mike Frysinger68182472014-11-05 22:38:39 -0500509 calls = [
510 mock.call('%s.Manifest' % tar,
511 'gs://chromiumos-sdk/%s.Manifest' % vtar),
512 mock.call(tar, 'gs://chromiumos-sdk/%s' % vtar),
513 ]
Gilad Arnold2b79e2d2015-06-02 11:26:07 -0700514 for to in to_tarballs:
515 to = to.split(':')
Gilad Arnoldad333182015-05-27 15:50:41 -0700516 calls.append(mock.call(
Gilad Arnold2b79e2d2015-06-02 11:26:07 -0700517 to[1],
518 ('gs://chromiumos-sdk/' + to_upload_path) % {'toolchains': to[0]}))
Mike Frysinger68182472014-11-05 22:38:39 -0500519 for tc in tc_tarballs:
520 tc = tc.split(':')
521 calls.append(mock.call(
522 tc[1], ('gs://chromiumos-sdk/' + tc_upload_path) % {'target': tc[0]}))
523 calls.append(mock.call(
524 mock.ANY, 'gs://chromiumos-sdk/cros-sdk-latest.conf'))
Mike Frysinger9e979b92012-11-29 02:55:09 -0500525
Mike Frysinger8092a632014-05-24 13:25:46 -0400526 self.uploader._UploadSdkTarball('amd64-host', '',
Gilad Arnold2b79e2d2015-06-02 11:26:07 -0700527 tar, to_tarballs, to_upload_path,
Gilad Arnoldad333182015-05-27 15:50:41 -0700528 tc_tarballs, tc_upload_path)
Mike Frysinger68182472014-11-05 22:38:39 -0500529 self.upload_mock.assert_has_calls(calls)
Mike Frysinger9e979b92012-11-29 02:55:09 -0500530
Gilad Arnoldad333182015-05-27 15:50:41 -0700531 def testBoardOverlayTarballUpload(self):
532 """Make sure processing of board-specific overlay tarballs works."""
Gilad Arnold2b79e2d2015-06-02 11:26:07 -0700533 to_tarballs = (
534 ('i686-pc-linux-gnu:'
535 '/some/path/built-sdk-overlay-toolchains-i686-pc-linux-gnu.tar.xz'),
536 ('armv7a-cros-linux-gnueabi-arm-none-eabi:'
537 '/some/path/built-sdk-overlay-toolchains-armv7a-cros-linux-gnueabi-'
538 'arm-none-eabi'),
Gilad Arnoldad333182015-05-27 15:50:41 -0700539 )
Gilad Arnold2b79e2d2015-06-02 11:26:07 -0700540 to_upload_path = (
541 '1994/04/cros-sdk-overlay-toolchains-%(toolchains)s-1994.04.02.tar.xz')
542 self.testSdkUpload(to_tarballs=to_tarballs, to_upload_path=to_upload_path)
Gilad Arnoldad333182015-05-27 15:50:41 -0700543
544 def testToolchainTarballUpload(self):
545 """Make sure processing of toolchain tarballs works."""
Mike Frysinger9e979b92012-11-29 02:55:09 -0500546 tc_tarballs = (
547 'i686:/some/i686.tar.xz',
548 'arm-none:/some/arm.tar.xz',
549 )
550 tc_upload_path = '1994/04/%(target)s-1994.04.02.tar.xz'
Gilad Arnoldad333182015-05-27 15:50:41 -0700551 self.testSdkUpload(tc_tarballs=tc_tarballs, tc_upload_path=tc_upload_path)