#!/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 build stages."""

import mox
import os
import shutil
import StringIO
import sys
import tempfile
import unittest

import constants
sys.path.append(constants.SOURCE_ROOT)
import chromite.buildbot.cbuildbot_config as config
import chromite.buildbot.cbuildbot_commands as commands
import chromite.buildbot.cbuildbot_stages as stages
import chromite.buildbot.manifest_version as manifest_version
import chromite.lib.cros_build_lib as cros_lib


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.
  """

  TRACKING_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-pre-flight-queue'
    self.build_config = config.config[self.bot_id]
    self.build_root = '/fake_root'

    self.url = 'fake_url'
    self.build_config['git_url'] = self.url

    self.options = self.mox.CreateMockAnything()
    self.options.buildroot = self.build_root
    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')
    stages.BuilderStage.rev_overlays = [self.overlay]
    stages.BuilderStage.push_overlays = [self.overlay]

    stages.BuilderStage.SetTrackingBranch(self.TRACKING_BRANCH)

    self.mox.StubOutWithMock(os.path, 'isdir')

  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 stages.BuilderStage(self.bot_id, self.options, self.build_config)

  def testGetPortageEnvVar(self):
    """Basic test case for _GetPortageEnvVar function."""
    self.mox.StubOutWithMock(cros_lib, 'OldRunCommand')
    envvar = 'EXAMPLE'
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)
    cros_lib.OldRunCommand(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('RESULT\n')
    self.mox.ReplayAll()
    stage = self.ConstructStage()
    board = self.build_config['board']
    result = stage._GetPortageEnvVar(envvar, board)
    self.mox.VerifyAll()
    self.assertEqual(result, 'RESULT')

  def testResolveOverlays(self):
    self.mox.StubOutWithMock(cros_lib, 'RunCommand')
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)
    for _ in range(3):
      output_obj = cros_lib.CommandResult()
      output_obj.output = 'public1 public2\n'
      cros_lib.RunCommand(
          mox.And(mox.IsA(list), mox.In('--noprivate')),
          print_cmd=False, redirect_stdout=True).AndReturn(output_obj)
      output_obj = cros_lib.CommandResult()
      output_obj.output = 'private1 private2\n'
      cros_lib.RunCommand(
          mox.And(mox.IsA(list), mox.In('--nopublic')),
          print_cmd=False, redirect_stdout=True).AndReturn(output_obj)
    self.mox.ReplayAll()
    stages.OVERLAY_LIST_CMD = '/bin/true'
    stage = self.ConstructStage()
    public_overlays = ['public1', 'public2', self.overlay]
    private_overlays = ['private1', 'private2']

    self.assertEqual(stage._ResolveOverlays('public'), public_overlays)
    self.assertEqual(stage._ResolveOverlays('private'), private_overlays)
    self.assertEqual(stage._ResolveOverlays('both'),
                     public_overlays + private_overlays)
    self.mox.VerifyAll()


class SyncStageTest(AbstractStageTest):

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    AbstractStageTest.setUp(self)
    self.mox.StubOutWithMock(commands, 'PreFlightRinse')

  def ConstructStage(self):
    return stages.SyncStage(self.bot_id, self.options, self.build_config)

  def testFullSync(self):
    """Tests whether we can perform a full sync with a missing .repo folder."""
    self.mox.StubOutWithMock(commands, 'FullCheckout')

    os.path.isdir(self.build_root + '/.repo').AndReturn(False)
    os.path.isdir(self.build_root + '/.repo').AndReturn(False)
    commands.FullCheckout(self.build_root, self.TRACKING_BRANCH,
                          url=self.url)
    os.path.isdir(self.overlay).AndReturn(True)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()

  def testIncrementalSync(self):
    """Tests whether we can perform a standard incremental sync."""
    self.mox.StubOutWithMock(commands, 'IncrementalCheckout')
    self.mox.StubOutWithMock(stages.BuilderStage, '_GetPortageEnvVar')

    os.path.isdir(self.build_root + '/.repo').AndReturn(True)
    board = self.build_config['board']
    commands.PreFlightRinse(self.build_root, board,
                            [self.overlay])
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)
    stages.BuilderStage._GetPortageEnvVar(stages._FULL_BINHOST, board)
    commands.IncrementalCheckout(self.build_root)
    os.path.isdir(self.overlay).AndReturn(True)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()


class ManifestVersionedSyncStageTest(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.version_file = 'version-file.sh'
    self.branch = 'master'
    self.build_name = 'x86-generic'
    self.incr_type = 'patch'

    self.build_config['manifest_version'] = self.manifest_version_url
    self.next_version = 'next_version'

    self.manager = manifest_version.BuildSpecsManager(
      self.tmpdir, self.source_repo, self.manifest_version_url, self.branch,
      self.build_name, self.incr_type, dry_run=True)

  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(manifest_version.BuildSpecsManager,
                             'GetNextBuildSpec')
    self.mox.StubOutWithMock(commands, 'ManifestCheckout')

    os.path.isdir(self.build_root + '/.repo').AndReturn(False)
    self.manager.GetNextBuildSpec(stages.VERSION_FILE,
        latest=True).AndReturn(self.next_version)

    commands.ManifestCheckout(self.build_root,
                              self.TRACKING_BRANCH,
                              self.next_version,
                              url=self.url)

    os.path.isdir('/fake_root/.repo').AndReturn(True)
    os.path.isdir('/fake_root/src/third_party/'
                  'chromiumos-overlay').AndReturn(True)


    self.mox.ReplayAll()
    stage = stages.ManifestVersionedSyncStage(self.bot_id,
                                              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')

    os.path.isdir(self.build_root + '/.repo').AndReturn(False)
    self.manager.UpdateStatus(success=True)

    self.mox.ReplayAll()
    stage = stages.ManifestVersionedSyncCompletionStage(self.bot_id,
                                                        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')

    os.path.isdir(self.build_root + '/.repo').AndReturn(False)
    self.manager.UpdateStatus(success=False)


    self.mox.ReplayAll()
    stage = stages.ManifestVersionedSyncCompletionStage(self.bot_id,
                                                        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

    os.path.isdir(self.build_root + '/.repo').AndReturn(False)

    self.mox.ReplayAll()
    stage = stages.ManifestVersionedSyncCompletionStage(self.bot_id,
                                                        self.options,
                                                        self.build_config,
                                                        success=False)
    stage.Run()
    self.mox.VerifyAll()


class BuildBoardTest(AbstractStageTest):

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    AbstractStageTest.setUp(self)

  def ConstructStage(self):
    return stages.BuildBoardStage(self.bot_id, self.options, self.build_config)

  def testFullBuild(self):
    """Tests whether 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(self.build_root + '/.repo').AndReturn(True)
    os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(True)
    commands.MakeChroot(buildroot=self.build_root,
                        fast=True,
                        replace=True,
                        usepkg=False)
    os.path.isdir(os.path.join(self.build_root, 'chroot/build',
                               self.build_config['board'])).AndReturn(False)
    commands.SetupBoard(self.build_root,
                        board=self.build_config['board'],
                        fast=True,
                        usepkg=False)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()

  def testBinBuild(self):
    """Tests whether we skip un-necessary steps for a binary builder."""
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)
    os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(True)
    os.path.isdir(os.path.join(self.build_root, 'chroot/build',
                               self.build_config['board'])).AndReturn(True)

    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(self.build_root + '/.repo').AndReturn(True)
    os.path.isdir(os.path.join(self.build_root, 'chroot')).AndReturn(False)
    commands.MakeChroot(buildroot=self.build_root,
                        replace=self.build_config['chroot_replace'],
                        fast=self.build_config['fast'],
                        usepkg=self.build_config['usepkg_chroot'])

    os.path.isdir(os.path.join(self.build_root, 'chroot/build',
                               self.build_config['board'])).AndReturn(False)
    commands.SetupBoard(self.build_root,
                        board=self.build_config['board'],
                        fast=self.build_config['fast'],
                        usepkg=self.build_config['usepkg_setup_board'])

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()


