# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import json
import os
import re
import shutil
import sys
import urlparse
import unittest

SRC = os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir)
sys.path.append(os.path.join(SRC, 'third_party', 'pymock'))

import bisect_perf_regression
import bisect_results
import bisect_state
import bisect_utils
import fetch_build
import mock
import source_control


# Regression confidence: 0%
CLEAR_NON_REGRESSION = [
    # Mean: 30.223 Std. Dev.: 11.383
    [[16.886], [16.909], [16.99], [17.723], [17.952], [18.118], [19.028],
     [19.552], [21.954], [38.573], [38.839], [38.965], [40.007], [40.572],
     [41.491], [42.002], [42.33], [43.109], [43.238]],
    # Mean: 34.76 Std. Dev.: 11.516
    [[16.426], [17.347], [20.593], [21.177], [22.791], [27.843], [28.383],
     [28.46], [29.143], [40.058], [40.303], [40.558], [41.918], [42.44],
     [45.223], [46.494], [50.002], [50.625], [50.839]]
]

# Regression confidence: ~ 90%
ALMOST_REGRESSION = [
    # Mean: 30.042 Std. Dev.: 2.002
    [[26.146], [28.04], [28.053], [28.074], [28.168], [28.209], [28.471],
     [28.652], [28.664], [30.862], [30.973], [31.002], [31.897], [31.929],
     [31.99], [32.214], [32.323], [32.452], [32.696]],
    # Mean: 33.008 Std. Dev.: 4.265
    [[34.963], [30.741], [39.677], [39.512], [34.314], [31.39], [34.361],
     [25.2], [30.489], [29.434]]
]

# Regression confidence: ~ 98%
BARELY_REGRESSION = [
    # Mean: 28.828 Std. Dev.: 1.993
    [[26.96], [27.605], [27.768], [27.829], [28.006], [28.206], [28.393],
     [28.911], [28.933], [30.38], [30.462], [30.808], [31.74], [31.805],
     [31.899], [32.077], [32.454], [32.597], [33.155]],
    # Mean: 31.156 Std. Dev.: 1.980
    [[28.729], [29.112], [29.258], [29.454], [29.789], [30.036], [30.098],
     [30.174], [30.534], [32.285], [32.295], [32.552], [32.572], [32.967],
     [33.165], [33.403], [33.588], [33.744], [34.147], [35.84]]
]

# Regression confidence: 99.5%
CLEAR_REGRESSION = [
    # Mean: 30.254 Std. Dev.: 2.987
    [[26.494], [26.621], [26.701], [26.997], [26.997], [27.05], [27.37],
     [27.488], [27.556], [31.846], [32.192], [32.21], [32.586], [32.596],
     [32.618], [32.95], [32.979], [33.421], [33.457], [34.97]],
    # Mean: 33.190 Std. Dev.: 2.972
    [[29.547], [29.713], [29.835], [30.132], [30.132], [30.33], [30.406],
     [30.592], [30.72], [34.486], [35.247], [35.253], [35.335], [35.378],
     [35.934], [36.233], [36.41], [36.947], [37.982]]
]

# Regression confidence > 95%, taken from: crbug.com/434318
# Specifically from Builder android_nexus10_perf_bisect Build #1198
MULTIPLE_VALUES = [
    [
        [18.916, 22.371, 8.527, 5.877, 5.407, 9.476, 8.100, 5.334,
         4.507, 4.842, 8.485, 8.308, 27.490, 4.560, 4.804, 23.068, 17.577,
         17.346, 26.738, 60.330, 32.307, 5.468, 27.803, 27.373, 17.823,
         5.158, 27.439, 5.236, 11.413],
        [18.999, 22.642, 8.158, 5.995, 5.495, 9.499, 8.092, 5.324,
         4.468, 4.788, 8.248, 7.853, 27.533, 4.410, 4.622, 22.341, 22.313,
         17.072, 26.731, 57.513, 33.001, 5.500, 28.297, 27.277, 26.462,
         5.009, 27.361, 5.130, 10.955]
    ],
    [
        [18.238, 22.365, 8.555, 5.939, 5.437, 9.463, 7.047, 5.345, 4.517,
         4.796, 8.593, 7.901, 27.499, 4.378, 5.040, 4.904, 4.816, 4.828,
         4.853, 57.363, 34.184, 5.482, 28.190, 27.290, 26.694, 5.099,
         4.905, 5.290, 4.813],
        [18.301, 22.522, 8.035, 6.021, 5.565, 9.037, 6.998, 5.321, 4.485,
         4.768, 8.397, 7.865, 27.636, 4.640, 5.015, 4.962, 4.933, 4.977,
         4.961, 60.648, 34.593, 5.538, 28.454, 27.297, 26.490, 5.099, 5,
         5.247, 4.945],
        [18.907, 23.368, 8.100, 6.169, 5.621, 9.971, 8.161, 5.331, 4.513,
         4.837, 8.255, 7.852, 26.209, 4.388, 5.045, 5.029, 5.032, 4.946,
         4.973, 60.334, 33.377, 5.499, 28.275, 27.550, 26.103, 5.108,
         4.951, 5.285, 4.910],
        [18.715, 23.748, 8.128, 6.148, 5.691, 9.361, 8.106, 5.334, 4.528,
         4.965, 8.261, 7.851, 27.282, 4.391, 4.949, 4.981, 4.964, 4.935,
         4.933, 60.231, 33.361, 5.489, 28.106, 27.457, 26.648, 5.108,
         4.963, 5.272, 4.954]
    ]
]

