| Index: commit-queue/tests/project_test.py
|
| ===================================================================
|
| --- commit-queue/tests/project_test.py (revision 249146)
|
| +++ commit-queue/tests/project_test.py (working copy)
|
| @@ -1,508 +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.
|
| -
|
| -"""Integration tests for project.py."""
|
| -
|
| -import logging
|
| -import os
|
| -import random
|
| -import shutil
|
| -import string
|
| -import StringIO
|
| -import sys
|
| -import tempfile
|
| -import time
|
| -import unittest
|
| -import urllib2
|
| -
|
| -ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
| -sys.path.insert(0, os.path.join(ROOT_DIR, '..'))
|
| -
|
| -import projects
|
| -from verification import base
|
| -from verification import presubmit_check
|
| -from verification import try_job_on_rietveld
|
| -
|
| -# From /tests
|
| -import mocks
|
| -
|
| -
|
| -def _try_comment(pc, issue=31337):
|
| - return (
|
| - "add_comment(%d, u'%shttp://localhost/user@example.com/%d/1\\n')" %
|
| - (issue, pc.TRYING_PATCH.replace('\n', '\\n'),
|
| - issue))
|
| -
|
| -
|
| -class TestCase(mocks.TestCase):
|
| - def setUp(self):
|
| - super(TestCase, self).setUp()
|
| - self.mock(projects, '_read_lines', self._read_lines)
|
| - self.mock(
|
| - projects.async_push,
|
| - 'AsyncPush', lambda _1, _2: mocks.AsyncPushMock(self))
|
| - class Dummy(object):
|
| - @staticmethod
|
| - def get_list():
|
| - return []
|
| - if not projects.chromium_committers:
|
| - projects.chromium_committers = Dummy()
|
| - self.mock(
|
| - projects.chromium_committers, 'get_list', self._get_committers_list)
|
| - if not projects.nacl_committers:
|
| - projects.nacl_committers = Dummy()
|
| - self.mock(projects.nacl_committers, 'get_list', self._get_committers_list)
|
| - self.mock(presubmit_check.subprocess2, 'check_output', self._check_output)
|
| - self.mock(urllib2, 'urlopen', self._urlopen)
|
| - self.mock(time, 'time', self._time)
|
| - self.check_output = []
|
| - self.read_lines = []
|
| - self.urlrequests = []
|
| - self.time = []
|
| -
|
| - def tearDown(self):
|
| - try:
|
| - if not self.has_failed():
|
| - self.assertEqual([], self.check_output)
|
| - self.assertEqual([], self.read_lines)
|
| - self.assertEqual([], self.urlrequests)
|
| - self.assertEqual([], self.time)
|
| - finally:
|
| - super(TestCase, self).tearDown()
|
| -
|
| - # Mocks
|
| - def _urlopen(self, url):
|
| - if not self.urlrequests:
|
| - self.fail(url)
|
| - expected_url, data = self.urlrequests.pop(0)
|
| - self.assertEqual(expected_url, url)
|
| - return StringIO.StringIO(data)
|
| -
|
| - @staticmethod
|
| - def _get_committers_list():
|
| - return ['user@example.com', 'user@example.org']
|
| -
|
| - def _read_lines(self, root, error):
|
| - if not self.read_lines:
|
| - self.fail(root)
|
| - a = self.read_lines.pop(0)
|
| - self.assertEqual(a[0], root)
|
| - self.assertEqual(a[1], error)
|
| - return a[2]
|
| -
|
| - def _check_output(self, *args, **kwargs):
|
| - # For now, ignore the arguments. Change if necessary.
|
| - if not self.check_output:
|
| - self.fail((args, kwargs))
|
| - return self.check_output.pop(0)
|
| -
|
| - def _time(self):
|
| - self.assertTrue(self.time)
|
| - return self.time.pop(0)
|
| -
|
| -
|
| -class ProjectTest(TestCase):
|
| - def setUp(self):
|
| - super(ProjectTest, self).setUp()
|
| -
|
| - def test_loaded(self):
|
| - members = (
|
| - 'blink', 'chromium', 'chromium_deps', 'gyp', 'nacl', 'skia', 'tools')
|
| - self.assertEqual(sorted(members), sorted(projects.supported_projects()))
|
| -
|
| - def test_all(self):
|
| - # Make sure it's possible to load each project.
|
| - self.time = [1] * 2
|
| - root_dir = os.path.join(os.getcwd(), 'root_dir')
|
| - chromium_status_pwd = os.path.join(root_dir, '.chromium_status_pwd')
|
| - skia_status_pwd = os.path.join(root_dir, '.skia_status_pwd')
|
| - mapping = {
|
| - 'blink': {
|
| - 'lines': [
|
| - chromium_status_pwd, 'chromium-status password', ['foo'],
|
| - ],
|
| - 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'],
|
| - 'verifiers': ['try job rietveld', 'tree status'],
|
| - },
|
| - 'chromium': {
|
| - 'lines': [
|
| - chromium_status_pwd, 'chromium-status password', ['foo'],
|
| - ],
|
| - 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'],
|
| - 'verifiers': ['try job rietveld', 'tree status'],
|
| - },
|
| - 'chromium_deps': {
|
| - 'lines': [
|
| - chromium_status_pwd, 'chromium-status password', ['foo'],
|
| - ],
|
| - 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'],
|
| - 'verifiers': ['presubmit'],
|
| - },
|
| - 'gyp': {
|
| - 'lines': [
|
| - chromium_status_pwd, 'chromium-status password', ['foo'],
|
| - ],
|
| - 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'],
|
| - 'verifiers': ['tree status'],
|
| - },
|
| - 'nacl': {
|
| - 'lines': [
|
| - chromium_status_pwd, 'chromium-status password', ['foo'],
|
| - ],
|
| - 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'],
|
| - 'verifiers': ['presubmit', 'tree status'],
|
| - },
|
| - 'skia': {
|
| - 'lines': [
|
| - skia_status_pwd, 'skia-status password', ['foo'],
|
| - ],
|
| - 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'],
|
| - 'verifiers': ['presubmit', 'tree status'],
|
| - },
|
| - 'tools': {
|
| - 'lines': [
|
| - chromium_status_pwd, 'chromium-status password', ['foo'],
|
| - ],
|
| - 'pre_patch_verifiers': ['project_bases', 'reviewer_lgtm'],
|
| - 'verifiers': ['presubmit'],
|
| - },
|
| - }
|
| - for project in sorted(projects.supported_projects()):
|
| - logging.debug(project)
|
| - self.assertEqual([], self.read_lines)
|
| - expected = mapping.pop(project)
|
| - self.read_lines = [expected['lines']]
|
| - p = projects.load_project(
|
| - project, 'user', root_dir, self.context.rietveld, True)
|
| - self.assertEqual(
|
| - expected['pre_patch_verifiers'],
|
| - [x.name for x in p.pre_patch_verifiers],
|
| - (expected['pre_patch_verifiers'],
|
| - [x.name for x in p.pre_patch_verifiers],
|
| - project))
|
| - self.assertEqual(
|
| - expected['verifiers'], [x.name for x in p.verifiers],
|
| - (expected['verifiers'],
|
| - [x.name for x in p.verifiers],
|
| - project))
|
| - if project == 'tools':
|
| - # Add special checks for it.
|
| - project_bases_verifier = p.pre_patch_verifiers[0]
|
| - branch = '\\@[a-zA-Z0-9\\-_\\.]+$'
|
| - self.assertEqual(
|
| - [
|
| - # svn
|
| - '^svn\\:\\/\\/svn\\.chromium\\.org\\/chrome/trunk/tools(|/.*)$',
|
| - '^svn\\:\\/\\/chrome\\-svn\\/chrome/trunk/tools(|/.*)$',
|
| - '^svn\\:\\/\\/chrome\\-svn\\.corp\\/chrome/trunk/tools(|/.*)$',
|
| - '^svn\\:\\/\\/chrome\\-svn\\.corp\\.google\\.com\\/chrome/trunk/'
|
| - 'tools(|/.*)$',
|
| - '^http\\:\\/\\/src\\.chromium\\.org\\/svn/trunk/tools(|/.*)$',
|
| - '^https\\:\\/\\/src\\.chromium\\.org\\/svn/trunk/tools(|/.*)$',
|
| - '^http\\:\\/\\/src\\.chromium\\.org\\/chrome/trunk/tools(|/.*)$',
|
| - '^https\\:\\/\\/src\\.chromium\\.org\\/chrome/trunk/tools(|/.*)$',
|
| -
|
| - # git
|
| - '^https?\\:\\/\\/git\\.chromium\\.org\\/git\\/chromium\\/tools\\/'
|
| - '([a-z0-9\\-_]+)(?:\\.git)?' + branch,
|
| - '^https?\\:\\/\\/git\\.chromium\\.org\\/chromium\\/tools\\/'
|
| - '([a-z0-9\\-_]+)(?:\\.git)?' + branch,
|
| - '^https?\\:\\/\\/chromium\\.googlesource\\.com\\/chromium\\/tools'
|
| - '\\/([a-z0-9\\-_]+)(?:\\.git)?' + branch,
|
| - '^https?\\:\\/\\/chromium\\.googlesource\\.com\\/a\\/chromium\\/'
|
| - 'tools\\/([a-z0-9\\-_]+)(?:\\.git)?' + branch,
|
| - ],
|
| - project_bases_verifier.project_bases)
|
| - self.assertEqual({}, mapping)
|
| -
|
| -
|
| -class ChromiumStateLoad(TestCase):
|
| - # Load a complete state and ensure the code is reacting properly.
|
| - def setUp(self):
|
| - super(ChromiumStateLoad, self).setUp()
|
| - self.buildbot = mocks.BuildbotMock(self)
|
| - self.mock(
|
| - try_job_on_rietveld.buildbot_json, 'Buildbot', lambda _: self.buildbot)
|
| - self.tempdir = tempfile.mkdtemp(prefix='project_test')
|
| - self.now = None
|
| -
|
| - def tearDown(self):
|
| - try:
|
| - shutil.rmtree(self.tempdir)
|
| - finally:
|
| - super(ChromiumStateLoad, self).tearDown()
|
| -
|
| - def _add_build(self, builder, buildnumber, revision, steps, completed):
|
| - """Adds a build with a randomly generated key."""
|
| - key = ''.join(random.choice(string.ascii_letters) for _ in xrange(8))
|
| - build = self.buildbot.add_build(
|
| - builder, buildnumber, revision, key, completed, None)
|
| - build.steps.extend(steps)
|
| - return key
|
| -
|
| - def _LoadPendingManagerState(self, issue):
|
| - self.urlrequests = [
|
| - ( 'http://chromium-status.appspot.com/allstatus?format=json&endTime=%d' %
|
| - (self.now - 300),
|
| - # In theory we should return something but nothing works fine.
|
| - '[]'),
|
| - ]
|
| - self.read_lines = [
|
| - [
|
| - os.path.join(self.tempdir, '.chromium_status_pwd'),
|
| - 'chromium-status password',
|
| - ['foo'],
|
| - ],
|
| - ]
|
| - self.context.rietveld.patchsets_properties[(issue, 1)] = {}
|
| -
|
| - self.time = [self.now] * 1
|
| - pc = projects.load_project(
|
| - 'chromium', 'invalid', self.tempdir, self.context.rietveld, False)
|
| - self.assertEqual(0, len(self.time))
|
| - pc.context = self.context
|
| - pc.load(os.path.join(ROOT_DIR, 'chromium.%d.json' % issue))
|
| -
|
| - # Verify the content a bit.
|
| - self.assertEqual(1, len(pc.queue.iterate()))
|
| - self.assertEqual(issue, pc.queue.get(issue).issue)
|
| - expected = [
|
| - u'presubmit',
|
| - u'project_bases',
|
| - u'reviewer_lgtm',
|
| - u'tree status',
|
| - u'try job rietveld',
|
| - ]
|
| - self.assertEqual(expected, sorted(pc.queue.get(issue).verifications))
|
| -
|
| - return pc
|
| -
|
| - def _verify_final_state(self, verifications, why_not, rietveld_calls):
|
| - for name, obj in verifications.iteritems():
|
| - if name == 'try job rietveld':
|
| - self.assertEqual(base.PROCESSING, obj.get_state(), name)
|
| - self.assertEqual(why_not, obj.why_not())
|
| - else:
|
| - self.assertEqual(base.SUCCEEDED, obj.get_state(), name)
|
| - self.assertEqual(None, obj.why_not())
|
| -
|
| - if name == 'tree status':
|
| - self.time = [self.now] * 1
|
| - self.assertEqual(False, obj.postpone(), name)
|
| - self.assertEqual(0, len(self.time))
|
| - else:
|
| - self.assertEqual(False, obj.postpone(), name)
|
| - self.context.rietveld.check_calls(rietveld_calls)
|
| -
|
| - def testLoadState(self):
|
| - self.now = 1354207000.
|
| - issue = 31337
|
| - pending_manager = self._LoadPendingManagerState(issue)
|
| -
|
| - # Then fix the crap out of it.
|
| - self.time = [self.now] * 3
|
| - pending_manager.update_status()
|
| - self.assertEqual(0, len(self.time))
|
| - self.assertEqual(1, len(pending_manager.queue.iterate()))
|
| -
|
| - why_not = (u'Waiting for the following jobs:\n'
|
| - ' win_rel: sync_integration_tests\n')
|
| - rietveld_calls = [
|
| - "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'win_rel': "
|
| - "[u'sync_integration_tests']})" % issue
|
| - ]
|
| - self._verify_final_state(pending_manager.queue.get(issue).verifications,
|
| - why_not, rietveld_calls)
|
| -
|
| - def testLoadState11299256(self):
|
| - # Loads a saved state and try to revive it.
|
| - self.now = 1354551606.
|
| - issue = 11299256
|
| - pending_manager = self._LoadPendingManagerState(issue)
|
| - self._add_build('ios_rel_device', 1, 2, [], 4)
|
| -
|
| - # Then fix the crap out of it.
|
| - self.time = [self.now] * 3
|
| - pending_manager.update_status()
|
| - self.assertEqual(1, len(self.time))
|
| - self.assertEqual(1, len(pending_manager.queue.iterate()))
|
| -
|
| - why_not = (u'Waiting for the following jobs:\n'
|
| - ' ios_rel_device: compile\n')
|
| - rietveld_calls = []
|
| - # ios_rel_device seems lost. CQ should not reissue it now to avoid
|
| - # overloading the tryserver.
|
| - self._verify_final_state(pending_manager.queue.get(issue).verifications,
|
| - why_not, rietveld_calls)
|
| -
|
| - def testLoadState12208028(self):
|
| - # Loads a saved state and try to revive it.
|
| - self.now = 1360256000.
|
| - issue = 12208028
|
| - pending_manager = self._LoadPendingManagerState(issue)
|
| -
|
| - # Then fix the crap out of it.
|
| - self.time = [self.now] * 3
|
| - pending_manager.update_status()
|
| - self.assertEqual(0, len(self.time))
|
| - self.assertEqual(1, len(pending_manager.queue.iterate()))
|
| -
|
| - why_not = (u'Waiting for the following jobs:\n'
|
| - ' android_dbg_triggered_tests: build\n')
|
| - rietveld_calls = [
|
| - "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'android_dbg': "
|
| - "[u'build']})" % issue
|
| - ]
|
| - self._verify_final_state(pending_manager.queue.get(issue).verifications,
|
| - why_not, rietveld_calls)
|
| -
|
| - def testLoadState12253015(self):
|
| - # Loads a saved state and try to revive it.
|
| - self.now = 1360256000.
|
| - issue = 12253015
|
| - pending_manager = self._LoadPendingManagerState(issue)
|
| -
|
| - # Then fix the crap out of it.
|
| - self.time = [self.now] * 3
|
| - pending_manager.update_status()
|
| - self.assertEqual(0, len(self.time))
|
| - self.assertEqual(1, len(pending_manager.queue.iterate()))
|
| -
|
| - why_not = (
|
| - u'Waiting for the following jobs:\n'
|
| - ' win7_aura: browser_tests\n'
|
| - ' win_rel: chrome_frame_tests,chrome_frame_net_tests,browser_tests,'
|
| - 'nacl_integration,sync_integration_tests,installer_util_unittests,'
|
| - 'content_browsertests,chrome_frame_unittests,mini_installer_test\n')
|
| - rietveld_calls = [
|
| - "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'win7_aura': "
|
| - "[u'browser_tests']})" % issue,
|
| - ]
|
| - self._verify_final_state(pending_manager.queue.get(issue).verifications,
|
| - why_not, rietveld_calls)
|
| -
|
| - def testLoadState12633013(self):
|
| - # Loads a saved state and try to revive it.
|
| - self.now = 1363610000.
|
| - issue = 12633013
|
| - pending_manager = self._LoadPendingManagerState(issue)
|
| -
|
| - # Then fix the crap out of it.
|
| - self.time = [self.now] * 3
|
| - pending_manager.update_status()
|
| - self.assertEqual(0, len(self.time))
|
| - self.assertEqual(1, len(pending_manager.queue.iterate()))
|
| -
|
| - why_not = (
|
| - u'Waiting for the following jobs:\n'
|
| - ' android_dbg_triggered_tests: slave_steps\n')
|
| - rietveld_calls = [
|
| - "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'android_dbg': "
|
| - "[u'slave_steps']})" % issue,
|
| - ]
|
| - self._verify_final_state(pending_manager.queue.get(issue).verifications,
|
| - why_not, rietveld_calls)
|
| -
|
| - def testLoadStateSwarm(self):
|
| - # Loads a saved state and try to revive it.
|
| - self.now = 1360256000.
|
| - issue = 666
|
| - pending_manager = self._LoadPendingManagerState(issue)
|
| -
|
| - # Then fix the crap out of it.
|
| - self.time = [self.now] * 5
|
| - pending_manager.update_status()
|
| - self.assertEqual(0, len(self.time))
|
| - self.assertEqual(1, len(pending_manager.queue.iterate()))
|
| -
|
| - why_not = (u'Waiting for the following jobs:\n'
|
| - ' linux_rel: browser_tests\n'
|
| - ' mac_rel: browser_tests\n'
|
| - ' win_rel: browser_tests\n')
|
| - # TODO(csharp): These triggered events should be the swarm versions,
|
| - # change them once swarm tests are enabled by default.
|
| - rietveld_calls = [
|
| - "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'linux_rel': "
|
| - "[u'browser_tests']})" % issue,
|
| - "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'mac_rel': "
|
| - "[u'browser_tests']})" % issue,
|
| - "trigger_try_jobs(%d, 1, 'CQ', False, 'HEAD', {u'win_rel': "
|
| - "[u'browser_tests']})" % issue,
|
| - ]
|
| - self._verify_final_state(pending_manager.queue.get(issue).verifications,
|
| - why_not, rietveld_calls)
|
| -
|
| - def test_tbr(self):
|
| - self.time = map(lambda x: float(x*35), range(15))
|
| - self.urlrequests = [
|
| - ('https://chromium-status.appspot.com/allstatus?format=json&endTime=85',
|
| - # Cheap hack here.
|
| - '[]'),
|
| - ]
|
| - root_dir = os.path.join(os.getcwd(), 'root_dir')
|
| - self.read_lines = [
|
| - [
|
| - os.path.join(root_dir, '.chromium_status_pwd'),
|
| - 'chromium-status password',
|
| - ['foo'],
|
| - ],
|
| - ]
|
| - pc = projects.load_project(
|
| - 'chromium', 'commit-bot-test', root_dir, self.context.rietveld, True)
|
| - pc.context = self.context
|
| - issue = self.context.rietveld.issues[31337]
|
| - self.context.rietveld.patchsets_properties[(31337, 1)] = {}
|
| -
|
| - # A TBR= patch without reviewer nor messages, like a webkit roll.
|
| - issue['description'] += '\nTBR='
|
| - issue['reviewers'] = []
|
| - issue['messages'] = []
|
| - issue['owner_email'] = u'user@example.com'
|
| - issue['base_url'] = u'svn://svn.chromium.org/chrome/trunk/src'
|
| - pc.look_for_new_pending_commit()
|
| - pc.process_new_pending_commit()
|
| - pc.update_status()
|
| - pc.scan_results()
|
| - self.assertEqual(1, len(pc.queue.iterate()))
|
| - key = self._add_build('chromium_presubmit', 123456, 124,
|
| - [mocks.BuildbotBuildStep('presubmit', False)], True)
|
| - self.context.rietveld.patchsets_properties[(31337, 1)] = {
|
| - 'try_job_results': [{
|
| - 'builder': "chromium_presubmit",
|
| - 'key': key,
|
| - 'buildnumber': "123456",
|
| - }]}
|
| - build = self.buildbot.builders['chromium_presubmit'].builds[123456]
|
| - build.steps[0].simplified_result = True
|
| - pc.update_status()
|
| - pc.scan_results()
|
| - self.assertEqual(0, len(pc.queue.iterate()))
|
| - # check_calls
|
| - self.context.rietveld.check_calls([
|
| - _try_comment(pc),
|
| - "trigger_try_jobs(31337, 1, 'CQ', False, 'HEAD', "
|
| - "{u'chromium_presubmit': ['presubmit']})",
|
| - 'close_issue(31337)',
|
| - "update_description(31337, u'foo\\nTBR=')",
|
| - "add_comment(31337, 'Change committed as 125')",
|
| - ])
|
| - self.context.checkout.check_calls([
|
| - 'prepare(None)',
|
| - 'apply_patch(%r)' % self.context.rietveld.patchsets[0],
|
| - 'prepare(None)',
|
| - 'apply_patch(%r)' % self.context.rietveld.patchsets[1],
|
| - "commit(u'foo\\nTBR=\\n\\nReview URL: http://nowhere/31337', "
|
| - "u'user@example.com')",
|
| - ])
|
| - self.context.status.check_names(['initial', 'why not', 'why not',
|
| - 'why not', 'commit'])
|
| -
|
| -
|
| -
|
| -if __name__ == '__main__':
|
| - logging.basicConfig(
|
| - level=logging.DEBUG if '-v' in sys.argv else logging.WARNING,
|
| - format='%(levelname)5s %(module)15s(%(lineno)3d): %(message)s')
|
| - unittest.main()
|
|
|