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 |