Index: tests/git_cl_test.py |
diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py |
index 2e869a20ea910bb248c53b68eae3c2a970a0b357..b8b694fa546ec3fdecd0674503843c934bc53a61 100755 |
--- a/tests/git_cl_test.py |
+++ b/tests/git_cl_test.py |
@@ -10,6 +10,7 @@ import StringIO |
import stat |
import sys |
import unittest |
+import urlparse |
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
@@ -73,6 +74,100 @@ class AuthenticatorMock(object): |
return True |
+class TestGitClBasic(unittest.TestCase): |
+ def _test_ParseIssueUrl(self, func, url, issue, patchset, hostname, fail): |
+ parsed = urlparse.urlparse(url) |
+ result = func(parsed) |
+ if fail: |
+ self.assertIsNone(result) |
+ return None |
+ self.assertIsNotNone(result) |
+ self.assertEqual(result.issue, issue) |
+ self.assertEqual(result.patchset, patchset) |
+ self.assertEqual(result.hostname, hostname) |
+ return result |
+ |
+ def test_ParseIssueURL_rietveld(self): |
+ def test(url, issue=None, patchset=None, hostname=None, patch_url=None, |
+ fail=None): |
+ result = self._test_ParseIssueUrl( |
+ git_cl._RietveldChangelistImpl.ParseIssueURL, |
+ url, issue, patchset, hostname, fail) |
+ if not fail: |
+ self.assertEqual(result.patch_url, patch_url) |
+ |
+ test('http://codereview.chromium.org/123', |
+ 123, None, 'codereview.chromium.org') |
+ test('https://codereview.chromium.org/123', |
+ 123, None, 'codereview.chromium.org') |
+ test('https://codereview.chromium.org/123/', |
+ 123, None, 'codereview.chromium.org') |
+ test('https://codereview.chromium.org/123/whatever', |
+ 123, None, 'codereview.chromium.org') |
+ test('http://codereview.chromium.org/download/issue123_4.diff', |
+ 123, 4, 'codereview.chromium.org', |
+ patch_url='https://codereview.chromium.org/download/issue123_4.diff') |
+ # This looks like bad Gerrit, but is actually valid Rietveld. |
+ test('https://chrome-review.source.com/123/4/', |
+ 123, None, 'chrome-review.source.com') |
+ |
+ test('https://codereview.chromium.org/deadbeaf', fail=True) |
+ test('https://codereview.chromium.org/api/123', fail=True) |
+ test('bad://codereview.chromium.org/123', fail=True) |
+ test('http://codereview.chromium.org/download/issue123_4.diffff', fail=True) |
+ |
+ def test_ParseIssueURL_gerrit(self): |
+ def test(url, issue=None, patchset=None, hostname=None, fail=None): |
+ self._test_ParseIssueUrl( |
+ git_cl._GerritChangelistImpl.ParseIssueURL, |
+ url, issue, patchset, hostname, fail) |
+ |
+ test('http://chrome-review.source.com/c/123', |
+ 123, None, 'chrome-review.source.com') |
+ test('https://chrome-review.source.com/c/123/', |
+ 123, None, 'chrome-review.source.com') |
+ test('https://chrome-review.source.com/c/123/4', |
+ 123, 4, 'chrome-review.source.com') |
+ test('https://chrome-review.source.com/#/c/123/4', |
+ 123, 4, 'chrome-review.source.com') |
+ test('https://chrome-review.source.com/c/123/4', |
+ 123, 4, 'chrome-review.source.com') |
+ test('https://chrome-review.source.com/123', |
+ 123, None, 'chrome-review.source.com') |
+ test('https://chrome-review.source.com/123/4', |
+ 123, 4, 'chrome-review.source.com') |
+ |
+ test('https://chrome-review.source.com/c/123/1/whatisthis', fail=True) |
+ test('https://chrome-review.source.com/c/abc/', fail=True) |
+ test('ssh://chrome-review.source.com/c/123/1/', fail=True) |
+ |
+ def test_ParseIssueNumberArgument(self): |
+ def test(arg, issue=None, patchset=None, hostname=None, fail=False): |
+ result = git_cl.ParseIssueNumberArgument(arg) |
+ self.assertIsNotNone(result) |
+ if fail: |
+ self.assertFalse(result.valid) |
+ else: |
+ self.assertEqual(result.issue, issue) |
+ self.assertEqual(result.patchset, patchset) |
+ self.assertEqual(result.hostname, hostname) |
+ |
+ test('123', 123) |
+ test('', fail=True) |
+ test('abc', fail=True) |
+ test('123/1', fail=True) |
+ test('123a', fail=True) |
+ test('ssh://chrome-review.source.com/#/c/123/4/', fail=True) |
+ # Rietveld. |
+ test('https://codereview.source.com/123', |
+ 123, None, 'codereview.source.com') |
+ test('https://codereview.source.com/www123', fail=True) |
+ # Gerrrit. |
+ test('https://chrome-review.source.com/c/123/4', |
+ 123, 4, 'chrome-review.source.com') |
+ test('https://chrome-review.source.com/bad/123/4', fail=True) |
+ |
+ |
class TestGitCl(TestCase): |
def setUp(self): |
super(TestGitCl, self).setUp() |
@@ -99,8 +194,12 @@ class TestGitCl(TestCase): |
# It's important to reset settings to not have inter-tests interference. |
git_cl.settings = None |
+ |
def tearDown(self): |
try: |
+ # Note: has_failed returns True if at least 1 test ran so far, current |
+ # included, has failed. That means current test may have actually ran |
+ # fine, and the check for no leftover calls would be skipped. |
if not self.has_failed(): |
self.assertEquals([], self.calls) |
finally: |
@@ -916,6 +1015,14 @@ class TestGitCl(TestCase): |
def test_patch_when_dirty(self): |
# Patch when local tree is dirty |
self.mock(git_common, 'is_dirty_git_tree', lambda x: True) |
+ self.calls = [ |
+ ((['git', 'symbolic-ref', 'HEAD'],), 'master'), |
+ ((['git', 'config', 'branch.master.rietveldissue'],), ''), |
+ ((['git', 'config', 'branch.master.gerritissue'],), ''), |
+ ((['git', 'config', 'rietveld.autoupdate'],), ''), |
+ ((['git', 'config', 'gerrit.host'],), ''), |
+ ((['git', 'config', 'rietveld.server'],), 'codereview.example.com'), |
+ ] |
self.assertNotEqual(git_cl.main(['patch', '123456']), 0) |
def test_diff_when_dirty(self): |
@@ -923,23 +1030,52 @@ class TestGitCl(TestCase): |
self.mock(git_common, 'is_dirty_git_tree', lambda x: True) |
self.assertNotEqual(git_cl.main(['diff']), 0) |
- def _patch_common(self): |
+ def _patch_common(self, is_gerrit=False): |
self.mock(git_cl._RietveldChangelistImpl, 'GetMostRecentPatchset', |
lambda x: '60001') |
self.mock(git_cl._RietveldChangelistImpl, 'GetPatchSetDiff', |
lambda *args: None) |
+ self.mock(git_cl._GerritChangelistImpl, '_GetChangeDetail', |
+ lambda *args: { |
+ 'current_revision': '7777777777', |
+ 'revisions': { |
+ '1111111111': { |
+ '_number': 1, |
+ 'fetch': {'http': { |
+ 'url': 'https://chromium.googlesource.com/my/repo', |
+ 'ref': 'refs/changes/56/123456/1', |
+ }}, |
+ }, |
+ '7777777777': { |
+ '_number': 7, |
+ 'fetch': {'http': { |
+ 'url': 'https://chromium.googlesource.com/my/repo', |
+ 'ref': 'refs/changes/56/123456/7', |
+ }}, |
+ }, |
+ }, |
+ }) |
self.mock(git_cl.Changelist, 'GetDescription', |
lambda *args: 'Description') |
- self.mock(git_cl.Changelist, 'SetIssue', lambda *args: None) |
- self.mock(git_cl.Changelist, 'SetPatchset', lambda *args: None) |
self.mock(git_cl, 'IsGitVersionAtLeast', lambda *args: True) |
self.calls = [ |
+ ((['git', 'symbolic-ref', 'HEAD'],), 'master'), |
+ ((['git', 'config', 'branch.master.rietveldissue'],), ''), |
+ ((['git', 'config', 'branch.master.gerritissue'],), ''), |
((['git', 'config', 'rietveld.autoupdate'],), ''), |
- ((['git', 'config', 'rietveld.server'],), 'codereview.example.com'), |
- ((['git', 'rev-parse', '--show-cdup'],), ''), |
- ((['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'],), ''), |
] |
+ if is_gerrit: |
+ self.calls += [ |
+ ((['git', 'config', 'gerrit.host'],), 'true'), |
+ ] |
+ else: |
+ self.calls += [ |
+ ((['git', 'config', 'gerrit.host'],), ''), |
+ ((['git', 'config', 'rietveld.server'],), 'codereview.example.com'), |
+ ((['git', 'rev-parse', '--show-cdup'],), ''), |
+ ((['sed', '-e', 's|^--- a/|--- |; s|^+++ b/|+++ |'],), ''), |
+ ] |
def test_patch_successful(self): |
self._patch_common() |
@@ -949,8 +1085,11 @@ class TestGitCl(TestCase): |
'Description\n\n' + |
'patch from issue 123456 at patchset 60001 ' + |
'(http://crrev.com/123456#ps60001)'],), ''), |
- ((['git', 'symbolic-ref', 'HEAD'],), 'master'), |
+ ((['git', 'config', 'branch.master.rietveldissue', '123456'],), ''), |
((['git', 'config', 'branch.master.rietveldserver'],), ''), |
+ ((['git', 'config', 'branch.master.rietveldserver', |
+ 'https://codereview.example.com'],), ''), |
+ ((['git', 'config', 'branch.master.rietveldpatchset', '60001'],), ''), |
] |
self.assertEqual(git_cl.main(['patch', '123456']), 0) |
@@ -962,6 +1101,57 @@ class TestGitCl(TestCase): |
] |
self.assertNotEqual(git_cl.main(['patch', '123456']), 0) |
+ def test_gerrit_patch_successful(self): |
+ self._patch_common(is_gerrit=True) |
+ self.calls += [ |
+ ((['git', 'fetch', 'https://chromium.googlesource.com/my/repo', |
+ 'refs/changes/56/123456/7'],), ''), |
+ ((['git', 'cherry-pick', 'FETCH_HEAD'],), ''), |
+ ((['git', 'config', 'branch.master.gerritissue', '123456'],), ''), |
+ ((['git', 'config', 'branch.master.gerritserver'],), ''), |
+ ((['git', 'config', 'branch.master.merge'],), 'master'), |
+ ((['git', 'config', 'branch.master.remote'],), 'origin'), |
+ ((['git', 'config', 'remote.origin.url'],), |
+ 'https://chromium.googlesource.com/my/repo'), |
+ ((['git', 'config', 'branch.master.gerritserver', |
+ 'https://chromium-review.googlesource.com'],), ''), |
+ ((['git', 'config', 'branch.master.gerritpatchset', '7'],), ''), |
+ ] |
+ self.assertEqual(git_cl.main(['patch', '123456']), 0) |
+ |
+ def test_gerrit_patch_url_successful(self): |
+ self._patch_common(is_gerrit=True) |
+ self.calls += [ |
+ ((['git', 'fetch', 'https://chromium.googlesource.com/my/repo', |
+ 'refs/changes/56/123456/1'],), ''), |
+ ((['git', 'cherry-pick', 'FETCH_HEAD'],), ''), |
+ ((['git', 'config', 'branch.master.gerritissue', '123456'],), ''), |
+ ((['git', 'config', 'branch.master.gerritserver', |
+ 'https://chromium-review.googlesource.com'],), ''), |
+ ((['git', 'config', 'branch.master.gerritpatchset', '1'],), ''), |
+ ] |
+ self.assertEqual(git_cl.main( |
+ ['patch', 'https://chromium-review.googlesource.com/#/c/123456/1']), 0) |
+ |
+ def test_gerrit_patch_conflict(self): |
+ self._patch_common(is_gerrit=True) |
+ self.mock(git_cl, 'DieWithError', |
+ lambda msg: self._mocked_call(['DieWithError', msg])) |
+ class SystemExitMock(Exception): |
+ pass |
+ self.calls += [ |
+ ((['git', 'fetch', 'https://chromium.googlesource.com/my/repo', |
+ 'refs/changes/56/123456/1'],), ''), |
+ ((['git', 'cherry-pick', 'FETCH_HEAD'],), |
+ '', subprocess2.CalledProcessError(1, '', '', '', '')), |
+ ((['DieWithError', 'git cherry-pick FETCH_HEAD" failed.\n'],), |
+ '', SystemExitMock()), |
+ ] |
+ with self.assertRaises(SystemExitMock): |
+ git_cl.main(['patch', |
+ 'https://chromium-review.googlesource.com/#/c/123456/1']) |
+ |
+ |
if __name__ == '__main__': |
git_cl.logging.basicConfig( |
level=git_cl.logging.DEBUG if '-v' in sys.argv else git_cl.logging.ERROR) |