blob: 6b9bfc4c8a2b9835708de0bcc33248f5f2d72902 [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 build stages."""
import mox
import os
import shutil
import StringIO
import sys
import tempfile
import unittest
import constants
sys.path.insert(0, constants.SOURCE_ROOT)
from chromite.buildbot import builderstage as bs
from chromite.buildbot import cbuildbot_background as background
from chromite.buildbot import cbuildbot_config as config
from chromite.buildbot import cbuildbot_commands as commands
from chromite.buildbot import cbuildbot_results as results_lib
from chromite.buildbot import cbuildbot_stages as stages
from chromite.buildbot import lkgm_manager
from chromite.buildbot import manifest_version
from chromite.buildbot import repository
from chromite.buildbot import portage_utilities
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.scripts import cbuildbot
# pylint: disable=E1120,W0212,R0904
class AbstractStageTest(mox.MoxTestBase):
"""Base class for tests that test a particular build stage.
Abstract base class that sets up the build config and options with some
default values for testing BuilderStage and its derivatives.
"""
TARGET_MANIFEST_BRANCH = 'ooga_booga'
def ConstructStage(self):
"""Returns an instance of the stage to be tested.
Implement in subclasses.
"""
raise NotImplementedError, "return an instance of stage to be tested."
def setUp(self):
mox.MoxTestBase.setUp(self)
# Always stub RunCommmand out as we use it in every method.
self.bot_id = 'x86-generic-paladin'
self.build_config = config.config[self.bot_id].copy()
self.build_root = '/fake_root'
self._boards = self.build_config['boards']
self._current_board = self._boards[0]
self.url = 'fake_url'
self.build_config['git_url'] = self.url
# Use the cbuildbot parser to create properties and populate default values.
parser = cbuildbot._CreateParser()
(self.options, _) = parser.parse_args([])
self.options.buildroot = self.build_root
self.options.buildbot = True
self.options.debug = False
self.options.prebuilts = False
self.options.clobber = False
self.options.buildnumber = 1234
self.overlay = os.path.join(self.build_root,
'src/third_party/chromiumos-overlay')
self.portage_overlay = os.path.join(self.build_root,
'src/third_party/portage-stable')
bs.BuilderStage.SetManifestBranch(self.TARGET_MANIFEST_BRANCH)
portage_utilities._OVERLAY_LIST_CMD = '/bin/true'
def RunStage(self):
"""Creates and runs an instance of the stage to be tested.
Requires ConstructStage() to be implemented.
Raises:
NotImplementedError: ConstructStage() was not implemented.
"""
# Stage construction is usually done as late as possible because the tests
# set up the build configuration and options used in constructing the stage.
stage = self.ConstructStage()
stage.Run()
class BuilderStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
def ConstructStage(self):
return bs.BuilderStage(self.options, self.build_config)
def testGetPortageEnvVar(self):
"""Basic test case for _GetPortageEnvVar function."""
self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
envvar = 'EXAMPLE'
obj = cros_test_lib.EasyAttr(output='RESULT\n')
cros_build_lib.RunCommand(mox.And(mox.IsA(list), mox.In(envvar)),
cwd='%s/src/scripts' % self.build_root,
redirect_stdout=True, enter_chroot=True,
error_ok=True).AndReturn(obj)
self.mox.ReplayAll()
stage = self.ConstructStage()
board = self._current_board
result = stage._GetPortageEnvVar(envvar, board)
self.mox.VerifyAll()
self.assertEqual(result, 'RESULT')
class ManifestVersionedSyncStageTest(AbstractStageTest):
"""Tests the two (heavily related) stages ManifestVersionedSync, and
ManifestVersionedSyncCompleted.
"""
# pylint: disable=W0223
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.tmpdir = tempfile.mkdtemp()
self.source_repo = 'ssh://source/repo'
self.manifest_version_url = 'fake manifest url'
self.branch = 'master'
self.build_name = 'x86-generic'
self.incr_type = 'branch'
self.build_config['manifest_version'] = self.manifest_version_url
self.next_version = 'next_version'
repo = repository.RepoRepository(
self.source_repo, self.tmpdir, self.branch)
self.manager = manifest_version.BuildSpecsManager(
repo, self.manifest_version_url, self.build_name,
self.incr_type, force=False, dry_run=True)
stages.ManifestVersionedSyncStage.manifest_manager = self.manager
def tearDown(self):
if os.path.exists(self.tmpdir): shutil.rmtree(self.tmpdir)
def testManifestVersionedSyncOnePartBranch(self):
"""Tests basic ManifestVersionedSyncStage with branch ooga_booga"""
self.mox.StubOutWithMock(stages.ManifestVersionedSyncStage,
'Initialize')
self.mox.StubOutWithMock(manifest_version.BuildSpecsManager,
'GetNextBuildSpec')
self.mox.StubOutWithMock(stages.SyncStage, 'ManifestCheckout')
stages.ManifestVersionedSyncStage.Initialize()
self.manager.GetNextBuildSpec().AndReturn(self.next_version)
stages.SyncStage.ManifestCheckout(self.next_version)
self.mox.ReplayAll()
stage = stages.ManifestVersionedSyncStage(self.options, self.build_config)
stage.Run()
self.mox.VerifyAll()
def testManifestVersionedSyncCompletedSuccess(self):
"""Tests basic ManifestVersionedSyncStageCompleted on success"""
stages.ManifestVersionedSyncStage.manifest_manager = self.manager
self.mox.StubOutWithMock(manifest_version.BuildSpecsManager, 'UpdateStatus')
self.manager.UpdateStatus(success=True)
self.mox.ReplayAll()
stage = stages.ManifestVersionedSyncCompletionStage(self.options,
self.build_config,
success=True)
stage.Run()
self.mox.VerifyAll()
def testManifestVersionedSyncCompletedFailure(self):
"""Tests basic ManifestVersionedSyncStageCompleted on failure"""
stages.ManifestVersionedSyncStage.manifest_manager = self.manager
self.mox.StubOutWithMock(manifest_version.BuildSpecsManager, 'UpdateStatus')
self.manager.UpdateStatus(success=False)
self.mox.ReplayAll()
stage = stages.ManifestVersionedSyncCompletionStage(self.options,
self.build_config,
success=False)
stage.Run()
self.mox.VerifyAll()
def testManifestVersionedSyncCompletedIncomplete(self):
"""Tests basic ManifestVersionedSyncStageCompleted on incomplete build."""
stages.ManifestVersionedSyncStage.manifest_manager = None
self.mox.ReplayAll()
stage = stages.ManifestVersionedSyncCompletionStage(self.options,
self.build_config,
success=False)
stage.Run()
self.mox.VerifyAll()
class LKGMCandidateSyncCompletionStage(AbstractStageTest):
"""Tests the two (heavily related) stages ManifestVersionedSync, and
ManifestVersionedSyncCompleted.
"""
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.tmpdir = tempfile.mkdtemp()
self.source_repo = 'ssh://source/repo'
self.manifest_version_url = 'fake manifest url'
self.branch = 'master'
self.build_name = 'x86-generic-paladin'
self.build_type = constants.PFQ_TYPE
self.build_config['manifest_version'] = True
self.build_config['build_type'] = self.build_type
self.build_config['master'] = True
repo = repository.RepoRepository(
self.source_repo, self.tmpdir, self.branch)
self.manager = lkgm_manager.LKGMManager(
repo, self.manifest_version_url, self.build_name,
self.build_type, incr_type='branch', force=False, dry_run=True)
self.sub_manager = lkgm_manager.LKGMManager(
repo, self.manifest_version_url, self.build_name,
self.build_type, incr_type='branch', force=False, dry_run=True)
stages.ManifestVersionedSyncStage.manifest_manager = self.manager
stages.LKGMCandidateSyncStage.sub_manager = self.manager
def ConstructStage(self):
return stages.LKGMCandidateSyncCompletionStage(self.options,
self.build_config,
success=True)
def _GetTestConfig(self):
test_config = {}
test_config['test1'] = {
'manifest_version': True,
'build_type': constants.PFQ_TYPE,
'overlays': 'public',
'important': True,
'chrome_rev': None,
'unified_manifest_version': False,
'branch': False,
'internal': False,
}
test_config['test2'] = {
'manifest_version': True,
'build_type': constants.PFQ_TYPE,
'overlays': 'public',
'important': True,
'chrome_rev': None,
'unified_manifest_version': False,
'branch': False,
'internal': False,
}
test_config['test3'] = {
'manifest_version': True,
'build_type': constants.PFQ_TYPE,
'overlays': 'public',
'important': False,
'chrome_rev': None,
'unified_manifest_version': False,
'branch': False,
'internal': False,
}
test_config['test4'] = {
'manifest_version': False,
'build_type': constants.PFQ_TYPE,
'overlays': 'public',
'important': True,
'chrome_rev': None,
'unified_manifest_version': False,
'branch': False,
'internal': False,
}
test_config['test5'] = {
'manifest_version': True,
'build_type': constants.PFQ_TYPE,
'overlays': 'both',
'important': True,
'chrome_rev': None,
'unified_manifest_version': True,
'branch': False,
'internal': True,
}
test_config['test6'] = {
'manifest_version': True,
'build_type': constants.PFQ_TYPE,
'overlays': 'both',
'important': True,
'chrome_rev': None,
'unified_manifest_version': True,
'branch': True,
'internal': True,
}
test_config['test7'] = {
'manifest_version': True,
'build_type': constants.PFQ_TYPE,
'overlays': 'public',
'important': True,
'chrome_rev': None,
'unified_manifest_version': True,
'branch': False,
'internal': False,
}
return test_config
def testGetUnifiedSlavesStatus(self):
"""Tests that we get the statuses for a fake unified master completion."""
self.mox.StubOutWithMock(bs.BuilderStage, '_GetSlavesForUnifiedMaster')
self.mox.StubOutWithMock(lkgm_manager.LKGMManager, 'GetBuildersStatus')
self.build_config['unified_manifest_version'] = True
p_bs = ['s1', 's2']
pr_bs = ['s3']
status1 = dict(s1='pass', s2='fail')
status2 = dict(s3='pass')
bs.BuilderStage._GetSlavesForUnifiedMaster().AndReturn((p_bs, pr_bs,))
lkgm_manager.LKGMManager.GetBuildersStatus(
p_bs, os.path.join(self.build_root, constants.VERSION_FILE)).AndReturn(
status1)
lkgm_manager.LKGMManager.GetBuildersStatus(
pr_bs, os.path.join(self.build_root, constants.VERSION_FILE)).AndReturn(
status2)
self.mox.ReplayAll()
stage = self.ConstructStage()
statuses = stage._GetSlavesStatus()
self.mox.VerifyAll()
for k, v in status1.iteritems():
self.assertTrue(v, statuses.get(k))
for k, v in status2.iteritems():
self.assertTrue(v, statuses.get(k))
def testGetSlavesForMaster(self):
"""Tests that we get the slaves for a fake master configuration."""
test_config = self._GetTestConfig()
self.build_config['unified_manifest_version'] = False
self.mox.ReplayAll()
stage = self.ConstructStage()
important_configs = stage._GetSlavesForMaster(test_config)
self.mox.VerifyAll()
self.assertTrue('test1' in important_configs)
self.assertTrue('test2' in important_configs)
self.assertFalse('test3' in important_configs)
self.assertFalse('test4' in important_configs)
self.assertFalse('test5' in important_configs)
self.assertFalse('test6' in important_configs)
def testGetSlavesForUnifiedMaster(self):
"""Tests that we get the slaves for a fake unified master configuration."""
test_config = self._GetTestConfig()
self.build_config['unified_manifest_version'] = True
self.mox.ReplayAll()
stage = self.ConstructStage()
p, pr = stage._GetSlavesForUnifiedMaster(test_config)
self.mox.VerifyAll()
important_configs = p + pr
self.assertTrue('test7' in p)
self.assertTrue('test5' in pr)
self.assertFalse('test1' in important_configs)
self.assertFalse('test2' in important_configs)
self.assertFalse('test3' in important_configs)
self.assertFalse('test4' in important_configs)
self.assertFalse('test6' in important_configs)
class BuildBoardTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.mox.StubOutWithMock(os.path, 'isdir')
def ConstructStage(self):
return stages.BuildBoardStage(self.options, self.build_config)
def testFullBuild(self):
"""Tests whether we correctly run make chroot and setup board for a full."""
self.bot_id = 'x86-generic-full'
self.build_config = config.config[self.bot_id]
self.mox.StubOutWithMock(commands, 'MakeChroot')
self.mox.StubOutWithMock(commands, 'SetupBoard')
os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(True)
commands.MakeChroot(buildroot=self.build_root,
replace=True,
use_sdk=True,
chrome_root=None,
extra_env=mox.IgnoreArg()
)
os.path.isdir(os.path.join(self.build_root, 'chroot', 'build',
self._current_board)).AndReturn(False)
commands.SetupBoard(self.build_root,
board=self._current_board,
usepkg=False,
latest_toolchain=False,
extra_env={},
profile=None,
chroot_upgrade=False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testFullBuildWithProfile(self):
"""Tests whether full builds add profile flag when requested."""
self.bot_id = 'x86-generic-full'
self.build_config = config.config[self.bot_id]
self.mox.StubOutWithMock(commands, 'MakeChroot')
self.mox.StubOutWithMock(commands, 'SetupBoard')
self.mox.StubOutWithMock(commands, 'RunChrootUpgradeHooks')
os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(True)
commands.MakeChroot(buildroot=self.build_root,
replace=True,
use_sdk=True,
chrome_root=None,
extra_env=mox.IgnoreArg()
)
os.path.isdir(os.path.join(self.build_root, 'chroot', 'build',
self._current_board)).AndReturn(False)
commands.SetupBoard(self.build_root,
board=self._current_board,
usepkg=False,
latest_toolchain=False,
extra_env={},
profile=self.build_config['profile'],
chroot_upgrade=False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testFullBuildWithOverriddenProfile(self):
"""Tests whether full builds add overridden profile flag when requested."""
self.bot_id = 'x86-generic-full'
self.options.profile = 'smock'
self.build_config = config.config[self.bot_id]
self.mox.StubOutWithMock(commands, 'MakeChroot')
self.mox.StubOutWithMock(commands, 'SetupBoard')
self.mox.StubOutWithMock(commands, 'RunChrootUpgradeHooks')
os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(True)
commands.MakeChroot(buildroot=self.build_root,
replace=True,
use_sdk=True,
chrome_root=None,
extra_env=mox.IgnoreArg()
)
os.path.isdir(os.path.join(self.build_root, 'chroot', 'build',
self._current_board)).AndReturn(False)
commands.SetupBoard(self.build_root,
board=self._current_board,
usepkg=False,
latest_toolchain=False,
extra_env={},
profile='smock',
chroot_upgrade=False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
self.options.profile = None
def testBinBuild(self):
"""Tests whether we skip un-necessary steps for a binary builder."""
self.mox.StubOutWithMock(commands, 'MakeChroot')
self.mox.StubOutWithMock(commands, 'SetupBoard')
self.mox.StubOutWithMock(commands, 'RunChrootUpgradeHooks')
os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(True)
os.path.isdir(os.path.join(self.build_root, 'chroot', 'build',
self._current_board)).AndReturn(True)
commands.RunChrootUpgradeHooks(self.build_root)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testBinBuildAfterClobber(self):
"""Tests whether we make chroot and board after a clobber."""
self.mox.StubOutWithMock(commands, 'MakeChroot')
self.mox.StubOutWithMock(commands, 'SetupBoard')
os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(False)
commands.MakeChroot(buildroot=self.build_root,
replace=self.build_config['chroot_replace'],
use_sdk=self.build_config['use_sdk'],
chrome_root=None,
extra_env=mox.IgnoreArg()
)
os.path.isdir(os.path.join(self.build_root, 'chroot', 'build',
self._current_board)).AndReturn(False)
commands.SetupBoard(self.build_root,
board=self._current_board,
usepkg=self.build_config['usepkg_setup_board'],
latest_toolchain=self.build_config['latest_toolchain'],
extra_env={},
profile=None,
chroot_upgrade=False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
class VMTestStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.fake_results_dir = '/tmp/fake_results_dir'
self.fake_chroot_results_dir = '/my/fake_chroot/tmp/fake_results_dir'
self.mox.StubOutWithMock(commands, 'ArchiveTestResults')
self.archive_stage_mock = self.mox.CreateMock(stages.ArchiveStage)
def ConstructStage(self):
return stages.VMTestStage(self.options, self.build_config,
self._current_board, self.archive_stage_mock)
def testFullTests(self):
"""Tests if full unit and cros_au_test_harness tests are run correctly."""
self.bot_id = 'x86-generic-full'
self.build_config = config.config[self.bot_id].copy()
self.build_config['vm_tests'] = constants.FULL_AU_TEST_TYPE
self.mox.StubOutWithMock(commands, 'RunTestSuite')
self.mox.StubOutWithMock(commands, 'CreateTestRoot')
self.mox.StubOutWithMock(tempfile, 'mkdtemp')
commands.CreateTestRoot(self.build_root).AndReturn(self.fake_results_dir)
commands.RunTestSuite(self.build_root,
self._current_board,
mox.IgnoreArg(),
os.path.join(self.fake_results_dir,
'test_harness'),
build_config=self.bot_id,
whitelist_chrome_crashes=True,
test_type=constants.FULL_AU_TEST_TYPE)
commands.ArchiveTestResults(self.build_root, self.fake_results_dir,
prefix='').AndReturn('some tarball')
self.archive_stage_mock.TestResultsReady('some tarball')
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testQuickTests(self):
"""Tests if quick unit and cros_au_test_harness tests are run correctly."""
self.bot_id = 'x86-generic-full'
self.build_config = config.config[self.bot_id].copy()
self.build_config['vm_tests'] = constants.SIMPLE_AU_TEST_TYPE
self.mox.StubOutWithMock(commands, 'RunTestSuite')
self.mox.StubOutWithMock(commands, 'CreateTestRoot')
self.mox.StubOutWithMock(tempfile, 'mkdtemp')
commands.CreateTestRoot(self.build_root).AndReturn(self.fake_results_dir)
commands.RunTestSuite(self.build_root,
self._current_board,
mox.IgnoreArg(),
os.path.join(self.fake_results_dir,
'test_harness'),
build_config=self.bot_id,
whitelist_chrome_crashes=True,
test_type=constants.SIMPLE_AU_TEST_TYPE)
commands.ArchiveTestResults(self.build_root, self.fake_results_dir,
prefix='').AndReturn('some tarball')
self.archive_stage_mock.TestResultsReady('some tarball')
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
class UnitTestStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.bot_id = 'x86-generic-full'
self.build_config = config.config[self.bot_id].copy()
self.mox.StubOutWithMock(commands, 'RunUnitTests')
def ConstructStage(self):
return stages.UnitTestStage(self.options, self.build_config,
self._current_board)
def testQuickTests(self):
self.build_config['quick_unit'] = True
commands.RunUnitTests(self.build_root, self._current_board, full=False,
nowithdebug=mox.IgnoreArg())
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testFullTests(self):
"""Tests if full unit and cros_au_test_harness tests are run correctly."""
self.build_config['quick_unit'] = False
commands.RunUnitTests(self.build_root, self._current_board, full=True,
nowithdebug=mox.IgnoreArg())
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
class HWTestStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.bot_id = 'x86-mario-release'
self.build_config = config.config[self.bot_id].copy()
self.archive_stage_mock = self.mox.CreateMock(stages.ArchiveStage)
self.suite = 'bvt'
def ConstructStage(self):
return stages.HWTestStage(self.options, self.build_config,
self._current_board, self.archive_stage_mock,
self.suite)
def testRemoteTrybotWithHWTest(self):
"""Test remote trybot with hw test enabled"""
self.archive_stage_mock.WaitForHWTestUploads().AndReturn(True)
self.mox.StubOutWithMock(commands, 'RunHWTestSuite')
argv = ['--remote-trybot', '--hwtest', '-r', self.build_root, self.bot_id]
parser = cbuildbot._CreateParser()
(self.options, _args) = cbuildbot._ParseCommandLine(parser, argv)
build = 'trybot-%s/%s' % (self.bot_id,
self.archive_stage_mock.GetVersion().
AndReturn('ver'))
commands.RunHWTestSuite(build,
self.suite,
self._current_board,
constants.HWTEST_MACH_POOL,
False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testRemoteTrybotNoHWTest(self):
"""Test remote trybot with no hw test"""
self.archive_stage_mock.WaitForHWTestUploads().AndReturn(True)
self.mox.StubOutWithMock(commands, 'RunHWTestSuite')
argv = ['--remote-trybot', '-r', self.build_root, self.bot_id]
parser = cbuildbot._CreateParser()
(self.options, _args) = cbuildbot._ParseCommandLine(parser, argv)
build = '%s/%s' % (self.bot_id,
self.archive_stage_mock.GetVersion().AndReturn('ver'))
commands.RunHWTestSuite(build,
self.suite,
self._current_board,
constants.HWTEST_MACH_POOL,
True)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testWithSuite(self):
"""Test if run correctly with a test suite."""
self.archive_stage_mock.WaitForHWTestUploads().AndReturn(True)
self.mox.StubOutWithMock(commands, 'RunHWTestSuite')
build = '%s/%s' % (self.bot_id,
self.archive_stage_mock.GetVersion().AndReturn('ver'))
commands.RunHWTestSuite(build,
self.suite,
self._current_board,
constants.HWTEST_MACH_POOL,
False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testWithSuiteWithInfrastructureFailure(self):
"""Tests that we warn correctly if we get a returncode of 2."""
self.archive_stage_mock.WaitForHWTestUploads().AndReturn(True)
self.mox.StubOutWithMock(commands, 'RunHWTestSuite')
self.mox.StubOutWithMock(bs.BuilderStage, '_HandleExceptionAsWarning')
build = '%s/%s' % (self.bot_id,
self.archive_stage_mock.GetVersion().AndReturn('ver'))
result = cros_build_lib.CommandResult(cmd='run_hw_tests', returncode=2)
error = cros_build_lib.RunCommandError('HWTests failed', result)
commands.RunHWTestSuite(build,
self.suite,
self._current_board,
constants.HWTEST_MACH_POOL,
False).AndRaise(error)
bs.BuilderStage._HandleExceptionAsWarning(mox.IgnoreArg())
self.mox.ReplayAll()
try:
self.RunStage()
except Exception:
pass
self.mox.VerifyAll()
class UprevStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
# Disable most paths by default and selectively enable in tests
self.options.chrome_rev = None
self.build_config['uprev'] = False
self.mox.StubOutWithMock(commands, 'MarkChromeAsStable')
self.mox.StubOutWithMock(commands, 'UprevPackages')
self.mox.StubOutWithMock(sys, 'exit')
def ConstructStage(self):
return stages.UprevStage(self.options, self.build_config)
def testChromeRevSuccess(self):
"""Case where MarkChromeAsStable returns an atom. We shouldn't exit."""
self.options.chrome_rev = 'tot'
chrome_atom = 'chromeos-base/chromeos-chrome-12.0.719.0_alpha-r1'
commands.MarkChromeAsStable(
self.build_root,
self.TARGET_MANIFEST_BRANCH,
self.options.chrome_rev,
self._boards,
chrome_root=None,
chrome_version=None).AndReturn(chrome_atom)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testChromeRevFoundNothing(self):
"""Verify we exit when MarkChromeAsStable doesn't return an atom."""
self.options.chrome_rev = 'tot'
commands.MarkChromeAsStable(
self.build_root,
self.TARGET_MANIFEST_BRANCH,
self.options.chrome_rev,
self._boards,
chrome_root=None,
chrome_version=None)
sys.exit(0)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testBuildRev(self):
"""Uprevving the build without uprevving chrome."""
self.build_config['uprev'] = True
commands.UprevPackages(
self.build_root,
self._boards,
[self.overlay, self.portage_overlay])
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testNoRev(self):
"""No paths are enabled."""
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testUprevAll(self):
"""Uprev both Chrome and built packages."""
self.build_config['uprev'] = True
self.options.chrome_rev = 'tot'
# Even if MarkChromeAsStable didn't find anything to rev,
# if we rev the build then we don't exit
commands.MarkChromeAsStable(
self.build_root,
self.TARGET_MANIFEST_BRANCH,
self.options.chrome_rev,
self._boards,
chrome_root=None,
chrome_version=None).AndReturn(None)
commands.UprevPackages(
self.build_root,
self._boards,
[self.overlay, self.portage_overlay])
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def _DoSteps(steps):
for step in steps:
step()
class BuildTargetStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.images_root = os.path.join(self.build_root,
'src/build/images/x86-generic')
latest_image_dir = os.path.join(self.images_root, 'latest')
latest_built_image_dir = os.path.join(self.images_root, 'latest-cbuildbot')
self.mox.StubOutWithMock(os, 'readlink')
self.mox.StubOutWithMock(os, 'symlink')
os.readlink(latest_image_dir).AndReturn('myimage')
self.version = '1423.0.0'
self.version_to_test = self.version
os.readlink(latest_built_image_dir).AndReturn(self.version)
self.latest_cbuildbot = '%s-cbuildbot' % latest_image_dir
os.symlink('myimage', self.latest_cbuildbot)
# Disable most paths by default and selectively enable in tests
self.build_config['vm_tests'] = None
self.build_config['build_type'] = constants.PFQ_TYPE
self.build_config['usepkg_chroot'] = False
self.latest_versioned_build = os.path.join(self.images_root, self.version)
self.options.prebuilts = True
self.options.tests = False
self.mox.StubOutWithMock(shutil, 'move')
self.mox.StubOutWithMock(commands, 'Build')
self.mox.StubOutWithMock(commands, 'UploadPrebuilts')
self.mox.StubOutWithMock(commands, 'BuildImage')
self.mox.StubOutWithMock(commands, 'BuildVMImageForTesting')
self.mox.StubOutWithMock(bs.BuilderStage, '_GetPortageEnvVar')
self.mox.StubOutWithMock(shutil, 'copyfile')
self.mox.StubOutWithMock(tempfile, 'mkdtemp')
self.mox.StubOutWithMock(os.path, 'isdir')
self.mox.StubOutWithMock(background, 'RunParallelSteps')
background.RunParallelSteps(mox.IgnoreArg()).WithSideEffects(_DoSteps)
self.mox.StubOutWithMock(commands, 'BuildAutotestTarballs')
self.mox.StubOutWithMock(os, 'rename')
self.archive_stage_mock = self.mox.CreateMock(stages.ArchiveStage)
def ConstructStage(self):
return stages.BuildTargetStage(
self.options, self.build_config, self._current_board,
self.archive_stage_mock, self.version_to_test)
def testAllConditionalPaths(self):
"""Enable all paths to get line coverage."""
self.build_config['vm_tests'] = constants.SIMPLE_AU_TEST_TYPE
self.options.tests = True
self.build_config['build_type'] = constants.BUILD_FROM_SOURCE_TYPE
self.build_config['build_tests'] = True
self.build_config['archive_build_debug'] = True
self.build_config['usepkg_chroot'] = True
self.build_config['usepkg_setup_board'] = True
self.build_config['usepkg_build_packages'] = True
self.build_config['images'] = ['base', 'dev', 'test', 'factory_test',
'factory_install']
self.build_config['useflags'] = ['ALPHA', 'BRAVO', 'CHARLIE']
self.build_config['skip_toolchain_update'] = False
self.build_config['nowithdebug'] = False
self.build_config['hw_tests'] = ['bvt']
proper_env = {'USE' : ' '.join(self.build_config['useflags'])}
# Convenience variables.
fake_autotest_dir = '/fake/autotest'
autotest_tarball_name = 'autotest.tar'
test_suites_tarball_name = 'test_suites.tar.bz2'
autotest_tarball_path = os.path.join(fake_autotest_dir,
autotest_tarball_name)
test_suites_tarball_path = os.path.join(fake_autotest_dir,
test_suites_tarball_name)
tarballs = autotest_tarball_path, test_suites_tarball_path
commands.Build(self.build_root,
self._current_board,
build_autotest=True,
usepkg=True,
skip_toolchain_update=False,
nowithdebug=False,
extra_env=proper_env)
commands.BuildImage(self.build_root, self._current_board,
['test', 'base', 'dev'], version=self.version,
root_boost=None, extra_env=proper_env)
commands.BuildVMImageForTesting(self.build_root, self._current_board,
extra_env=proper_env)
tempfile.mkdtemp(prefix='autotest').AndReturn(fake_autotest_dir)
commands.BuildAutotestTarballs(self.build_root, self._current_board,
fake_autotest_dir).AndReturn(tarballs)
self.archive_stage_mock.AutotestTarballsReady(tarballs)
os.path.isdir(self.latest_cbuildbot).AndReturn(True)
self.archive_stage_mock.SetVersion(self.version)
shutil.copyfile(autotest_tarball_path,
os.path.join(self.images_root, 'latest-cbuildbot',
autotest_tarball_name))
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testFalseBuildArgs(self):
"""Make sure our logic for Build arguments can toggle to false."""
self.build_config['useflags'] = None
commands.Build(self.build_root,
self._current_board,
build_autotest=mox.IgnoreArg(),
usepkg=mox.IgnoreArg(),
skip_toolchain_update=mox.IgnoreArg(),
nowithdebug=mox.IgnoreArg(),
extra_env={})
self.archive_stage_mock.AutotestTarballsReady(None)
commands.BuildImage(self.build_root, self._current_board, ['test'],
root_boost=None, version=self.version, extra_env={})
os.path.isdir(self.latest_cbuildbot).AndReturn(True)
self.archive_stage_mock.SetVersion(self.version)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testFalseTestArg(self):
"""Make sure our logic for build test arg can toggle to false."""
self.build_config['vm_tests'] = None
self.options.tests = True
self.options.hw_tests = True
self.build_config['build_type'] = constants.BUILD_FROM_SOURCE_TYPE
self.build_config['usepkg_chroot'] = True
self.build_config['usepkg_setup_board'] = True
self.build_config['usepkg_build_packages'] = True
self.build_config['useflags'] = ['ALPHA', 'BRAVO', 'CHARLIE']
self.build_config['nowithdebug'] = True
self.build_config['skip_toolchain_update'] = False
proper_env = {'USE' : ' '.join(self.build_config['useflags'])}
commands.Build(self.build_root,
self._current_board,
build_autotest=True,
usepkg=True,
skip_toolchain_update=False,
nowithdebug=True,
extra_env=proper_env)
self.archive_stage_mock.AutotestTarballsReady(None)
commands.BuildImage(self.build_root, self._current_board, ['test'],
root_boost=None, version=self.version,
extra_env=proper_env)
os.path.isdir(self.latest_cbuildbot).AndReturn(True)
self.archive_stage_mock.SetVersion(self.version)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testUnversionedCodePath(self):
"""Make sure our logic for build test works for unversioned code paths."""
self.version_to_test = None
self.build_config['vm_tests'] = constants.SIMPLE_AU_TEST_TYPE
self.options.tests = True
self.build_config['build_type'] = constants.BUILD_FROM_SOURCE_TYPE
self.build_config['build_tests'] = True
self.build_config['archive_build_debug'] = True
self.build_config['usepkg_chroot'] = True
self.build_config['usepkg_setup_board'] = True
self.build_config['usepkg_build_packages'] = True
self.build_config['images'] = ['base', 'dev', 'test', 'factory_test',
'factory_install']
self.build_config['useflags'] = ['ALPHA', 'BRAVO', 'CHARLIE']
self.build_config['skip_toolchain_update'] = False
self.build_config['nowithdebug'] = False
self.build_config['hw_tests'] = ['bvt']
proper_env = {'USE' : ' '.join(self.build_config['useflags'])}
# Convenience variables.
fake_autotest_dir = '/fake/autotest'
autotest_tarball_name = 'autotest.tar'
test_suites_tarball_name = 'test_suites.tar.bz2'
autotest_tarball_path = os.path.join(fake_autotest_dir,
autotest_tarball_name)
test_suites_tarball_path = os.path.join(fake_autotest_dir,
test_suites_tarball_name)
tarballs = autotest_tarball_path, test_suites_tarball_path
commands.Build(self.build_root,
self._current_board,
build_autotest=True,
usepkg=True,
skip_toolchain_update=False,
nowithdebug=False,
extra_env=proper_env)
commands.BuildImage(self.build_root, self._current_board,
['test', 'base', 'dev'], version='', root_boost=None,
extra_env=proper_env)
commands.BuildVMImageForTesting(self.build_root, self._current_board,
extra_env=proper_env)
tempfile.mkdtemp(prefix='autotest').AndReturn(fake_autotest_dir)
commands.BuildAutotestTarballs(self.build_root, self._current_board,
fake_autotest_dir).AndReturn(tarballs)
self.archive_stage_mock.AutotestTarballsReady(tarballs)
os.path.isdir(self.latest_cbuildbot).AndReturn(True)
self.archive_stage_mock.SetVersion('%s-b%s' % (self.version,
self.options.buildnumber))
shutil.copyfile(autotest_tarball_path,
os.path.join(self.images_root, 'latest-cbuildbot',
autotest_tarball_name))
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def _replace_archive_path(functor):
# If/when mox grows the ability to replace parts of a module selectively,
# use that and kill this.
# Till then, we just mutate the module and restore it on the way out.
def f(self):
original = stages.BUILDBOT_ARCHIVE_PATH
try:
stages.BUILDBOT_ARCHIVE_PATH = self.tempdir
return functor(self)
finally:
stages.BUILDBOT_ARCHIVE_PATH = original
return osutils.TempDirDecorator(f)
class ArchiveStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self._build_config = self.build_config.copy()
self._build_config['upload_symbols'] = True
self._build_config['push_image'] = True
self.mox.StubOutWithMock(stages.ArchiveStage, 'GetVersion')
stages.ArchiveStage.GetVersion().MultipleTimes().AndReturn('0.0.0.1')
self.mox.StubOutWithMock(background, 'RunParallelSteps')
self.mox.StubOutWithMock(commands, 'PushImages')
self.mox.StubOutWithMock(commands, 'RemoveOldArchives')
self.mox.StubOutWithMock(commands, 'UpdateLatestFile')
self.mox.StubOutWithMock(commands, 'UploadArchivedFile')
def ConstructStage(self):
return stages.ArchiveStage(self.options, self._build_config,
self._current_board)
@_replace_archive_path
def testArchive(self):
"""Simple did-it-run test."""
# TODO(davidjames): Test the individual archive steps as well.
background.RunParallelSteps(mox.IgnoreArg())
commands.PushImages(self.build_root,
board=self._current_board,
branch_name='master',
archive_url=mox.IgnoreArg(),
profile=None)
commands.RemoveOldArchives(mox.IgnoreArg(), mox.IgnoreArg())
commands.UpdateLatestFile(mox.IgnoreArg(), mox.IgnoreArg())
commands.UploadArchivedFile(mox.IgnoreArg(), mox.IgnoreArg(),
'LATEST', False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
@osutils.TempDirDecorator
def testNoPushImagesForRemoteTrybot(self):
"""Test that remote trybot overrides work to disable push images."""
argv = ['--remote-trybot', '-r', self.tempdir, '--buildnumber=1234',
'x86-mario-release']
parser = cbuildbot._CreateParser()
(self.options, _args) = cbuildbot._ParseCommandLine(parser, argv)
test_config = config.config['x86-mario-release']
self._build_config = config.OverrideConfigForTrybot(test_config, True)
background.RunParallelSteps(mox.IgnoreArg())
commands.RemoveOldArchives(mox.IgnoreArg(), mox.IgnoreArg())
commands.UpdateLatestFile(mox.IgnoreArg(), mox.IgnoreArg())
commands.UploadArchivedFile(mox.IgnoreArg(), mox.IgnoreArg(),
'LATEST', False)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
class UploadPrebuiltsStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
self.options.chrome_rev = 'tot'
self.options.prebuilts = True
self.mox.StubOutWithMock(stages.UploadPrebuiltsStage, '_GetPortageEnvVar')
self.mox.StubOutWithMock(commands, 'UploadPrebuilts')
self.archive_stage = self.mox.CreateMock(stages.ArchiveStage)
def ConstructStage(self):
self.mox.CreateMock(stages.ArchiveStage)
return stages.UploadPrebuiltsStage(self.options,
self.build_config,
self._current_board,
self.archive_stage)
def ConstructBinhosts(self):
for board in (self._current_board, None):
binhost = 'http://binhost/?board=' + str(board)
stages.UploadPrebuiltsStage._GetPortageEnvVar(stages._PORTAGE_BINHOST,
board).AndReturn(binhost)
def testChromeUpload(self):
"""Test uploading of prebuilts for chrome build."""
self.build_config['build_type'] = constants.CHROME_PFQ_TYPE
chrome_version = 'awesome_chrome_version'
self.archive_stage.GetVersion().AndReturn(chrome_version)
self.ConstructBinhosts()
commands.UploadPrebuilts(
self.build_root, self._current_board,
False,
self.build_config['build_type'],
self.options.chrome_rev,
self.build_config['binhost_bucket'],
self.build_config['binhost_key'],
self.build_config['binhost_base_url'],
False,
self.build_config['git_sync'],
mox.IgnoreArg())
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
def testPreflightUpload(self):
"""Test uploading of prebuilts for preflight build."""
self.build_config['build_type'] = constants.PFQ_TYPE
pfq_version = 'awesome_pfq_version'
self.archive_stage.GetVersion().AndReturn(pfq_version)
self.ConstructBinhosts()
commands.UploadPrebuilts(
self.build_root, self._current_board,
False,
self.build_config['build_type'],
self.options.chrome_rev,
self.build_config['binhost_bucket'],
self.build_config['binhost_key'],
self.build_config['binhost_base_url'],
False,
self.build_config['git_sync'],
mox.IgnoreArg())
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
class PublishUprevChangesStageTest(AbstractStageTest):
def setUp(self):
mox.MoxTestBase.setUp(self)
AbstractStageTest.setUp(self)
# Disable most paths by default and selectively enable in tests
self.build_config['build_type'] = constants.BUILD_FROM_SOURCE_TYPE
self.options.chrome_rev = constants.CHROME_REV_TOT
self.options.prebuilts = True
self.mox.StubOutWithMock(stages.PublishUprevChangesStage,
'_GetPortageEnvVar')
self.mox.StubOutWithMock(commands, 'UploadPrebuilts')
self.mox.StubOutWithMock(commands, 'UprevPush')
def ConstructStage(self):
return stages.PublishUprevChangesStage(self.options, self.build_config)
def testPush(self):
"""Test values for PublishUprevChanges."""
self.build_config['push_overlays'] = constants.PUBLIC_OVERLAYS
self.build_config['master'] = True
commands.UprevPush(
self.build_root,
[self.overlay],
self.options.debug)
self.mox.ReplayAll()
self.RunStage()
self.mox.VerifyAll()
class BuildStagesResultsTest(unittest.TestCase):
def setUp(self):
unittest.TestCase.setUp(self)
# Always stub RunCommmand out as we use it in every method.
self.bot_id = 'x86-generic-paladin'
self.build_config = config.config[self.bot_id]
self.build_root = '/fake_root'
self.url = 'fake_url'
# Create a class to hold
class Options(object):
pass
self.options = Options()
self.options.buildroot = self.build_root
self.options.debug = False
self.options.prebuilts = False
self.options.clobber = False
self.options.buildnumber = 1234
self.options.chrome_rev = None
self.failException = Exception("FailStage needs to fail.")
def _runStages(self):
"""Run a couple of stages so we can capture the results"""
# Save off our self where FailStage._PerformStage can find it.
outer_self = self
class PassStage(bs.BuilderStage):
"""PassStage always works"""
pass
class Pass2Stage(bs.BuilderStage):
"""Pass2Stage always works"""
pass
class FailStage(bs.BuilderStage):
"""FailStage always throws an exception"""
def _PerformStage(self):
"""Throw the exception to make us fail."""
raise outer_self.failException
# Run two pass stages, and one fail stage.
PassStage(self.options, self.build_config).Run()
Pass2Stage(self.options, self.build_config).Run()
self.assertRaises(
bs.NonBacktraceBuildException,
FailStage(self.options, self.build_config).Run)
def _verifyRunResults(self, expectedResults):
actualResults = results_lib.Results.Get()
# Break out the asserts to be per item to make debugging easier
self.assertEqual(len(expectedResults), len(actualResults))
for i in xrange(len(expectedResults)):
name, result, description, runtime = actualResults[i]
if result != results_lib.Results.SUCCESS:
self.assertTrue(isinstance(description, str))
self.assertTrue(runtime >= 0 and runtime < 2.0)
self.assertEqual(expectedResults[i], (name, result))
def _PassString(self):
return results_lib.Results.SPLIT_TOKEN.join(['Pass', 'None', '0\n'])
def testRunStages(self):
"""Run some stages and verify the captured results"""
results_lib.Results.Clear()
self.assertEqual(results_lib.Results.Get(), [])
self._runStages()
# Verify that the results are what we expect.
expectedResults = [
('Pass', results_lib.Results.SUCCESS),
('Pass2', results_lib.Results.SUCCESS),
('Fail', self.failException)]
self._verifyRunResults(expectedResults)
def testSuccessTest(self):
"""Run some stages and verify the captured results"""
results_lib.Results.Clear()
results_lib.Results.Record('Pass', results_lib.Results.SUCCESS)
self.assertTrue(results_lib.Results.BuildSucceededSoFar())
results_lib.Results.Record('Fail', self.failException, time=1)
self.assertFalse(results_lib.Results.BuildSucceededSoFar())
results_lib.Results.Record('Pass2', results_lib.Results.SUCCESS)
self.assertFalse(results_lib.Results.BuildSucceededSoFar())
def testStagesReportSuccess(self):
"""Tests Stage reporting."""
stages.ManifestVersionedSyncStage.manifest_manager = None
# Store off a known set of results and generate a report
results_lib.Results.Clear()
results_lib.Results.Record('Pass', results_lib.Results.SUCCESS, time=1)
results_lib.Results.Record('Pass2', results_lib.Results.SUCCESS, time=2)
results_lib.Results.Record('Fail', self.failException, time=3)
result = cros_build_lib.CommandResult(cmd=['/bin/false', '/nosuchdir'],
returncode=2)
results_lib.Results.Record(
'FailRunCommand',
cros_build_lib.RunCommandError(
'Command "/bin/false /nosuchdir" failed.\n',
result), time=4)
results = StringIO.StringIO()
results_lib.Results.Report(results)
expectedResults = (
"************************************************************\n"
"** Stage Results\n"
"************************************************************\n"
"** PASS Pass (0:00:01)\n"
"************************************************************\n"
"** PASS Pass2 (0:00:02)\n"
"************************************************************\n"
"** FAIL Fail (0:00:03) with Exception\n"
"************************************************************\n"
"** FAIL FailRunCommand (0:00:04) in /bin/false\n"
"************************************************************\n")
expectedLines = expectedResults.split('\n')
actualLines = results.getvalue().split('\n')
# Break out the asserts to be per item to make debugging easier
for i in xrange(len(expectedLines)):
self.assertEqual(expectedLines[i], actualLines[i])
self.assertEqual(len(expectedLines), len(actualLines))
def testStagesReportError(self):
"""Tests Stage reporting with exceptions."""
stages.ManifestVersionedSyncStage.manifest_manager = None
# Store off a known set of results and generate a report
results_lib.Results.Clear()
results_lib.Results.Record('Sync', results_lib.Results.SUCCESS, time=1)
results_lib.Results.Record('Build', results_lib.Results.SUCCESS, time=2)
results_lib.Results.Record('Test', self.failException,
'failException Msg\nLine 2', time=3)
result = cros_build_lib.CommandResult(cmd=['/bin/false', '/nosuchdir'],
returncode=2)
results_lib.Results.Record(
'Archive',
cros_build_lib.RunCommandError(
'Command "/bin/false /nosuchdir" failed.\n',
result),
'FailRunCommand msg', time=4)
results = StringIO.StringIO()
results_lib.Results.Report(results)
expectedResults = (
"************************************************************\n"
"** Stage Results\n"
"************************************************************\n"
"** PASS Sync (0:00:01)\n"
"************************************************************\n"
"** PASS Build (0:00:02)\n"
"************************************************************\n"
"** FAIL Test (0:00:03) with Exception\n"
"************************************************************\n"
"** FAIL Archive (0:00:04) in /bin/false\n"
"************************************************************\n"
"\n"
"Failed in stage Test:\n"
"\n"
"failException Msg\n"
"Line 2\n")
expectedLines = expectedResults.split('\n')
actualLines = results.getvalue().split('\n')
# Break out the asserts to be per item to make debugging easier
for i in xrange(len(expectedLines)):
self.assertEqual(expectedLines[i], actualLines[i])
self.assertEqual(len(expectedLines), len(actualLines))
def testStagesReportReleaseTag(self):
"""Tests Release Tag entry in stages report."""
current_version = "release_tag_string"
archive_urls = {'board1': 'result_url1',
'board2': 'result_url2'}
# Store off a known set of results and generate a report
results_lib.Results.Clear()
results_lib.Results.Record('Pass', results_lib.Results.SUCCESS, time=1)
results = StringIO.StringIO()
results_lib.Results.Report(results, archive_urls, current_version)
expectedResults = (
"************************************************************\n"
"** RELEASE VERSION: release_tag_string\n"
"************************************************************\n"
"** Stage Results\n"
"************************************************************\n"
"** PASS Pass (0:00:01)\n"
"************************************************************\n"
"** BUILD ARTIFACTS FOR THIS BUILD CAN BE FOUND AT:\n"
"** board1: result_url1\n"
"@@@STEP_LINK@Artifacts[board1]@result_url1@@@\n"
"** board2: result_url2\n"
"@@@STEP_LINK@Artifacts[board2]@result_url2@@@\n"
"************************************************************\n")
expectedLines = expectedResults.split('\n')
actualLines = results.getvalue().split('\n')
# Break out the asserts to be per item to make debugging easier
for i in xrange(len(expectedLines)):
self.assertEqual(expectedLines[i], actualLines[i])
self.assertEqual(len(expectedLines), len(actualLines))
def testSaveCompletedStages(self):
"""Tests that we can save out completed stages."""
# Run this again to make sure we have the expected results stored
results_lib.Results.Clear()
results_lib.Results.Record('Pass', results_lib.Results.SUCCESS)
results_lib.Results.Record('Fail', self.failException)
results_lib.Results.Record('Pass2', results_lib.Results.SUCCESS)
saveFile = StringIO.StringIO()
results_lib.Results.SaveCompletedStages(saveFile)
self.assertEqual(saveFile.getvalue(), self._PassString())
def testRestoreCompletedStages(self):
"""Tests that we can read in completed stages."""
results_lib.Results.Clear()
results_lib.Results.RestoreCompletedStages(
StringIO.StringIO(self._PassString()))
previous = results_lib.Results.GetPrevious()
self.assertEqual(previous.keys(), ['Pass'])
def testRunAfterRestore(self):
"""Tests that we skip previously completed stages."""
# Fake results_lib.Results.RestoreCompletedStages
results_lib.Results.Clear()
results_lib.Results.RestoreCompletedStages(
StringIO.StringIO(self._PassString()))
self._runStages()
# Verify that the results are what we expect.
expectedResults = [
('Pass', results_lib.Results.SUCCESS),
('Pass2', results_lib.Results.SUCCESS),
('Fail', self.failException)]
self._verifyRunResults(expectedResults)
if __name__ == '__main__':
unittest.main()