| Index: commit-queue/tests/try_server_test.py
|
| ===================================================================
|
| --- commit-queue/tests/try_server_test.py (revision 249146)
|
| +++ commit-queue/tests/try_server_test.py (working copy)
|
| @@ -1,886 +0,0 @@
|
| -#!/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()
|
|
|