#!/usr/bin/env python
# Copyright (c) 2012 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.

"""Unit tests for verification/try_server.py."""

import json
import logging
import optparse
import os
import re
import StringIO
import sys
import time
import unittest
import urllib

ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(ROOT_DIR, '..'))

# In tests/
import mocks  # pylint: disable=W0403

from testing_support import auto_stub

# In root
import buildbot_json
from verification import base
from verification import try_server

# pylint: disable=W0212
SUCCESS = buildbot_json.SUCCESS
WARNINGS = buildbot_json.WARNINGS
FAILURE = buildbot_json.FAILURE
SKIPPED = buildbot_json.SKIPPED
EXCEPTION = buildbot_json.EXCEPTION


class FakeTryServer(auto_stub.SimpleMock):
  """Stateful try server mock.

  Includes calls to send try jobs TryChange() and visible results from HTTP
  requests.
  """
  def __init__(self, unit_test):
    super(FakeTryServer, self).__init__(unit_test)

    # Try server immutable properties.
    self.steps = ['update', 'compile', 'test1', 'test2']
    self.server_url = 'http://foo/bar'

    # State of the try server.
    self._builds = { 'linux': [], 'mac': [] }
    self.pending_builds = {
      'linux': [],
      'mac': []
    }
    # Default mocks.
    self.unit_test.mock(urllib, 'urlopen', self._mockurlopen)
    self.unit_test.mock(try_server.trychange, 'TryChange', self.TryChangeMock)

  def TryChangeMock(self, cmd, _change, swallow_exception):
    """Mocks trychange.py."""
    self.assertEqual(swallow_exception, True)
    parser = optparse.OptionParser()
    parser.add_option('--bot', action='append')
    parser.add_option('--clobber', action='store_true', default=False)
    parser.add_option('--email')
    parser.add_option('--issue', type='int')
    parser.add_option('--name')
    parser.add_option('--no_search', action='store_true')
    parser.add_option('--patchset', type='int')
    parser.add_option('--revision')
    parser.add_option('--rietveld_url')
    parser.add_option('--user')
    options, args = parser.parse_args(cmd)
    self.assertEqual(options.email, 'user1@example.com')
    self.assertEqual(options.issue, 42)
    self.assertEqual(options.no_search, True)
    self.assertEqual(options.patchset, 23)
    self.assertEqual(
        options.rietveld_url,
        '%s/download/issue42_23.diff' % self.unit_test.context.rietveld.url)
    self.assertEqual(options.user, 'user1')
    self.assertEqual(args, ['extra_flags'])
    bot = ', '.join(options.bot)
    call = 'trychange b={%s} c=%s r=%s' % (
        bot, options.clobber, options.revision)
    if options.name != '42-23':
      call += ' n=%s' % options.name
    self.calls.append(call)
    logging.debug(self.calls[-1])

  def _mockurlopen_internal(self, sub_url):
    """Returns data to be encoded before returning."""
    # sub_url is str on python <= 2.6 and unicode for >= 2.7
    self.unit_test.assertTrue(isinstance(sub_url, basestring))
    expected_url = self.server_url + '/json/'
    self.unit_test.assertTrue(sub_url.startswith(expected_url))
    self.calls.append(sub_url[len(expected_url):])
    baseurl = '^%s/json/' % re.escape(self.server_url)
    match = re.match(baseurl + r'builders/(\w+)/builds/\?(.+)$', sub_url)
    if match:
      data = {}
      for query in match.group(2).split('&'):
        m = re.match(r'select=(\w+)', query)
        self.unit_test.assertTrue(m, (match.group(2), query))
        build = int(m.group(1))
        data[str(build)] = self._builds[match.group(1)][build]
      return data

    match = re.match(baseurl + r'builders/(\w+)/builds/_all$', sub_url)
    if match:
      # Data is not stored exactly as the try server serves it.
      data = {}
      for i, build in enumerate(self._builds[match.group(1)]):
        data[str(i)] = build
      return data

    match = re.match(baseurl + r'builders/\?(.+)$', sub_url)
    if match:
      data = {}
      for query in match.group(1).split('&'):
        m = re.match(r'select=(\w+)', query)
        self.unit_test.assertTrue(m, (match.group(1), query))
        builder = m.group(1)
        data[builder] = {
          'cachedBuilds': range(len(self._builds[builder])),
          'pendingBuilds': len(self.pending_builds.get(builder, [])),
        }
      return data

    match = re.match(baseurl + r'builders/(\w+)/pendingBuilds$', sub_url)
    if match:
      return self.pending_builds[match.group(1)]

  def _mockurlopen(self, sub_url):
    """Mocks urllib.urlopen() and JSON encode + StringIO buffers."""
    sub_url = re.match(r'^(.+)[\&\?]filter=1$', sub_url).group(1)
    data = self._mockurlopen_internal(sub_url)
    self.unit_test.assertNotEquals(None, data, sub_url)
    #logging.debug('_mockurlopen(%s) -> %s' % (sub_url, data))
    return StringIO.StringIO(json.dumps(data))

  def add_build(self, builder, revision, reason, step_results):
    """Add a build to a builder."""
    self.assertEqual(len(self.steps), len(step_results))
    assert isinstance(revision, (str, int))
    data = {
      'reason': reason or self.unit_test.pending.pending_name(),
      'sourceStamp': {
        'revision': 'sol@%s' % revision,
        'hasPatch': True,
      },
      'steps': [],
      'blame': ['user1@example.com'],
      'number': 0,
      'slave': 'foo',
    }
    result = max(step_results)
    if result in (SUCCESS, WARNINGS) and step_results[-1] is None:
      result = None
    for i, step in enumerate(self.steps):
      data['steps'].append({
        'name': step,
        'results': [step_results[i]],
      })
    data['results'] = [result]
    self._builds[builder].append(data)

  def set_build_result(self, builder, result):
    """Override the build result for every steps to |result|."""
    for step in self._builds[builder][-1]['steps']:
      step['results'] = [result]
    self._builds[builder][-1]['results'] = [result]