class TestStageTest(AbstractStageTest):

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    AbstractStageTest.setUp(self)
    self.fake_results_dir = '/tmp/fake_results_dir'

  def ConstructStage(self):
    return stages.TestStage(self.bot_id, self.options, self.build_config)

  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['quick_unit'] = False
    self.build_config['quick_vm'] = False

    self.mox.StubOutWithMock(cros_lib, 'OldRunCommand')

    self.mox.StubOutWithMock(commands, 'RunUnitTests')
    self.mox.StubOutWithMock(commands, 'RunTestSuite')
    self.mox.StubOutWithMock(commands, 'ArchiveTestResults')
    self.mox.StubOutWithMock(stages.TestStage, '_CreateTestRoot')

    os.path.isdir(self.build_root + '/.repo').AndReturn(True)
    stages.TestStage._CreateTestRoot().AndReturn(self.fake_results_dir)
    commands.RunUnitTests(self.build_root, full=True,
                          nowithdebug=mox.IgnoreArg())
    commands.RunTestSuite(self.build_root,
                          self.build_config['board'],
                          os.path.join(self.fake_results_dir,
                                       'test_harness'),
                          full=True)
    commands.ArchiveTestResults(self.build_root, self.fake_results_dir)

    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['quick_unit'] = True
    self.build_config['quick_vm'] = True

    self.mox.StubOutWithMock(commands, 'RunUnitTests')
    self.mox.StubOutWithMock(commands, 'RunTestSuite')
    self.mox.StubOutWithMock(commands, 'ArchiveTestResults')
    self.mox.StubOutWithMock(stages.TestStage, '_CreateTestRoot')

    os.path.isdir(self.build_root + '/.repo').AndReturn(True)
    stages.TestStage._CreateTestRoot().AndReturn(self.fake_results_dir)
    commands.RunUnitTests(self.build_root, full=False,
                          nowithdebug=mox.IgnoreArg())
    commands.RunTestSuite(self.build_root,
                            self.build_config['board'],
                            os.path.join(self.fake_results_dir,
                                         'test_harness'),
                            full=False)
    commands.ArchiveTestResults(self.build_root, self.fake_results_dir)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()


