blob: e929a89ad7547b816a0effb045b08584b4c033c7 [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2011 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.
"""Unit tests for portage_utilities.py."""
import fileinput
import mox
import os
import re
import sys
import tempfile
import unittest
import constants
if __name__ == '__main__':
sys.path.append(constants.SOURCE_ROOT)
from chromite.lib import cros_build_lib
from chromite.buildbot import portage_utilities
class _Package(object):
def __init__(self, package):
self.package = package
class _DummyCommandResult(object):
"""Create mock RunCommand results."""
def __init__(self, output):
# Members other than 'output' are expected to be unused, so
# we omit them here.
#
# All shell output will be newline terminated; we add the
# newline here for convenience.
self.output = output + '\n'
class EBuildTest(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
def _makeFakeEbuild(self, fake_ebuild_path):
self.mox.StubOutWithMock(fileinput, 'input')
fileinput.input(fake_ebuild_path).AndReturn('')
self.mox.ReplayAll()
fake_ebuild = portage_utilities.EBuild(fake_ebuild_path)
self.mox.VerifyAll()
return fake_ebuild
def testParseEBuildPath(self):
# Test with ebuild with revision number.
fake_ebuild_path = '/path/to/test_package/test_package-0.0.1-r1.ebuild'
fake_ebuild = self._makeFakeEbuild(fake_ebuild_path)
self.assertEquals(fake_ebuild._category, 'to')
self.assertEquals(fake_ebuild._pkgname, 'test_package')
self.assertEquals(fake_ebuild._version_no_rev, '0.0.1')
self.assertEquals(fake_ebuild.current_revision, 1)
self.assertEquals(fake_ebuild.version, '0.0.1-r1')
self.assertEquals(fake_ebuild.package, 'to/test_package')
self.assertEquals(fake_ebuild._ebuild_path_no_version,
'/path/to/test_package/test_package')
self.assertEquals(fake_ebuild.ebuild_path_no_revision,
'/path/to/test_package/test_package-0.0.1')
self.assertEquals(fake_ebuild._unstable_ebuild_path,
'/path/to/test_package/test_package-9999.ebuild')
self.assertEquals(fake_ebuild.ebuild_path, fake_ebuild_path)
def testParseEBuildPathNoRevisionNumber(self):
# Test with ebuild without revision number.
fake_ebuild_path = '/path/to/test_package/test_package-9999.ebuild'
fake_ebuild = self._makeFakeEbuild(fake_ebuild_path)
self.assertEquals(fake_ebuild._category, 'to')
self.assertEquals(fake_ebuild._pkgname, 'test_package')
self.assertEquals(fake_ebuild._version_no_rev, '9999')
self.assertEquals(fake_ebuild.current_revision, 0)
self.assertEquals(fake_ebuild.version, '9999')
self.assertEquals(fake_ebuild.package, 'to/test_package')
self.assertEquals(fake_ebuild._ebuild_path_no_version,
'/path/to/test_package/test_package')
self.assertEquals(fake_ebuild.ebuild_path_no_revision,
'/path/to/test_package/test_package-9999')
self.assertEquals(fake_ebuild._unstable_ebuild_path,
'/path/to/test_package/test_package-9999.ebuild')
self.assertEquals(fake_ebuild.ebuild_path, fake_ebuild_path)
def testGetCommitId(self):
fake_sources = '/path/to/sources'
fake_category = 'test_category'
fake_package = 'test_package'
fake_ebuild_path = os.path.join(fake_sources, 'overlay',
fake_category, fake_package,
fake_package + '-9999.ebuild')
fake_ebuild = self._makeFakeEbuild(fake_ebuild_path)
self.mox.UnsetStubs()
fake_hash = '24ab3c9f6d6b5c744382dba2ca8fb444b9808e9f'
fake_project = 'chromiumos/third_party/test_project'
fake_subdir = 'test_project/'
# We expect Die() will not be called; mock it out so that if
# we're wrong, it won't just terminate the test.
self.mox.StubOutWithMock(portage_utilities.cros_build_lib, 'Die')
self.mox.StubOutWithMock(portage_utilities.os.path, 'isdir')
self.mox.StubOutWithMock(
portage_utilities.cros_build_lib, 'RunCommand')
# The first RunCommand does 'grep' magic on the ebuild.
result1 = _DummyCommandResult(' '.join([fake_project, fake_subdir]))
portage_utilities.cros_build_lib.RunCommand(
mox.IgnoreArg(),
print_cmd=fake_ebuild.verbose,
redirect_stdout=True,
shell=True).AndReturn(result1)
# ... the result is used to construct a path, which the EBuild
# code expects to be a directory.
portage_utilities.os.path.isdir(
os.path.join(fake_sources, 'third_party', fake_subdir)).AndReturn(True)
# ... the next RunCommand does 'git config --get ...'
result2 = _DummyCommandResult(fake_project)
portage_utilities.cros_build_lib.RunCommand(
mox.IgnoreArg(),
print_cmd=fake_ebuild.verbose,
redirect_stdout=True,
shell=True).AndReturn(result2)
# ... and the final RunCommand does 'git rev-parse HEAD'
result3 = _DummyCommandResult(fake_hash)
portage_utilities.cros_build_lib.RunCommand(
mox.IgnoreArg(),
print_cmd=fake_ebuild.verbose,
redirect_stdout=True,
shell=True).AndReturn(result3)
self.mox.ReplayAll()
test_hash = fake_ebuild._GetCommitId(fake_sources)
self.mox.VerifyAll()
self.assertEquals(test_hash, fake_hash)
class StubEBuild(portage_utilities.EBuild):
def __init__(self, path):
super(StubEBuild, self).__init__(path)
self.is_workon = True
self.is_stable = True
def _ReadEBuild(self, path):
pass
def _GetCommitId(self, srcroot):
if srcroot == '/sources':
return 'my_id'
else:
return 'you_lose'
class EBuildRevWorkonTest(mox.MoxTestBase):
# Lines that we will feed as fake ebuild contents to
# EBuild.MarAsStable(). This is the minimum content needed
# to test the various branches in the function's main processing
# loop.
_mock_ebuild = ['EAPI=2\n',
'CROS_WORKON_COMMIT=old_id\n',
'KEYWORDS=\"~x86 ~arm\"\n',
'src_unpack(){}\n']
def setUp(self):
mox.MoxTestBase.setUp(self)
package_name = '/sources/overlay/category/test_package/test_package-0.0.1'
ebuild_path = package_name + '-r1.ebuild'
self.m_ebuild = StubEBuild(ebuild_path)
self.revved_ebuild_path = package_name + '-r2.ebuild'
def createRevWorkOnMocks(self, ebuild_content):
self.mox.StubOutWithMock(portage_utilities.os.path, 'exists')
self.mox.StubOutWithMock(portage_utilities.cros_build_lib, 'Die')
self.mox.StubOutWithMock(portage_utilities.shutil, 'copyfile')
self.mox.StubOutWithMock(portage_utilities.os, 'unlink')
self.mox.StubOutWithMock(portage_utilities.EBuild, '_RunCommand')
self.mox.StubOutWithMock(portage_utilities.filecmp, 'cmp')
self.mox.StubOutWithMock(portage_utilities.fileinput, 'input')
ebuild_9999 = self.m_ebuild._unstable_ebuild_path
portage_utilities.os.path.exists(ebuild_9999).AndReturn(True)
# These calls come from MarkAsStable()
portage_utilities.shutil.copyfile(ebuild_9999, self.revved_ebuild_path)
m_file = self.mox.CreateMock(file)
portage_utilities.fileinput.input(self.revved_ebuild_path,
inplace=1).AndReturn(ebuild_content)
m_file.write('EAPI=2\n')
m_file.write('CROS_WORKON_COMMIT="my_id"\n')
m_file.write('KEYWORDS=\"x86 arm\"\n')
m_file.write( 'src_unpack(){}\n')
# MarkAsStable() returns here
return m_file
def testRevWorkOnEBuild(self):
m_file = self.createRevWorkOnMocks(self._mock_ebuild)
portage_utilities.filecmp.cmp(self.m_ebuild.ebuild_path,
self.revved_ebuild_path,
shallow=False).AndReturn(False)
portage_utilities.EBuild._RunCommand(
'git add ' + self.revved_ebuild_path)
portage_utilities.EBuild._RunCommand(
'git rm ' + self.m_ebuild.ebuild_path)
message = portage_utilities._GIT_COMMIT_MESSAGE % (
self.m_ebuild.package, 'my_id')
portage_utilities.EBuild._RunCommand('git commit -am "%s"' % message)
self.mox.ReplayAll()
result = self.m_ebuild.RevWorkOnEBuild('/sources', redirect_file=m_file)
self.mox.VerifyAll()
self.assertEqual(result, 'category/test_package-0.0.1-r2')
def testRevUnchangedEBuild(self):
m_file = self.createRevWorkOnMocks(self._mock_ebuild)
portage_utilities.filecmp.cmp(self.m_ebuild.ebuild_path,
self.revved_ebuild_path,
shallow=False).AndReturn(True)
portage_utilities.os.unlink(self.revved_ebuild_path)
self.mox.ReplayAll()
result = self.m_ebuild.RevWorkOnEBuild('/sources', redirect_file=m_file)
self.mox.VerifyAll()
self.assertEqual(result, None)
def testRevMissingEBuild(self):
self.revved_ebuild_path = self.m_ebuild.ebuild_path
self.m_ebuild.ebuild_path = self.m_ebuild._unstable_ebuild_path
self.m_ebuild.current_revision = 0
self.m_ebuild.is_stable = False
m_file = self.createRevWorkOnMocks(
self._mock_ebuild[0:1] + self._mock_ebuild[2:])
portage_utilities.filecmp.cmp(self.m_ebuild.ebuild_path,
self.revved_ebuild_path,
shallow=False).AndReturn(False)
portage_utilities.EBuild._RunCommand(
'git add ' + self.revved_ebuild_path)
message = portage_utilities._GIT_COMMIT_MESSAGE % (
self.m_ebuild.package, 'my_id')
portage_utilities.EBuild._RunCommand('git commit -am "%s"' % message)
self.mox.ReplayAll()
result = self.m_ebuild.RevWorkOnEBuild('/sources', redirect_file=m_file)
self.mox.VerifyAll()
self.assertEqual(result, 'category/test_package-0.0.1-r1')
def testCommitChange(self):
self.mox.StubOutWithMock(portage_utilities.EBuild, '_RunCommand')
mock_message = 'Commit me'
portage_utilities.EBuild._RunCommand(
'git commit -am "%s"' % mock_message)
self.mox.ReplayAll()
self.m_ebuild.CommitChange(mock_message)
self.mox.VerifyAll()
class FindOverlaysTest(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
self.build_root = '/fake_root'
self.overlay = os.path.join(self.build_root,
'src/third_party/chromiumos-overlay')
def testFindOverlays(self):
self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
stub_list_cmd = '/bin/true'
public_output = 'public1\npublic2\n'
private_output = 'private1\nprivate2\n'
output_obj = cros_build_lib.CommandResult()
output_obj.output = public_output
cros_build_lib.RunCommand(
[stub_list_cmd, '--all_boards', '--noprivate'],
print_cmd=False, redirect_stdout=True).AndReturn(output_obj)
output_obj = cros_build_lib.CommandResult()
output_obj.output = private_output
cros_build_lib.RunCommand(
[stub_list_cmd, '--all_boards', '--nopublic'],
print_cmd=False, redirect_stdout=True).AndReturn(output_obj)
output_obj = cros_build_lib.CommandResult()
output_obj.output = private_output + public_output
cros_build_lib.RunCommand(
[stub_list_cmd, '--all_boards'],
print_cmd=False, redirect_stdout=True).AndReturn(output_obj)
self.mox.ReplayAll()
portage_utilities._OVERLAY_LIST_CMD = stub_list_cmd
public_overlays = ['public1', 'public2', self.overlay]
private_overlays = ['private1', 'private2']
self.assertEqual(portage_utilities.FindOverlays(self.build_root, 'public'),
public_overlays)
self.assertEqual(portage_utilities.FindOverlays(self.build_root, 'private'),
private_overlays)
self.assertEqual(portage_utilities.FindOverlays(self.build_root, 'both'),
private_overlays + public_overlays)
self.mox.VerifyAll()
class BuildEBuildDictionaryTest(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
self.mox.StubOutWithMock(portage_utilities.os, 'walk')
self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
self.package = 'chromeos-base/test_package'
self.root = '/overlay/chromeos-base/test_package'
self.package_path = self.root + '/test_package-0.0.1.ebuild'
paths = [[self.root, [], []]]
portage_utilities.os.walk("/overlay").AndReturn(paths)
self.mox.StubOutWithMock(portage_utilities, '_FindUprevCandidates')
def testWantedPackage(self):
overlays = {"/overlay": []}
package = _Package(self.package)
portage_utilities._FindUprevCandidates(
[], mox.IgnoreArg()).AndReturn(package)
self.mox.ReplayAll()
portage_utilities.BuildEBuildDictionary(
overlays, False, [self.package])
self.mox.VerifyAll()
self.assertEquals(len(overlays), 1)
self.assertEquals(overlays["/overlay"], [package])
def testUnwantedPackage(self):
overlays = {"/overlay": []}
package = _Package(self.package)
portage_utilities._FindUprevCandidates(
[], mox.IgnoreArg()).AndReturn(package)
self.mox.ReplayAll()
portage_utilities.BuildEBuildDictionary(overlays, False, [])
self.assertEquals(len(overlays), 1)
self.assertEquals(overlays["/overlay"], [])
self.mox.VerifyAll()
class BlacklistManagerTest(mox.MoxTestBase):
"""Class that tests the blacklist manager."""
FAKE_BLACKLIST = """
# A Fake blacklist file.
chromeos-base/fake-package
"""
def setUp(self):
mox.MoxTestBase.setUp(self)
def testInitializeFromFile(self):
"""Tests whether we can correctly initialize from a fake blacklist file."""
file_path = tempfile.mktemp()
with open(file_path, 'w+') as fh:
fh.write(self.FAKE_BLACKLIST)
saved_black_list = portage_utilities._BlackListManager.BLACK_LIST_FILE
try:
portage_utilities._BlackListManager.BLACK_LIST_FILE = file_path
black_list_manager = portage_utilities._BlackListManager()
self.assertTrue(black_list_manager.IsPackageBlackListed(
'/some/crazy/path/'
'chromeos-base/fake-package/fake-package-0.0.5.ebuild'))
self.assertEqual(len(black_list_manager.black_list_re_array), 1)
finally:
os.remove(file_path)
portage_utilities._BlackListManager.BLACK_LIST_FILE = saved_black_list
def testIsPackageBlackListed(self):
"""Tests if we can correctly check if a package is blacklisted."""
self.mox.StubOutWithMock(portage_utilities._BlackListManager,
'_Initialize')
portage_utilities._BlackListManager._Initialize()
self.mox.ReplayAll()
black_list_manager = portage_utilities._BlackListManager()
black_list_manager.black_list_re_array = [
re.compile('.*/fake/pkg/pkg-.*\.ebuild') ]
self.assertTrue(black_list_manager.IsPackageBlackListed(
'/some/crazy/path/'
'fake/pkg/pkg-version.ebuild'))
self.assertFalse(black_list_manager.IsPackageBlackListed(
'/some/crazy/path/'
'fake/diff-pkg/diff-pkg-version.ebuild'))
self.mox.VerifyAll()
if __name__ == '__main__':
unittest.main()