class TryServerSvnTest(mocks.TestCase):
  def setUp(self):
    super(TryServerSvnTest, self).setUp()
    self.email = 'user1@example.com'
    self.user = 'user1'
    self.timestamp = [1.]
    # Mocks http://chromium-status.appspot.com/lkgr
    self.lkgr = 123
    self.try_server = FakeTryServer(self)
    self.mock(time, 'time', lambda: self.timestamp[-1])

    try_server.TryRunnerSvn.update_latency = 0
    self.builders_and_tests = {
      'linux': ['test1', 'test2'],
      'mac': ['test1', 'test2'],
    }
    self.try_runner = try_server.TryRunnerSvn(
        self.context,
        self.try_server.server_url,
        self.email,
        self.builders_and_tests,
        ['ignored_step'],
        'sol',
        ['extra_flags',],
        lambda: self.lkgr,
        )
    self.pending.revision = 123

  def tearDown(self):
    try:
      if not self.has_failed():
        self.try_server.check_calls([])
    finally:
      super(TryServerSvnTest, self).tearDown()

  def get_verif(self):
    return self.pending.verifications[self.try_runner.name]

  def assertPending(
      self, state, nb_jobs, error_message,
      linux_build=1,
      mac_build=1,
      linux_state=None,
      mac_state=None,
      linux_clobber=False,
      mac_clobber=False,
      linux_rev=123,
      mac_rev=123,
      linux_sent=1,
      mac_sent=1,
      linux_name='42-23',
      mac_name='42-23'):
    if linux_state is None:
      linux_state = state
    if mac_state is None:
      mac_state = state
    self.assertEqual([self.try_runner.name], self.pending.verifications.keys())
    self.assertEqual(error_message, self.get_verif().error_message)
    self.assertEqual(nb_jobs, len(self.get_verif().try_jobs))
    self.assertEqual(
        len(self.builders_and_tests), len(self.get_verif().try_jobs))
    self.assertEqual(linux_name, self.get_verif().try_jobs[0].name)
    self.assertEqual('linux', self.get_verif().try_jobs[0].builder)
    self.assertEqual(linux_rev, self.get_verif().try_jobs[0].revision)
    self.assertEqual(linux_sent, self.get_verif().try_jobs[0].sent)
    self.assertEqual(linux_clobber, self.get_verif().try_jobs[0].clobber)
    self.assertEqual(linux_build, self.get_verif().try_jobs[0].build)
    self.assertEqual(linux_state, self.get_verif().try_jobs[0].get_state())
    if len(self.builders_and_tests) > 1:
      self.assertEqual(mac_name, self.get_verif().try_jobs[1].name)
      self.assertEqual('mac', self.get_verif().try_jobs[1].builder)
      self.assertEqual(mac_rev, self.get_verif().try_jobs[1].revision)
      self.assertEqual(mac_sent, self.get_verif().try_jobs[1].sent)
      self.assertEqual(mac_clobber, self.get_verif().try_jobs[1].clobber)
      self.assertEqual(mac_build, self.get_verif().try_jobs[1].build)
      self.assertEqual(mac_state, self.get_verif().try_jobs[1].get_state())
    self.assertEqual(state, self.get_verif().get_state())

  def testVoid(self):
    self.assertEqual(self.pending.verifications.keys(), [])

  def testVerificationVoid(self):
    self.try_runner.verify(self.pending)
    self.assertPending(base.PROCESSING, 2, None, linux_build=None,
        mac_build=None)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])
    self.context.status.check_names(['try server'] * 2)

  def testVoidUpdate(self):
    self.try_runner.update_status([])

  def test_steps_quality(self):
    self.assertEqual(None, try_server.steps_quality([]))
    self.assertEqual(True, try_server.steps_quality([True, None]))
    self.assertEqual(False, try_server.steps_quality([True, None, False]))

  def testStepQualityNone(self):
    self.try_runner.status.builders['linux'].builds.cache()
    self.assertEqual(
        (None, 0),
        self.try_runner.step_db.revision_quality_builder_steps('linux', 123))
    self.try_server.check_calls(['builders/linux/builds/_all'])

  def testStepQualityGood(self):
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, None, None, None])
    self.try_runner.status.builders['linux'].builds.cache()
    self.try_server.check_calls(['builders/linux/builds/_all'])
    self.assertEqual(
        ([True, None, None, None], 1),
        self.try_runner.step_db.revision_quality_builder_steps('linux', 123))
    self.try_server.set_build_result('linux', SUCCESS)
    self.try_runner.status.builders['linux'].builds.refresh()
    self.assertEqual(
        ([True] * 4, 1),
        self.try_runner.step_db.revision_quality_builder_steps('linux', 123))
    self.try_server.check_calls(['builders/linux/builds/_all'])

  def testStepQualityBad(self):
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, FAILURE, SUCCESS])
    self.try_runner.status.builders['linux'].builds.cache()
    # Also test that FakeTryServer.add_build() is implemented correctly.
    self.assertEqual(
        ([True, True, False, True], 1),
        self.try_runner.step_db.revision_quality_builder_steps('linux', 123))
    self.try_server.check_calls(['builders/linux/builds/_all'])

  def testStepQualityBadIncomplete(self):
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, FAILURE, None])
    self.try_runner.status.builders['linux'].builds.cache()
    # Also test that FakeTryServer.add_build() is implemented correctly.
    self.assertEqual(
        ([True, True, False, None], 1),
        self.try_runner.step_db.revision_quality_builder_steps('linux', 123))
    self.try_server.check_calls(['builders/linux/builds/_all'])

  def testStepQualityGoodAndBad(self):
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_server.add_build('linux', 123, None, [FAILURE, None, None, None])
    self.try_runner.status.builders['linux'].builds.cache()
    self.try_server.check_calls(['builders/linux/builds/_all'])
    self.assertEqual(
        ([True] * 4, 2),
        self.try_runner.step_db.revision_quality_builder_steps('linux', 123))

  def testQualityAutomatic(self):
    self.try_runner.verify(self.pending)
    self.assertEqual(
        (None, 0),
        self.try_runner.step_db.revision_quality_builder_steps(
          'linux', 123))
    self.try_server.add_build(
        'linux', 123, 'georges tried stuff',
        [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_runner.update_status([self.pending])
    self.assertEqual(
        ([True] * 4, 1),
        self.try_runner.step_db.revision_quality_builder_steps(
          'linux', 123))
    self.try_server.check_calls(
        [ 'trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123',
          'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])
    self.context.status.check_names(['try server'] * 2)

  def testQualityManual(self):
    self.try_server.add_build(
        'linux', 123, 'georges tried stuff',
        [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_runner.status.builders['linux'].builds.cache()
    self.assertEqual(
        ([True] * 4, 1),
        self.try_runner.step_db.revision_quality_builder_steps(
          'linux', 123))
    self.try_server.check_calls(['builders/linux/builds/_all'])

  def _simple(self, status_linux, status_mac=None, error_msg=None):
    """status_linux affects test1, status_mac affects test2."""
    def is_failure(status):
      return status in (FAILURE, EXCEPTION)

    self.assertEqual(
        bool(is_failure(status_linux) or is_failure(status_mac)),
        bool(error_msg))
    if status_mac is None:
      status_mac = status_linux
    self.lkgr = 12
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_server.add_build(
        'mac', 123, None, [SUCCESS, SUCCESS, SUCCESS, SUCCESS])

    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, status_linux, SUCCESS])
    self.try_server.add_build(
        'mac', 123, None, [SUCCESS, SUCCESS, SUCCESS, status_mac])
    self.try_runner.update_status([self.pending])

    if is_failure(status_linux):
      self.assertEqual(123, self.try_runner.get_lkgr('linux'))
      self.assertEqual(
          123, self.try_runner.step_db.last_good_revision_builder('linux'))
    else:
      self.assertEqual(123, self.try_runner.get_lkgr('linux'))
      self.assertEqual(
          123, self.try_runner.step_db.last_good_revision_builder('linux'))
    if is_failure(status_mac):
      self.assertEqual(123, self.try_runner.get_lkgr('mac'))
      self.assertEqual(
          123, self.try_runner.step_db.last_good_revision_builder('mac'))
    else:
      self.assertEqual(123, self.try_runner.get_lkgr('mac'))
      self.assertEqual(
          123, self.try_runner.step_db.last_good_revision_builder('mac'))

    if error_msg:
      # Can't test failure without testing automatic retry mechanism.
      expected = (
          [ 'builders/?select=linux&select=mac',
            'builders/linux/builds/_all', 'builders/mac/builds/_all'])

      if is_failure(status_linux):
        expected.append(
            'trychange b={linux:test1} c=False r=sol@123 n=42-23 (retry)')
        linux_build = None
        linux_state = base.PROCESSING
        linux_name = '42-23 (retry)'
      else:
        linux_build = 1
        linux_state = base.SUCCEEDED
        linux_name = '42-23'

      if is_failure(status_mac):
        expected.append(
            'trychange b={mac:test2} c=False r=sol@123 n=42-23 (retry)')
        mac_build = None
        mac_state = base.PROCESSING
        mac_name = '42-23 (retry)'
      else:
        mac_build = 1
        mac_state = base.SUCCEEDED
        mac_name = '42-23'

      self.assertPending(
          base.PROCESSING, 2, None, linux_build=linux_build,
          mac_build=mac_build, linux_state=linux_state, mac_state=mac_state,
          linux_name=linux_name, mac_name=mac_name)
      self.try_server.check_calls(expected)

      if is_failure(status_linux):
        self.try_server.add_build(
            'linux', 123, linux_name, [SUCCESS, SUCCESS, status_linux, SUCCESS])
      if is_failure(status_mac):
        self.try_server.add_build(
            'mac', 123, mac_name, [SUCCESS, SUCCESS, SUCCESS, status_mac])

      self.try_runner.update_status([self.pending])
      if is_failure(status_linux):
        linux_state = base.FAILED
        linux_build = 2
      else:
        linux_build = 1
      if is_failure(status_mac):
        mac_state = base.FAILED
        mac_build = 2
      else:
        mac_build = 1
      self.assertPending(
          base.FAILED, 2, error_msg,
          linux_build=linux_build, mac_build=mac_build,
          linux_state=linux_state, mac_state=mac_state,
          linux_name=linux_name, mac_name=mac_name)

      if is_failure(status_linux) and is_failure(status_mac):
        self.try_server.check_calls(
            [ 'builders/?select=linux&select=mac',
              'builders/linux/builds/_all', 'builders/mac/builds/_all'])
        self.context.checkout.check_calls(
            [ 'prepare(123)',
              'apply_patch(%r)' % self.context.rietveld.patchsets[-2],
              'prepare(123)',
              'apply_patch(%r)' % self.context.rietveld.patchsets[-1]])
      elif is_failure(status_linux):
        self.try_server.check_calls(
            ['builders/?select=linux', 'builders/linux/builds/_all'])
        self.context.checkout.check_calls(
            [ 'prepare(123)',
              'apply_patch(%r)' % self.context.rietveld.patchsets[-1]])
      else:
        self.try_server.check_calls(
            ['builders/?select=mac', 'builders/mac/builds/_all'])
        self.context.checkout.check_calls(
            [ 'prepare(123)',
              'apply_patch(%r)' % self.context.rietveld.patchsets[-1]])
    else:
      self.assertPending(base.SUCCEEDED, 2, None)
      self.try_server.check_calls(
          [ 'builders/?select=linux&select=mac',
            'builders/linux/builds/_all', 'builders/mac/builds/_all'])
    count = 6 + 3 * (
        int(is_failure(status_linux)) + int(is_failure(status_mac)))
    self.context.status.check_names(['try server'] * count)

  def testImmediateSuccess(self):
    self._simple(SUCCESS)

  def testImmediateWarnings(self):
    self._simple(WARNINGS)

  def testImmediateSkipped(self):
    self._simple(SKIPPED)

  def second_fail_msg(
      self, clname, step2, step1, builder, number, is_clobber=False):
    extra = ''
    if is_clobber:
      extra = ' (clobber build)'
    return (
        u'Try job failure for %s on %s for step "%s"%s.\n'
        u'It\'s a second try, previously, step "%s" failed.\n'
        u'%s/buildstatus?builder=%s&number=%s\n') % (
            clname, builder, step2, extra, step1, self.try_server.server_url,
            builder, number)
  def testImmediateFailureLinux(self):
    self._simple(
        FAILURE, SUCCESS,
        self.second_fail_msg('42-23 (retry)', 'test1', 'test1', 'linux', 2))

  def testImmediateFailureMac(self):
    self._simple(
        SUCCESS, FAILURE,
        self.second_fail_msg('42-23 (retry)', 'test2', 'test2', 'mac', 2))

  def testImmediateDoubleFailure(self):
    self._simple(
        FAILURE, FAILURE,
        self.second_fail_msg('42-23 (retry)', 'test2', 'test2', 'mac', 2))

  def testImmediateException(self):
    self._simple(
        SUCCESS, EXCEPTION,
        self.second_fail_msg('42-23 (retry)', 'test2', 'test2', 'mac', 2))

  def testSuccess(self):
    self.lkgr = 2
    # Normal workflow with incremental success.
    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])

    self.try_runner.update_status([self.pending])
    self.assertPending(
        base.PROCESSING, 2, None, linux_build=None, mac_build=None)
    self.try_server.check_calls(
        ['builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])

    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, None, None, None])
    self.try_runner.update_status([self.pending])
    self.assertPending(base.PROCESSING, 2, None, linux_build=0, mac_build=None)
    self.try_server.check_calls(
        ['builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])

    self.try_server.add_build(
        'mac', 123, None, [SUCCESS, None, None, None])
    self.try_runner.update_status([self.pending])
    self.assertPending(base.PROCESSING, 2, None, linux_build=0, mac_build=0)
    self.try_server.check_calls(
        ['builders/?select=mac',
          'builders/mac/builds/_all', 'builders/linux/builds/?select=0'])

    # This one will be cached since it's now immutable.
    self.try_server.set_build_result('mac', SUCCESS)
    self.try_runner.update_status([self.pending])
    self.assertPending(
        base.PROCESSING, 2, None, linux_build=0, mac_build=0,
        mac_state=base.SUCCEEDED)
    self.try_server.check_calls(
        ['builders/linux/builds/?select=0', 'builders/mac/builds/?select=0'])

    self.try_server.set_build_result('linux', SUCCESS)
    self.try_runner.update_status([self.pending])
    self.assertPending(base.SUCCEEDED, 2, None, linux_build=0, mac_build=0)
    self.assertEqual(
        123, self.try_runner.step_db.last_good_revision_builder('linux'))
    self.assertEqual(
        123, self.try_runner.step_db.last_good_revision_builder('mac'))
    self.assertEqual(
        ([True] * 4, 1),
        self.try_runner.step_db.revision_quality_builder_steps(
          'linux', 123))
    self.assertEqual(
        ([True] * 4, 1),
        self.try_runner.step_db.revision_quality_builder_steps(
          'mac', 123))
    self.try_server.check_calls(['builders/linux/builds/?select=0'])
    self.context.status.check_names(['try server'] * 6)

  def testIgnorePreviousJobs(self):
    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])

    self.try_runner.update_status([self.pending])
    self.try_server.check_calls(
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])

    self.try_server.add_build('linux', 12, None, [None, None, None, None])
    self.try_server.add_build('mac', 12, None, [None, None, None, None])
    self.try_runner.update_status([self.pending])
    self.assertPending(
        base.PROCESSING, 2, None, linux_build=None,
        mac_build=None)
    self.try_server.check_calls(
        ['builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])

    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_server.add_build(
        'mac', 123, None, [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_runner.update_status([self.pending])
    self.assertPending(base.SUCCEEDED, 2, None)
    self.assertEqual(
        123, self.try_runner.step_db.last_good_revision_builder('linux'))
    self.assertEqual(
        123, self.try_runner.step_db.last_good_revision_builder('mac'))
    self.assertEqual(
        ([True] * 4, 1),
        self.try_runner.step_db.revision_quality_builder_steps(
          'linux', 123))
    self.assertEqual(
        ([True] * 4, 1),
        self.try_runner.step_db.revision_quality_builder_steps(
          'mac', 123))
    self.try_server.check_calls(
        ['builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])
    self.context.status.check_names(['try server'] * 6)

  def testNames(self):
    job = try_server.TryJob(
        builder='builder', revision=123, tests=['test1'], clobber=False)
    self.assertEqual(None, job.name)

  def testLostJob(self):
    # Test that a job is automatically retried if it was never started up. It
    # does happen.
    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])

    # Keep a copy of the try jobs to compare later.
    self.try_runner.update_status([self.pending])
    self.try_server.check_calls(
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])
    self.assertPending(
        base.PROCESSING, 2, None, mac_sent=self.timestamp[-1],
        linux_build=None, mac_build=None)

    # lost_try_job_delay + 2 seconds later.
    # linux is pending, mac is lost.
    self.try_server.pending_builds['linux'] = [
      {
        'reason': '42-23',
      }
    ]
    self.timestamp.append(self.try_runner.lost_try_job_delay + 2)
    self.try_runner.update_status([self.pending])
    self.assertPending(
        base.PROCESSING, 2, None, mac_sent=self.timestamp[-1],
        linux_build=None, mac_build=None,
        mac_name='42-23 (previous was lost)')
    self.try_server.check_calls(
        # Look if there is pending build on each builder.
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all',
          'builders/linux/pendingBuilds',
          # Retry only mac.
          'trychange b={mac:test1,test2} c=False r=sol@123 n=42-23 (previous '
          'was lost)'])

    # linux job was completed.
    self.try_server.pending_builds['linux'] = []
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_runner.update_status([self.pending])
    self.assertPending(
        base.PROCESSING, 2, None, mac_sent=self.timestamp[1],
        linux_build=0, mac_build=None,
        linux_state=base.SUCCEEDED,
        mac_name='42-23 (previous was lost)')
    self.try_server.check_calls(
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])

    # 2 * (lost_try_job_delay + 2) seconds later, mac job started and completed.
    self.timestamp.append(2 * (self.try_runner.lost_try_job_delay + 2))
    self.try_server.add_build(
        'mac', 123, '42-23 (previous was lost)',
        [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_runner.update_status([self.pending])
    self.assertPending(
        base.SUCCEEDED, 2, None, mac_sent=self.timestamp[1],
        linux_build=0, mac_build=0,
        mac_name='42-23 (previous was lost)')
    self.try_server.check_calls(
        ['builders/?select=mac', 'builders/mac/builds/_all'])

    self.try_runner.update_status([self.pending])
    self.context.checkout.check_calls(
        [ 'prepare(123)',
          'apply_patch(%r)' % self.context.rietveld.patchsets[-1]])
    self.context.status.check_names(['try server'] * 7)

  def testFailedStepRetryLkgr(self):
    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, FAILURE, SUCCESS])

    self.lkgr = 122
    self.try_runner.update_status([self.pending])
    self.try_server.check_calls(
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all',
          # Only the failed test is retried, on lkgr revision.
          'trychange b={linux:test1} c=False r=sol@122 n=42-23 (retry)'])
    self.assertEqual(['test1'], self.get_verif().try_jobs[0].failed_steps)
    self.context.checkout.check_calls(
        [ 'prepare(122)',
          'apply_patch(%r)' % self.context.rietveld.patchsets[-1]])
    self.context.status.check_names(['try server'] * 5)

  def testFailedUpdate(self):
    # It must not retry a failed update.
    # Add succeededing builds, this sets quality to True, which disable retry
    # mechanism.
    self.try_server.add_build(
        'linux', 123, 'georges tried stuff',
        [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.try_server.add_build(
        'mac', 123, 'georges tried stuff', [SUCCESS, SUCCESS, SUCCESS, SUCCESS])
    self.lkgr = 123

    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])
    self.try_server.add_build(
        'linux', 123, None, [FAILURE, None, None, None])
    self.try_runner.update_status([self.pending])
    self.try_server.check_calls(
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])
    self.assertEqual('linux', self.get_verif().try_jobs[0].builder)
    self.assertEqual(['update'], self.get_verif().try_jobs[0].failed_steps)
    self.assertPending(
        base.FAILED, 2,
        (u'Try job failure for 42-23 on linux for step '
        u'"update".\n%s/buildstatus?builder=linux&number=1\n\n'
        u'Step "update" is always a major failure.\n'
        u'Look at the try server FAQ for more details.') %
            self.try_server.server_url,
        mac_build=None,
        mac_state=base.PROCESSING)
    self.context.status.check_names(['try server'] * 4)

  def testFailedCompileRetryClobber(self):
    # It must retry once a non-clobber compile.
    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])
    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, FAILURE, None, None])
    self.lkgr = 122
    self.try_runner.update_status([self.pending])
    self.context.checkout.check_calls(
        [ 'prepare(122)',
          'apply_patch(%r)' % self.context.rietveld.patchsets[-1]])
    self.try_server.check_calls(
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all',
          # Retries at lkgr.
          'trychange b={linux:test1,test2} c=True r=sol@122 n=42-23 (retry)'])
    self.assertEqual(['compile'], self.get_verif().try_jobs[0].failed_steps)
    self.assertPending(
        base.PROCESSING, 2, None, linux_rev=122,
        linux_clobber=True, linux_build=None, mac_build=None,
        linux_name='42-23 (retry)')

    self.try_server.add_build(
        'linux', 122, '42-23 (retry)', [SUCCESS, FAILURE, None, None])
    self.try_runner.update_status([self.pending])
    self.try_server.check_calls(
        [ 'builders/?select=linux&select=mac',
          'builders/linux/builds/_all', 'builders/mac/builds/_all'])
    self.assertEqual(['compile'], self.get_verif().try_jobs[0].failed_steps)
    self.assertPending(
        base.FAILED, 2,
        self.second_fail_msg('42-23 (retry)', 'compile', 'compile', 'linux', 1,
            True),
        linux_rev=122,
        linux_clobber=True,
        mac_build=None,
        mac_state=base.PROCESSING,
        linux_name='42-23 (retry)')
    self.context.status.check_names(['try server'] * 7)

  def testTooManyRetries(self):
    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])
    job = self.pending.verifications[self.try_runner.name].try_jobs[0]
    self.try_runner._send_jobs(
        self.pending, [job], False, {job.builder:job.tests}, 'foo')
    self.try_server.check_calls(
        [ 'trychange b={linux:test1,test2} c=False r=sol@123 n=foo'])
    job = self.pending.verifications[self.try_runner.name].try_jobs[0]
    self.try_runner._send_jobs(
        self.pending, [job], False, {job.builder:job.tests}, 'foo')
    self.try_server.check_calls(
        [ 'trychange b={linux:test1,test2} c=False r=sol@123 n=foo'])
    job = self.pending.verifications[self.try_runner.name].try_jobs[0]
    self.try_runner._send_jobs(
        self.pending, [job], False, {job.builder:job.tests}, 'foo')
    self.try_server.check_calls(
        [ 'trychange b={linux:test1,test2} c=False r=sol@123 n=foo'])
    job = self.pending.verifications[self.try_runner.name].try_jobs[0]
    try:
      self.try_runner._send_jobs(
          self.pending, [job], False, {job.builder:job.tests}, 'foo')
      self.fail()
    except base.DiscardPending:
      pass
    self.context.status.check_names(['try server'] * 5)

  def testNoTry(self):
    self.pending.description += '\nNOTRY=true'
    self.try_runner.verify(self.pending)
    self.assertEqual(
        base.SUCCEEDED,
        self.pending.verifications[self.try_runner.name].get_state())

  def testNoTryWrong(self):
    self.pending.description += '\nNOTRY=true2'
    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2, mac:test1,test2} c=False r=sol@123'])
    self.context.status.check_names(['try server'] * 2)
    self.assertEqual(
        base.PROCESSING,
        self.pending.verifications[self.try_runner.name].get_state())

  def testSuccessIgnoredFailure(self):
    # Simplify testing code by removing mac.
    del self.try_runner.builders_and_tests['mac']
    # Add fake failing ignored step.
    self.try_server.steps = [
        'update', 'compile', 'ignored_step', 'test1', 'test2']

    self.try_runner.verify(self.pending)
    self.try_server.check_calls(
        ['trychange b={linux:test1,test2} c=False r=sol@123'])

    self.try_runner.update_status([self.pending])
    self.assertPending(
        base.PROCESSING, 1, None, linux_build=None, mac_build=None)
    self.try_server.check_calls(
        ['builders/?select=linux', 'builders/linux/builds/_all'])

    self.try_server.add_build(
        'linux', 123, None, [SUCCESS, SUCCESS, FAILURE, SUCCESS, SUCCESS])
    self.try_runner.update_status([self.pending])
    self.assertPending(base.SUCCEEDED, 1, None, linux_build=0, mac_build=None)
    self.try_server.check_calls(
        ['builders/?select=linux', 'builders/linux/builds/_all'])

    self.try_server.set_build_result('linux', SUCCESS)
    self.try_runner.update_status([self.pending])
    self.assertPending(base.SUCCEEDED, 1, None, linux_build=0, mac_build=0)
    # TODO(maruel): Fix, since StepDb doesn't know about ignored steps.
    self.assertEqual(
        None, self.try_runner.step_db.last_good_revision_builder('linux'))
    self.assertEqual(
        ([True, True, False, True, True], 1),
        self.try_runner.step_db.revision_quality_builder_steps(
          'linux', 123))
    self.context.status.check_names(['try server'] * 3)


if __name__ == '__main__':
  logging.basicConfig(
      level=[logging.WARNING, logging.INFO, logging.DEBUG][
        min(sys.argv.count('-v'), 2)],
      format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s')
  unittest.main()