# Default options for the dry run
DEFAULT_OPTIONS = {
    'debug_ignore_build': True,
    'debug_ignore_sync': True,
    'debug_ignore_perf_test': True,
    'debug_ignore_regression_confidence': True,
    'command': 'fake_command',
    'metric': 'fake/metric',
    'good_revision': 280000,
    'bad_revision': 280005,
}

# This global is a placeholder for a generator to be defined by the test cases
# that use _MockRunTests.
_MockResultsGenerator = (x for x in [])

def _MakeMockRunTests(bisect_mode_is_return_code=False):
  def _MockRunTests(*args, **kwargs):  # pylint: disable=unused-argument
    return _FakeTestResult(
        _MockResultsGenerator.next(), bisect_mode_is_return_code)

  return _MockRunTests


def _FakeTestResult(values, bisect_mode_is_return_code):
  mean = 0.0
  if bisect_mode_is_return_code:
    mean = 0 if (all(v == 0 for v in values)) else 1
  result_dict = {'mean': mean, 'std_err': 0.0, 'std_dev': 0.0, 'values': values}
  success_code = 0
  return (result_dict, success_code)


def _SampleBisecResult(opts):
  revisions = [
      'ae7ef14ba2d9b5ef0d2c1c092ec98a417e44740d'
      'ab55ead638496b061c9de61685b982f7cea38ca7',
      '89aa0c99e4b977b9a4f992ac14da0d6624f7316e']
  state = bisect_state.BisectState(depot='chromium', revisions=revisions)
  depot_registry = bisect_perf_regression.DepotDirectoryRegistry('/mock/src')
  results = bisect_results.BisectResults(
      bisect_state=state, depot_registry=depot_registry, opts=opts,
      runtime_warnings=[])
  results.confidence = 99.9
  results.culprit_revisions = [(
      'ab55ead638496b061c9de61685b982f7cea38ca7',
      {
          'date': 'Thu, 26 Jun 2014 14:29:49 +0000',
          'body': 'Fix',
          'author': 'author@chromium.org',
          'subject': 'Fix',
          'email': 'author@chromium.org',
      },
      'chromium')]
  return results


def _GetMockCallArg(function_mock, call_index):
  """Gets the list of called arguments for call at |call_index|.

  Args:
    function_mock: A Mock object.
    call_index: The index at which the mocked function was called.

  Returns:
    The called argument list.
  """
  call_args_list = function_mock.call_args_list
  if not call_args_list or len(call_args_list) <= call_index:
    return None
  args, _ = call_args_list[call_index]
  return args


def _GetBisectPerformanceMetricsInstance(options_dict):
  """Returns an instance of the BisectPerformanceMetrics class."""
  opts = bisect_perf_regression.BisectOptions.FromDict(options_dict)
  return bisect_perf_regression.BisectPerformanceMetrics(opts, os.getcwd())


def _GetExtendedOptions(improvement_dir, fake_first, ignore_confidence=True,
                        **extra_opts):
  """Returns the a copy of the default options dict plus some options."""
  result = dict(DEFAULT_OPTIONS)
  result.update({
      'improvement_direction': improvement_dir,
      'debug_fake_first_test_mean': fake_first,
      'debug_ignore_regression_confidence': ignore_confidence
  })
  result.update(extra_opts)
  return result


