# Copyright 2017 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.

"""Test git_bisector module."""

from __future__ import print_function

import mock
import os

from chromite.cros_bisect import common
from chromite.cros_bisect import builder as builder_module
from chromite.cros_bisect import evaluator as evaluator_module
from chromite.cros_bisect import git_bisector
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import partial_mock


class GitMock(partial_mock.PartialCmdMock):
  """Mocks git.RunGit.

  Usage:
    mock = GitMock('/path/to/git_repository')
    mock.AddRunGitResult(git_command, output=...)
    # call git.RunGit(...)
  """
  TARGET = 'chromite.lib.git'
  ATTRS = ('RunGit', )
  DEFAULT_ATTR = 'RunGit'

  def __init__(self, cwd):
    """Constructor.

    Args:
      cwd: default git repository.
    """
    super(GitMock, self).__init__()
    self.cwd = cwd

  def RunGit(self, *args, **kwargs):
    """Mocked RunGit."""
    return self._results['RunGit'].LookupResult(args, kwargs=kwargs)

  def AddRunGitResult(self, cmd, cwd=None, returncode=0, output='', error='',
                      kwargs=None, strict=False, side_effect=None):
    """Adds git command and results."""
    cwd = self.cwd if cwd is None else cwd
    result = self.CmdResult(returncode, output, error)
    self._results['RunGit'].AddResultForParams(
        (cwd, cmd,), result, kwargs=kwargs, side_effect=side_effect,
        strict=strict)


