# -*- coding: utf-8 -*-
# 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 copy
import os

import mock

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
from chromite.lib import cros_logging as logging

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

  Examples:
    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."""
    try:
      return self._results['RunGit'].LookupResult(args, kwargs=kwargs)
    except cros_build_lib.RunCommandError as e:
      # Copy the logic of error_code_ok from run.
      if kwargs.get('error_code_ok'):
        return e.result
      raise e

  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 = cros_build_lib.CommandResult(
        returncode=returncode, output=output, error=error)
    if returncode != 0 and not side_effect:
      side_effect = cros_build_lib.RunCommandError('non-zero returncode',
                                                   result)
    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)

  # Be aware that GOOD_COMMIT_INFO and BAD_COMMIT_INFO should be assigned via
  # copy.deepcopy() as their users are likely to change the content.
  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, auto_threshold=False, reuse_eval=False,
        eval_raise_on_error=False, skip_failed_commit=False)

    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 setDefaultCommitInfo(self):
    """Sets up default commit info."""
    self.bisector.good_commit_info = copy.deepcopy(self.GOOD_COMMIT_INFO)
    self.bisector.bad_commit_info = copy.deepcopy(self.BAD_COMMIT_INFO)

  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_commit_info)
    self.assertIsNone(self.bisector.bad_commit_info)
    self.assertEqual(0, len(self.bisector.bisect_log))
    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 testCheckCommitFormat(self):
    """Tests CheckCommitFormat()."""
    sha1 = '900d900d'
    self.assertEqual(sha1, git_bisector.GitBisector.CheckCommitFormat(sha1))
    not_sha1 = 'bad_sha1'
    self.assertIsNone(git_bisector.GitBisector.CheckCommitFormat(not_sha1))

  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=128)
    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))

    self.assertTrue(self.bisector.SanityCheck())

  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]),
        returncode=128)

    # 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')

    self.assertFalse(self.bisector.SanityCheck())

    # SyncToHead() called because DoesCommitExistInRepo() returns False for
    # good commit.
    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)

    # 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))

    self.assertTrue(self.bisector.SanityCheck())

    # 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))

    self.assertFalse(self.bisector.SanityCheck())

  def testObtainBisectBoundaryScoreImpl(self):
    """Tests ObtainBisectBoundaryScoreImpl()."""
    git_mock = self.StartPatcher(GitMock(self.repo_dir))
    git_mock.AddRunGitResult(['checkout', self.GOOD_COMMIT_SHA1])
    git_mock.AddRunGitResult(['checkout', self.BAD_COMMIT_SHA1])

    build_deploy_eval_mock = self.PatchObject(
        git_bisector.GitBisector, 'BuildDeployEval',
        side_effect=[self.GOOD_COMMIT_SCORE, self.BAD_COMMIT_SCORE])

    self.assertEqual(self.GOOD_COMMIT_SCORE,
                     self.bisector.ObtainBisectBoundaryScoreImpl(True))
    self.assertEqual(self.BAD_COMMIT_SCORE,
                     self.bisector.ObtainBisectBoundaryScoreImpl(False))

    self.assertEqual(
        [mock.call(self.repo_dir, ['checkout', self.GOOD_COMMIT_SHA1],
                   error_code_ok=True),
         mock.call(self.repo_dir, ['checkout', self.BAD_COMMIT_SHA1],
                   error_code_ok=True)],
        git_mock.call_args_list)
    build_deploy_eval_mock.assert_called()

  def testObtainBisectBoundaryScore(self):
    """Tests ObtainBisectBoundaryScore(). Normal case."""

    def MockedObtainBisectBoundaryScoreImpl(good_side):
      if good_side:
        self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)
      else:
        self.bisector.current_commit = copy.deepcopy(self.BAD_COMMIT_INFO)
      return self.bisector.current_commit.score

    obtain_score_mock = self.PatchObject(
        git_bisector.GitBisector, 'ObtainBisectBoundaryScoreImpl',
        side_effect=MockedObtainBisectBoundaryScoreImpl)

    self.assertTrue(self.bisector.ObtainBisectBoundaryScore())
    self.assertEqual(self.GOOD_COMMIT_SCORE,
                     self.bisector.good_commit_info.score)
    self.assertEqual('last-known-good  ', self.bisector.good_commit_info.label)
    self.assertEqual(self.BAD_COMMIT_SCORE, self.bisector.bad_commit_info.score)
    self.assertEqual('last-known-bad   ', self.bisector.bad_commit_info.label)
    obtain_score_mock.assert_called()

  def testObtainBisectBoundaryScoreBadScoreUnavailable(self):
    """Tests ObtainBisectBoundaryScore(). Bad score unavailable."""

    def UpdateCurrentCommitSideEffect(good_side):
      if good_side:
        self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)
      else:
        self.bisector.current_commit = copy.deepcopy(self.BAD_COMMIT_INFO)
        self.bisector.current_commit.score = None
      return self.bisector.current_commit.score

    obtain_score_mock = self.PatchObject(
        git_bisector.GitBisector, 'ObtainBisectBoundaryScoreImpl',
        side_effect=UpdateCurrentCommitSideEffect)

    self.assertFalse(self.bisector.ObtainBisectBoundaryScore())
    self.assertEqual(self.GOOD_COMMIT_SCORE,
                     self.bisector.good_commit_info.score)
    self.assertEqual('last-known-good  ', self.bisector.good_commit_info.label)
    self.assertIsNone(self.bisector.bad_commit_info.score)
    self.assertEqual('last-known-bad   ', self.bisector.bad_commit_info.label)
    obtain_score_mock.assert_called()

  def testGetThresholdFromUser(self):
    """Tests GetThresholdFromUser()."""
    logging.notice('testGetThresholdFromUser')
    self.setDefaultCommitInfo()
    input_mock = self.PatchObject(cros_build_lib, 'GetInput',
                                  return_value=self.THRESHOLD_SPLITTER)
    self.assertTrue(self.bisector.GetThresholdFromUser())
    self.assertEqual(self.THRESHOLD, self.bisector.threshold)
    input_mock.assert_called()

  def testGetThresholdFromUserAutoPick(self):
    """Tests GetThresholdFromUser()."""
    self.setDefaultCommitInfo()
    self.bisector.auto_threshold = True

    self.assertTrue(self.bisector.GetThresholdFromUser())
    self.assertEqual(10, self.bisector.threshold)

  def testGetThresholdFromUserOutOfBoundFail(self):
    """Tests GetThresholdFromUser() with out-of-bound input."""
    self.setDefaultCommitInfo()
    input_mock = self.PatchObject(cros_build_lib, 'GetInput',
                                  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.setDefaultCommitInfo()
    input_mock = self.PatchObject(
        cros_build_lib, 'GetInput',
        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 testBuildDeploy(self):
    """Tests BuildDeploy()."""
    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    build_to_deploy = '/build/to/deploy'
    build_mock = self.PatchObject(builder_module.Builder, 'Build',
                                  return_value=build_to_deploy)
    deploy_mock = self.PatchObject(builder_module.Builder, 'Deploy')

    self.assertTrue(self.bisector.BuildDeploy())

    build_label = self.GOOD_COMMIT_INFO.sha1
    build_mock.assert_called_with(build_label)
    deploy_mock.assert_called_with(self.DUT, build_to_deploy, build_label)

  def testBuildDeployBuildFail(self):
    """Tests BuildDeploy() with Build() failure."""
    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    # Build() failed.
    build_mock = self.PatchObject(builder_module.Builder, 'Build',
                                  return_value=None)
    deploy_mock = self.PatchObject(builder_module.Builder, 'Deploy')

    self.assertFalse(self.bisector.BuildDeploy())
    build_mock.assert_called()
    deploy_mock.assert_not_called()

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

    The patch objects are to mock:
      git_bisector.UpdateCurrentCommit()
      evaluator.CheckLastEvaluate()
      git_bisector.BuildDeploy()
      evaluator.Evaluate()
    """
    return {
        'UpdateCurrentCommit': self.PatchObject(git_bisector.GitBisector,
                                                'UpdateCurrentCommit'),
        'CheckLastEvaluate': self.PatchObject(evaluator_module.Evaluator,
                                              'CheckLastEvaluate'),
        'BuildDeploy': self.PatchObject(git_bisector.GitBisector, 'BuildDeploy',
                                        return_value=True),
        'Evaluate': self.PatchObject(evaluator_module.Evaluator, 'Evaluate')}

  def testBuildDeployEvalShortcutCheckLastEvaluate(self):
    """Tests BuildDeployEval() with CheckLastEvaluate() found last score."""
    mocks = self.PatchObjectForBuildDeployEval()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    mocks['CheckLastEvaluate'].return_value = self.GOOD_COMMIT_SCORE

    score = self.bisector.BuildDeployEval()
    self.assertEqual(self.GOOD_COMMIT_SCORE, score)
    self.assertEqual(self.GOOD_COMMIT_SCORE, self.bisector.current_commit.score)
    for method_called in ['UpdateCurrentCommit', 'CheckLastEvaluate']:
      mocks[method_called].assert_called()
    mocks['CheckLastEvaluate'].assert_called_with(self.GOOD_COMMIT_SHA1,
                                                  self.REPEAT)

    for method_called in ['BuildDeploy', 'Evaluate']:
      mocks[method_called].assert_not_called()

  def AssertBuildDeployEvalMocksAllCalled(self, mocks):
    for method_called in ['UpdateCurrentCommit', 'CheckLastEvaluate',
                          'BuildDeploy', 'Evaluate']:
      mocks[method_called].assert_called()
    mocks['CheckLastEvaluate'].assert_called_with(self.GOOD_COMMIT_SHA1,
                                                  self.REPEAT)
    mocks['Evaluate'].assert_called_with(self.DUT, self.GOOD_COMMIT_SHA1,
                                         self.REPEAT)

  def testBuildDeployEvalNoCheckLastEvaluate(self):
    """Tests BuildDeployEval() without last score."""
    mocks = self.PatchObjectForBuildDeployEval()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    mocks['CheckLastEvaluate'].return_value = common.Score()
    mocks['Evaluate'].return_value = self.GOOD_COMMIT_SCORE

    self.assertEqual(self.GOOD_COMMIT_SCORE, self.bisector.BuildDeployEval())
    self.assertEqual(self.GOOD_COMMIT_SCORE, self.bisector.current_commit.score)
    self.AssertBuildDeployEvalMocksAllCalled(mocks)

  def testBuildDeployEvalBuildFail(self):
    """Tests BuildDeployEval() with BuildDeploy failure."""
    mocks = self.PatchObjectForBuildDeployEval()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    mocks['CheckLastEvaluate'].return_value = common.Score()
    mocks['BuildDeploy'].return_value = False

    score = self.bisector.BuildDeployEval()
    self.assertFalse(score)
    self.assertFalse(self.bisector.current_commit.score)

    for method_called in ['UpdateCurrentCommit', 'CheckLastEvaluate',
                          'BuildDeploy']:
      mocks[method_called].assert_called()
    mocks['CheckLastEvaluate'].assert_called_with(self.GOOD_COMMIT_SHA1,
                                                  self.REPEAT)

    mocks['Evaluate'].assert_not_called()

  def testBuildDeployEvalNoCheckLastEvaluateSpecifyEvalLabel(self):
    """Tests BuildDeployEval() with eval_label specified."""
    mocks = self.PatchObjectForBuildDeployEval()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    mocks['CheckLastEvaluate'].return_value = common.Score()
    mocks['Evaluate'].return_value = self.GOOD_COMMIT_SCORE

    eval_label = 'customized_label'
    self.assertEqual(self.GOOD_COMMIT_SCORE,
                     self.bisector.BuildDeployEval(eval_label=eval_label))
    self.assertEqual(self.GOOD_COMMIT_SCORE, self.bisector.current_commit.score)

    for method_called in ['UpdateCurrentCommit', 'CheckLastEvaluate',
                          'BuildDeploy', 'Evaluate']:
      mocks[method_called].assert_called()
    # Use given label instead of SHA1 as eval label.
    mocks['CheckLastEvaluate'].assert_called_with(eval_label, self.REPEAT)
    mocks['Evaluate'].assert_called_with(self.DUT, eval_label, self.REPEAT)

  @staticmethod
  def _DummyMethod():
    """A dummy method for test to call and mock."""
    pass

  def testBuildDeployEvalNoCheckLastEvaluateSpecifyBuildDeploy(self):
    """Tests BuildDeployEval() with customize_build_deploy specified."""
    mocks = self.PatchObjectForBuildDeployEval()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    mocks['CheckLastEvaluate'].return_value = common.Score()
    mocks['Evaluate'].return_value = self.GOOD_COMMIT_SCORE

    dummy_method = self.PatchObject(
        TestGitBisector, '_DummyMethod', return_value=True)

    eval_label = 'customized_label'
    self.assertEqual(self.GOOD_COMMIT_SCORE,
                     self.bisector.BuildDeployEval(
                         eval_label=eval_label,
                         customize_build_deploy=TestGitBisector._DummyMethod))
    self.assertEqual(self.GOOD_COMMIT_SCORE, self.bisector.current_commit.score)

    for method_called in ['UpdateCurrentCommit', 'CheckLastEvaluate',
                          'Evaluate']:
      mocks[method_called].assert_called()
    mocks['BuildDeploy'].assert_not_called()
    dummy_method.assert_called()
    # Use given label instead of SHA1 as eval label.
    mocks['CheckLastEvaluate'].assert_called_with(eval_label, self.REPEAT)
    mocks['Evaluate'].assert_called_with(self.DUT, eval_label, self.REPEAT)

  def testBuildDeployEvalRaiseNoScore(self):
    """Tests BuildDeployEval() without score with eval_raise_on_error set."""
    self.options.eval_raise_on_error = True
    self.bisector = git_bisector.GitBisector(self.options, self.builder,
                                             self.evaluator)

    mocks = self.PatchObjectForBuildDeployEval()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    mocks['CheckLastEvaluate'].return_value = common.Score()
    mocks['Evaluate'].return_value = common.Score()

    self.assertRaises(Exception, self.bisector.BuildDeployEval)
    self.assertFalse(self.bisector.current_commit.score)
    self.AssertBuildDeployEvalMocksAllCalled(mocks)

  def testBuildDeployEvalSuppressRaiseNoScore(self):
    """Tests BuildDeployEval() without score with eval_raise_on_error unset."""
    mocks = self.PatchObjectForBuildDeployEval()

    # Inject this as UpdateCurrentCommit's side effect.
    self.bisector.current_commit = copy.deepcopy(self.GOOD_COMMIT_INFO)

    mocks['CheckLastEvaluate'].return_value = common.Score()
    mocks['Evaluate'].return_value = common.Score()

    self.assertFalse(self.bisector.BuildDeployEval())
    self.assertFalse(self.bisector.current_commit.score)
    self.AssertBuildDeployEvalMocksAllCalled(mocks)

  def testLabelBuild(self):
    """Tests LabelBuild()."""
    # Inject good(100), bad(80) score and threshold.
    self.setDefaultCommitInfo()
    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 testLabelBuildSkipNoScore(self):
    """Tests LabelBuild()."""
    self.options.skip_failed_commit = True
    self.bisector = git_bisector.GitBisector(self.options, self.builder,
                                             self.evaluator)

    # Inject good(100), bad(80) score and threshold.
    self.setDefaultCommitInfo()
    self.bisector.threshold = self.THRESHOLD

    # No score, skip.
    self.assertEqual('skip', self.bisector.LabelBuild(None))
    self.assertEqual('skip', 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_commit_info = copy.deepcopy(self.BAD_COMMIT_INFO)
    self.bisector.bad_commit_info = copy.deepcopy(self.GOOD_COMMIT_INFO)
    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',
        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',
        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.good_commit_info = copy.deepcopy(self.GOOD_COMMIT_INFO)
    bisector_mock.bad_commit_info = copy.deepcopy(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['PrepareBisect'].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 = ('PrepareBisect', 'GitBisect', 'BuildDeployEval', 'LabelBuild')

  def __init__(self):
    super(GitBisectorMock, self).__init__()
    self.good_commit_info = None
    self.bad_commit_info = 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 PrepareBisect(self, this):
    this.good_commit_info = self.good_commit_info
    this.bad_commit_info = self.bad_commit_info
    this.threshold = self.threshold
    return True

  def GitBisect(self, _, bisect_op):
    (expected_op, result) = self.git_bisect_args_result.pop(0)
    assert expected_op == bisect_op
    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)