class UprevStageTest(AbstractStageTest):

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    AbstractStageTest.setUp(self)
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)

    # 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.bot_id, 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.TRACKING_BRANCH,
        self.options.chrome_rev,
        self.build_config['board']).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.TRACKING_BRANCH,
        self.options.chrome_rev,
        self.build_config['board'])

    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.build_config['board'],
        [self.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.TRACKING_BRANCH,
        self.options.chrome_rev,
        self.build_config['board']).AndReturn(None)

    commands.UprevPackages(
        self.build_root,
        self.build_config['board'],
        [self.overlay])

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()


class BuildTargetStageTest(AbstractStageTest):

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    AbstractStageTest.setUp(self)
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)

    # Disable most paths by default and selectively enable in tests

    self.build_config['vm_tests'] = False
    self.build_config['build_type'] = 'binary'
    self.build_config['usepkg_chroot'] = False
    self.build_config['fast'] = False

    self.options.prebuilts = True
    self.options.tests = False

    self.mox.StubOutWithMock(commands, 'Build')
    self.mox.StubOutWithMock(commands, 'UploadPrebuilts')
    self.mox.StubOutWithMock(commands, 'BuildImage')
    self.mox.StubOutWithMock(commands, 'BuildVMImageForTesting')
    self.mox.StubOutWithMock(stages.BuilderStage, '_GetPortageEnvVar')

  def ConstructStage(self):
    return stages.BuildTargetStage(self.bot_id,
                                    self.options,
                                    self.build_config)

  def testAllConditionalPaths(self):
    """Enable all paths to get line coverage."""
    self.build_config['vm_tests'] = True
    self.options.tests = True
    self.build_config['build_type'] = 'full'
    self.build_config['usepkg_chroot'] = True
    self.build_config['usepkg_setup_board'] = True
    self.build_config['usepkg_build_packages'] = True
    self.build_config['fast'] = True
    self.build_config['useflags'] = ['ALPHA', 'BRAVO', 'CHARLIE']
    self.build_config['nowithdebug'] = False
    proper_env = {'USE' : ' '.join(self.build_config['useflags'])}

    board = self.build_config['board']
    stages.BuilderStage._GetPortageEnvVar('FULL_BINHOST',
        board).AndReturn('new.com')
    stages.BuilderStage.old_binhost = 'old.com'

    commands.Build(self.build_root,
                   build_autotest=True,
                   emptytree=True,
                   usepkg=True,
                   fast=True,
                   nowithdebug=False,
                   extra_env=proper_env)

    commands.UploadPrebuilts(
        self.build_root, self.build_config['board'],
        self.build_config['rev_overlays'], [],
        self.build_config['build_type'], None, self.options.buildnumber)

    commands.BuildImage(self.build_root, extra_env=proper_env)
    commands.BuildVMImageForTesting(self.build_root, extra_env=proper_env)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()

  def testFalseBuildArgs1(self):
    """Make sure our logic for Build arguments can toggle to false."""
    board = self.build_config['board']
    stages.BuilderStage._GetPortageEnvVar('FULL_BINHOST',
        board).AndReturn('new.com')
    stages.BuilderStage.old_binhost = 'new.com'
    self.build_config['useflags'] = None

    commands.Build(self.build_root,
                   build_autotest=mox.IgnoreArg(),
                   emptytree=mox.IgnoreArg(),
                   fast=mox.IgnoreArg(),
                   usepkg=mox.IgnoreArg(),
                   nowithdebug=mox.IgnoreArg(),
                   extra_env={})
    commands.BuildImage(self.build_root, extra_env={})

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()

  def testFalseBuildArgs2(self):
    """Verify emptytree flag is false when there is no old binhost."""
    board = self.build_config['board']
    stages.BuilderStage._GetPortageEnvVar('FULL_BINHOST',
        board).AndReturn('new.com')
    stages.BuilderStage.old_binhost = False
    self.build_config['useflags'] = ['BAKER']
    proper_env = {'USE' : ' '.join(self.build_config['useflags'])}

    commands.Build(self.build_root,
                   build_autotest=mox.IgnoreArg(),
                   emptytree=False,
                   fast=mox.IgnoreArg(),
                   usepkg=mox.IgnoreArg(),
                   nowithdebug=False,
                   extra_env=proper_env)

    commands.BuildImage(self.build_root, extra_env=proper_env)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()


