# -*- 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 check from run.
      if not kwargs.get('check', True):
        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 = str(cm.exception)
    self.assertIn('Missing command line', exception_message)
    self.assertIn('GitBisector', exception_message)
    for arg in git_bisector.GitBisector.REQUIRED_ARGS:
      self.assertIn(arg, 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],
                   check=False),
         mock.call(self.repo_dir, ['checkout', self.BAD_COMMIT_SHA1],
                   check=False)],
        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."""

  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)