def _GenericDryRun(options, print_results=False):
  """Performs a dry run of the bisector.

  Args:
    options: Dictionary containing the options for the bisect instance.
    print_results: Boolean telling whether to call FormatAndPrintResults.

  Returns:
    The results dictionary as returned by the bisect Run method.
  """
  _AbortIfThereAreStagedChanges()
  # Disable rmtree to avoid deleting local trees.
  old_rmtree = shutil.rmtree
  shutil.rmtree = lambda path, on_error: None
  # git reset HEAD may be run during the dry run, which removes staged changes.
  try:
    bisect_instance = _GetBisectPerformanceMetricsInstance(options)
    results = bisect_instance.Run(
        bisect_instance.opts.command, bisect_instance.opts.bad_revision,
        bisect_instance.opts.good_revision, bisect_instance.opts.metric)

    if print_results:
      bisect_instance.printer.FormatAndPrintResults(results)

    return results
  finally:
    shutil.rmtree = old_rmtree


def _AbortIfThereAreStagedChanges():
  """Exits the test prematurely if there are staged changes."""
  # The output of "git status --short" will be an empty string if there are
  # no staged changes in the current branch. Untracked files are ignored
  # because when running the presubmit on the trybot there are sometimes
  # untracked changes to the run-perf-test.cfg and bisect.cfg files.
  status_output = bisect_utils.CheckRunGit(
      ['status', '--short', '--untracked-files=no'])
  if status_output:
    print 'There are un-committed changes in the current branch.'
    print 'Aborting the tests to avoid destroying local changes. Changes:'
    print status_output
    sys.exit(1)


