Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: tests/git_drover_test.py

Issue 1397313002: Support merging with conflicts with git-drover. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « man/src/git-drover.demo.4.sh ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved. 2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 """Tests for git_drover.""" 5 """Tests for git_drover."""
6 6
7 import os 7 import os
8 import shutil 8 import shutil
9 import subprocess 9 import subprocess
10 import sys 10 import sys
(...skipping 12 matching lines...) Expand all
23 super(GitDroverTest, self).setUp() 23 super(GitDroverTest, self).setUp()
24 self._temp_directory = tempfile.mkdtemp() 24 self._temp_directory = tempfile.mkdtemp()
25 self._parent_repo = os.path.join(self._temp_directory, 'parent_repo') 25 self._parent_repo = os.path.join(self._temp_directory, 'parent_repo')
26 self._target_repo = os.path.join(self._temp_directory, 'drover_branch_123') 26 self._target_repo = os.path.join(self._temp_directory, 'drover_branch_123')
27 os.makedirs(os.path.join(self._parent_repo, '.git')) 27 os.makedirs(os.path.join(self._parent_repo, '.git'))
28 with open(os.path.join(self._parent_repo, '.git', 'config'), 'w') as f: 28 with open(os.path.join(self._parent_repo, '.git', 'config'), 'w') as f:
29 f.write('config') 29 f.write('config')
30 with open(os.path.join(self._parent_repo, '.git', 'HEAD'), 'w') as f: 30 with open(os.path.join(self._parent_repo, '.git', 'HEAD'), 'w') as f:
31 f.write('HEAD') 31 f.write('HEAD')
32 os.mkdir(os.path.join(self._parent_repo, '.git', 'info')) 32 os.mkdir(os.path.join(self._parent_repo, '.git', 'info'))
33 with open(os.path.join(self._parent_repo, '.git', 'info', 'refs'), 33 with open(
34 'w') as f: 34 os.path.join(self._parent_repo, '.git', 'info', 'refs'), 'w') as f:
35 f.write('refs') 35 f.write('refs')
36 self.mock(tempfile, 'mkdtemp', self._mkdtemp) 36 self.mock(tempfile, 'mkdtemp', self._mkdtemp)
37 self.mock(__builtins__, 'raw_input', self._get_input) 37 self.mock(__builtins__, 'raw_input', self._get_input)
38 self.mock(subprocess, 'check_call', self._check_call) 38 self.mock(subprocess, 'check_call', self._check_call)
39 self.mock(subprocess, 'check_output', self._check_call) 39 self.mock(subprocess, 'check_output', self._check_call)
40 self._commands = [] 40 self._commands = []
41 self._input = [] 41 self._input = []
42 self._fail_on_command = None 42 self._fail_on_command = None
43 self._has_os_symlink = hasattr(os, 'symlink')
44 if not self._has_os_symlink:
45 os.symlink = lambda source, dest: None
46 43
47 self.REPO_CHECK_COMMANDS = [ 44 self.REPO_CHECK_COMMANDS = [
48 (['git', '--help'], self._parent_repo), 45 (['git', '--help'], self._parent_repo),
49 (['git', 'status'], self._parent_repo), 46 (['git', 'status'], self._parent_repo),
50 (['git', 'fetch', 'origin'], self._parent_repo), 47 (['git', 'fetch', 'origin'], self._parent_repo),
51 (['git', 'rev-parse', 'refs/remotes/branch-heads/branch^{commit}'], 48 (['git', 'rev-parse', 'refs/remotes/branch-heads/branch^{commit}'],
52 self._parent_repo), 49 self._parent_repo),
53 (['git', 'rev-parse', 'cl^{commit}'], self._parent_repo), 50 (['git', 'rev-parse', 'cl^{commit}'], self._parent_repo),
54 (['git', 'show', '-s', 'cl'], self._parent_repo), 51 (['git', 'show', '-s', 'cl'], self._parent_repo),
55 ] 52 ]
56 self.LOCAL_REPO_COMMANDS = [ 53 self.LOCAL_REPO_COMMANDS = [
57 (['git', 'rev-parse', '--git-dir'], self._parent_repo), 54 (['git', 'rev-parse', '--git-dir'], self._parent_repo),
58 (['git', 'config', 'core.sparsecheckout', 'true'], self._target_repo), 55 (['git', 'config', 'core.sparsecheckout', 'true'], self._target_repo),
59 (['git', 'checkout', '-b', 'drover_branch_123', 56 (['git', 'checkout', '-b', 'drover_branch_123',
60 'refs/remotes/branch-heads/branch'], self._target_repo), 57 'refs/remotes/branch-heads/branch'], self._target_repo),
61 (['git', 'cherry-pick', '-x', 'cl'], self._target_repo), 58 (['git', 'cherry-pick', '-x', 'cl'], self._target_repo),
59 ]
60 self.UPLOAD_COMMANDS = [
62 (['git', 'reset', '--hard'], self._target_repo), 61 (['git', 'reset', '--hard'], self._target_repo),
62 (['git', 'cl', 'upload'], self._target_repo),
63 ] 63 ]
64 self.UPLOAD_COMMAND = [(['git', 'cl', 'upload'], self._target_repo)]
65 self.LAND_COMMAND = [ 64 self.LAND_COMMAND = [
66 (['git', 'cl', 'land', '--bypass-hooks'], self._target_repo), 65 (['git', 'cl', 'land', '--bypass-hooks'], self._target_repo),
67 ] 66 ]
68 self.BRANCH_CLEANUP_COMMANDS = [ 67 if os.name == 'nt':
69 (['git', 'cherry-pick', '--abort'], self._target_repo), 68 self.BRANCH_CLEANUP_COMMANDS = [
70 (['git', 'checkout', '--detach'], self._target_repo), 69 (['rmdir', '/s', '/q', self._target_repo], None),
71 (['git', 'branch', '-D', 'drover_branch_123'], self._target_repo), 70 (['git', 'branch', '-D', 'drover_branch_123'], self._parent_repo),
71 ]
72 else:
73 self.BRANCH_CLEANUP_COMMANDS = [
74 (['git', 'branch', '-D', 'drover_branch_123'], self._parent_repo),
75 ]
76 self.MANUAL_RESOLVE_PREPARATION_COMMANDS = [
77 (['git', 'status', '--porcelain'], self._target_repo),
78 (['git', 'update-index', '--skip-worktree', '--', 'foo', 'bar'],
79 self._target_repo),
80 ]
81 self.FINISH_MANUAL_RESOLVE_COMMANDS = [
82 (['git', 'commit', '--no-edit'], self._target_repo),
72 ] 83 ]
73 84
74 def tearDown(self): 85 def tearDown(self):
75 shutil.rmtree(self._temp_directory) 86 shutil.rmtree(self._temp_directory)
76 if not self._has_os_symlink:
77 del os.symlink
78 super(GitDroverTest, self).tearDown() 87 super(GitDroverTest, self).tearDown()
79 88
80 def _mkdtemp(self, prefix='tmp'): 89 def _mkdtemp(self, prefix='tmp'):
81 self.assertEqual('drover_branch_', prefix) 90 self.assertEqual('drover_branch_', prefix)
82 os.mkdir(self._target_repo) 91 os.mkdir(self._target_repo)
83 return self._target_repo 92 return self._target_repo
84 93
85 def _get_input(self, message): 94 def _get_input(self, message):
86 result = self._input.pop(0) 95 result = self._input.pop(0)
87 if result == 'EOF': 96 if result == 'EOF':
88 raise EOFError 97 raise EOFError
89 return result 98 return result
90 99
91 def _check_call(self, args, stderr=None, stdout=None, shell='', cwd=None): 100 def _check_call(self, args, stderr=None, stdout=None, shell='', cwd=None):
92 self.assertFalse(shell) 101 if args[0] == 'rmdir':
102 subprocess.call(args, shell=shell)
103 else:
104 self.assertFalse(shell)
93 self._commands.append((args, cwd)) 105 self._commands.append((args, cwd))
94 if (self._fail_on_command is not None and 106 if (self._fail_on_command is not None and
95 self._fail_on_command == len(self._commands)): 107 self._fail_on_command == len(self._commands)):
108 self._fail_on_command = None
96 raise subprocess.CalledProcessError(1, args[0]) 109 raise subprocess.CalledProcessError(1, args[0])
97 if args == ['git', 'rev-parse', '--git-dir']: 110 if args == ['git', 'rev-parse', '--git-dir']:
98 return os.path.join(self._parent_repo, '.git') 111 return os.path.join(self._parent_repo, '.git')
112 if args == ['git', 'status', '--porcelain']:
113 return ' D foo\nUU baz\n D bar\n'
114 return ''
99 115
100 def testSuccess(self): 116 def testSuccess(self):
101 self._input = ['y', 'y'] 117 self._input = ['y', 'y']
102 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False) 118 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False)
103 self.assertEqual( 119 self.assertEqual(
104 self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS + 120 self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS +
105 self.UPLOAD_COMMAND + self.LAND_COMMAND + self.BRANCH_CLEANUP_COMMANDS, 121 self.UPLOAD_COMMANDS + self.LAND_COMMAND + self.BRANCH_CLEANUP_COMMANDS,
106 self._commands) 122 self._commands)
107 self.assertFalse(os.path.exists(self._target_repo)) 123 self.assertFalse(os.path.exists(self._target_repo))
108 self.assertFalse(self._input) 124 self.assertFalse(self._input)
109 125
110 def testDryRun(self): 126 def testDryRun(self):
111 self._input = ['y'] 127 self._input = ['y']
112 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, True) 128 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, True)
113 self.assertEqual( 129 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS +
114 self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS + 130 self.BRANCH_CLEANUP_COMMANDS, self._commands)
115 self.BRANCH_CLEANUP_COMMANDS, self._commands)
116 self.assertFalse(os.path.exists(self._target_repo)) 131 self.assertFalse(os.path.exists(self._target_repo))
117 self.assertFalse(self._input) 132 self.assertFalse(self._input)
118 133
119 def testCancelEarly(self): 134 def testCancelEarly(self):
120 self._input = ['n'] 135 self._input = ['n']
121 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False) 136 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False)
122 self.assertEqual(self.REPO_CHECK_COMMANDS, self._commands) 137 self.assertEqual(self.REPO_CHECK_COMMANDS, self._commands)
123 self.assertFalse(os.path.exists(self._target_repo)) 138 self.assertFalse(os.path.exists(self._target_repo))
124 self.assertFalse(self._input) 139 self.assertFalse(self._input)
125 140
126 def testEOFOnConfirm(self): 141 def testEOFOnConfirm(self):
127 self._input = ['EOF'] 142 self._input = ['EOF']
128 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False) 143 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False)
129 self.assertEqual(self.REPO_CHECK_COMMANDS, self._commands) 144 self.assertEqual(self.REPO_CHECK_COMMANDS, self._commands)
130 self.assertFalse(os.path.exists(self._target_repo)) 145 self.assertFalse(os.path.exists(self._target_repo))
131 self.assertFalse(self._input) 146 self.assertFalse(self._input)
132 147
133 def testCancelLate(self): 148 def testCancelLate(self):
134 self._input = ['y', 'n'] 149 self._input = ['y', 'n']
135 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False) 150 git_drover.cherry_pick_change('branch', 'cl', self._parent_repo, False)
136 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS + 151 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS +
137 self.UPLOAD_COMMAND + self.BRANCH_CLEANUP_COMMANDS, 152 self.UPLOAD_COMMANDS + self.BRANCH_CLEANUP_COMMANDS,
138 self._commands) 153 self._commands)
139 self.assertFalse(os.path.exists(self._target_repo)) 154 self.assertFalse(os.path.exists(self._target_repo))
140 self.assertFalse(self._input) 155 self.assertFalse(self._input)
141 156
142 def testFailDuringCheck(self): 157 def testFailDuringCheck(self):
143 self._input = [] 158 self._input = []
144 self._fail_on_command = 1 159 self._fail_on_command = 1
145 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch', 160 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch',
146 'cl', self._parent_repo, False) 161 'cl', self._parent_repo, False)
147 self.assertEqual(self.REPO_CHECK_COMMANDS[:1], self._commands) 162 self.assertEqual(self.REPO_CHECK_COMMANDS[:1], self._commands)
148 self.assertFalse(os.path.exists(self._target_repo)) 163 self.assertFalse(os.path.exists(self._target_repo))
149 self.assertFalse(self._input) 164 self.assertFalse(self._input)
150 165
151 def testFailDuringBranchCreation(self): 166 def testFailDuringBranchCreation(self):
152 self._input = ['y'] 167 self._input = ['y']
153 self._fail_on_command = 8 168 self._fail_on_command = 8
154 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch', 169 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch',
155 'cl', self._parent_repo, False) 170 'cl', self._parent_repo, False)
156 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS[:2], 171 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS[:2] +
172 self.BRANCH_CLEANUP_COMMANDS[:-1], self._commands)
173 self.assertFalse(os.path.exists(self._target_repo))
174 self.assertFalse(self._input)
175
176 def testFailDuringCherryPickAndAbort(self):
177 self._input = ['y']
178 self._fail_on_command = 10
179 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch',
180 'cl', self._parent_repo, False)
181 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS[:4] +
182 self.MANUAL_RESOLVE_PREPARATION_COMMANDS, self._commands)
183 self.assertTrue(os.path.exists(self._target_repo))
184 self.assertFalse(self._input)
185 self._commands = []
186 git_drover.abort_cherry_pick(self._target_repo)
187 self.assertEqual(self.BRANCH_CLEANUP_COMMANDS, self._commands)
188 self.assertFalse(os.path.exists(self._target_repo))
189
190 def testFailDuringCherryPickAndContinue(self):
191 self._input = ['y']
192 self._fail_on_command = 10
193 self.assertRaises(git_drover.PatchError, git_drover.cherry_pick_change,
194 'branch', 'cl', self._parent_repo, False)
195 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS[:4] +
196 self.MANUAL_RESOLVE_PREPARATION_COMMANDS, self._commands)
197 self.assertTrue(os.path.exists(self._target_repo))
198 self.assertFalse(self._input)
199
200 self._commands = []
201 self._input = ['n']
202 git_drover.continue_cherry_pick(self._target_repo)
203 self.assertEqual(self.UPLOAD_COMMANDS, self._commands)
204 self.assertTrue(os.path.exists(self._target_repo))
205 self.assertFalse(self._input)
206
207 self._commands = []
208 self._input = ['y']
209 git_drover.continue_cherry_pick(self._target_repo)
210 self.assertEqual(
211 self.UPLOAD_COMMANDS + self.LAND_COMMAND + self.BRANCH_CLEANUP_COMMANDS,
212 self._commands)
213 self.assertFalse(os.path.exists(self._target_repo))
214 self.assertFalse(self._input)
215
216 def testFailDuringCherryPickAndContinueWithoutCommitting(self):
217 self._input = ['y']
218 self._fail_on_command = 10
219 self.assertRaises(git_drover.PatchError, git_drover.cherry_pick_change,
220 'branch', 'cl', self._parent_repo, False)
221 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS[:4] +
222 self.MANUAL_RESOLVE_PREPARATION_COMMANDS, self._commands)
223 self.assertTrue(os.path.exists(self._target_repo))
224 self.assertFalse(self._input)
225 self._commands = []
226 with open(os.path.join(self._target_repo, '.git', 'CHERRY_PICK_HEAD'), 'w'):
227 pass
228
229 self._commands = []
230 self._input = ['y']
231 git_drover.continue_cherry_pick(self._target_repo)
232 self.assertEqual(self.FINISH_MANUAL_RESOLVE_COMMANDS + self.UPLOAD_COMMANDS
233 + self.LAND_COMMAND + self.BRANCH_CLEANUP_COMMANDS,
157 self._commands) 234 self._commands)
158 self.assertFalse(os.path.exists(self._target_repo)) 235 self.assertFalse(os.path.exists(self._target_repo))
159 self.assertFalse(self._input) 236 self.assertFalse(self._input)
160 237
161 def testFailDuringCherryPick(self): 238 def testFailDuringCherryPickAndContinueWithoutResolving(self):
162 self._input = ['y'] 239 self._input = ['y']
163 self._fail_on_command = 10 240 self._fail_on_command = 10
164 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch', 241 self.assertRaises(git_drover.PatchError, git_drover.cherry_pick_change,
165 'cl', self._parent_repo, False) 242 'branch', 'cl', self._parent_repo, False)
166 self.assertEqual( 243 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS[:4] +
167 self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS[:4] + 244 self.MANUAL_RESOLVE_PREPARATION_COMMANDS, self._commands)
168 self.BRANCH_CLEANUP_COMMANDS, self._commands) 245 self.assertTrue(os.path.exists(self._target_repo))
246 self.assertFalse(self._input)
247 self._commands = []
248 self._fail_on_command = 1
249 with open(os.path.join(self._target_repo, '.git', 'CHERRY_PICK_HEAD'), 'w'):
250 pass
251 self.assertRaisesRegexp(git_drover.Error,
252 'All conflicts must be resolved before continuing',
253 git_drover.continue_cherry_pick, self._target_repo)
254 self.assertEqual(self.FINISH_MANUAL_RESOLVE_COMMANDS, self._commands)
255 self.assertTrue(os.path.exists(self._target_repo))
256
257 self._commands = []
258 git_drover.abort_cherry_pick(self._target_repo)
259 self.assertEqual(self.BRANCH_CLEANUP_COMMANDS, self._commands)
169 self.assertFalse(os.path.exists(self._target_repo)) 260 self.assertFalse(os.path.exists(self._target_repo))
170 self.assertFalse(self._input)
171 261
172 def testFailAfterCherryPick(self): 262 def testFailAfterCherryPick(self):
173 self._input = ['y'] 263 self._input = ['y']
174 self._fail_on_command = 11 264 self._fail_on_command = 11
175 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch', 265 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch',
176 'cl', self._parent_repo, False) 266 'cl', self._parent_repo, False)
177 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS + 267 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS +
178 self.BRANCH_CLEANUP_COMMANDS, self._commands) 268 self.UPLOAD_COMMANDS[:1] + self.BRANCH_CLEANUP_COMMANDS,
269 self._commands)
179 self.assertFalse(os.path.exists(self._target_repo)) 270 self.assertFalse(os.path.exists(self._target_repo))
180 self.assertFalse(self._input) 271 self.assertFalse(self._input)
181 272
182 def testFailOnUpload(self): 273 def testFailOnUpload(self):
183 self._input = ['y'] 274 self._input = ['y']
184 self._fail_on_command = 12 275 self._fail_on_command = 12
185 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch', 276 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch',
186 'cl', self._parent_repo, False) 277 'cl', self._parent_repo, False)
187 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS + 278 self.assertEqual(self.REPO_CHECK_COMMANDS + self.LOCAL_REPO_COMMANDS +
188 self.UPLOAD_COMMAND + self.BRANCH_CLEANUP_COMMANDS, 279 self.UPLOAD_COMMANDS + self.BRANCH_CLEANUP_COMMANDS,
189 self._commands) 280 self._commands)
190 self.assertFalse(os.path.exists(self._target_repo)) 281 self.assertFalse(os.path.exists(self._target_repo))
191 self.assertFalse(self._input) 282 self.assertFalse(self._input)
192 283
193 def testInvalidParentRepoDirectory(self): 284 def testInvalidParentRepoDirectory(self):
194 self.assertRaises( 285 self.assertRaises(git_drover.Error, git_drover.cherry_pick_change, 'branch',
195 git_drover.Error, git_drover.cherry_pick_change, 'branch', 'cl', 286 'cl', os.path.join(self._parent_repo, 'fake'), False)
196 os.path.join(self._parent_repo, 'fake'), False)
197 self.assertFalse(self._commands) 287 self.assertFalse(self._commands)
198 self.assertFalse(os.path.exists(self._target_repo)) 288 self.assertFalse(os.path.exists(self._target_repo))
199 self.assertFalse(self._input) 289 self.assertFalse(self._input)
200 290
291 def testContinueInvalidWorkdir(self):
292 self.assertRaises(git_drover.Error, git_drover.continue_cherry_pick,
293 self._parent_repo)
294
295 def testAbortInvalidWorkdir(self):
296 self.assertRaises(git_drover.Error, git_drover.abort_cherry_pick,
297 self._parent_repo)
298
201 299
202 if __name__ == '__main__': 300 if __name__ == '__main__':
203 unittest.main() 301 unittest.main()
OLDNEW
« no previous file with comments | « man/src/git-drover.demo.4.sh ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698