| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """Common mocks.""" | |
| 6 | |
| 7 import copy | |
| 8 import os | |
| 9 import sys | |
| 10 | |
| 11 ROOT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| 12 sys.path.insert(0, os.path.join(ROOT_DIR, '..')) | |
| 13 | |
| 14 import find_depot_tools # pylint: disable=W0611 | |
| 15 import breakpad | |
| 16 import patch | |
| 17 | |
| 18 import async_push | |
| 19 import context | |
| 20 import pending_manager | |
| 21 | |
| 22 from testing_support import auto_stub | |
| 23 | |
| 24 | |
| 25 SVN_PATCH = ( | |
| 26 'Index: chrome/file.cc\n' | |
| 27 '===================================================================\n' | |
| 28 '--- chrome/file.cc\t(revision 74690)\n' | |
| 29 '+++ chrome/file.cc\t(working copy)\n' | |
| 30 '@@ -80,10 +80,10 @@\n' | |
| 31 ' // Foo\n' | |
| 32 ' // Bar\n' | |
| 33 ' void foo() {\n' | |
| 34 '- return bar;\n' | |
| 35 '+ return foo;\n' | |
| 36 ' }\n' | |
| 37 ' \n' | |
| 38 ' \n') | |
| 39 | |
| 40 | |
| 41 class RietveldMock(auto_stub.SimpleMock): | |
| 42 url = 'http://nowhere' | |
| 43 email = 'fake_email' | |
| 44 password = 'fake_password' | |
| 45 | |
| 46 def __init__(self, unit_test): | |
| 47 super(RietveldMock, self).__init__(unit_test) | |
| 48 self.issues = { | |
| 49 31337: { | |
| 50 "description": u"foo", | |
| 51 "created": "2010-12-27 03:23:31.149045", | |
| 52 "cc": ["cc@example.com",], | |
| 53 "reviewers": ["rev@example.com"], | |
| 54 "owner_email": "author@example.com", | |
| 55 "patchsets": [1], | |
| 56 "modified": "2011-01-10 20:52:39.127231", | |
| 57 "private": False, | |
| 58 "base_url": "svn://fake/repo", | |
| 59 "closed": False, | |
| 60 "owner": "Author", | |
| 61 "issue": 31337, | |
| 62 "subject": 'foo', | |
| 63 "messages": [ | |
| 64 { | |
| 65 "date": "2010-12-27 03:23:32.489999", | |
| 66 "text": u"hi!", | |
| 67 "sender": "author@example.com", | |
| 68 "recipients": ["rev@example.com", "cc@example.com"], | |
| 69 "approval": False, | |
| 70 }, | |
| 71 { | |
| 72 "date": "2010-12-27 03:23:32.489999", | |
| 73 "text": u"hi!", | |
| 74 "sender": "rev@example.com", | |
| 75 "recipients": ["rev@example.com", "cc@example.com"], | |
| 76 "approval": True, | |
| 77 }, | |
| 78 ], | |
| 79 "commit": True, | |
| 80 }, | |
| 81 } | |
| 82 self.patchsets = [] | |
| 83 # Key is (issue, patchset) | |
| 84 self.patchsets_properties = {} | |
| 85 | |
| 86 def get_pending_issues(self): | |
| 87 return self.issues.keys() | |
| 88 | |
| 89 def get_issue_properties(self, issue_id, _): | |
| 90 return copy.deepcopy(self.issues[issue_id]) | |
| 91 | |
| 92 def get_patchset_properties(self, issue_id, patchset): | |
| 93 key = (issue_id, patchset) | |
| 94 self.unit_test.assertTrue( | |
| 95 key in self.patchsets_properties, (key, self.patchsets_properties)) | |
| 96 return copy.deepcopy(self.patchsets_properties[key]) | |
| 97 | |
| 98 def close_issue(self, *args, **kwargs): | |
| 99 self._register_call(*args, **kwargs) | |
| 100 | |
| 101 def update_description(self, *args, **kwargs): | |
| 102 self._register_call(*args, **kwargs) | |
| 103 | |
| 104 def set_flag(self, *args, **kwargs): | |
| 105 self._register_call(*args, **kwargs) | |
| 106 return True | |
| 107 | |
| 108 def add_comment(self, *args, **kwargs): | |
| 109 self._register_call(*args, **kwargs) | |
| 110 | |
| 111 def get_patch(self, _issue, _patchset): | |
| 112 self.patchsets.append(patch.PatchSet([ | |
| 113 patch.FilePatchDiff('chrome/file.cc', SVN_PATCH, []), | |
| 114 patch.FilePatchDelete('other/place/foo', True), | |
| 115 patch.FilePatchBinary('foo', 'data', [], True), | |
| 116 ])) | |
| 117 return self.patchsets[-1] | |
| 118 | |
| 119 def _send(self, *args, **kwargs): | |
| 120 self._register_call(*args, **kwargs) | |
| 121 | |
| 122 def trigger_try_jobs(self, *args, **kwargs): | |
| 123 self._register_call(*args, **kwargs) | |
| 124 | |
| 125 @staticmethod | |
| 126 def xsrf_token(): | |
| 127 return 'XSRF-free' | |
| 128 | |
| 129 def post(self, *args, **kwargs): | |
| 130 self._register_call(*args, **kwargs) | |
| 131 | |
| 132 | |
| 133 class SvnCheckoutMock(auto_stub.SimpleMock): | |
| 134 def __init__(self, *args): | |
| 135 super(SvnCheckoutMock, self).__init__(*args) | |
| 136 self.project_path = os.getcwd() | |
| 137 self.project_name = os.path.basename(self.project_path) | |
| 138 self.post_processors = [] | |
| 139 | |
| 140 def prepare(self, revision): | |
| 141 self._register_call(revision) | |
| 142 # prepare() should always return a valid revision. | |
| 143 return revision or 124 | |
| 144 | |
| 145 def apply_patch(self, *args): | |
| 146 self._register_call(*args) | |
| 147 | |
| 148 def commit(self, *args): | |
| 149 self._register_call(*args) | |
| 150 return 125 | |
| 151 | |
| 152 @staticmethod | |
| 153 def get_settings(_key): | |
| 154 return None | |
| 155 | |
| 156 @staticmethod | |
| 157 def revisions(_revision1, _revision2): | |
| 158 """Number of revisions between 2 revisions.""" | |
| 159 return 3 | |
| 160 | |
| 161 | |
| 162 class AsyncPushMock(auto_stub.SimpleMock, async_push.AsyncPushNoop): | |
| 163 def __init__(self, *args): | |
| 164 auto_stub.SimpleMock.__init__(self, *args) | |
| 165 async_push.AsyncPushNoop.__init__(self) | |
| 166 self.queue = [] | |
| 167 | |
| 168 def send(self, packet, pending): | |
| 169 self.queue.append(self._package(packet, pending)) | |
| 170 | |
| 171 def pop_packets(self): | |
| 172 packets = self.queue | |
| 173 self.queue = [] | |
| 174 return packets | |
| 175 | |
| 176 def check_packets(self, expected): | |
| 177 self.assertEqual(expected, self.pop_packets()) | |
| 178 | |
| 179 def check_names(self, expected): | |
| 180 self.assertEqual(expected, [i['verification'] for i in self.pop_packets()]) | |
| 181 | |
| 182 | |
| 183 class BuildbotBuilder(object): | |
| 184 def __init__(self): | |
| 185 self.builds = {} | |
| 186 class Data(object): | |
| 187 def __init__(self): | |
| 188 self.data = {} | |
| 189 self.pending_builds = Data() | |
| 190 | |
| 191 | |
| 192 class BuildbotBuild(object): | |
| 193 def __init__(self, revision, key, completed, parent_key): | |
| 194 self.properties_as_dict = { | |
| 195 'try_job_key': key, | |
| 196 'parent_try_job_key': parent_key, | |
| 197 } | |
| 198 self.revision = revision | |
| 199 self.start_time = 1 | |
| 200 self.steps = [] | |
| 201 self.completed = completed | |
| 202 self.duration = 180 | |
| 203 | |
| 204 | |
| 205 class BuildbotBuildStep(object): | |
| 206 def __init__(self, name, result): | |
| 207 self.name = name | |
| 208 self.simplified_result = result | |
| 209 | |
| 210 | |
| 211 class BuildbotBuilders(object): | |
| 212 def __init__(self, initial): | |
| 213 self.values = initial.copy() | |
| 214 | |
| 215 def __getitem__(self, key): | |
| 216 return self.values[key] | |
| 217 | |
| 218 @property | |
| 219 def keys(self): | |
| 220 return self.values.keys() | |
| 221 | |
| 222 def setdefault(self, key, value): | |
| 223 return self.values.setdefault(key, value) | |
| 224 | |
| 225 | |
| 226 class BuildbotMock(auto_stub.SimpleMock): | |
| 227 """Stateful try server mock.""" | |
| 228 | |
| 229 def __init__(self, unit_test): | |
| 230 super(BuildbotMock, self).__init__(unit_test) | |
| 231 self.builders = BuildbotBuilders({ | |
| 232 u'mac': BuildbotBuilder(), | |
| 233 u'linux': BuildbotBuilder(), | |
| 234 }) | |
| 235 | |
| 236 def discard(self): | |
| 237 pass | |
| 238 | |
| 239 def add_build(self, builder, number, revision, key, completed, parent_key): | |
| 240 """Add a build to a builder.""" | |
| 241 builder = self.builders.setdefault(builder, BuildbotBuilder()) | |
| 242 builder.builds[number] = BuildbotBuild(revision, key, completed, parent_key) | |
| 243 return builder.builds[number] | |
| 244 | |
| 245 | |
| 246 class TestCase(auto_stub.TestCase): | |
| 247 def setUp(self): | |
| 248 super(TestCase, self).setUp() | |
| 249 self.mock(breakpad, 'SendStack', self._send_stack_mock) | |
| 250 self.context = context.Context( | |
| 251 RietveldMock(self), SvnCheckoutMock(self), AsyncPushMock(self), False) | |
| 252 self.pending = pending_manager.PendingCommit( | |
| 253 issue=42, | |
| 254 owner='owner@example.com', | |
| 255 reviewers=[], | |
| 256 patchset=23, | |
| 257 base_url='', | |
| 258 description=u'bleh', | |
| 259 messages=[]) | |
| 260 | |
| 261 def tearDown(self): | |
| 262 try: | |
| 263 if not self.has_failed(): | |
| 264 self.context.rietveld.check_calls([]) | |
| 265 self.context.checkout.check_calls([]) | |
| 266 self.context.status.check_packets([]) | |
| 267 finally: | |
| 268 super(TestCase, self).tearDown() | |
| 269 | |
| 270 def _send_stack_mock(self, last_tb, stack, *_args, **_kwargs): | |
| 271 """Fails a test that calls SendStack. | |
| 272 | |
| 273 In practice it doesn't happen when a test pass but will when a test fails so | |
| 274 hook it here so breakpad doesn't send too many stack traces to maintainers. | |
| 275 """ | |
| 276 self.fail('%s, %s' % (last_tb, stack)) | |
| OLD | NEW |