class BisectPerfRegressionTest(unittest.TestCase):
  """Test case for other functions and classes in bisect-perf-regression.py."""

  def setUp(self):
    self.cwd = os.getcwd()
    os.chdir(os.path.abspath(os.path.join(os.path.dirname(__file__),
                                          os.path.pardir, os.path.pardir)))

  def tearDown(self):
    os.chdir(self.cwd)

  def testBisectOptionsCanPrintHelp(self):
    """Tests that the argument parser can be made and can print help."""
    bisect_options = bisect_perf_regression.BisectOptions()
    parser = bisect_options._CreateCommandLineParser()
    parser.format_help()

  def testParseDEPSStringManually(self):
    """Tests DEPS parsing."""
    deps_file_contents = """
    vars = {
        'ffmpeg_hash':
             '@ac4a9f31fe2610bd146857bbd55d7a260003a888',
        'webkit_url':
             'https://chromium.googlesource.com/chromium/blink.git',
        'git_url':
             'https://chromium.googlesource.com',
        'webkit_rev':
             '@e01ac0a267d1017288bc67fa3c366b10469d8a24',
        'angle_revision':
             '74697cf2064c0a2c0d7e1b1b28db439286766a05'
    }"""

    # Should only expect SVN/git revisions to come through, and URLs should be
    # filtered out.
    expected_vars_dict = {
        'ffmpeg_hash': '@ac4a9f31fe2610bd146857bbd55d7a260003a888',
        'webkit_rev': '@e01ac0a267d1017288bc67fa3c366b10469d8a24',
        'angle_revision': '74697cf2064c0a2c0d7e1b1b28db439286766a05'
    }
    # Testing private function.
    # pylint: disable=W0212
    vars_dict = bisect_perf_regression._ParseRevisionsFromDEPSFileManually(
        deps_file_contents)
    self.assertEqual(vars_dict, expected_vars_dict)

  def _AssertParseResult(self, expected_values, result_string):
    """Asserts some values are parsed from a RESULT line."""
    results_template = ('RESULT other_chart: other_trace= 123 count\n'
                        'RESULT my_chart: my_trace= %(value)s\n')
    results = results_template % {'value': result_string}
    metric = ['my_chart', 'my_trace']
    # Testing private function.
    # pylint: disable=W0212
    values = bisect_perf_regression._TryParseResultValuesFromOutput(
        metric, results)
    self.assertEqual(expected_values, values)

  def testTryParseResultValuesFromOutput_WithSingleValue(self):
    """Tests result pattern <*>RESULT <graph>: <trace>= <value>"""
    self._AssertParseResult([66.88], '66.88 kb')
    self._AssertParseResult([66.88], '66.88 ')
    self._AssertParseResult([-66.88], '-66.88 kb')
    self._AssertParseResult([66], '66 kb')
    self._AssertParseResult([0.66], '.66 kb')
    self._AssertParseResult([], '. kb')
    self._AssertParseResult([], 'aaa kb')

  def testTryParseResultValuesFromOutput_WithMultiValue(self):
    """Tests result pattern <*>RESULT <graph>: <trace>= [<value>,<value>, ..]"""
    self._AssertParseResult([66.88], '[66.88] kb')
    self._AssertParseResult([66.88, 99.44], '[66.88, 99.44]kb')
    self._AssertParseResult([66.88, 99.44], '[ 66.88, 99.44 ]')
    self._AssertParseResult([-66.88, 99.44], '[-66.88, 99.44] kb')
    self._AssertParseResult([-66, 99], '[-66,99] kb')
    self._AssertParseResult([-66, 99], '[-66,99,] kb')
    self._AssertParseResult([-66, 0.99], '[-66,.99] kb')
    self._AssertParseResult([], '[] kb')
    self._AssertParseResult([], '[-66,abc] kb')

  def testTryParseResultValuesFromOutputWithMeanStd(self):
    """Tests result pattern <*>RESULT <graph>: <trace>= {<mean, std}"""
    self._AssertParseResult([33.22], '{33.22, 3.6} kb')
    self._AssertParseResult([33.22], '{33.22, 3.6} kb')
    self._AssertParseResult([33.22], '{33.22,3.6}kb')
    self._AssertParseResult([33.22], '{33.22,3.6} kb')
    self._AssertParseResult([33.22], '{ 33.22,3.6 }kb')
    self._AssertParseResult([-33.22], '{-33.22,3.6}kb')
    self._AssertParseResult([22], '{22,6}kb')
    self._AssertParseResult([.22], '{.22,6}kb')
    self._AssertParseResult([], '{.22,6, 44}kb')
    self._AssertParseResult([], '{}kb')
    self._AssertParseResult([], '{XYZ}kb')

  # This method doesn't reference self; it fails if an error is thrown.
  # pylint: disable=R0201
  def testDryRun(self):
    """Does a dry run of the bisect script.

    This serves as a smoke test to catch errors in the basic execution of the
    script.
    """
    _GenericDryRun(DEFAULT_OPTIONS, True)

  def testBisectImprovementDirectionFails(self):
    """Dry run of a bisect with an improvement instead of regression."""
    # Test result goes from 0 to 100 where higher is better
    results = _GenericDryRun(_GetExtendedOptions(1, 100))
    self.assertIsNotNone(results.error)
    self.assertIn('not a regression', results.error)

    # Test result goes from 0 to -100 where lower is better
    results = _GenericDryRun(_GetExtendedOptions(-1, -100))
    self.assertIsNotNone(results.error)
    self.assertIn('not a regression', results.error)

  def testBisectImprovementDirectionSucceeds(self):
    """Bisects with improvement direction matching regression range."""
    # Test result goes from 0 to 100 where lower is better
    results = _GenericDryRun(_GetExtendedOptions(-1, 100))
    self.assertIsNone(results.error)
    # Test result goes from 0 to -100 where higher is better
    results = _GenericDryRun(_GetExtendedOptions(1, -100))
    self.assertIsNone(results.error)

  @mock.patch('urllib2.urlopen')
  def testBisectResultsPosted(self, mock_urlopen):
    options_dict = dict(DEFAULT_OPTIONS)
    options_dict.update({
        'bisect_mode': bisect_utils.BISECT_MODE_MEAN,
        'try_job_id': 1234,
    })
    opts = bisect_perf_regression.BisectOptions.FromDict(options_dict)
    bisect_instance = _GetBisectPerformanceMetricsInstance(options_dict)
    results = _SampleBisecResult(opts)
    bisect_instance.PostBisectResults(results)

    call_args = _GetMockCallArg(mock_urlopen, 0)
    self.assertIsNotNone(call_args)
    called_data = urlparse.parse_qs(call_args[1])
    results_data = json.loads(called_data['data'][0])
    self.assertEqual(1234, results_data['try_job_id'])

  def _CheckAbortsEarly(self, results, **extra_opts):
    """Returns True if the bisect job would abort early."""
    global _MockResultsGenerator
    _MockResultsGenerator = (r for r in results)
    bisect_class = bisect_perf_regression.BisectPerformanceMetrics
    original_run_tests = bisect_class.RunPerformanceTestAndParseResults
    bisect_class.RunPerformanceTestAndParseResults = _MakeMockRunTests()

    try:
      dry_run_results = _GenericDryRun(_GetExtendedOptions(
          improvement_dir=0, fake_first=0, ignore_confidence=False,
          **extra_opts))
    except StopIteration:
      # If StopIteration was raised, that means that the next value after
      # the first two values was requested, so the job was not aborted.
      return False
    finally:
      bisect_class.RunPerformanceTestAndParseResults = original_run_tests

    # If the job was aborted, there should be a warning about it.
    self.assertTrue(
        any('did not clearly reproduce a regression' in w
            for w in dry_run_results.warnings))
    return True

  def testBisectAbortedOnClearNonRegression(self):
    self.assertTrue(self._CheckAbortsEarly(CLEAR_NON_REGRESSION))

  def testBisectNotAborted_AlmostRegression(self):
    self.assertFalse(self._CheckAbortsEarly(ALMOST_REGRESSION))

  def testBisectNotAborted_ClearRegression(self):
    self.assertFalse(self._CheckAbortsEarly(CLEAR_REGRESSION))

  def testBisectNotAborted_BarelyRegression(self):
    self.assertFalse(self._CheckAbortsEarly(BARELY_REGRESSION))

  def testBisectNotAborted_MultipleValues(self):
    self.assertFalse(self._CheckAbortsEarly(MULTIPLE_VALUES))

  def testBisectNotAbortedWhenRequiredConfidenceIsZero(self):
    self.assertFalse(self._CheckAbortsEarly(
        CLEAR_NON_REGRESSION, required_initial_confidence=0))

  def _CheckAbortsEarlyForReturnCode(self, results):
    """Returns True if the bisect job would abort early in return code mode."""
    global _MockResultsGenerator
    _MockResultsGenerator = (r for r in results)
    bisect_class = bisect_perf_regression.BisectPerformanceMetrics
    original_run_tests = bisect_class.RunPerformanceTestAndParseResults
    bisect_class.RunPerformanceTestAndParseResults = _MakeMockRunTests(True)
    options = dict(DEFAULT_OPTIONS)
    options.update({'bisect_mode': 'return_code'})
    try:
      dry_run_results = _GenericDryRun(options)
    except StopIteration:
      # If StopIteration was raised, that means that the next value after
      # the first two values was requested, so the job was not aborted.
      return False
    finally:
      bisect_class.RunPerformanceTestAndParseResults = original_run_tests

    # If the job was aborted, there should be a warning about it.
    if ('known good and known bad revisions returned same' in
        dry_run_results.abort_reason):
      return True
    return False

  def testBisectAbortOn_SameReturnCode(self):
    self.assertTrue(self._CheckAbortsEarlyForReturnCode([[0,0,0], [0,0,0]]))

  def testBisectNotAbortedOn_DifferentReturnCode(self):
    self.assertFalse(self._CheckAbortsEarlyForReturnCode([[1,1,1], [0,0,0]]))

  def testGetCommitPosition(self):
    cp_git_rev = '7017a81991de983e12ab50dfc071c70e06979531'
    self.assertEqual(291765, source_control.GetCommitPosition(cp_git_rev))

    svn_git_rev = 'e6db23a037cad47299a94b155b95eebd1ee61a58'
    self.assertEqual(291467, source_control.GetCommitPosition(svn_git_rev))

  def testGetCommitPositionForV8(self):
    bisect_instance = _GetBisectPerformanceMetricsInstance(DEFAULT_OPTIONS)
    v8_rev = '818769db41cb3e83979aa16cc76c69b66045e369'
    depot_path = os.path.join(bisect_instance.src_cwd, 'v8')
    self.assertEqual(
        43769, source_control.GetCommitPosition(v8_rev, depot_path))

  def testGetCommitPositionForSkia(self):
    bisect_instance = _GetBisectPerformanceMetricsInstance(DEFAULT_OPTIONS)
    skia_rev = 'a94d028eCheckAbortsEarly0f2c77f159b3dac95eb90c3b4cf48c61'
    depot_path = os.path.join(bisect_instance.src_cwd, 'third_party', 'skia')
    # Skia doesn't use commit positions, and GetCommitPosition should
    # return None for repos that don't use commit positions.
    self.assertIsNone(source_control.GetCommitPosition(skia_rev, depot_path))

  def testUpdateDepsContent(self):
    bisect_instance = _GetBisectPerformanceMetricsInstance(DEFAULT_OPTIONS)
    deps_file = 'DEPS'
    # We are intentionally reading DEPS file contents instead of string literal
    # with few lines from DEPS because to check if the format we are expecting
    # to search is not changed in DEPS content.
    # TODO (prasadv): Add a separate test to validate the DEPS contents with the
    # format that bisect script expects.
    deps_contents = bisect_perf_regression.ReadStringFromFile(deps_file)
    deps_key = 'v8_revision'
    depot = 'v8'
    git_revision = 'a12345789a23456789a123456789a123456789'
    updated_content = bisect_instance.UpdateDepsContents(
        deps_contents, depot, git_revision, deps_key)
    self.assertIsNotNone(updated_content)
    ss = re.compile('["\']%s["\']: ["\']%s["\']' % (deps_key, git_revision))
    self.assertIsNotNone(re.search(ss, updated_content))

  @mock.patch('bisect_utils.RunGClient')
  def testSyncToRevisionForChromium(self, mock_RunGClient):
    bisect_instance = _GetBisectPerformanceMetricsInstance(DEFAULT_OPTIONS)
    mock_RunGClient.return_value = 0
    bisect_instance._SyncRevision(
        'chromium', 'e6db23a037cad47299a94b155b95eebd1ee61a58', 'gclient')
    expected_params = [
        'sync',
        '--verbose',
        '--nohooks',
        '--force',
        '--delete_unversioned_trees',
        '--revision',
        'src@e6db23a037cad47299a94b155b95eebd1ee61a58',
    ]

    mock_RunGClient.assert_called_with(expected_params, cwd=None)

  @mock.patch('bisect_utils.RunGit')
  def testSyncToRevisionForWebKit(self, mock_RunGit):
    bisect_instance = _GetBisectPerformanceMetricsInstance(DEFAULT_OPTIONS)
    mock_RunGit.return_value = None, None
    bisect_instance._SyncRevision(
        'webkit', 'a94d028e0f2c77f159b3dac95eb90c3b4cf48c61', None)
    expected_params = ['checkout', 'a94d028e0f2c77f159b3dac95eb90c3b4cf48c61']
    mock_RunGit.assert_called_with(expected_params)

  def testTryJobSvnRepo_PerfBuilderType_ReturnsRepoUrl(self):
    self.assertEqual(
        bisect_perf_regression.PERF_SVN_REPO_URL,
        bisect_perf_regression._TryJobSvnRepo(fetch_build.PERF_BUILDER))

  def testTryJobSvnRepo_FullBuilderType_ReturnsRepoUrl(self):
    self.assertEqual(
        bisect_perf_regression.FULL_SVN_REPO_URL,
        bisect_perf_regression._TryJobSvnRepo(fetch_build.FULL_BUILDER))

  def testTryJobSvnRepo_WithUnknownBuilderType_ThrowsError(self):
    with self.assertRaises(NotImplementedError):
      bisect_perf_regression._TryJobSvnRepo('foo')

  def _CheckIsDownloadable(self, depot, target_platform='chromium',
                           builder_type='perf'):
    opts = dict(DEFAULT_OPTIONS)
    opts.update({'target_platform': target_platform,
                 'builder_type': builder_type})
    bisect_instance = _GetBisectPerformanceMetricsInstance(opts)
    return bisect_instance.IsDownloadable(depot)

  def testIsDownloadable_ChromiumDepot_ReturnsTrue(self):
    self.assertTrue(self._CheckIsDownloadable(depot='chromium'))

  def testIsDownloadable_DEPSDepot_ReturnsTrue(self):
    self.assertTrue(self._CheckIsDownloadable(depot='v8'))

  def testIsDownloadable_AndroidChromeDepot_ReturnsTrue(self):
    self.assertTrue(self._CheckIsDownloadable(
        depot='android-chrome', target_platform='android-chrome'))

  def testIsDownloadable_AndroidChromeWithDEPSChromium_ReturnsFalse(self):
    self.assertFalse(self._CheckIsDownloadable(
        depot='chromium', target_platform='android-chrome'))

  def testIsDownloadable_AndroidChromeWithDEPSV8_ReturnsFalse(self):
    self.assertFalse(self._CheckIsDownloadable(
        depot='v8', target_platform='android-chrome'))

  def testIsDownloadable_NoBuilderType_ReturnsFalse(self):
    self.assertFalse(
        self._CheckIsDownloadable(depot='chromium', builder_type=''))


