blob: 148650497e52b5633738f85d1ae996416ea62a85 [file] [log] [blame]
maruel@chromium.orgddd59412011-11-30 14:20:38 +00001#!/usr/bin/env python
maruel@chromium.orgeb5edbc2012-01-16 17:03:28 +00002# Copyright (c) 2012 The Chromium Authors. All rights reserved.
maruel@chromium.orgddd59412011-11-30 14:20:38 +00003# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unit tests for git_cl.py."""
7
8import os
maruel@chromium.orga3353652011-11-30 14:26:57 +00009import StringIO
ukai@chromium.org78c4b982012-02-14 02:20:26 +000010import stat
maruel@chromium.orgddd59412011-11-30 14:20:38 +000011import sys
12import unittest
13
14sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
15
16from testing_support.auto_stub import TestCase
17
18import git_cl
19import subprocess2
20
21
maruel@chromium.org2e72bb12012-01-17 15:18:35 +000022class PresubmitMock(object):
23 def __init__(self, *args, **kwargs):
24 self.reviewers = []
25 @staticmethod
26 def should_continue():
27 return True
28
29
30class RietveldMock(object):
31 def __init__(self, *args, **kwargs):
32 pass
33 @staticmethod
34 def get_description(issue):
35 return 'Issue: %d' % issue
36
37
38class WatchlistsMock(object):
39 def __init__(self, _):
40 pass
41 @staticmethod
42 def GetWatchersForPaths(_):
43 return ['joe@example.com']
44
45
ukai@chromium.org78c4b982012-02-14 02:20:26 +000046class CodereviewSettingsFileMock(object):
47 def __init__(self):
48 pass
49 # pylint: disable=R0201
50 def read(self):
51 return ("CODE_REVIEW_SERVER: gerrit.chromium.org\n" +
52 "GERRIT_HOST: gerrit.chromium.org\n" +
53 "GERRIT_PORT: 29418\n")
54
55
maruel@chromium.orgddd59412011-11-30 14:20:38 +000056class TestGitCl(TestCase):
57 def setUp(self):
58 super(TestGitCl, self).setUp()
59 self.calls = []
60 self._calls_done = 0
maruel@chromium.org2e72bb12012-01-17 15:18:35 +000061 self.mock(subprocess2, 'call', self._mocked_call)
62 self.mock(subprocess2, 'check_call', self._mocked_call)
63 self.mock(subprocess2, 'check_output', self._mocked_call)
64 self.mock(subprocess2, 'communicate', self._mocked_call)
65 self.mock(subprocess2, 'Popen', self._mocked_call)
maruel@chromium.orgddd59412011-11-30 14:20:38 +000066 self.mock(git_cl, 'FindCodereviewSettingsFile', lambda: '')
maruel@chromium.org2e72bb12012-01-17 15:18:35 +000067 self.mock(git_cl, 'ask_for_data', self._mocked_call)
68 self.mock(git_cl.breakpad, 'post', self._mocked_call)
69 self.mock(git_cl.breakpad, 'SendStack', self._mocked_call)
maruel@chromium.orgddd59412011-11-30 14:20:38 +000070 self.mock(git_cl.presubmit_support, 'DoPresubmitChecks', PresubmitMock)
maruel@chromium.orgddd59412011-11-30 14:20:38 +000071 self.mock(git_cl.rietveld, 'Rietveld', RietveldMock)
maruel@chromium.orgddd59412011-11-30 14:20:38 +000072 self.mock(git_cl.upload, 'RealMain', self.fail)
maruel@chromium.orgddd59412011-11-30 14:20:38 +000073 self.mock(git_cl.watchlists, 'Watchlists', WatchlistsMock)
74 # It's important to reset settings to not have inter-tests interference.
75 git_cl.settings = None
76
77 def tearDown(self):
78 if not self.has_failed():
79 self.assertEquals([], self.calls)
80 super(TestGitCl, self).tearDown()
81
maruel@chromium.org2e72bb12012-01-17 15:18:35 +000082 def _mocked_call(self, *args, **kwargs):
83 self.assertTrue(
84 self.calls,
85 '@%d Expected: <Missing> Actual: %r' % (self._calls_done, args))
86 expected_args, result = self.calls.pop(0)
87 self.assertEquals(
88 expected_args,
89 args,
90 '@%d Expected: %r Actual: %r' % (
91 self._calls_done, expected_args, args))
92 self._calls_done += 1
93 return result
94
maruel@chromium.orga3353652011-11-30 14:26:57 +000095 @classmethod
iannucci@chromium.org79540052012-10-19 23:15:26 +000096 def _upload_calls(cls, similarity, find_copies):
97 return (cls._git_base_calls(similarity, find_copies) +
98 cls._git_upload_calls())
maruel@chromium.orga3353652011-11-30 14:26:57 +000099
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000100 @staticmethod
iannucci@chromium.org79540052012-10-19 23:15:26 +0000101 def _git_base_calls(similarity, find_copies):
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000102 if similarity is None:
103 similarity = '50'
104 similarity_call = ((['git', 'config', '--int', '--get',
105 'branch.master.git-cl-similarity'],), '')
106 else:
107 similarity_call = ((['git', 'config', '--int',
108 'branch.master.git-cl-similarity', similarity],), '')
iannucci@chromium.org79540052012-10-19 23:15:26 +0000109
110 if find_copies is None:
111 find_copies = True
112 find_copies_call = ((['git', 'config', '--int', '--get',
113 'branch.master.git-find-copies'],), '')
114 else:
115 val = str(int(find_copies))
116 find_copies_call = ((['git', 'config', '--int',
117 'branch.master.git-find-copies', val],), '')
118
119 if find_copies:
120 stat_call = ((['git', 'diff', '--no-ext-diff', '--stat',
121 '--find-copies-harder', '-l100000', '-C'+similarity,
122 'master...'],), '+dat')
123 else:
124 stat_call = ((['git', 'diff', '--no-ext-diff', '--stat',
125 '-M'+similarity, 'master...'],), '+dat')
126
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000127 return [
ukai@chromium.orge8077812012-02-03 03:41:46 +0000128 ((['git', 'config', 'gerrit.host'],), ''),
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000129 ((['git', 'config', 'rietveld.server'],), 'codereview.example.com'),
130 ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
131 similarity_call,
iannucci@chromium.org79540052012-10-19 23:15:26 +0000132 ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
133 find_copies_call,
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000134 ((['git', 'update-index', '--refresh', '-q'],), ''),
ukai@chromium.org259e4682012-10-25 07:36:33 +0000135 ((['git', 'diff-index', '--name-status', 'HEAD'],), ''),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000136 ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
137 ((['git', 'config', 'branch.master.merge'],), 'master'),
138 ((['git', 'config', 'branch.master.remote'],), 'origin'),
139 ((['git', 'rev-parse', '--show-cdup'],), ''),
140 ((['git', 'rev-parse', 'HEAD'],), '12345'),
141 ((['git', 'diff', '--name-status', '-r', 'master...', '.'],),
142 'M\t.gitignore\n'),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000143 ((['git', 'config', 'branch.master.rietveldissue'],), ''),
144 ((['git', 'config', 'branch.master.rietveldpatchset'],), ''),
maruel@chromium.org373af802012-05-25 21:07:33 +0000145 ((['git', 'log', '--pretty=format:%s%n%n%b', 'master...'],), 'foo'),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000146 ((['git', 'config', 'user.email'],), 'me@example.com'),
iannucci@chromium.org79540052012-10-19 23:15:26 +0000147 stat_call,
maruel@chromium.org373af802012-05-25 21:07:33 +0000148 ((['git', 'log', '--pretty=format:%s\n\n%b', 'master..'],), 'desc\n'),
maruel@chromium.orga3353652011-11-30 14:26:57 +0000149 ]
150
151 @staticmethod
152 def _git_upload_calls():
153 return [
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000154 ((['git', 'config', 'rietveld.cc'],), ''),
kalmard@homejinni.com6b0051e2012-04-03 15:45:08 +0000155 ((['git', 'config', 'branch.master.base-url'],), ''),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000156 ((['git', 'config', '--get-regexp', '^svn-remote\\.'],),
157 (('', None), 0)),
158 ((['git', 'rev-parse', '--show-cdup'],), ''),
159 ((['git', 'svn', 'info'],), ''),
160 ((['git', 'config', 'branch.master.rietveldissue', '1'],), ''),
161 ((['git', 'config', 'branch.master.rietveldserver',
162 'https://codereview.example.com'],), ''),
163 ((['git', 'config', 'branch.master.rietveldpatchset', '2'],), ''),
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000164 ]
165
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000166 @classmethod
167 def _dcommit_calls_1(cls):
168 return [
169 ((['git', 'config', '--get-regexp', '^svn-remote\\.'],),
170 ((('svn-remote.svn.url svn://svn.chromium.org/chrome\n'
171 'svn-remote.svn.fetch trunk/src:refs/remotes/origin/master'),
172 None),
173 0)),
174 ((['git', 'config', 'rietveld.server'],), 'codereview.example.com'),
175 ((['git', 'symbolic-ref', 'HEAD'],), 'refs/heads/working'),
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000176 ((['git', 'config', '--int', '--get',
177 'branch.working.git-cl-similarity'],), ''),
178 ((['git', 'symbolic-ref', 'HEAD'],), 'refs/heads/working'),
iannucci@chromium.org79540052012-10-19 23:15:26 +0000179 ((['git', 'config', '--int', '--get',
180 'branch.working.git-find-copies'],), ''),
181 ((['git', 'symbolic-ref', 'HEAD'],), 'refs/heads/working'),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000182 ((['git', 'config', 'branch.working.merge'],), 'refs/heads/master'),
183 ((['git', 'config', 'branch.working.remote'],), 'origin'),
szager@chromium.org9bb85e22012-06-13 20:28:23 +0000184 ((['git', 'rev-list', '--merges',
szager@chromium.orge84b7542012-06-15 21:26:58 +0000185 '--grep=^SVN changes up to revision [0-9]*$',
szager@chromium.org9bb85e22012-06-13 20:28:23 +0000186 'refs/remotes/origin/master^!'],), ''),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000187 ((['git', 'update-index', '--refresh', '-q'],), ''),
ukai@chromium.org259e4682012-10-25 07:36:33 +0000188 ((['git', 'diff-index', '--name-status', 'HEAD'],), ''),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000189 ((['git', 'rev-list', '^refs/heads/working',
190 'refs/remotes/origin/master'],),
191 ''),
192 ((['git', 'log', '--grep=^git-svn-id:', '-1', '--pretty=format:%H'],),
193 '3fc18b62c4966193eb435baabe2d18a3810ec82e'),
194 ((['git', 'rev-list', '^3fc18b62c4966193eb435baabe2d18a3810ec82e',
195 'refs/remotes/origin/master'],), ''),
196 ]
197
198 @classmethod
199 def _dcommit_calls_normal(cls):
200 return [
201 ((['git', 'rev-parse', '--show-cdup'],), ''),
202 ((['git', 'rev-parse', 'HEAD'],),
203 '00ff397798ea57439712ed7e04ab96e13969ef40'),
204 ((['git', 'diff', '--name-status', '-r', 'refs/remotes/origin/master...',
205 '.'],),
206 'M\tPRESUBMIT.py'),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000207 ((['git', 'config', 'branch.working.rietveldissue'],), '12345'),
evan@chromium.org0af9b702012-02-11 00:42:16 +0000208 ((['git', 'config', 'branch.working.rietveldpatchset'],), '31137'),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000209 ((['git', 'config', 'branch.working.rietveldserver'],),
210 'codereview.example.com'),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000211 ((['git', 'config', 'user.email'],), 'author@example.com'),
212 ((['git', 'config', 'rietveld.tree-status-url'],), ''),
213 ]
214
215 @classmethod
216 def _dcommit_calls_bypassed(cls):
217 return [
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000218 ((['git', 'config', 'branch.working.rietveldissue'],), '12345'),
219 ((['git', 'config', 'branch.working.rietveldserver'],),
220 'codereview.example.com'),
221 (('GitClHooksBypassedCommit',
222 'Issue https://codereview.example.com/12345 bypassed hook when '
223 'committing'), None),
224 ]
225
226 @classmethod
227 def _dcommit_calls_3(cls):
228 return [
maruel@chromium.org49e3d802012-07-18 23:54:45 +0000229 ((['git', 'diff', '--no-ext-diff', '--stat', '--find-copies-harder',
iannucci@chromium.org79540052012-10-19 23:15:26 +0000230 '-l100000', '-C50', 'refs/remotes/origin/master',
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000231 'refs/heads/working'],),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000232 (' PRESUBMIT.py | 2 +-\n'
233 ' 1 files changed, 1 insertions(+), 1 deletions(-)\n')),
234 (('About to commit; enter to confirm.',), None),
235 ((['git', 'show-ref', '--quiet', '--verify',
236 'refs/heads/git-cl-commit'],),
237 (('', None), 0)),
238 ((['git', 'branch', '-D', 'git-cl-commit'],), ''),
szager@chromium.org9bb85e22012-06-13 20:28:23 +0000239 ((['git', 'show-ref', '--quiet', '--verify',
240 'refs/heads/git-cl-cherry-pick'],), ''),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000241 ((['git', 'rev-parse', '--show-cdup'],), '\n'),
242 ((['git', 'checkout', '-q', '-b', 'git-cl-commit'],), ''),
243 ((['git', 'reset', '--soft', 'refs/remotes/origin/master'],), ''),
244 ((['git', 'commit', '-m',
245 'Issue: 12345\n\nReview URL: https://codereview.example.com/12345'],),
246 ''),
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000247 ((['git', 'svn', 'dcommit', '-C50', '--no-rebase', '--rmdir'],),
248 (('', None), 0)),
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000249 ((['git', 'checkout', '-q', 'working'],), ''),
250 ((['git', 'branch', '-D', 'git-cl-commit'],), ''),
251 ]
252
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000253 @staticmethod
iannucci@chromium.org79540052012-10-19 23:15:26 +0000254 def _cmd_line(description, args, similarity, find_copies):
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000255 """Returns the upload command line passed to upload.RealMain()."""
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000256 return [
257 'upload', '--assume_yes', '--server',
maruel@chromium.orgeb5edbc2012-01-16 17:03:28 +0000258 'https://codereview.example.com',
maruel@chromium.org71e12a92012-02-14 02:34:15 +0000259 '--message', description
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000260 ] + args + [
261 '--cc', 'joe@example.com',
iannucci@chromium.org79540052012-10-19 23:15:26 +0000262 '--git_similarity', similarity or '50'
263 ] + (['--git_no_find_copies'] if find_copies == False else []) + [
cmp@chromium.orgdb9b0e32012-06-06 19:10:17 +0000264 'master...'
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000265 ]
266
267 def _run_reviewer_test(
268 self,
269 upload_args,
270 expected_description,
271 returned_description,
272 final_description,
273 reviewers):
274 """Generic reviewer test framework."""
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000275 try:
276 similarity = upload_args[upload_args.index('--similarity')+1]
277 except ValueError:
278 similarity = None
iannucci@chromium.org79540052012-10-19 23:15:26 +0000279
280 if '--find-copies' in upload_args:
281 find_copies = True
282 elif '--no-find-copies' in upload_args:
283 find_copies = False
284 else:
285 find_copies = None
286
287 self.calls = self._upload_calls(similarity, find_copies)
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000288 def RunEditor(desc, _):
289 self.assertEquals(
290 '# Enter a description of the change.\n'
291 '# This will displayed on the codereview site.\n'
292 '# The first line will also be used as the subject of the review.\n' +
293 expected_description,
294 desc)
295 return returned_description
296 self.mock(git_cl.gclient_utils, 'RunEditor', RunEditor)
297 def check_upload(args):
iannucci@chromium.org79540052012-10-19 23:15:26 +0000298 cmd_line = self._cmd_line(final_description, reviewers, similarity,
299 find_copies)
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000300 self.assertEquals(cmd_line, args)
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000301 return 1, 2
302 self.mock(git_cl.upload, 'RealMain', check_upload)
303 git_cl.main(['upload'] + upload_args)
304
305 def test_no_reviewer(self):
306 self._run_reviewer_test(
307 [],
jamesr@chromium.org35d1a842012-07-27 00:20:43 +0000308 'desc\n\nBUG=\n',
309 '# Blah blah comment.\ndesc\n\nBUG=\n',
310 'desc\n\nBUG=\n',
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000311 [])
312
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000313 def test_keep_similarity(self):
314 self._run_reviewer_test(
315 ['--similarity', '70'],
316 'desc\n\nBUG=\n',
317 '# Blah blah comment.\ndesc\n\nBUG=\n',
318 'desc\n\nBUG=\n',
319 [])
320
iannucci@chromium.org79540052012-10-19 23:15:26 +0000321 def test_keep_find_copies(self):
322 self._run_reviewer_test(
323 ['--no-find-copies'],
324 'desc\n\nBUG=\n',
325 '# Blah blah comment.\ndesc\n\nBUG=\n',
326 'desc\n\nBUG=\n',
327 [])
328
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000329 def test_reviewers_cmd_line(self):
330 # Reviewer is passed as-is
jamesr@chromium.org35d1a842012-07-27 00:20:43 +0000331 description = 'desc\n\nR=foo@example.com\nBUG=\n'
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000332 self._run_reviewer_test(
333 ['-r' 'foo@example.com'],
334 description,
335 '\n%s\n' % description,
336 description,
337 ['--reviewers', 'foo@example.com'])
338
339 def test_reviewer_tbr_overriden(self):
340 # Reviewer is overriden with TBR
341 # Also verifies the regexp work without a trailing LF
342 description = 'Foo Bar\nTBR=reviewer@example.com\n'
343 self._run_reviewer_test(
344 ['-r' 'foo@example.com'],
jamesr@chromium.org35d1a842012-07-27 00:20:43 +0000345 'desc\n\nR=foo@example.com\nBUG=\n',
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000346 description.strip('\n'),
347 description,
348 ['--reviewers', 'reviewer@example.com'])
349
350 def test_reviewer_multiple(self):
351 # Handles multiple R= or TBR= lines.
352 description = (
353 'Foo Bar\nTBR=reviewer@example.com\nBUG=\nR=another@example.com\n')
354 self._run_reviewer_test(
355 [],
jamesr@chromium.org35d1a842012-07-27 00:20:43 +0000356 'desc\n\nBUG=\n',
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000357 description,
358 description,
359 ['--reviewers', 'reviewer@example.com,another@example.com'])
360
maruel@chromium.orga3353652011-11-30 14:26:57 +0000361 def test_reviewer_send_mail(self):
362 # --send-mail can be used without -r if R= is used
363 description = 'Foo Bar\nR=reviewer@example.com\n'
364 self._run_reviewer_test(
365 ['--send-mail'],
jamesr@chromium.org35d1a842012-07-27 00:20:43 +0000366 'desc\n\nBUG=\n',
maruel@chromium.orga3353652011-11-30 14:26:57 +0000367 description.strip('\n'),
368 description,
369 ['--reviewers', 'reviewer@example.com', '--send_mail'])
370
371 def test_reviewer_send_mail_no_rev(self):
372 # Fails without a reviewer.
373 class FileMock(object):
374 buf = StringIO.StringIO()
375 def write(self, content):
376 self.buf.write(content)
377
378 mock = FileMock()
379 try:
iannucci@chromium.org79540052012-10-19 23:15:26 +0000380 self.calls = self._git_base_calls(None, None)
maruel@chromium.orga3353652011-11-30 14:26:57 +0000381 def RunEditor(desc, _):
382 return desc
383 self.mock(git_cl.gclient_utils, 'RunEditor', RunEditor)
384 self.mock(sys, 'stderr', mock)
385 git_cl.main(['upload', '--send-mail'])
386 self.fail()
387 except SystemExit:
388 self.assertEquals(
389 'Must specify reviewers to send email.\n', mock.buf.getvalue())
390
maruel@chromium.org2e72bb12012-01-17 15:18:35 +0000391 def test_dcommit(self):
392 self.calls = (
393 self._dcommit_calls_1() +
394 self._dcommit_calls_normal() +
395 self._dcommit_calls_3())
396 git_cl.main(['dcommit'])
397
398 def test_dcommit_bypass_hooks(self):
399 self.calls = (
400 self._dcommit_calls_1() +
401 self._dcommit_calls_bypassed() +
402 self._dcommit_calls_3())
403 git_cl.main(['dcommit', '--bypass-hooks'])
404
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000405
ukai@chromium.orge8077812012-02-03 03:41:46 +0000406 @staticmethod
407 def _gerrit_base_calls():
408 return [
409 ((['git', 'config', 'gerrit.host'],), 'gerrit.example.com'),
iannucci@chromium.org53937ba2012-10-02 18:20:43 +0000410 ((['git', 'config', 'rietveld.server'],), 'codereview.example.com'),
411 ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
412 ((['git', 'config', '--int', '--get',
413 'branch.master.git-cl-similarity'],), ''),
iannucci@chromium.org79540052012-10-19 23:15:26 +0000414 ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
415 ((['git', 'config', '--int', '--get',
416 'branch.master.git-find-copies'],), ''),
ukai@chromium.orge8077812012-02-03 03:41:46 +0000417 ((['git', 'update-index', '--refresh', '-q'],), ''),
ukai@chromium.org259e4682012-10-25 07:36:33 +0000418 ((['git', 'diff-index', '--name-status', 'HEAD'],), ''),
ukai@chromium.orge8077812012-02-03 03:41:46 +0000419 ((['git', 'symbolic-ref', 'HEAD'],), 'master'),
420 ((['git', 'config', 'branch.master.merge'],), 'master'),
421 ((['git', 'config', 'branch.master.remote'],), 'origin'),
422 ((['git', 'rev-parse', '--show-cdup'],), ''),
423 ((['git', 'rev-parse', 'HEAD'],), '12345'),
424 ((['git', 'diff', '--name-status', '-r', 'master...', '.'],),
425 'M\t.gitignore\n'),
ukai@chromium.orge8077812012-02-03 03:41:46 +0000426 ((['git', 'config', 'branch.master.rietveldissue'],), ''),
427 ((['git', 'config', 'branch.master.rietveldpatchset'],), ''),
maruel@chromium.org373af802012-05-25 21:07:33 +0000428 ((['git', 'log', '--pretty=format:%s%n%n%b', 'master...'],), 'foo'),
ukai@chromium.orge8077812012-02-03 03:41:46 +0000429 ((['git', 'config', 'user.email'],), 'me@example.com'),
cmp@chromium.org5cf70222012-06-12 18:20:13 +0000430 ((['git', 'diff', '--no-ext-diff', '--stat', '--find-copies-harder',
iannucci@chromium.org79540052012-10-19 23:15:26 +0000431 '-l100000', '-C50', 'master...'],),
ukai@chromium.orge8077812012-02-03 03:41:46 +0000432 '+dat'),
433 ]
434
435 @staticmethod
436 def _gerrit_upload_calls(description, reviewers):
437 calls = [
maruel@chromium.org373af802012-05-25 21:07:33 +0000438 ((['git', 'log', '--pretty=format:%s\n\n%b', 'master..'],),
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000439 description)
440 ]
441 if git_cl.CHANGE_ID not in description:
442 calls += [
443 ((['git', 'log', '--pretty=format:%s\n\n%b', 'master..'],),
444 description),
445 ((['git', 'commit', '--amend', '-m', description],),
446 ''),
447 ((['git', 'log', '--pretty=format:%s\n\n%b', 'master..'],),
448 description)
449 ]
450 calls += [
ukai@chromium.orge8077812012-02-03 03:41:46 +0000451 ((['git', 'config', 'rietveld.cc'],), '')
452 ]
ukai@chromium.org19bbfa22012-02-03 16:18:11 +0000453 receive_pack = '--receive-pack=git receive-pack '
ukai@chromium.orge8077812012-02-03 03:41:46 +0000454 receive_pack += '--cc=joe@example.com' # from watch list
455 if reviewers:
456 receive_pack += ' '
457 receive_pack += ' '.join(['--reviewer=' + email for email in reviewers])
ukai@chromium.org19bbfa22012-02-03 16:18:11 +0000458 receive_pack += ''
ukai@chromium.orge8077812012-02-03 03:41:46 +0000459 calls += [
460 ((['git', 'push', receive_pack, 'origin', 'HEAD:refs/for/master'],),
461 '')
462 ]
463 return calls
464
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000465 def _run_gerrit_upload_test(
ukai@chromium.orge8077812012-02-03 03:41:46 +0000466 self,
467 upload_args,
468 description,
469 reviewers):
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000470 """Generic gerrit upload test framework."""
ukai@chromium.orge8077812012-02-03 03:41:46 +0000471 self.calls = self._gerrit_base_calls()
472 self.calls += self._gerrit_upload_calls(description, reviewers)
473 git_cl.main(['upload'] + upload_args)
474
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000475 def test_gerrit_upload_without_change_id(self):
476 self._run_gerrit_upload_test(
ukai@chromium.orge8077812012-02-03 03:41:46 +0000477 [],
jamesr@chromium.org35d1a842012-07-27 00:20:43 +0000478 'desc\n\nBUG=\n',
ukai@chromium.orge8077812012-02-03 03:41:46 +0000479 [])
480
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000481 def test_gerrit_no_reviewer(self):
482 self._run_gerrit_upload_test(
483 [],
484 'desc\n\nBUG=\nChange-Id:123456789\n',
485 [])
486
ukai@chromium.orge8077812012-02-03 03:41:46 +0000487 def test_gerrit_reviewers_cmd_line(self):
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000488 self._run_gerrit_upload_test(
ukai@chromium.orge8077812012-02-03 03:41:46 +0000489 ['-r', 'foo@example.com'],
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000490 'desc\n\nBUG=\nChange-Id:123456789',
ukai@chromium.orge8077812012-02-03 03:41:46 +0000491 ['foo@example.com'])
492
493 def test_gerrit_reviewer_multiple(self):
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000494 self._run_gerrit_upload_test(
ukai@chromium.orge8077812012-02-03 03:41:46 +0000495 [],
sivachandra@chromium.orgaebe87f2012-10-22 20:34:21 +0000496 'desc\nTBR=reviewer@example.com\nBUG=\nR=another@example.com\n'
497 'Change-Id:123456789\n',
ukai@chromium.orge8077812012-02-03 03:41:46 +0000498 ['reviewer@example.com', 'another@example.com'])
499
500
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000501 def test_config_gerrit_download_hook(self):
502 self.mock(git_cl, 'FindCodereviewSettingsFile', CodereviewSettingsFileMock)
503 def ParseCodereviewSettingsContent(content):
504 keyvals = {}
505 keyvals['CODE_REVIEW_SERVER'] = 'gerrit.chromium.org'
506 keyvals['GERRIT_HOST'] = 'gerrit.chromium.org'
507 keyvals['GERRIT_PORT'] = '29418'
508 return keyvals
509 self.mock(git_cl.gclient_utils, 'ParseCodereviewSettingsContent',
510 ParseCodereviewSettingsContent)
511 self.mock(git_cl.os, 'access', self._mocked_call)
512 self.mock(git_cl.os, 'chmod', self._mocked_call)
ukai@chromium.org91655502012-05-25 01:46:07 +0000513 src_dir = os.path.join(os.path.sep, 'usr', 'local', 'src')
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000514 def AbsPath(path):
ukai@chromium.org91655502012-05-25 01:46:07 +0000515 if not path.startswith(os.path.sep):
516 return os.path.join(src_dir, path)
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000517 return path
518 self.mock(git_cl.os.path, 'abspath', AbsPath)
ukai@chromium.org91655502012-05-25 01:46:07 +0000519 commit_msg_path = os.path.join(src_dir, '.git', 'hooks', 'commit-msg')
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000520 def Exists(path):
ukai@chromium.org91655502012-05-25 01:46:07 +0000521 if path == commit_msg_path:
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000522 return False
523 # others paths, such as /usr/share/locale/....
524 return True
525 self.mock(git_cl.os.path, 'exists', Exists)
joshua.lock@intel.com426f69b2012-08-02 23:41:49 +0000526 self.mock(git_cl, 'urlretrieve', self._mocked_call)
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000527 self.calls = [
528 ((['git', 'config', 'rietveld.server', 'gerrit.chromium.org'],), ''),
529 ((['git', 'config', '--unset-all', 'rietveld.cc'],), ''),
530 ((['git', 'config', '--unset-all', 'rietveld.tree-status-url'],), ''),
531 ((['git', 'config', '--unset-all', 'rietveld.viewvc-url'],), ''),
532 ((['git', 'config', 'gerrit.host', 'gerrit.chromium.org'],), ''),
533 ((['git', 'config', 'gerrit.port', '29418'],), ''),
534 # DownloadHooks(False)
535 ((['git', 'config', 'gerrit.host'],), 'gerrit.chromium.org'),
536 ((['git', 'config', 'rietveld.server'],), 'gerrit.chromium.org'),
537 ((['git', 'rev-parse', '--show-cdup'],), ''),
ukai@chromium.org91655502012-05-25 01:46:07 +0000538 ((commit_msg_path, os.X_OK,), False),
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000539 (('https://gerrit.chromium.org/tools/hooks/commit-msg',
ukai@chromium.org91655502012-05-25 01:46:07 +0000540 commit_msg_path,), ''),
541 ((commit_msg_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR,), ''),
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000542 # GetCodereviewSettingsInteractively
543 ((['git', 'config', 'rietveld.server'],), 'gerrit.chromium.org'),
544 (('Rietveld server (host[:port]) [https://gerrit.chromium.org]:',),
545 ''),
546 ((['git', 'config', 'rietveld.cc'],), ''),
547 (('CC list:',), ''),
548 ((['git', 'config', 'rietveld.tree-status-url'],), ''),
549 (('Tree status URL:',), ''),
550 ((['git', 'config', 'rietveld.viewvc-url'],), ''),
551 (('ViewVC URL:',), ''),
552 # DownloadHooks(True)
ukai@chromium.org91655502012-05-25 01:46:07 +0000553 ((commit_msg_path, os.X_OK,), True),
ukai@chromium.org78c4b982012-02-14 02:20:26 +0000554 ]
555 git_cl.main(['config'])
556
557
maruel@chromium.orgddd59412011-11-30 14:20:38 +0000558if __name__ == '__main__':
559 unittest.main()