blob: 2a53fac59b934e3bfc0338fa5e881561720c176f [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.
"""Unittests for commands. Needs to be run inside of chroot for mox."""
import mox
import os
import shutil
import socket
import sys
import unittest
import constants
sys.path.append(constants.SOURCE_ROOT)
import chromite.buildbot.cbuildbot_commands as commands
import chromite.lib.cros_build_lib as cros_lib
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_lib, 'OldRunCommand')
self.mox.StubOutWithMock(cros_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_lib.ReinterpretPathForChroot(p) for p in self._overlays
]
self._CWD = os.path.dirname(os.path.realpath(__file__))
def testGetManifestBranch(self):
"""Verify function for getting the chromite manifest branch."""
CWD = 'somedir'
self.mox.StubOutWithMock(commands, 'RunCommandInDir')
output = ('cros/11.1.241.B\n'
'cros/master\n'
'm/11.1.241.B -> cros/11.1.241.B')
commands.RunCommandInDir(mox.In('branch'), CWD).AndReturn(output)
self.mox.ReplayAll()
manifest_branch = commands.GetManifestBranch(CWD)
self.mox.VerifyAll()
self.assertEquals(manifest_branch, '11.1.241.B')
def testGetChromiteTrackingBranchSuccess(self):
"""Verify getting the tracking branch from the current branch."""
self.mox.StubOutWithMock(commands, 'RunCommandInDir')
commands.RunCommandInDir(
mox.In('symbolic-ref'),
mox.StrContains('chromite/buildbot')).AndReturn('refs/heads/tracking')
commands.RunCommandInDir(
mox.In('branch.tracking.merge'),
mox.StrContains('chromite/buildbot')).AndReturn('refs/heads/master')
self.mox.ReplayAll()
upstream_branch = commands.GetChromiteTrackingBranch()
self.mox.VerifyAll()
self.assertEquals(upstream_branch, 'master')
def testGetChromiteTrackingBranchDetachedHeadSuccess(self):
"""Case where repo is on detached head of manifest branch."""
self.mox.StubOutWithMock(commands, 'RunCommandInDir')
self.mox.StubOutWithMock(commands, 'GetManifestBranch')
error = cros_lib.RunCommandError('error', 'command')
commands.RunCommandInDir(
mox.In('symbolic-ref'),
mox.StrContains('chromite/buildbot')).AndRaise(error)
(commands.GetManifestBranch(mox.StrContains('chromite/buildbot'))
.AndReturn('master'))
commands.RunCommandInDir(
mox.In('rev-parse') and mox.In('HEAD'),
mox.StrContains('chromite/buildbot')).AndReturn('A2564A5B')
commands.RunCommandInDir(
mox.In('rev-parse') and mox.In('cros/master'),
mox.StrContains('chromite/buildbot')).AndReturn('A2564A5B')
self.mox.ReplayAll()
upstream_branch = commands.GetChromiteTrackingBranch()
self.mox.VerifyAll()
self.assertEquals(upstream_branch, 'master')
def testGetChromiteTrackingBranchDetachedHeadFailure(self):
"""Case where repo is on detached head, but not of manifest branch."""
self.mox.StubOutWithMock(commands, 'RunCommandInDir')
self.mox.StubOutWithMock(commands, 'GetManifestBranch')
error = cros_lib.RunCommandError('error', 'command')
commands.RunCommandInDir(
mox.In('symbolic-ref'),
mox.StrContains('chromite/buildbot')).AndRaise(error)
(commands.GetManifestBranch(mox.StrContains('chromite/buildbot'))
.AndReturn('master'))
commands.RunCommandInDir(
mox.In('rev-parse') and mox.In('HEAD'),
mox.StrContains('chromite/buildbot')).AndReturn('A2564A5B')
commands.RunCommandInDir(
mox.In('rev-parse') and mox.In('cros/master'),
mox.StrContains('chromite/buildbot')).AndReturn('BD3445CC')
self.mox.ReplayAll()
self.assertRaises(commands.BranchError, commands.GetChromiteTrackingBranch)
self.mox.VerifyAll()
def testGetChromiteTrackingBranchNoUpstream(self):
"""Case where current branch is not tracking a remote branch."""
self.mox.StubOutWithMock(commands, 'RunCommandInDir')
self.mox.StubOutWithMock(commands, 'GetManifestBranch')
error = cros_lib.RunCommandError('error', 'command')
CWD = 'somedir'
commands.RunCommandInDir(
mox.In('symbolic-ref'),
mox.StrContains('chromite/buildbot')).AndReturn('refs/heads/tracking')
commands.RunCommandInDir(
mox.In('branch.tracking.merge'),
mox.StrContains('chromite/buildbot')).AndRaise(error)
(commands.GetManifestBranch(mox.StrContains('chromite/buildbot'))
.AndReturn('master'))
self.mox.ReplayAll()
self.assertRaises(commands.BranchError, commands.GetChromiteTrackingBranch)
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'
archive_tarball = os.path.join(buildroot, 'test_results.tgz')
test_results_dir = 'fake_results_dir'
# Convenience variables to make archive easier to understand.
path_to_results = os.path.join(buildroot, 'chroot', test_results_dir)
cros_lib.OldRunCommand(['sudo', 'chmod', '-R', 'a+rw', path_to_results],
print_cmd=False)
cros_lib.OldRunCommand(['tar',
'czf',
archive_tarball,
'--directory=%s' % path_to_results,
'.'])
shutil.rmtree(path_to_results)
self.mox.ReplayAll()
return_ball = commands.ArchiveTestResults(buildroot, test_results_dir)
self.mox.VerifyAll()
self.assertEqual(return_ball, archive_tarball)
def testUprevAllPackages(self):
"""Test if we get None in revisions.pfq indicating Full Builds."""
drop_file = commands._PACKAGE_FILE % {'buildroot': self._buildroot}
cros_lib.OldRunCommand(
['../../chromite/buildbot/cros_mark_as_stable', '--all',
'--board=%s' % self._test_board,
'--overlays=%s' % ':'.join(self._chroot_overlays),
'--drop_file=%s' % cros_lib.ReinterpretPathForChroot(drop_file),
'commit'],
cwd='%s/src/scripts' % 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."""
binhost = 'http://www.example.com'
binhosts = [binhost, None]
buildnumber = 4
check = mox.And(mox.IsA(list), mox.In(binhost), mox.Not(mox.In(None)),
mox.In('gs://chromeos-prebuilt'), mox.In('binary'))
cros_lib.OldRunCommand(check, cwd=os.path.dirname(commands.__file__))
self.mox.ReplayAll()
commands.UploadPrebuilts(self._buildroot, self._test_board, 'public',
binhosts, 'binary', None, buildnumber)
self.mox.VerifyAll()
def testUploadPrivatePrebuilts(self):
"""Test _UploadPrebuilts with a private location."""
binhost = 'http://www.example.com'
binhosts = [binhost, None]
buildnumber = 4
check = mox.And(mox.IsA(list), mox.In(binhost), mox.Not(mox.In(None)),
mox.In('gs://chromeos-%s/%s/%d/prebuilts/' %
(self._test_board, 'full', buildnumber)),
mox.In('full'))
cros_lib.OldRunCommand(check, cwd=os.path.dirname(commands.__file__))
self.mox.ReplayAll()
commands.UploadPrebuilts(self._buildroot, self._test_board, 'private',
binhosts, 'full', None, buildnumber)
self.mox.VerifyAll()
def testChromePrebuilts(self):
"""Test _UploadPrebuilts for Chrome prebuilts."""
binhost = 'http://www.example.com'
binhosts = [binhost, None]
buildnumber = 4
check = mox.And(mox.IsA(list), mox.In(binhost), mox.Not(mox.In(None)),
mox.In('gs://chromeos-prebuilt'), mox.In('chrome'))
cros_lib.OldRunCommand(check, cwd=os.path.dirname(commands.__file__))
self.mox.ReplayAll()
commands.UploadPrebuilts(self._buildroot, self._test_board, 'public',
binhosts, 'chrome', 'tot', buildnumber)
self.mox.VerifyAll()
def testRepoSyncRetriesFail(self):
"""Case where we exceed default retry attempts."""
cros_lib.OldRunCommand(mox.In('sync'),
cwd=self._buildroot).AndRaise(Exception("failed"))
cros_lib.OldRunCommand(mox.In('sync'),
cwd=self._buildroot).AndRaise(Exception("failed"))
cros_lib.OldRunCommand(mox.In('sync'),
cwd=self._buildroot).AndRaise(Exception("failed"))
self.mox.ReplayAll()
self.assertRaises(Exception, lambda: commands._RepoSync(self._buildroot))
self.mox.VerifyAll()
def testRepoSyncRetriesPass(self):
"""Case where we fail twice and pass on the third try."""
cros_lib.OldRunCommand(mox.In('sync'),
cwd=self._buildroot).AndRaise(Exception("failed"))
cros_lib.OldRunCommand(mox.In('sync'),
cwd=self._buildroot).AndRaise(Exception("failed"))
cros_lib.OldRunCommand(mox.In('sync'), cwd=self._buildroot)
cros_lib.OldRunCommand(mox.In('forall'), cwd=self._buildroot)
cros_lib.OldRunCommand(mox.In('manifest'), cwd=self._buildroot)
self.mox.ReplayAll()
commands._RepoSync(self._buildroot)
self.mox.VerifyAll()
def testRepoSyncCustomRetriesFail(self):
"""Case where _RepoSync is called with a custom retry value of 1. Should
throw exception after first failure."""
cros_lib.OldRunCommand(mox.In('sync'),
cwd=self._buildroot).AndRaise(Exception("failed"))
self.mox.ReplayAll()
self.assertRaises(
Exception,
lambda: commands._RepoSync(self._buildroot, retries=1))
self.mox.VerifyAll()
def testRepoSyncCustomRetriesPass(self):
"""Case where _RepoSync is called with a custom retry value of 2 and passes
the second time."""
cros_lib.OldRunCommand(mox.In('sync'),
cwd=self._buildroot).AndRaise(Exception("failed"))
cros_lib.OldRunCommand(mox.In('sync'), cwd=self._buildroot)
cros_lib.OldRunCommand(mox.In('forall'), cwd=self._buildroot)
cros_lib.OldRunCommand(mox.In('manifest'), cwd=self._buildroot)
self.mox.ReplayAll()
commands._RepoSync(self._buildroot, retries=2)
self.mox.VerifyAll()
def testBuildMinimal(self):
"""Base case where Build is called with minimal options."""
buildroot = '/bob/'
cros_lib.RunCommand(['./build_packages', '--fast', '--nowithautotest',
'--nousepkg'],
cwd=mox.StrContains(buildroot),
enter_chroot=True,
extra_env={})
self.mox.ReplayAll()
commands.Build(buildroot=buildroot,
emptytree=False,
build_autotest=False,
fast=True,
usepkg=False,
nowithdebug=False)
self.mox.VerifyAll()
def testBuildMaximum(self):
"""Base case where Build is called with all options (except extra_evn)."""
buildroot = '/bob/'
cros_lib.RunCommand(['./build_packages', '--fast', '--nowithdebug'],
cwd=mox.StrContains(buildroot),
enter_chroot=True,
extra_env={'EXTRA_BOARD_FLAGS': '--emptytree'})
self.mox.ReplayAll()
commands.Build(buildroot=buildroot,
emptytree=True,
fast=True,
build_autotest=True,
usepkg=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_lib.RunCommand(
mox.IgnoreArg(),
cwd=mox.StrContains(buildroot),
enter_chroot=True,
extra_env=mox.And(
mox.ContainsKeyValue('A', 'Av'), mox.ContainsKeyValue('B', 'Bv')))
self.mox.ReplayAll()
commands.Build(buildroot=buildroot,
emptytree=True,
build_autotest=False,
fast=False,
usepkg=False,
nowithdebug=False,
extra_env=extra)
self.mox.VerifyAll()
def testLegacyArchiveBuildMinimal(self):
"""Test Legacy Archive Command, with minimal values."""
buildroot = '/bob'
buildnumber = 4
test_tarball = None
buildconfig = {}
buildconfig['board'] = 'config_board'
buildconfig['gs_path'] = None
buildconfig['factory_test_mod'] = False
buildconfig['test_mod'] = False
buildconfig['factory_install_mod'] = False
buildconfig['useflags'] = None
buildconfig['archive_build_debug'] = False
self.mox.StubOutWithMock(os.path, 'exists')
self.mox.StubOutWithMock(socket, 'gethostname')
output_obj = cros_lib.CommandResult()
output_obj.output = ('archive to dir: /var/archive/dir \n'
'CROS_ARCHIVE_URL=http://gs/archive/url \n')
cros_lib.RunCommand(['./archive_build.sh',
'--build_number', '4',
'--to', '/var/www/archive/bot_id',
'--keep_max', '3',
'--board', buildconfig['board'],
'--noarchive_debug',
'--notest_mod'],
combine_stdout_stderr=True,
cwd='/bob/src/scripts',
redirect_stderr=True,
redirect_stdout=True).AndReturn(output_obj)
socket.gethostname().AndReturn('testhost')
self.mox.ReplayAll()
result = commands.LegacyArchiveBuild(buildroot,
'bot_id',
buildconfig,
buildnumber,
test_tarball,
debug=False)
self.mox.VerifyAll()
self.assertTrue(result == ('http://testhost/archive/dir',
'/var/archive/dir'), result)
def testLegacyArchiveBuildMaximum(self):
"""Test Legacy Archive Command, with all values."""
buildroot = '/bob'
buildnumber = 4
test_tarball = '/path/test.tar.gz'
buildconfig = {}
buildconfig['board'] = 'config_board'
buildconfig['gs_path'] = 'gs://gs/path'
buildconfig['factory_test_mod'] = True
buildconfig['test_mod'] = True
buildconfig['factory_install_mod'] = True
buildconfig['useflags'] = ['use_a', 'use_b']
buildconfig['archive_build_debug'] = True
self.mox.StubOutWithMock(os.path, 'exists')
self.mox.StubOutWithMock(socket, 'gethostname')
output_obj = cros_lib.CommandResult()
output_obj.output = ('archive to dir: /var/archive/dir \n'
'CROS_ARCHIVE_URL=http://gs/archive/url \n')
cros_lib.RunCommand(['./archive_build.sh',
'--build_number', '4',
'--to', '/var/www/archive/bot_id',
'--keep_max', '3',
'--board', 'config_board',
'--gsutil_archive', 'gs://gs/path',
'--acl', '/home/chrome-bot/slave_archive_acl',
'--gsd_gen_index',
'/b/scripts/gsd_generate_index/gsd_generate_index.py',
'--gsutil', '/b/scripts/slave/gsutil',
'--factory_test_mod',
'--test_tarball', test_tarball,
'--debug',
'--factory_install_mod',
'--useflags', 'use_a use_b'],
combine_stdout_stderr=True,
cwd='/bob/src/scripts',
redirect_stderr=True,
redirect_stdout=True).AndReturn(output_obj)
self.mox.ReplayAll()
result = commands.LegacyArchiveBuild(buildroot,
'bot_id',
buildconfig,
buildnumber,
test_tarball,
debug=True)
self.mox.VerifyAll()
self.assertTrue(result == ('http://gs/archive/url',
'/var/archive/dir'), result)
def testUploadSymbols(self):
"""Test UploadSymbols Command."""
buildroot = '/bob'
board = 'board_name'
cros_lib.RunCommand(['./upload_symbols',
'--board=board_name',
'--yes',
'--verbose',
'--official_build'],
cwd='/bob/src/scripts',
error_ok=True,
enter_chroot=True)
cros_lib.RunCommand(['./upload_symbols',
'--board=board_name',
'--yes',
'--verbose'],
cwd='/bob/src/scripts',
error_ok=True,
enter_chroot=True)
self.mox.ReplayAll()
commands.UploadSymbols(buildroot, board, official=True)
commands.UploadSymbols(buildroot, board, official=False)
self.mox.VerifyAll()
def testPushImages(self):
"""Test UploadSymbols Command."""
buildroot = '/bob'
board = 'board_name'
branch_name = 'branch_name'
archive_dir = '/archive/dir'
cros_lib.RunCommand(['./pushimage',
'--board=board_name',
'--branch=branch_name',
'/archive/dir'],
cwd=mox.StrContains('crostools'))
self.mox.ReplayAll()
commands.PushImages(buildroot, board, branch_name, archive_dir)
self.mox.VerifyAll()
if __name__ == '__main__':
unittest.main()