class TestGitBisector(cros_test_lib.MockTempDirTestCase):
  """Tests GitBisector class."""

  BOARD = 'samus'
  TEST_NAME = 'graphics_WebGLAquarium'
  METRIC = 'avg_fps_1000_fishes/summary/value'
  REPORT_FILE = 'reports.json'
  DUT_ADDR = '192.168.1.1'
  DUT = commandline.DeviceParser(commandline.DEVICE_SCHEME_SSH)(DUT_ADDR)

  GOOD_COMMIT_SHA1 = '44af5c9a5505'
  GOOD_COMMIT_TIMESTAMP = 1486526594
  GOOD_COMMIT_SCORE = common.Score([100])
  GOOD_COMMIT_INFO = common.CommitInfo(
      sha1=GOOD_COMMIT_SHA1, timestamp=GOOD_COMMIT_TIMESTAMP, title='good',
      label='last-known-good  ', score=GOOD_COMMIT_SCORE)

  BAD_COMMIT_SHA1 = '6a163bb66c3e'
  BAD_COMMIT_TIMESTAMP = 1486530021
  BAD_COMMIT_SCORE = common.Score([80])
  BAD_COMMIT_INFO = common.CommitInfo(
      sha1=BAD_COMMIT_SHA1, timestamp=BAD_COMMIT_TIMESTAMP, title='bad',
      label='last-known-bad   ', score=BAD_COMMIT_SCORE)

  CULPRIT_COMMIT_SHA1 = '12345abcde'
  CULPRIT_COMMIT_TIMESTAMP = 1486530000
  CULPRIT_COMMIT_SCORE = common.Score([81])
  CULPRIT_COMMIT_INFO = common.CommitInfo(
      sha1=CULPRIT_COMMIT_SHA1, timestamp=CULPRIT_COMMIT_TIMESTAMP, title='bad',
      score=CULPRIT_COMMIT_SCORE)

  THRESHOLD_SPLITTER = 95  # Score between good and bad, closer to good side.
  THRESHOLD = 5  # Distance between good score and splitter.

  REPEAT = 3

  def setUp(self):
    """Sets up test case."""
    self.options = cros_test_lib.EasyAttr(
        base_dir=self.tempdir, board=self.BOARD, reuse_repo=True,
        good=self.GOOD_COMMIT_SHA1, bad=self.BAD_COMMIT_SHA1, remote=self.DUT,
        eval_repeat=self.REPEAT)

    self.evaluator = evaluator_module.Evaluator(self.options)
    self.builder = builder_module.Builder(self.options)
    self.bisector = git_bisector.GitBisector(self.options, self.builder,
                                             self.evaluator)
    self.repo_dir = os.path.join(self.tempdir,
                                 builder_module.Builder.DEFAULT_REPO_DIR)

  def testInit(self):
    """Tests GitBisector() to expect default data members."""
    self.assertEqual(self.GOOD_COMMIT_SHA1, self.bisector.good_commit)
    self.assertEqual(self.BAD_COMMIT_SHA1, self.bisector.bad_commit)
    self.assertEqual(self.DUT_ADDR, self.bisector.remote.raw)
    self.assertEqual(self.REPEAT, self.bisector.eval_repeat)
    self.assertEqual(self.builder, self.bisector.builder)
    self.assertEqual(self.repo_dir, self.bisector.repo_dir)

    self.assertIsNone(self.bisector.good_score)
    self.assertIsNone(self.bisector.bad_score)
    self.assertIsNone(self.bisector.threshold)
    self.assertTrue(not self.bisector.current_commit)

  def testInitMissingRequiredArgs(self):
    """Tests that GitBisector raises error when missing required arguments."""
    options = cros_test_lib.EasyAttr()
    with self.assertRaises(common.MissingRequiredOptionsException) as cm:
      git_bisector.GitBisector(options, self.builder, self.evaluator)
    exception_message = cm.exception.message
    self.assertTrue('Missing command line' in exception_message)
    self.assertTrue('GitBisector' in exception_message)
    for arg in git_bisector.GitBisector.REQUIRED_ARGS:
      self.assertTrue(arg in exception_message)

  def testSetUp(self):
    """Tests that SetUp() calls builder.SetUp()."""
    with mock.patch.object(builder_module.Builder, 'SetUp') as builder_mock:
      self.bisector.SetUp()
      builder_mock.assert_called_with()

  def testGit(self):
    """Tests that Git() invokes git.RunGit() as expected."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    git_mock.AddRunGitResult(['ls'])
    self.bisector.Git(['ls'])

  def testUpdateCurrentCommit(self):
    """Tests that UpdateCurrentCommit() updates self.current_commit."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    git_mock.AddRunGitResult(
        partial_mock.In('show'),
        output='4fcbdaf6 1493010050 Add "cros bisect" command.\n')
    self.bisector.UpdateCurrentCommit()
    current_commit = self.bisector.current_commit
    self.assertEqual('4fcbdaf6', current_commit.sha1)
    self.assertEqual(1493010050, current_commit.timestamp)
    self.assertEqual('Add "cros bisect" command.', current_commit.title)

  def testUpdateCurrentCommitFail(self):
    """Tests UpdateCurrentCommit() when 'git show' returns nonzero."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    git_mock.AddRunGitResult(partial_mock.In('show'), returncode=1)
    self.bisector.UpdateCurrentCommit()
    self.assertTrue(not self.bisector.current_commit)

  def testUpdateCurrentCommitFailUnexpectedOutput(self):
    """Tests UpdateCurrentCommit() when 'git show' gives unexpected output."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    git_mock.AddRunGitResult(partial_mock.In('show'), output='Not expected')
    self.bisector.UpdateCurrentCommit()
    self.assertTrue(not self.bisector.current_commit)

  def MockOutBuildDeployEvaluateForSanityCheck(self):
    """Mocks out BuildDeployEvaluate behavior for SaintyCheck test.

    It mocks UpdateCurrentCommit() to emit good and bad commits. And mocks
    CheckLastEvaluate() to return good and bad commit score.
    """
    commit_info_list = [
        common.CommitInfo(sha1=self.GOOD_COMMIT_SHA1, title='good',
                          timestamp=self.GOOD_COMMIT_TIMESTAMP),
        common.CommitInfo(sha1=self.BAD_COMMIT_SHA1, title='bad',
                          timestamp=self.BAD_COMMIT_TIMESTAMP)]
    # This mock is problematic. The side effect should modify "self" when
    # the member method is called.
    def UpdateCurrentCommitSideEffect():
      self.bisector.current_commit = commit_info_list.pop(0)
    self.PatchObject(
        git_bisector.GitBisector, 'UpdateCurrentCommit',
        side_effect=UpdateCurrentCommitSideEffect)

    self.PatchObject(
        evaluator_module.Evaluator, 'CheckLastEvaluate',
        side_effect=[self.GOOD_COMMIT_SCORE, self.BAD_COMMIT_SCORE])

  def testGetCommitTimestamp(self):
    """Tests GetCommitTimeStamp by mocking git.RunGit."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))

    # Mock git result for GetCommitTimestamp.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.GOOD_COMMIT_SHA1]),
        output=str(self.GOOD_COMMIT_TIMESTAMP))

    self.assertEqual(self.GOOD_COMMIT_TIMESTAMP,
                     self.bisector.GetCommitTimestamp(self.GOOD_COMMIT_SHA1))

  def testGetCommitTimestampNotFound(self):
    """Tests GetCommitTimeStamp when the commit is not found."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    nonexist_sha1 = '12345'
    # Mock git result for GetCommitTimestamp.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', nonexist_sha1]),
        output='commit does not exist')

    self.assertIsNone(self.bisector.GetCommitTimestamp(nonexist_sha1))

  def testSanityCheck(self):
    """Tests SanityCheck().

    It tests by mocking out git commands called by SanityCheck().
    """
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    # Mock git result for DoesCommitExistInRepo.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.GOOD_COMMIT_SHA1]))
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.BAD_COMMIT_SHA1]))

    # Mock git result for GetCommitTimestamp.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.GOOD_COMMIT_SHA1]),
        output=str(self.GOOD_COMMIT_TIMESTAMP))
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.BAD_COMMIT_SHA1]),
        output=str(self.BAD_COMMIT_TIMESTAMP))

    git_mock.AddRunGitResult(['checkout', self.GOOD_COMMIT_SHA1])
    git_mock.AddRunGitResult(['checkout', self.BAD_COMMIT_SHA1])
    self.MockOutBuildDeployEvaluateForSanityCheck()

    good_commit_info, bad_commit_info = self.bisector.SanityCheck()
    self.assertTrue(good_commit_info == self.GOOD_COMMIT_INFO)
    self.assertTrue(bad_commit_info == self.BAD_COMMIT_INFO)

  def testSanityCheckGoodCommitNotExist(self):
    """Tests SanityCheck() that good commit does not exist."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    sync_to_head_mock = self.PatchObject(builder_module.Builder, 'SyncToHead')
    # Mock git result for DoesCommitExistInRepo to return False.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.GOOD_COMMIT_SHA1]))
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.BAD_COMMIT_SHA1]))

    # Mock invalid result for GetCommitTimestamp to return None.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.GOOD_COMMIT_SHA1]),
        output='invalid commit')
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.BAD_COMMIT_SHA1]),
        output='invalid commit')

    good_commit_info, bad_commit_info = self.bisector.SanityCheck()
    self.assertIsNone(good_commit_info)
    self.assertIsNone(bad_commit_info)

    sync_to_head_mock.assert_called()

  def testSanityCheckSyncToHeadWorks(self):
    """Tests SanityCheck() that good and bad commit do not exist.

    As good and bad commit do not exist, it calls SyncToHead().
    """
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    sync_to_head_mock = self.PatchObject(builder_module.Builder, 'SyncToHead')
    # Mock git result for DoesCommitExistInRepo to return False.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.GOOD_COMMIT_SHA1]),
        returncode=128)
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.BAD_COMMIT_SHA1]),
        returncode=128)

    # Mock git result for GetCommitTimestamp.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.GOOD_COMMIT_SHA1]),
        output=str(self.GOOD_COMMIT_TIMESTAMP))
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.BAD_COMMIT_SHA1]),
        output=str(self.BAD_COMMIT_TIMESTAMP))

    git_mock.AddRunGitResult(['checkout', self.GOOD_COMMIT_SHA1])
    git_mock.AddRunGitResult(['checkout', self.BAD_COMMIT_SHA1])
    self.MockOutBuildDeployEvaluateForSanityCheck()

    good_commit_info, bad_commit_info = self.bisector.SanityCheck()
    self.assertTrue(good_commit_info == self.GOOD_COMMIT_INFO)
    self.assertTrue(bad_commit_info == self.BAD_COMMIT_INFO)

    # After SyncToHead, found both bad and good commit.
    sync_to_head_mock.assert_called()

  def testSanityCheckWrongTimeOrder(self):
    """Tests SanityCheck() that good and bad commit have wrong time order."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    # Mock git result for DoesCommitExistInRepo.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.GOOD_COMMIT_SHA1]))
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['rev-list', self.BAD_COMMIT_SHA1]))

    # Mock git result for GetCommitTimestamp, but swap timestamp.
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.GOOD_COMMIT_SHA1]),
        output=str(self.BAD_COMMIT_TIMESTAMP))
    git_mock.AddRunGitResult(
        partial_mock.InOrder(['show', self.BAD_COMMIT_SHA1]),
        output=str(self.GOOD_COMMIT_TIMESTAMP))

    good_commit_info, bad_commit_info = self.bisector.SanityCheck()
    self.assertIsNone(good_commit_info)
    self.assertIsNone(bad_commit_info)

  def testGetThresholdFromUser(self):
    """Tests GetThresholdFromUser()."""
    self.bisector.good_score = self.GOOD_COMMIT_SCORE
    self.bisector.bad_score = self.BAD_COMMIT_SCORE

    input_mock = self.PatchObject(cros_build_lib, 'GetInput')
    input_mock.return_value = self.THRESHOLD_SPLITTER
    self.assertTrue(self.bisector.GetThresholdFromUser())
    self.assertEqual(self.THRESHOLD, self.bisector.threshold)

  def testGetThresholdFromUserOutOfBoundFail(self):
    """Tests GetThresholdFromUser() with out-of-bound input."""
    self.bisector.good_score = self.GOOD_COMMIT_SCORE
    self.bisector.bad_score = self.BAD_COMMIT_SCORE

    input_mock = self.PatchObject(cros_build_lib, 'GetInput')
    input_mock.side_effect = ['0', '1000', '-10']
    self.assertFalse(self.bisector.GetThresholdFromUser())
    self.assertIsNone(self.bisector.threshold)
    self.assertEqual(3, input_mock.call_count)

  def testGetThresholdFromUserRetrySuccess(self):
    """Tests GetThresholdFromUser() with retry."""
    self.bisector.good_score = self.GOOD_COMMIT_SCORE
    self.bisector.bad_score = self.BAD_COMMIT_SCORE

    input_mock = self.PatchObject(cros_build_lib, 'GetInput')
    input_mock.side_effect = ['not_a_number', '1000', self.THRESHOLD_SPLITTER]
    self.assertTrue(self.bisector.GetThresholdFromUser())
    self.assertEqual(self.THRESHOLD, self.bisector.threshold)
    self.assertEqual(3, input_mock.call_count)

  def PatchObjectForBuildDeployEval(self):
    """Returns list of patch objects.

    The patch objects are to mock:
      git_bisector.UpdateCurrentCommit()
      evaluator.CheckLastEvaluate()
      builder.Build()
      builder.Deploy()
      evaluator.Evaluate()
    """
    return [
        self.PatchObject(git_bisector.GitBisector, 'UpdateCurrentCommit'),
        self.PatchObject(evaluator_module.Evaluator, 'CheckLastEvaluate'),
        self.PatchObject(builder_module.Builder, 'Build'),
        self.PatchObject(builder_module.Builder, 'Deploy'),
        self.PatchObject(evaluator_module.Evaluator, 'Evaluate')]

  def testBuildDeployEvalShortcutCheckLastEvaluate(self):
    """Tests BuildDeployEval() with CheckLastEvaluate() found last score."""
    mocks = self.PatchObjectForBuildDeployEval()
    mocks[1].return_value = self.GOOD_COMMIT_SCORE

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = common.CommitInfo(
        sha1=self.GOOD_COMMIT_SHA1, timestamp=self.GOOD_COMMIT_TIMESTAMP,
        title='good')

    score = self.bisector.BuildDeployEval()
    self.assertEqual(self.GOOD_COMMIT_SCORE, score)
    self.assertEqual(self.GOOD_COMMIT_SCORE, self.bisector.current_commit.score)
    for m in mocks[:2]:
      getattr(m, 'assert_called')()
    mocks[1].assert_called_with(self.GOOD_COMMIT_SHA1, self.REPEAT)

    for m in mocks[2:]:
      getattr(m, 'assert_not_called')()

  def testBuildDeployEvalNoCheckLastEvaluate(self):
    """Tests BuildDeployEval() without last score."""
    mocks = self.PatchObjectForBuildDeployEval()
    mocks[1].return_value = common.Score()
    mocks[4].return_value = self.GOOD_COMMIT_SCORE

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = common.CommitInfo(
        sha1=self.GOOD_COMMIT_SHA1, timestamp=self.GOOD_COMMIT_TIMESTAMP,
        title='good')

    score = self.bisector.BuildDeployEval()
    self.assertEqual(self.GOOD_COMMIT_SCORE, score)
    self.assertEqual(self.GOOD_COMMIT_SCORE, self.bisector.current_commit.score)
    for m in mocks:
      getattr(m, 'assert_called')()
    mocks[1].assert_called_with(self.GOOD_COMMIT_SHA1, self.REPEAT)
    mocks[2].assert_called_with(self.GOOD_COMMIT_SHA1)
    mocks[3].assert_called_with(self.DUT, mock.ANY, self.GOOD_COMMIT_SHA1)
    mocks[4].assert_called_with(self.DUT, self.GOOD_COMMIT_SHA1, self.REPEAT)

  def testBuildDeployEvalRaiseNoScore(self):
    """Tests BuildDeployEval() when Evaluate() failed to obtain score."""
    mocks = self.PatchObjectForBuildDeployEval()
    mocks[1].return_value = common.Score()

    # Evaluate() failed to obtain score.
    mocks[4].return_value = common.Score()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = common.CommitInfo(
        sha1=self.GOOD_COMMIT_SHA1, timestamp=self.GOOD_COMMIT_TIMESTAMP,
        title='good')

    self.assertRaises(Exception, self.bisector.BuildDeployEval)
    self.assertFalse(self.bisector.current_commit.score)
    for m in mocks:
      getattr(m, 'assert_called')()
    mocks[1].assert_called_with(self.GOOD_COMMIT_SHA1, self.REPEAT)
    mocks[2].assert_called_with(self.GOOD_COMMIT_SHA1)
    mocks[3].assert_called_with(self.DUT, mock.ANY, self.GOOD_COMMIT_SHA1)
    mocks[4].assert_called_with(self.DUT, self.GOOD_COMMIT_SHA1, self.REPEAT)

  def testBuildDeployEvalSuppressRaiseNoScore(self):
    """Tests BuildDeployEval() with raise_on_error unset."""
    mocks = self.PatchObjectForBuildDeployEval()
    mocks[1].return_value = common.Score()

    # Evaluate() failed to obtain score.
    mocks[4].return_value = common.Score()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = common.CommitInfo(
        sha1=self.GOOD_COMMIT_SHA1, timestamp=self.GOOD_COMMIT_TIMESTAMP,
        title='good')

    score = self.bisector.BuildDeployEval(raise_on_error=False)
    self.assertFalse(score)
    self.assertFalse(self.bisector.current_commit.score)
    for m in mocks:
      getattr(m, 'assert_called')()
    mocks[1].assert_called_with(self.GOOD_COMMIT_SHA1, self.REPEAT)
    mocks[2].assert_called_with(self.GOOD_COMMIT_SHA1)
    mocks[3].assert_called_with(self.DUT, mock.ANY, self.GOOD_COMMIT_SHA1)
    mocks[4].assert_called_with(self.DUT, self.GOOD_COMMIT_SHA1, self.REPEAT)

  def testLabelBuild(self):
    """Tests LabelBuild()."""
    # Inject good(100), bad(80) score and threshold.
    self.bisector.good_score = self.GOOD_COMMIT_SCORE
    self.bisector.bad_score = self.BAD_COMMIT_SCORE
    self.bisector.threshold = self.THRESHOLD
    good = 'good'
    bad = 'bad'

    # Worse than given bad score.
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score([70])))

    # Better than bad score, but not good enough.
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score([85])))
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score([90])))

    # On the margin.
    self.assertEqual(good, self.bisector.LabelBuild(common.Score([95])))

    # Better than the margin.
    self.assertEqual(good, self.bisector.LabelBuild(common.Score([98])))

    # Better than given good score.
    self.assertEqual(good, self.bisector.LabelBuild(common.Score([110])))

    # No score, default bad.
    self.assertEqual(bad, self.bisector.LabelBuild(None))
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score()))


  def testLabelBuildLowerIsBetter(self):
    """Tests LabelBuild() in lower-is-better condition."""
    # Reverse good(80) and bad(100) score (lower is better), same threshold.
    self.bisector.good_score = self.BAD_COMMIT_SCORE
    self.bisector.bad_score = self.GOOD_COMMIT_SCORE
    self.bisector.threshold = self.THRESHOLD
    good = 'good'
    bad = 'bad'

    # Better than given good score.
    self.assertEqual(good, self.bisector.LabelBuild(common.Score([70])))

    # Worse than good score, but still better than  margin.
    self.assertEqual(good, self.bisector.LabelBuild(common.Score([80])))
    self.assertEqual(good, self.bisector.LabelBuild(common.Score([82])))

    # On the margin.
    self.assertEqual(good, self.bisector.LabelBuild(common.Score([85])))

    # Worse than the margin.
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score([88])))
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score([90])))
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score([95])))

    # Worse than given bad score.
    self.assertEqual(bad, self.bisector.LabelBuild(common.Score([110])))

  def testGitBisect(self):
    """Tests GitBisect()."""
    git_mock = self.PatchObject(git_bisector.GitBisector, 'Git')
    git_mock.return_value = cros_build_lib.CommandResult(
        cmd=['git', 'bisect', 'reset'], output='We are not bisecting.',
        returncode=0)

    result, done = self.bisector.GitBisect(['reset'])
    git_mock.assert_called_with(['bisect', 'reset'])
    self.assertFalse(done)
    self.assertEqual('We are not bisecting.', result.output)
    self.assertListEqual(['git', 'bisect', 'reset'], result.cmd)

  def testGitBisectDone(self):
    """Tests GitBisect() when culprit is found."""
    git_mock = self.PatchObject(git_bisector.GitBisector, 'Git')
    git_mock.return_value = cros_build_lib.CommandResult(
        cmd=['git', 'bisect', 'bad'],
        output='abcedf is the first bad commit\ncommit abcdef',
        returncode=0)

    result, done = self.bisector.GitBisect(['bad'])
    git_mock.assert_called_with(['bisect', 'bad'])
    self.assertTrue(done)
    self.assertListEqual(['git', 'bisect', 'bad'], result.cmd)

  def testRun(self):
    """Tests Run()."""
    bisector_mock = self.StartPatcher(GitBisectorMock())
    bisector_mock.sanity_check_result = (self.GOOD_COMMIT_INFO,
                                         self.BAD_COMMIT_INFO)
    bisector_mock.threshold = self.THRESHOLD
    bisector_mock.git_bisect_args_result = [
        (['reset'], (None, False)),
        (['start'], (None, False)),
        (['bad', self.BAD_COMMIT_SHA1], (None, False)),
        (['good', self.GOOD_COMMIT_SHA1], (None, False)),
        (['bad'],
         (cros_build_lib.CommandResult(
             cmd=['git', 'bisect', 'bad'],
             output='%s is the first bad commit\ncommit %s' % (
                 self.CULPRIT_COMMIT_SHA1, self.CULPRIT_COMMIT_SHA1),
             returncode=0),
          True)),         # bisect bad (assume it found the first bad commit).
        (['log'], (None, False)),
        (['reset'], (None, False))]
    bisector_mock.build_deploy_eval_current_commit = [self.CULPRIT_COMMIT_INFO]
    bisector_mock.build_deploy_eval_result = [self.CULPRIT_COMMIT_SCORE]
    bisector_mock.label_build_result = ['bad']

    run_result = self.bisector.Run()

    self.assertTrue(bisector_mock.patched['SanityCheck'].called)
    self.assertTrue(bisector_mock.patched['GetThresholdFromUser'].called)
    self.assertEqual(7, bisector_mock.patched['GitBisect'].call_count)
    self.assertTrue(bisector_mock.patched['BuildDeployEval'].called)
    self.assertTrue(bisector_mock.patched['LabelBuild'].called)
    self.assertEqual(self.CULPRIT_COMMIT_SHA1, run_result)


class GitBisectorMock(partial_mock.PartialMock):
  """Partial mock GitBisector to test GitBisector.Run()."""

  TARGET = 'chromite.cros_bisect.git_bisector.GitBisector'
  ATTRS = ('SanityCheck', 'GetThresholdFromUser', 'GitBisect',
           'BuildDeployEval', 'LabelBuild')

  def __init__(self):
    super(GitBisectorMock, self).__init__()
    self.sanity_check_result = (None, None)
    self.threshold = None
    self.git_bisect_args_result = []
    self.build_deploy_eval_current_commit = []
    self.build_deploy_eval_result = []
    self.label_build_result = None

  def SanityCheck(self, _):
    return self.sanity_check_result

  def GetThresholdFromUser(self, this):
    this.threshold = self.threshold
    return True

  def GitBisect(self, _, bisect_op):
    (expected_op, result) = self.git_bisect_args_result.pop(0)
    assert cmp(expected_op, bisect_op) == 0
    return result

  def BuildDeployEval(self, this):
    this.current_commit = self.build_deploy_eval_current_commit.pop(0)
    return self.build_deploy_eval_result.pop(0)

  def LabelBuild(self, _, unused_score):
    return self.label_build_result.pop(0)
