blob: 9351802aa7d4cae55f5048887db02eab184e769f [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2012 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 commands. Needs to be run inside of chroot for mox."""
import mox
import os
import shutil
import sys
import tempfile
import unittest
import constants
sys.path.insert(0, constants.SOURCE_ROOT)
from chromite.buildbot import cbuildbot_commands as commands
from chromite.buildbot import cbuildbot_results as results_lib
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
# pylint: disable=E1101,W0212,R0904
class RunBuildScriptTest(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
def tearDown(self):
self.mox.UnsetStubs()
def _assertRunBuildScript(self, in_chroot=False, tmpf=None, raises=None):
"""Test the RunBuildScript function.
Args:
in_chroot: Whether to enter the chroot or not.
tmpf: If the chroot tempdir exists, a NamedTemporaryFile that contains
a list of the packages that failed to build.
raises: If the command should fail, the exception to be raised.
"""
# Mock out functions used by RunBuildScript.
self.mox.StubOutWithMock(cros_build_lib, 'ReinterpretPathForChroot')
self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
self.mox.StubOutWithMock(cros_build_lib, 'Error')
self.mox.StubOutWithMock(os.path, 'exists')
self.mox.StubOutWithMock(tempfile, 'NamedTemporaryFile')
buildroot = '.'
cmd = ['example', 'command']
# If we enter the chroot, _RunBuildScript will try to create a temporary
# status file inside the chroot to track what packages failed (if any.)
kwargs = dict()
if in_chroot:
tempdir = os.path.join(buildroot, 'chroot', 'tmp')
os.path.exists(tempdir).AndReturn(tmpf is not None)
if tmpf is not None:
tempfile.NamedTemporaryFile(dir=tempdir).AndReturn(tmpf)
cros_build_lib.ReinterpretPathForChroot(tmpf.name).AndReturn(tmpf.name)
kwargs['extra_env'] = {'PARALLEL_EMERGE_STATUS_FILE': tmpf.name}
# Run the command, throwing an exception if it fails.
ret = cros_build_lib.RunCommand(cmd, cwd=buildroot, enter_chroot=in_chroot,
**kwargs)
if raises:
result = cros_build_lib.CommandResult()
ex = cros_build_lib.RunCommandError('command totally failed', result)
ret.AndRaise(ex)
cros_build_lib.Error('\n%s', ex)
# If the script failed, the exception should be raised and printed.
self.mox.ReplayAll()
if raises:
self.assertRaises(raises, commands._RunBuildScript, buildroot,
cmd, enter_chroot=in_chroot)
else:
commands._RunBuildScript(buildroot, cmd, enter_chroot=in_chroot)
self.mox.VerifyAll()
def testSuccessOutsideChroot(self):
"""Test executing a command outside the chroot."""
self._assertRunBuildScript()
def testSuccessInsideChrootWithoutTempdir(self):
"""Test executing a command inside a chroot without a tmp dir."""
self._assertRunBuildScript(in_chroot=True)
def testSuccessInsideChrootWithTempdir(self):
"""Test executing a command inside a chroot with a tmp dir."""
with tempfile.NamedTemporaryFile() as tmpf:
self._assertRunBuildScript(in_chroot=True, tmpf=tmpf)
def testFailureOutsideChroot(self):
"""Test a command failure outside the chroot."""
self._assertRunBuildScript(raises=results_lib.BuildScriptFailure)
def testFailureInsideChrootWithoutTempdir(self):
"""Test a command failure inside the chroot without a temp directory."""
self._assertRunBuildScript(in_chroot=True,
raises=results_lib.BuildScriptFailure)
def testFailureInsideChrootWithTempdir(self):
"""Test a command failure inside the chroot with a temp directory."""
with tempfile.NamedTemporaryFile() as tmpf:
self._assertRunBuildScript(in_chroot=True, tmpf=tmpf,
raises=results_lib.BuildScriptFailure)
def testPackageBuildFailure(self):
"""Test detecting a package build failure."""
with tempfile.NamedTemporaryFile() as tmpf:
tmpf.write('chromeos-base/chromeos-chrome')
self._assertRunBuildScript(in_chroot=True, tmpf=tmpf,
raises=results_lib.PackageBuildFailure)
class CBuildBotTest(mox.MoxTestBase):
def setUp(self):
mox.MoxTestBase.setUp(self)
# Always stub RunCommmand out as we use it in every method.
self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
self._test_repos = [['kernel', 'third_party/kernel/files'],
['login_manager', 'platform/login_manager']
]
self._test_cros_workon_packages = (
'chromeos-base/kernel\nchromeos-base/chromeos-login\n')
self._test_board = 'test-board'
self._buildroot = '.'
self._test_dict = {'kernel': ['chromos-base/kernel', 'dev-util/perf'],
'cros': ['chromos-base/libcros']
}
self._test_string = 'kernel.git@12345test cros.git@12333test'
self._test_string += ' crosutils.git@blahblah'
self._revision_file = 'test-revisions.pfq'
self._test_parsed_string_array = [['chromeos-base/kernel', '12345test'],
['dev-util/perf', '12345test'],
['chromos-base/libcros', '12345test']]
self._overlays = ['%s/src/third_party/chromiumos-overlay' % self._buildroot]
self._chroot_overlays = [
cros_build_lib.ReinterpretPathForChroot(p) for p in self._overlays
]
self._CWD = os.path.dirname(os.path.realpath(__file__))
self._work_dir = tempfile.mkdtemp()
os.makedirs(self._work_dir + '/chroot/tmp/taco')
def tearDown(self):
shutil.rmtree(self._work_dir)
self.mox.UnsetStubs()
def testRunTestSuite(self):
"""Tests if we can parse the test_types so that sane commands are called."""
def ItemsNotInList(items, list_):
"""Helper function that returns whether items are not in a list."""
return set(items).isdisjoint(set(list_))
cwd = self._work_dir + '/src/scripts'
obj = cros_test_lib.EasyAttr(returncode=0)
cros_build_lib.RunCommand(
mox.Func(lambda x: ItemsNotInList(['--quick', '--only_verify'], x)),
cwd=cwd, error_ok=True).AndReturn(obj)
self.mox.ReplayAll()
commands.RunTestSuite(self._work_dir, self._test_board, self._buildroot,
'/tmp/taco', build_config='test_config',
whitelist_chrome_crashes=False,
test_type=constants.FULL_AU_TEST_TYPE)
self.mox.VerifyAll()
self.mox.ResetAll()
cros_build_lib.RunCommand(mox.In('--quick'), cwd=cwd,
error_ok=True).AndReturn(obj)
self.mox.ReplayAll()
commands.RunTestSuite(self._work_dir, self._test_board, self._buildroot,
'/tmp/taco', build_config='test_config',
whitelist_chrome_crashes=False,
test_type=constants.SIMPLE_AU_TEST_TYPE)
self.mox.VerifyAll()
self.mox.ResetAll()
cros_build_lib.RunCommand(
mox.And(mox.In('--quick'), mox.In('--only_verify')),
cwd=cwd, error_ok=True).AndReturn(obj)
self.mox.ReplayAll()
commands.RunTestSuite(self._work_dir, self._test_board, self._buildroot,
'/tmp/taco', build_config='test_config',
whitelist_chrome_crashes=False,
test_type=constants.SMOKE_SUITE_TEST_TYPE)
self.mox.VerifyAll()
def testArchiveTestResults(self):
"""Test if we can archive the latest results dir to Google Storage."""
# Set vars for call.
self.mox.StubOutWithMock(shutil, 'rmtree')
buildroot = '/fake_dir'
test_tarball = os.path.join(buildroot, 'test_results.tgz')
test_results_dir = 'fake_results_dir'
# Convenience variables to make archive easier to understand.
chroot = os.path.join(buildroot, 'chroot')
path_to_results = os.path.join(chroot, test_results_dir)
gzip = cros_build_lib.FindCompressor(
cros_build_lib.COMP_GZIP, chroot=chroot)
cros_build_lib.SudoRunCommand(
['chmod', '-R', 'a+rw', path_to_results], print_cmd=False)
cros_build_lib.RunCommand(
['tar', '-I', gzip, '-cf', test_tarball,
'--directory=%s' % path_to_results, '.'],
print_cmd=False)
shutil.rmtree(path_to_results)
self.mox.ReplayAll()
commands.ArchiveTestResults(buildroot, test_results_dir, '')
self.mox.VerifyAll()
def testGenerateMinidumpStackTraces(self):
"""Test if we can generate stack traces for minidumps."""
temp_dir = '/chroot/temp_dir'
gzipped_test_tarball = '/test_results.tgz'
test_tarball = '/test_results.tar'
dump_file = os.path.join(temp_dir, 'test.dmp')
buildroot = '/'
board = 'test_board'
symbol_dir = os.path.join('/build', board, 'usr', 'lib', 'debug',
'breakpad')
cwd = os.path.join(buildroot, 'src', 'scripts')
archive_dir = '/archive/dir'
self.mox.StubOutWithMock(tempfile, 'mkdtemp')
tempfile.mkdtemp(dir=mox.IgnoreArg(), prefix=mox.IgnoreArg()). \
AndReturn(temp_dir)
self.mox.StubOutWithMock(os, 'walk')
dump_file_dir, dump_file_name = os.path.split(dump_file)
os.walk(mox.IgnoreArg()).AndReturn([(dump_file_dir, [''],
[dump_file_name])])
self.mox.StubOutWithMock(cros_build_lib, 'ReinterpretPathForChroot')
cros_build_lib.ReinterpretPathForChroot(
mox.IgnoreArg()).AndReturn(dump_file)
self.mox.StubOutWithMock(commands, 'ArchiveFile')
self.mox.StubOutWithMock(os, 'unlink')
self.mox.StubOutWithMock(shutil, 'rmtree')
gzip = cros_build_lib.FindCompressor(cros_build_lib.COMP_GZIP)
cros_build_lib.RunCommand([gzip, '-df', gzipped_test_tarball])
cros_build_lib.RunCommand(
['tar',
'xf',
test_tarball,
'--directory=%s' % temp_dir,
'--wildcards', '*.dmp'],
error_ok=True,
redirect_stderr=True).AndReturn(cros_build_lib.CommandResult())
stack_trace = '%s.txt' % dump_file
cros_build_lib.RunCommand(
['minidump_stackwalk', dump_file, symbol_dir], cwd=cwd,
enter_chroot=True, error_ok=True, log_stdout_to_file=stack_trace,
redirect_stderr=True)
commands.ArchiveFile(stack_trace, archive_dir)
cros_build_lib.RunCommand(
['tar', 'uf', test_tarball, '--directory=%s' % temp_dir, '.'])
cros_build_lib.RunCommand(
'%s -c %s > %s' % (gzip, test_tarball, gzipped_test_tarball),
shell=True)
os.unlink(test_tarball)
shutil.rmtree(temp_dir)
self.mox.ReplayAll()
commands.GenerateMinidumpStackTraces(buildroot, board,
gzipped_test_tarball,
archive_dir)
self.mox.VerifyAll()
def testUprevAllPackages(self):
"""Test if we get None in revisions.pfq indicating Full Builds."""
drop_file = commands._PACKAGE_FILE % {'buildroot': self._buildroot}
cros_build_lib.RunCommand(
['cros_mark_as_stable', '--all', '--boards=%s' % self._test_board,
'--overlays=%s' % ':'.join(self._chroot_overlays),
'--drop_file=%s' % cros_build_lib.ReinterpretPathForChroot(drop_file),
'commit'], cwd=self._buildroot, enter_chroot=True)
self.mox.ReplayAll()
commands.UprevPackages(self._buildroot,
[self._test_board],
self._overlays)
self.mox.VerifyAll()
def testUploadPublicPrebuilts(self):
"""Test _UploadPrebuilts with a public location."""
check = mox.And(mox.IsA(list),
mox.In('gs://chromeos-prebuilt'),
mox.In(constants.PFQ_TYPE))
cros_build_lib.RunCommand(check, cwd=constants.CHROMITE_BIN_DIR)
self.mox.ReplayAll()
commands.UploadPrebuilts(self._buildroot, self._test_board, False,
constants.PFQ_TYPE, None)
self.mox.VerifyAll()
def testUploadPrivatePrebuilts(self):
"""Test _UploadPrebuilts with a private location."""
check = mox.And(mox.IsA(list),
mox.In('gs://chromeos-prebuilt'),
mox.In(constants.PFQ_TYPE))
cros_build_lib.RunCommand(check, cwd=constants.CHROMITE_BIN_DIR)
self.mox.ReplayAll()
commands.UploadPrebuilts(self._buildroot, self._test_board, True,
constants.PFQ_TYPE, None)
self.mox.VerifyAll()
def testChromePrebuilts(self):
"""Test _UploadPrebuilts for Chrome prebuilts."""
check = mox.And(mox.IsA(list),
mox.In('gs://chromeos-prebuilt'),
mox.In(constants.CHROME_PFQ_TYPE))
cros_build_lib.RunCommand(check, cwd=constants.CHROMITE_BIN_DIR)
self.mox.ReplayAll()
commands.UploadPrebuilts(self._buildroot, self._test_board, False,
constants.CHROME_PFQ_TYPE, 'tot')
self.mox.VerifyAll()
def testBuildMinimal(self):
"""Base case where Build is called with minimal options."""
buildroot = '/bob/'
cmd = ['./build_packages', '--nowithautotest',
'--board=x86-generic'] + commands._LOCAL_BUILD_FLAGS
cros_build_lib.RunCommand(mox.SameElementsAs(cmd),
cwd=mox.StrContains(buildroot),
chroot_args=[],
enter_chroot=True,
extra_env=None)
self.mox.ReplayAll()
commands.Build(buildroot=buildroot,
board='x86-generic',
build_autotest=False,
usepkg=False,
skip_toolchain_update=False,
nowithdebug=False,
)
self.mox.VerifyAll()
def testBuildMaximum(self):
"""Base case where Build is called with all options (except extra_evn)."""
buildroot = '/bob/'
arg_test = mox.SameElementsAs(['./build_packages',
'--board=x86-generic',
'--skip_toolchain_update',
'--nowithdebug'])
cros_build_lib.RunCommand(arg_test,
cwd=mox.StrContains(buildroot),
chroot_args=[],
enter_chroot=True,
extra_env=None)
self.mox.ReplayAll()
commands.Build(buildroot=buildroot,
board='x86-generic',
build_autotest=True,
usepkg=True,
skip_toolchain_update=True,
nowithdebug=True,
)
self.mox.VerifyAll()
def testBuildWithEnv(self):
"""Case where Build is called with a custom environment."""
buildroot = '/bob/'
extra = {'A' :'Av', 'B' : 'Bv'}
cros_build_lib.RunCommand(
mox.IgnoreArg(),
cwd=mox.StrContains(buildroot),
chroot_args=[],
enter_chroot=True,
extra_env=mox.And(
mox.ContainsKeyValue('A', 'Av'), mox.ContainsKeyValue('B', 'Bv')))
self.mox.ReplayAll()
commands.Build(buildroot=buildroot,
board='x86-generic',
build_autotest=False,
usepkg=False,
skip_toolchain_update=False,
nowithdebug=False,
extra_env=extra)
self.mox.VerifyAll()
def testUploadSymbols(self):
"""Test UploadSymbols Command."""
buildroot = '/bob'
board = 'board_name'
cros_build_lib.RunCommandCaptureOutput(
['./upload_symbols', '--board=board_name', '--yes', '--verbose',
'--official_build'], cwd='/bob/src/scripts',
enter_chroot=True, combine_stdout_stderr=True)
cros_build_lib.RunCommandCaptureOutput(
['./upload_symbols', '--board=board_name', '--yes', '--verbose'],
cwd='/bob/src/scripts', enter_chroot=True, combine_stdout_stderr=True)
self.mox.ReplayAll()
commands.UploadSymbols(buildroot, board, official=True)
commands.UploadSymbols(buildroot, board, official=False)
self.mox.VerifyAll()
def testPushImages(self):
"""Test PushImages Command."""
buildroot = '/bob'
board = 'board_name'
branch_name = 'branch_name'
archive_url = 'gs://archive/url'
cros_build_lib.RunCommand(
['./pushimage', '--board=board_name', '--branch=branch_name',
archive_url], cwd=mox.StrContains('crostools'))
self.mox.ReplayAll()
commands.PushImages(buildroot, board, branch_name, archive_url, False, None)
self.mox.VerifyAll()
def testPushImages2(self):
"""Test PushImages Command with profile."""
buildroot = '/bob'
board = 'board_name'
branch_name = 'branch_name'
profile_name = 'profile_name'
archive_url = 'gs://archive/url'
cros_build_lib.RunCommand(
['./pushimage', '--board=board_name', '--profile=profile_name',
'--branch=branch_name', archive_url], cwd=mox.StrContains('crostools'))
self.mox.ReplayAll()
commands.PushImages(buildroot, board, branch_name, archive_url,
dryrun=False, profile=profile_name)
self.mox.VerifyAll()
if __name__ == '__main__':
cros_build_lib.SetupBasicLogging()
unittest.main()