class ArchiveStageTest(AbstractStageTest):

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    AbstractStageTest.setUp(self)
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)

    self._build_config = self.build_config.copy()
    self._build_config['upload_symbols'] = True
    self._build_config['push_image'] = True

  def ConstructStage(self):
    return stages.ArchiveStage(self.bot_id, self.options, self._build_config)

  def testArchive(self):
    """Simple did-it-run test."""
    self.mox.StubOutWithMock(commands, 'LegacyArchiveBuild')
    self.mox.StubOutWithMock(commands, 'UploadSymbols')
    self.mox.StubOutWithMock(commands, 'PushImages')



    commands.LegacyArchiveBuild(
        self.build_root, self.bot_id, self._build_config,
        self.options.buildnumber, None,
        self.options.debug).AndReturn((None, '/archive/dir'))

    commands.UploadSymbols(self.build_root,
                           board=self._build_config['board'],
                           official=self._build_config['chromeos_official'])

    commands.PushImages(self.build_root,
                        board=self._build_config['board'],
                        branch_name='master',
                        archive_dir='/archive/dir')

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()


class PushChangesStageTest(AbstractStageTest):

  def setUp(self):
    mox.MoxTestBase.setUp(self)
    AbstractStageTest.setUp(self)
    os.path.isdir(self.build_root + '/.repo').AndReturn(True)

    # Disable most paths by default and selectively enable in tests

    self.build_config['build_type'] = 'full'
    self.options.chrome_rev = 'tot'
    self.options.prebuilts = True
    self.mox.StubOutWithMock(stages.PushChangesStage, '_GetPortageEnvVar')
    self.mox.StubOutWithMock(commands, 'UploadPrebuilts')
    self.mox.StubOutWithMock(commands, 'UprevPush')

  def ConstructStage(self):
    return stages.PushChangesStage(self.bot_id,
                                   self.options,
                                   self.build_config)

  def ConstructBinhosts(self):
    binhosts = []
    for board in (self.build_config['board'], None):
      binhost = 'http://binhost/?board=' + str(board)
      stages.PushChangesStage._GetPortageEnvVar(stages._PORTAGE_BINHOST,
          board).AndReturn(binhost)
      binhosts.append(binhost)
    return binhosts

  def testChromePush(self):
    """Test uploading of prebuilts for chrome build."""
    self.build_config['build_type'] = 'chrome'

    binhosts = self.ConstructBinhosts()
    commands.UploadPrebuilts(
        self.build_root, self.build_config['board'],
        self.build_config['rev_overlays'], binhosts,
        self.build_config['build_type'],
        self.options.chrome_rev,
        self.options.buildnumber)

    commands.UprevPush(
        self.build_root,
        self.build_config['board'],
        [self.overlay],
        self.options.debug)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()

  def testPreflightPush(self):
    """Test uploading of prebuilts for preflight build."""
    self.build_config['build_type'] = 'binary'

    binhosts = self.ConstructBinhosts()
    commands.UploadPrebuilts(
        self.build_root, self.build_config['board'],
        self.build_config['rev_overlays'], binhosts,
        self.build_config['build_type'],
        self.options.chrome_rev,
        self.options.buildnumber)

    commands.UprevPush(
        self.build_root,
        self.build_config['board'],
        [self.overlay],
        self.options.debug)

    self.mox.ReplayAll()
    self.RunStage()
    self.mox.VerifyAll()

  def testFullPush(self):
    """Shouldn't upload prebuilts for a full build."""
    self.build_config['build_type'] = 'full'

    commands.UprevPush(
        self.build_root,
        self.build_config['board'],
        [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-pre-flight-queue'
    self.build_config = config.config[self.bot_id]
    self.build_root = '/fake_root'
    self.url = 'fake_url'

    # Create a class to hold
    class Options:
      pass

    self.options = Options()
    self.options.buildroot = self.build_root
    self.options.debug = False
    self.options.prebuilts = False
    self.options.clobber = False
    self.options.url = self.url
    self.options.buildnumber = 1234

    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(stages.BuilderStage):
      """PassStage always works"""
      pass

    class Pass2Stage(stages.BuilderStage):
      """Pass2Stage always works"""
      pass

    class FailStage(stages.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.bot_id, self.options, self.build_config).Run()
    Pass2Stage(self.bot_id, self.options, self.build_config).Run()

    self.assertRaises(
      stages.BuildException,
      FailStage(self.bot_id, self.options, self.build_config).Run)

  def _verifyRunResults(self, expectedResults):

    actualResults = stages.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 not in (stages.Results.SUCCESS,
                         stages.Results.SKIPPED):
        self.assertTrue(isinstance(description, str))

      # Skipped stages take no time, all other test stages take a little time
      if result == stages.Results.SKIPPED:
        self.assertEqual(runtime, 0)
      else:
        self.assertTrue(runtime >= 0 and runtime < 2.0)

      self.assertEqual(expectedResults[i], (name, result))

  def testRunStages(self):
    """Run some stages and verify the captured results"""

    stages.Results.Clear()
    self.assertEqual(stages.Results.Get(), [])

    self._runStages()

    # Verify that the results are what we expect.
    expectedResults = [
        ('Pass', stages.Results.SUCCESS),
        ('Pass2', stages.Results.SUCCESS),
        ('Fail', self.failException)]

    self._verifyRunResults(expectedResults)

  def testSuccessTest(self):
    """Run some stages and verify the captured results"""

    stages.Results.Clear()
    stages.Results.Record('Pass', stages.Results.SKIPPED)

    self.assertTrue(stages.Results.Success())

    stages.Results.Record('Fail', self.failException, time=1)

    self.assertFalse(stages.Results.Success())

    stages.Results.Record('Pass2', stages.Results.SUCCESS)

    self.assertFalse(stages.Results.Success())

  def testStagesReportSuccess(self):
    """Tests Stage reporting."""

    stages.BuilderStage.archive_url = None
    stages.ManifestVersionedSyncStage.manifest_manager = None

    # Store off a known set of results and generate a report
    stages.Results.Clear()
    stages.Results.Record('Pass', stages.Results.SKIPPED, time=1)
    stages.Results.Record('Pass2', stages.Results.SUCCESS, time=2)
    stages.Results.Record('Fail', self.failException, time=3)
    stages.Results.Record(
        'FailRunCommand',
        cros_lib.RunCommandError(
            'Command "/bin/false /nosuchdir" failed.\n',
            ['/bin/false', '/nosuchdir']), time=4)
    stages.Results.Record(
        'FailOldRunCommand',
        cros_lib.RunCommandException(
            'Command "[\'/bin/false\', \'/nosuchdir\']" failed.\n',
            ['/bin/false', '/nosuchdir']), time=5)

    results = StringIO.StringIO()

    stages.Results.Report(results)

    expectedResults = (
        "************************************************************\n"
        "** Stage Results\n"
        "************************************************************\n"
        "** Pass previously completed\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"
        "** FAIL FailOldRunCommand (0:00:05) 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.BuilderStage.archive_url = None
    stages.ManifestVersionedSyncStage.manifest_manager = None

    # Store off a known set of results and generate a report
    stages.Results.Clear()
    stages.Results.Record('Pass', stages.Results.SKIPPED, time=1)
    stages.Results.Record('Pass2', stages.Results.SUCCESS, time=2)
    stages.Results.Record('Fail', self.failException,
                                       'failException Msg\nLine 2', time=3)
    stages.Results.Record(
        'FailRunCommand',
        cros_lib.RunCommandError(
            'Command "/bin/false /nosuchdir" failed.\n',
            ['/bin/false', '/nosuchdir']),
        'FailRunCommand msg', time=4)
    stages.Results.Record(
        'FailOldRunCommand',
        cros_lib.RunCommandException(
            'Command "[\'/bin/false\', \'/nosuchdir\']" failed.\n',
            ['/bin/false', '/nosuchdir']),
        'FailOldRunCommand msg', time=5)

    results = StringIO.StringIO()

    stages.Results.Report(results)

    expectedResults = (
        "************************************************************\n"
        "** Stage Results\n"
        "************************************************************\n"
        "** Pass previously completed\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"
        "** FAIL FailOldRunCommand (0:00:05) in /bin/false\n"
        "************************************************************\n"
        "\n"
        "Build failed with:\n"
        "\n"
        "failException Msg\n"
        "Line 2")

    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."""

    manifest_manager = mox.MockAnything()
    manifest_manager.current_version = "release_tag_string"
    stages.ManifestVersionedSyncStage.manifest_manager = manifest_manager

    stages.BuilderStage.archive_url = 'result_url'

    # Store off a known set of results and generate a report
    stages.Results.Clear()
    stages.Results.Record('Pass', stages.Results.SUCCESS, time=1)

    results = StringIO.StringIO()

    stages.Results.Report(results)

    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"
        "**  result_url\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
    stages.Results.Clear()
    stages.Results.Record('Pass', stages.Results.SUCCESS)
    stages.Results.Record('Fail', self.failException)
    stages.Results.Record('Pass2', stages.Results.SUCCESS)

    saveFile = StringIO.StringIO()
    stages.Results.SaveCompletedStages(saveFile)
    self.assertEqual(saveFile.getvalue(), 'Pass\n')

  def testRestoreCompletedStages(self):
    """Tests that we can read in completed stages."""

    stages.Results.Clear()
    stages.Results.RestoreCompletedStages(
        StringIO.StringIO('Pass\n'))

    self.assertEqual(stages.Results.GetPrevious(), ['Pass'])

  def testRunAfterRestore(self):
    """Tests that we skip previously completed stages."""

    # Fake stages.Results.RestoreCompletedStages
    stages.Results.Clear()
    stages.Results.RestoreCompletedStages(
        StringIO.StringIO('Pass\n'))

    self._runStages()

    # Verify that the results are what we expect.
    expectedResults = [
        ('Pass', stages.Results.SKIPPED),
        ('Pass2', stages.Results.SUCCESS),
        ('Fail', self.failException)]

    self._verifyRunResults(expectedResults)


if __name__ == '__main__':
  unittest.main()