class DepotDirectoryRegistryTest(unittest.TestCase):

  def setUp(self):
    self.old_chdir = os.chdir
    os.chdir = self.mockChdir
    self.old_depot_names = bisect_utils.DEPOT_NAMES
    bisect_utils.DEPOT_NAMES = ['mock_depot']
    self.old_depot_deps_name = bisect_utils.DEPOT_DEPS_NAME
    bisect_utils.DEPOT_DEPS_NAME = {'mock_depot': {'src': 'src/foo'}}

    self.registry = bisect_perf_regression.DepotDirectoryRegistry('/mock/src')
    self.cur_dir = None

  def tearDown(self):
    os.chdir = self.old_chdir
    bisect_utils.DEPOT_NAMES = self.old_depot_names
    bisect_utils.DEPOT_DEPS_NAME = self.old_depot_deps_name

  def mockChdir(self, new_dir):
    self.cur_dir = new_dir

  def testReturnsCorrectResultForChrome(self):
    self.assertEqual(self.registry.GetDepotDir('chromium'), '/mock/src')

  def testUsesDepotSpecToInitializeRegistry(self):
    self.assertEqual(self.registry.GetDepotDir('mock_depot'), '/mock/src/foo')

  def testChangedTheDirectory(self):
    self.registry.ChangeToDepotDir('mock_depot')
    self.assertEqual(self.cur_dir, '/mock/src/foo')


