blob: 37ade864d497edfe82420b1a39126ca716b1085a [file] [log] [blame]
# 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.
"""Common mocks."""
import copy
import os
import sys
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(ROOT_DIR, '..'))
import find_depot_tools # pylint: disable=W0611
import breakpad
import patch
import async_push
import context
import pending_manager
from testing_support import auto_stub
SVN_PATCH = (
'Index: chrome/file.cc\n'
'===================================================================\n'
'--- chrome/file.cc\t(revision 74690)\n'
'+++ chrome/file.cc\t(working copy)\n'
'@@ -80,10 +80,10 @@\n'
' // Foo\n'
' // Bar\n'
' void foo() {\n'
'- return bar;\n'
'+ return foo;\n'
' }\n'
' \n'
' \n')
class RietveldMock(auto_stub.SimpleMock):
url = 'http://nowhere'
email = 'fake_email'
password = 'fake_password'
def __init__(self, unit_test):
super(RietveldMock, self).__init__(unit_test)
self.issues = {
31337: {
"description": u"foo",
"created": "2010-12-27 03:23:31.149045",
"cc": ["cc@example.com",],
"reviewers": ["rev@example.com"],
"owner_email": "author@example.com",
"patchsets": [1],
"modified": "2011-01-10 20:52:39.127231",
"private": False,
"base_url": "svn://fake/repo",
"closed": False,
"owner": "Author",
"issue": 31337,
"subject": 'foo',
"messages": [
{
"date": "2010-12-27 03:23:32.489999",
"text": u"hi!",
"sender": "author@example.com",
"recipients": ["rev@example.com", "cc@example.com"],
"approval": False,
},
{
"date": "2010-12-27 03:23:32.489999",
"text": u"hi!",
"sender": "rev@example.com",
"recipients": ["rev@example.com", "cc@example.com"],
"approval": True,
},
],
"commit": True,
},
}
self.patchsets = []
# Key is (issue, patchset)
self.patchsets_properties = {}
def get_pending_issues(self):
return self.issues.keys()
def get_issue_properties(self, issue_id, _):
return copy.deepcopy(self.issues[issue_id])
def get_patchset_properties(self, issue_id, patchset):
key = (issue_id, patchset)
self.unit_test.assertTrue(
key in self.patchsets_properties, (key, self.patchsets_properties))
return copy.deepcopy(self.patchsets_properties[key])
def close_issue(self, *args, **kwargs):
self._register_call(*args, **kwargs)
def update_description(self, *args, **kwargs):
self._register_call(*args, **kwargs)
def set_flag(self, *args, **kwargs):
self._register_call(*args, **kwargs)
return True
def add_comment(self, *args, **kwargs):
self._register_call(*args, **kwargs)
def get_patch(self, _issue, _patchset):
self.patchsets.append(patch.PatchSet([
patch.FilePatchDiff('chrome/file.cc', SVN_PATCH, []),
patch.FilePatchDelete('other/place/foo', True),
patch.FilePatchBinary('foo', 'data', [], True),
]))
return self.patchsets[-1]
def _send(self, *args, **kwargs):
self._register_call(*args, **kwargs)
def trigger_try_jobs(self, *args, **kwargs):
self._register_call(*args, **kwargs)
@staticmethod
def xsrf_token():
return 'XSRF-free'
def post(self, *args, **kwargs):
self._register_call(*args, **kwargs)
class SvnCheckoutMock(auto_stub.SimpleMock):
def __init__(self, *args):
super(SvnCheckoutMock, self).__init__(*args)
self.project_path = os.getcwd()
self.project_name = os.path.basename(self.project_path)
self.post_processors = []
def prepare(self, revision):
self._register_call(revision)
# prepare() should always return a valid revision.
return revision or 124
def apply_patch(self, *args):
self._register_call(*args)
def commit(self, *args):
self._register_call(*args)
return 125
@staticmethod
def get_settings(_key):
return None
@staticmethod
def revisions(_revision1, _revision2):
"""Number of revisions between 2 revisions."""
return 3
class AsyncPushMock(auto_stub.SimpleMock, async_push.AsyncPushNoop):
def __init__(self, *args):
auto_stub.SimpleMock.__init__(self, *args)
async_push.AsyncPushNoop.__init__(self)
self.queue = []
def send(self, packet, pending):
self.queue.append(self._package(packet, pending))
def pop_packets(self):
packets = self.queue
self.queue = []
return packets
def check_packets(self, expected):
self.assertEqual(expected, self.pop_packets())
def check_names(self, expected):
self.assertEqual(expected, [i['verification'] for i in self.pop_packets()])
class BuildbotBuilder(object):
def __init__(self):
self.builds = {}
class Data(object):
def __init__(self):
self.data = {}
self.pending_builds = Data()
class BuildbotBuild(object):
def __init__(self, revision, key, completed, parent_key):
self.properties_as_dict = {
'try_job_key': key,
'parent_try_job_key': parent_key,
}
self.revision = revision
self.start_time = 1
self.steps = []
self.completed = completed
self.duration = 180
class BuildbotBuildStep(object):
def __init__(self, name, result):
self.name = name
self.simplified_result = result
class BuildbotBuilders(object):
def __init__(self, initial):
self.values = initial.copy()
def __getitem__(self, key):
return self.values[key]
@property
def keys(self):
return self.values.keys()
def setdefault(self, key, value):
return self.values.setdefault(key, value)
class BuildbotMock(auto_stub.SimpleMock):
"""Stateful try server mock."""
def __init__(self, unit_test):
super(BuildbotMock, self).__init__(unit_test)
self.builders = BuildbotBuilders({
u'mac': BuildbotBuilder(),
u'linux': BuildbotBuilder(),
})
def discard(self):
pass
def add_build(self, builder, number, revision, key, completed, parent_key):
"""Add a build to a builder."""
builder = self.builders.setdefault(builder, BuildbotBuilder())
builder.builds[number] = BuildbotBuild(revision, key, completed, parent_key)
return builder.builds[number]
class TestCase(auto_stub.TestCase):
def setUp(self):
super(TestCase, self).setUp()
self.mock(breakpad, 'SendStack', self._send_stack_mock)
self.context = context.Context(
RietveldMock(self), SvnCheckoutMock(self), AsyncPushMock(self), False)
self.pending = pending_manager.PendingCommit(
issue=42,
owner='owner@example.com',
reviewers=[],
patchset=23,
base_url='',
description=u'bleh',
messages=[])
def tearDown(self):
try:
if not self.has_failed():
self.context.rietveld.check_calls([])
self.context.checkout.check_calls([])
self.context.status.check_packets([])
finally:
super(TestCase, self).tearDown()
def _send_stack_mock(self, last_tb, stack, *_args, **_kwargs):
"""Fails a test that calls SendStack.
In practice it doesn't happen when a test pass but will when a test fails so
hook it here so breakpad doesn't send too many stack traces to maintainers.
"""
self.fail('%s, %s' % (last_tb, stack))