| # -*- coding: utf-8 -*-path + os.sep) |
| # Copyright 2019 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Unittests for the binhost.py service.""" |
| |
| from __future__ import print_function |
| |
| import os |
| |
| import mock |
| |
| from chromite.lib import binpkg |
| from chromite.lib import build_target_lib |
| from chromite.lib import chroot_lib |
| from chromite.lib import constants |
| from chromite.lib import cros_test_lib |
| from chromite.lib import osutils |
| from chromite.lib import parallel |
| from chromite.lib import portage_util |
| from chromite.lib import sysroot_lib |
| from chromite.service import binhost |
| |
| |
| class GetPrebuiltAclArgsTest(cros_test_lib.MockTempDirTestCase): |
| """GetPrebuiltAclArgs tests.""" |
| |
| _ACL_FILE = """ |
| # Comment |
| -g group1:READ |
| |
| # Another Comment |
| -u user:FULL_CONTROL # EOL Comment |
| |
| |
| |
| # Comment # Comment |
| -g group2:READ |
| """ |
| |
| def setUp(self): |
| self.build_target = build_target_lib.BuildTarget('board') |
| self.acl_file = os.path.join(self.tempdir, 'googlestorage_acl.txt') |
| osutils.WriteFile(self.acl_file, self._ACL_FILE) |
| |
| def testParse(self): |
| """Test parsing a valid file.""" |
| self.PatchObject(portage_util, 'FindOverlayFile', |
| return_value=self.acl_file) |
| |
| expected_acls = [['-g', 'group1:READ'], ['-u', 'user:FULL_CONTROL'], |
| ['-g', 'group2:READ']] |
| |
| acls = binhost.GetPrebuiltAclArgs(self.build_target) |
| |
| self.assertCountEqual(expected_acls, acls) |
| |
| def testNoFile(self): |
| """Test no file handling.""" |
| self.PatchObject(portage_util, 'FindOverlayFile', return_value=None) |
| |
| with self.assertRaises(binhost.NoAclFileFound): |
| binhost.GetPrebuiltAclArgs(self.build_target) |
| |
| |
| class SetBinhostTest(cros_test_lib.MockTempDirTestCase): |
| """Unittests for SetBinhost.""" |
| |
| def setUp(self): |
| self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir) |
| |
| self.public_conf_dir = os.path.join( |
| self.tempdir, constants.PUBLIC_BINHOST_CONF_DIR, 'target') |
| osutils.SafeMakedirs(self.public_conf_dir) |
| |
| self.private_conf_dir = os.path.join( |
| self.tempdir, constants.PRIVATE_BINHOST_CONF_DIR, 'target') |
| osutils.SafeMakedirs(self.private_conf_dir) |
| |
| def tearDown(self): |
| osutils.EmptyDir(self.tempdir) |
| |
| def testSetBinhostPublic(self): |
| """SetBinhost returns correct public path and updates conf file.""" |
| actual = binhost.SetBinhost( |
| 'coral', 'BINHOST_KEY', 'gs://prebuilts', private=False) |
| expected = os.path.join(self.public_conf_dir, 'coral-BINHOST_KEY.conf') |
| self.assertEqual(actual, expected) |
| self.assertEqual(osutils.ReadFile(actual), 'BINHOST_KEY="gs://prebuilts"') |
| |
| def testSetBinhostPrivate(self): |
| """SetBinhost returns correct private path and updates conf file.""" |
| actual = binhost.SetBinhost('coral', 'BINHOST_KEY', 'gs://prebuilts') |
| expected = os.path.join(self.private_conf_dir, 'coral-BINHOST_KEY.conf') |
| self.assertEqual(actual, expected) |
| self.assertEqual(osutils.ReadFile(actual), 'BINHOST_KEY="gs://prebuilts"') |
| |
| def testSetBinhostEmptyConf(self): |
| """SetBinhost rejects existing but empty conf files.""" |
| conf_path = os.path.join(self.private_conf_dir, 'multi-BINHOST_KEY.conf') |
| osutils.WriteFile(conf_path, ' ') |
| with self.assertRaises(ValueError): |
| binhost.SetBinhost('multi', 'BINHOST_KEY', 'gs://blah') |
| |
| def testSetBinhostMultilineConf(self): |
| """SetBinhost rejects existing multiline conf files.""" |
| conf_path = os.path.join(self.private_conf_dir, 'multi-BINHOST_KEY.conf') |
| osutils.WriteFile(conf_path, '\n'.join(['A="foo"', 'B="bar"'])) |
| with self.assertRaises(ValueError): |
| binhost.SetBinhost('multi', 'BINHOST_KEY', 'gs://blah') |
| |
| def testSetBinhhostBadConfLine(self): |
| """SetBinhost rejects existing conf files with malformed lines.""" |
| conf_path = os.path.join(self.private_conf_dir, 'bad-BINHOST_KEY.conf') |
| osutils.WriteFile(conf_path, 'bad line') |
| with self.assertRaises(ValueError): |
| binhost.SetBinhost('bad', 'BINHOST_KEY', 'gs://blah') |
| |
| def testSetBinhostMismatchedKey(self): |
| """SetBinhost rejects existing conf files with a mismatched key.""" |
| conf_path = os.path.join(self.private_conf_dir, 'bad-key-GOOD_KEY.conf') |
| osutils.WriteFile(conf_path, 'BAD_KEY="https://foo.bar"') |
| with self.assertRaises(KeyError): |
| binhost.SetBinhost('bad-key', 'GOOD_KEY', 'gs://blah') |
| |
| |
| class GetPrebuiltsRootTest(cros_test_lib.MockTempDirTestCase): |
| """Unittests for GetPrebuiltsRoot.""" |
| |
| def setUp(self): |
| self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir) |
| self.chroot_path = os.path.join(self.tempdir, 'chroot') |
| self.sysroot_path = '/build/foo' |
| self.root = os.path.join(self.chroot_path, self.sysroot_path.lstrip('/'), |
| 'packages') |
| |
| self.chroot = chroot_lib.Chroot(self.chroot_path) |
| self.sysroot = sysroot_lib.Sysroot(self.sysroot_path) |
| self.build_target = build_target_lib.BuildTarget('foo') |
| |
| osutils.SafeMakedirs(self.root) |
| |
| def testGetPrebuiltsRoot(self): |
| """GetPrebuiltsRoot returns correct root for given build target.""" |
| actual = binhost.GetPrebuiltsRoot(self.chroot, self.sysroot, |
| self.build_target) |
| self.assertEqual(actual, self.root) |
| |
| def testGetPrebuiltsBadTarget(self): |
| """GetPrebuiltsRoot dies on missing root (target probably not built.)""" |
| with self.assertRaises(binhost.EmptyPrebuiltsRoot): |
| binhost.GetPrebuiltsRoot(self.chroot, sysroot_lib.Sysroot('/build/bar'), |
| build_target_lib.BuildTarget('bar')) |
| |
| |
| class GetPrebuiltsFilesTest(cros_test_lib.MockTempDirTestCase): |
| """Unittests for GetPrebuiltsFiles.""" |
| |
| def setUp(self): |
| self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir) |
| self.root = os.path.join(self.tempdir, 'chroot/build/target/packages') |
| osutils.SafeMakedirs(self.root) |
| |
| def testGetPrebuiltsFiles(self): |
| """GetPrebuiltsFiles returns all archives for all packages.""" |
| packages_content = """\ |
| ARCH: amd64 |
| URI: gs://foo_prebuilts |
| |
| CPV: package/prebuilt_a |
| |
| CPV: package/prebuilt_b |
| """ |
| osutils.WriteFile(os.path.join(self.root, 'Packages'), packages_content) |
| osutils.WriteFile(os.path.join(self.root, 'package/prebuilt_a.tbz2'), 'a', |
| makedirs=True) |
| osutils.WriteFile(os.path.join(self.root, 'package/prebuilt_b.tbz2'), 'b') |
| |
| actual = binhost.GetPrebuiltsFiles(self.root) |
| expected = ['package/prebuilt_a.tbz2', 'package/prebuilt_b.tbz2'] |
| self.assertEqual(actual, expected) |
| |
| def testGetPrebuiltsFilesWithDebugSymbols(self): |
| """GetPrebuiltsFiles returns debug symbols archive if specified in index.""" |
| packages_content = """\ |
| ARCH: amd64 |
| URI: gs://foo_prebuilts |
| |
| CPV: package/prebuilt |
| DEBUG_SYMBOLS: yes |
| """ |
| osutils.WriteFile(os.path.join(self.root, 'Packages'), packages_content) |
| osutils.WriteFile(os.path.join(self.root, 'package/prebuilt.tbz2'), 'foo', |
| makedirs=True) |
| osutils.WriteFile(os.path.join(self.root, 'package/prebuilt.debug.tbz2'), |
| 'debug', makedirs=True) |
| |
| actual = binhost.GetPrebuiltsFiles(self.root) |
| expected = ['package/prebuilt.tbz2', 'package/prebuilt.debug.tbz2'] |
| self.assertEqual(actual, expected) |
| |
| def testGetPrebuiltsFilesBadFile(self): |
| """GetPrebuiltsFiles dies if archive file does not exist.""" |
| packages_content = """\ |
| ARCH: amd64 |
| URI: gs://foo_prebuilts |
| |
| CPV: package/prebuilt |
| """ |
| osutils.WriteFile(os.path.join(self.root, 'Packages'), packages_content) |
| |
| with self.assertRaises(LookupError): |
| binhost.GetPrebuiltsFiles(self.root) |
| |
| |
| class UpdatePackageIndexTest(cros_test_lib.MockTempDirTestCase): |
| """Unittests for UpdatePackageIndex.""" |
| |
| def setUp(self): |
| self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir) |
| self.root = os.path.join(self.tempdir, 'chroot/build/target/packages') |
| osutils.SafeMakedirs(self.root) |
| |
| def testAbsoluteUploadPath(self): |
| """Test UpdatePackageIndex raises an error for absolute paths.""" |
| with self.assertRaises(AssertionError): |
| binhost.UpdatePackageIndex(self.root, 'gs://chromeos-prebuilt', '/target') |
| |
| def testUpdatePackageIndex(self): |
| """UpdatePackageIndex writes updated file to disk.""" |
| packages_content = """\ |
| ARCH: amd64 |
| TTL: 0 |
| |
| CPV: package/prebuilt |
| """ |
| osutils.WriteFile(os.path.join(self.root, 'Packages'), packages_content) |
| |
| binhost.UpdatePackageIndex(self.root, 'gs://chromeos-prebuilt', 'target/') |
| |
| actual = binpkg.GrabLocalPackageIndex(self.root) |
| self.assertEqual(actual.header['URI'], 'gs://chromeos-prebuilt') |
| self.assertEqual(int(actual.header['TTL']), 60 * 60 * 24 * 365) |
| self.assertEqual( |
| actual.packages, |
| [{'CPV': 'package/prebuilt', 'PATH': 'target/package/prebuilt.tbz2'}]) |
| |
| |
| class RegenBuildCacheTest(cros_test_lib.MockTempDirTestCase): |
| """Unittests for RegenBuildCache.""" |
| |
| def testCallsRegenPortageCache(self): |
| """Test that overlays=None works.""" |
| overlays_found = [os.path.join(self.tempdir, 'path/to')] |
| for o in overlays_found: |
| osutils.SafeMakedirs(o) |
| find_overlays = self.PatchObject( |
| portage_util, 'FindOverlays', return_value=overlays_found) |
| run_tasks = self.PatchObject(parallel, 'RunTasksInProcessPool') |
| |
| binhost.RegenBuildCache(chroot_lib.Chroot, None) |
| find_overlays.assert_called_once_with(None) |
| run_tasks.assert_called_once_with(mock.ANY, [overlays_found]) |
| |
| |
| class ReadDevInstallPackageFileTest(cros_test_lib.MockTempDirTestCase): |
| """Unittests for ReadDevInstallPackageFile.""" |
| |
| def setUp(self): |
| self.root = os.path.join( |
| self.tempdir, |
| 'chroot/build/target/build/dev-install/') |
| self.packages_file = os.path.join( |
| self.root, 'package.installable') |
| osutils.SafeMakedirs(self.root) |
| package_file_content = """\ |
| x11-apps/intel-gpu-tools-1.22 |
| x11-libs/gdk-pixbuf-2.36.12-r1 |
| x11-misc/read-edid-1.4.2 |
| virtual/acl-0-r1 |
| """ |
| osutils.WriteFile(self.packages_file, package_file_content) |
| |
| |
| def testReadDevInstallPackageFile(self): |
| """Test that parsing valid file works.""" |
| packages = binhost.ReadDevInstallPackageFile(self.packages_file) |
| expected_packages = ['x11-apps/intel-gpu-tools-1.22', |
| 'x11-libs/gdk-pixbuf-2.36.12-r1', |
| 'x11-misc/read-edid-1.4.2', |
| 'virtual/acl-0-r1'] |
| self.assertEqual(packages, expected_packages) |
| |
| |
| class CreateDevInstallPackageFileTest(cros_test_lib.MockTempDirTestCase): |
| """Unittests for CreateDevInstallPackageFile.""" |
| |
| def setUp(self): |
| self.PatchObject(constants, 'SOURCE_ROOT', new=self.tempdir) |
| self.root = os.path.join(self.tempdir, 'chroot/build/target/packages') |
| osutils.SafeMakedirs(self.root) |
| self.devinstall_package_list = ['virtual/python-enum34-1'] |
| self.devinstall_packages_filename = os.path.join(self.root, |
| 'package.installable') |
| packages_content = """\ |
| ARCH: amd64 |
| TTL: 0 |
| |
| CPV: package/prebuilt |
| |
| CPV: virtual/python-enum34-1 |
| |
| """ |
| osutils.WriteFile(os.path.join(self.root, 'Packages'), packages_content) |
| |
| devinstall_packages_content = """\ |
| virtual/python-enum34-1 |
| """ |
| osutils.WriteFile(self.devinstall_packages_filename, |
| devinstall_packages_content) |
| self.upload_dir = os.path.join(self.root, 'upload_dir') |
| osutils.SafeMakedirs(self.upload_dir) |
| self.upload_packages_file = os.path.join(self.upload_dir, 'Packages') |
| |
| |
| def testCreateFilteredPackageIndex(self): |
| """CreateDevInstallPackageFile writes updated file to disk.""" |
| binhost.CreateFilteredPackageIndex(self.root, |
| self.devinstall_package_list, |
| self.upload_packages_file, |
| 'gs://chromeos-prebuilt', 'target/') |
| |
| # We need to verify that a file was created at self.devinstall_package_list |
| actual = binpkg.GrabLocalPackageIndex(self.upload_dir) |
| self.assertEqual(actual.header['URI'], 'gs://chromeos-prebuilt') |
| self.assertEqual(int(actual.header['TTL']), 60 * 60 * 24 * 365) |
| self.assertEqual( |
| actual.packages, |
| [{'CPV': 'virtual/python-enum34-1', |
| 'PATH': 'target/virtual/python-enum34-1.tbz2'}]) |