# The tests below test private functions (W0212).
# pylint: disable=W0212
class GitTryJobTestCases(unittest.TestCase):

  """Test case for bisect try job."""
  def setUp(self):
    bisect_utils_patcher = mock.patch('bisect_perf_regression.bisect_utils')
    self.mock_bisect_utils = bisect_utils_patcher.start()
    self.addCleanup(bisect_utils_patcher.stop)

  def _SetupRunGitMock(self, git_cmds):
    """Setup RunGit mock with expected output for given git command."""
    def side_effect(git_cmd_args):
      for val in git_cmds:
        if set(val[0]) == set(git_cmd_args):
          return val[1]
    self.mock_bisect_utils.RunGit = mock.Mock(side_effect=side_effect)

  def _AssertRunGitExceptions(self, git_cmds, func, *args):
    """Setup RunGit mock and tests RunGitException.

    Args:
      git_cmds: List of tuples with git command and expected output.
      func: Callback function to be executed.
      args: List of arguments to be passed to the function.
    """
    self._SetupRunGitMock(git_cmds)
    self.assertRaises(bisect_perf_regression.RunGitError,
                      func,
                      *args)

  def testNotGitRepo(self):
    new_branch = bisect_perf_regression.BISECT_TRYJOB_BRANCH
    parent_branch = bisect_perf_regression.BISECT_MASTER_BRANCH
    cmds = [(['rev-parse', '--abbrev-ref', 'HEAD'], (None, 128))]
    self._AssertRunGitExceptions(cmds,
                                 bisect_perf_regression._PrepareBisectBranch,
                                 parent_branch, new_branch)

  def testFailedCheckoutMaster(self):
    new_branch = bisect_perf_regression.BISECT_TRYJOB_BRANCH
    parent_branch = bisect_perf_regression.BISECT_MASTER_BRANCH
    cmds = [
        (['rev-parse', '--abbrev-ref', 'HEAD'], (new_branch, 0)),
        (['checkout', '-f', parent_branch], ('Checkout Failed', 1)),
    ]
    self._AssertRunGitExceptions(cmds,
                                 bisect_perf_regression._PrepareBisectBranch,
                                 parent_branch, new_branch)

  def testDeleteBisectBranchIfExists(self):
    new_branch = bisect_perf_regression.BISECT_TRYJOB_BRANCH
    parent_branch = bisect_perf_regression.BISECT_MASTER_BRANCH
    cmds = [
        (['rev-parse', '--abbrev-ref', 'HEAD'], (parent_branch, 0)),
        (['branch', '--list'], ('bisect-tryjob\n*master\nsomebranch', 0)),
        (['branch', '-D', new_branch], ('Failed to delete branch', 128)),
    ]
    self._AssertRunGitExceptions(cmds,
                                 bisect_perf_regression._PrepareBisectBranch,
                                 parent_branch, new_branch)

  def testCreatNewBranchFails(self):
    new_branch = bisect_perf_regression.BISECT_TRYJOB_BRANCH
    parent_branch = bisect_perf_regression.BISECT_MASTER_BRANCH
    cmds = [
        (['rev-parse', '--abbrev-ref', 'HEAD'], (parent_branch, 0)),
        (['branch', '--list'], ('bisect-tryjob\n*master\nsomebranch', 0)),
        (['branch', '-D', new_branch], ('None', 0)),
        (['update-index', '--refresh', '-q'], (None, 0)),
        (['diff-index', 'HEAD'], (None, 0)),
        (['checkout', '-b', new_branch], ('Failed to create branch', 128)),
    ]
    self._AssertRunGitExceptions(cmds,
                                 bisect_perf_regression._PrepareBisectBranch,
                                 parent_branch, new_branch)

  def testSetUpstreamToFails(self):
    new_branch = bisect_perf_regression.BISECT_TRYJOB_BRANCH
    parent_branch = bisect_perf_regression.BISECT_MASTER_BRANCH
    cmds = [
        (['rev-parse', '--abbrev-ref', 'HEAD'], (parent_branch, 0)),
        (['branch', '--list'], ('bisect-tryjob\n*master\nsomebranch', 0)),
        (['branch', '-D', new_branch], ('None', 0)),
        (['update-index', '--refresh', '-q'], (None, 0)),
        (['diff-index', 'HEAD'], (None, 0)),
        (['checkout', '-b', new_branch], ('None', 0)),
        (['branch', '--set-upstream-to', parent_branch],
         ('Setuptream fails', 1)),
    ]
    self._AssertRunGitExceptions(cmds,
                                 bisect_perf_regression._PrepareBisectBranch,
                                 parent_branch, new_branch)

  def testStartBuilderTryJobForException(self):
    git_revision = 'ac4a9f31fe2610bd146857bbd55d7a260003a888'
    bot_name = 'linux_perf_bisect_builder'
    bisect_job_name = 'testBisectJobname'
    patch = None
    patch_content = '/dev/null'
    new_branch = bisect_perf_regression.BISECT_TRYJOB_BRANCH
    parent_branch = bisect_perf_regression.BISECT_MASTER_BRANCH
    try_cmd = [
        (['rev-parse', '--abbrev-ref', 'HEAD'], (parent_branch, 0)),
        (['branch', '--list'], ('bisect-tryjob\n*master\nsomebranch', 0)),
        (['branch', '-D', new_branch], ('None', 0)),
        (['update-index', '--refresh', '-q'], (None, 0)),
        (['diff-index', 'HEAD'], (None, 0)),
        (['checkout', '-b', new_branch], ('None', 0)),
        (['branch', '--set-upstream-to', parent_branch],
         ('Setuptream fails', 0)),
        (['try',
          '--bot=%s' % bot_name,
          '--revision=%s' % git_revision,
          '--name=%s' % bisect_job_name,
          '--svn_repo=%s' % bisect_perf_regression.PERF_SVN_REPO_URL,
          '--diff=%s' % patch_content],
         (None, 1)),
    ]
    self._AssertRunGitExceptions(
        try_cmd, bisect_perf_regression._StartBuilderTryJob,
        fetch_build.PERF_BUILDER, git_revision, bot_name, bisect_job_name,
        patch)

  def testBuilderTryJob(self):
    git_revision = 'ac4a9f31fe2610bd146857bbd55d7a260003a888'
    bot_name = 'linux_perf_bisect_builder'
    bisect_job_name = 'testBisectJobname'
    patch = None
    patch_content = '/dev/null'
    new_branch = bisect_perf_regression.BISECT_TRYJOB_BRANCH
    parent_branch = bisect_perf_regression.BISECT_MASTER_BRANCH
    try_cmd = [
        (['rev-parse', '--abbrev-ref', 'HEAD'], (parent_branch, 0)),
        (['branch', '--list'], ('bisect-tryjob\n*master\nsomebranch', 0)),
        (['branch', '-D', new_branch], ('None', 0)),
        (['update-index', '--refresh', '-q'], (None, 0)),
        (['diff-index', 'HEAD'], (None, 0)),
        (['checkout', '-b', new_branch], ('None', 0)),
        (['branch', '--set-upstream-to', parent_branch],
         ('Setuptream fails', 0)),
        (['try',
          '--bot=%s' % bot_name,
          '--revision=%s' % git_revision,
          '--name=%s' % bisect_job_name,
          '--svn_repo=%s' % bisect_perf_regression.PERF_SVN_REPO_URL,
          '--diff=%s' % patch_content],
         (None, 0)),
    ]
    self._SetupRunGitMock(try_cmd)
    bisect_perf_regression._StartBuilderTryJob(
        fetch_build.PERF_BUILDER, git_revision, bot_name, bisect_job_name,
        patch)


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