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

Side by Side Diff: tests/git_common_test.py

Issue 184253003: Add git-reup and friends (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@freeze_thaw
Patch Set: minor fixes Created 6 years, 9 months 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 2013 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 5
6 """Unit tests for git_common.py""" 6 """Unit tests for git_common.py"""
7 7
8 import binascii 8 import binascii
9 import collections 9 import collections
10 import os 10 import os
11 import signal 11 import signal
12 import sys 12 import sys
13 import tempfile 13 import tempfile
14 import time 14 import time
15 import unittest 15 import unittest
16 16
17 DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 17 DEPOT_TOOLS_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18 sys.path.insert(0, DEPOT_TOOLS_ROOT) 18 sys.path.insert(0, DEPOT_TOOLS_ROOT)
19 19
20 from testing_support import coverage_utils 20 from testing_support import coverage_utils
21 from testing_support import git_test_utils 21 from testing_support import git_test_utils
22 22
23 23
24 class GitCommonTestBase(unittest.TestCase): 24 class GitCommonTestBase(unittest.TestCase):
25 @classmethod 25 @classmethod
26 def setUpClass(cls): 26 def setUpClass(cls):
27 super(GitCommonTestBase, cls).setUpClass() 27 super(GitCommonTestBase, cls).setUpClass()
28 import git_common 28 import git_common
29 cls.gc = git_common 29 cls.gc = git_common
30 cls.gc.TEST_MODE = True
30 31
31 32
32 class Support(GitCommonTestBase): 33 class Support(GitCommonTestBase):
33 def _testMemoizeOneBody(self, threadsafe): 34 def _testMemoizeOneBody(self, threadsafe):
34 calls = collections.defaultdict(int) 35 calls = collections.defaultdict(int)
35 def double_if_even(val): 36 def double_if_even(val):
36 calls[val] += 1 37 calls[val] += 1
37 return val * 2 if val % 2 == 0 else None 38 return val * 2 if val % 2 == 0 else None
38 # Use this explicitly as a wrapper fn instead of a decorator. Otherwise 39 # Use this explicitly as a wrapper fn instead of a decorator. Otherwise
39 # pylint crashes (!!) 40 # pylint crashes (!!)
(...skipping 16 matching lines...) Expand all
56 self.assertEqual(None, double_if_even(1)) 57 self.assertEqual(None, double_if_even(1))
57 self.assertEqual(20, double_if_even(10)) 58 self.assertEqual(20, double_if_even(10))
58 self.assertDictEqual({1: 4, 2: 2, 10: 1}, calls) 59 self.assertDictEqual({1: 4, 2: 2, 10: 1}, calls)
59 60
60 def testMemoizeOne(self): 61 def testMemoizeOne(self):
61 self._testMemoizeOneBody(threadsafe=False) 62 self._testMemoizeOneBody(threadsafe=False)
62 63
63 def testMemoizeOneThreadsafe(self): 64 def testMemoizeOneThreadsafe(self):
64 self._testMemoizeOneBody(threadsafe=True) 65 self._testMemoizeOneBody(threadsafe=True)
65 66
67 def testOnce(self):
68 testlist = []
69
70 @self.gc.once
71 def add_to_list():
72 testlist.append('dog')
73
74 add_to_list()
75 add_to_list()
76 add_to_list()
77 add_to_list()
78
79 self.assertEquals(testlist, ['dog'])
80
66 81
67 def slow_square(i): 82 def slow_square(i):
68 """Helper for ScopedPoolTest. 83 """Helper for ScopedPoolTest.
69 84
70 Must be global because non top-level functions aren't pickleable. 85 Must be global because non top-level functions aren't pickleable.
71 """ 86 """
72 return i ** 2 87 return i ** 2
73 88
74 89
75 class ScopedPoolTest(GitCommonTestBase): 90 class ScopedPoolTest(GitCommonTestBase):
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 """This test is probably racy, but I don't have a better alternative.""" 142 """This test is probably racy, but I don't have a better alternative."""
128 fmt = '%(count)d/10' 143 fmt = '%(count)d/10'
129 stream = self.FakeStream() 144 stream = self.FakeStream()
130 145
131 pp = self.gc.ProgressPrinter(fmt, enabled=True, fout=stream, period=0.01) 146 pp = self.gc.ProgressPrinter(fmt, enabled=True, fout=stream, period=0.01)
132 with pp as inc: 147 with pp as inc:
133 for _ in xrange(10): 148 for _ in xrange(10):
134 time.sleep(0.02) 149 time.sleep(0.02)
135 inc() 150 inc()
136 151
137 filtered = set(x.strip() for x in stream.data) 152 filtered = {x.strip() for x in stream.data}
138 rslt = set(fmt % {'count': i} for i in xrange(11)) 153 rslt = {fmt % {'count': i} for i in xrange(11)}
139 self.assertSetEqual(filtered, rslt) 154 self.assertSetEqual(filtered, rslt)
140 self.assertGreaterEqual(stream.count, 10) 155 self.assertGreaterEqual(stream.count, 10)
141 156
142 157
143 class GitReadOnlyFunctionsTest(git_test_utils.GitRepoReadOnlyTestBase, 158 class GitReadOnlyFunctionsTest(git_test_utils.GitRepoReadOnlyTestBase,
144 GitCommonTestBase): 159 GitCommonTestBase):
145 REPO = """ 160 REPO_SCHEMA = """
146 A B C D 161 A B C D
147 B E D 162 B E D
148 """ 163 """
149 164
150 COMMIT_A = { 165 COMMIT_A = {
151 'some/files/file1': {'data': 'file1'}, 166 'some/files/file1': {'data': 'file1'},
152 'some/files/file2': {'data': 'file2'}, 167 'some/files/file2': {'data': 'file2'},
153 'some/files/file3': {'data': 'file3'}, 168 'some/files/file3': {'data': 'file3'},
154 'some/other/file': {'data': 'otherfile'}, 169 'some/other/file': {'data': 'otherfile'},
155 } 170 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 ], ret) 202 ], ret)
188 self.assertEquals( 203 self.assertEquals(
189 self.repo.run(self.gc.hash_one, 'branch_D'), 204 self.repo.run(self.gc.hash_one, 'branch_D'),
190 self.repo['D'] 205 self.repo['D']
191 ) 206 )
192 207
193 def testStream(self): 208 def testStream(self):
194 items = set(self.repo.commit_map.itervalues()) 209 items = set(self.repo.commit_map.itervalues())
195 210
196 def testfn(): 211 def testfn():
197 for line in self.gc.stream('log', '--format=%H').xreadlines(): 212 for line in self.gc.run_stream('log', '--format=%H').xreadlines():
198 line = line.strip() 213 line = line.strip()
199 self.assertIn(line, items) 214 self.assertIn(line, items)
200 items.remove(line) 215 items.remove(line)
201 216
202 self.repo.run(testfn) 217 self.repo.run(testfn)
203 218
204 def testCurrentBranch(self): 219 def testCurrentBranch(self):
220 def cur_branch_out_of_git():
221 os.chdir('..')
222 return self.gc.current_branch()
223 self.assertIsNone(self.repo.run(cur_branch_out_of_git))
224
205 self.repo.git('checkout', 'branch_D') 225 self.repo.git('checkout', 'branch_D')
206 self.assertEqual(self.repo.run(self.gc.current_branch), 'branch_D') 226 self.assertEqual(self.repo.run(self.gc.current_branch), 'branch_D')
207 227
208 def testBranches(self): 228 def testBranches(self):
209 self.assertEqual(self.repo.run(set, self.gc.branches()), 229 self.assertEqual(self.repo.run(set, self.gc.branches()),
210 set(('branch_D', 'root_A'))) 230 {'master', 'branch_D', 'root_A'})
211 231
212 def testTags(self): 232 def testDormant(self):
213 self.assertEqual(set(self.repo.run(self.gc.tags)), 233 self.assertFalse(self.repo.run(self.gc.is_dormant, 'master'))
214 {'tag_'+l for l in 'ABCDE'}) 234 self.repo.git('config', 'branch.master.dormant', 'true')
235 self.assertTrue(self.repo.run(self.gc.is_dormant, 'master'))
215 236
216 def testParseCommitrefs(self): 237 def testParseCommitrefs(self):
217 ret = self.repo.run( 238 ret = self.repo.run(
218 self.gc.parse_commitrefs, *[ 239 self.gc.parse_commitrefs, *[
219 'master', 240 'master',
220 'master~3', 241 'master~3',
221 self.repo['E']+'~', 242 self.repo['E']+'~',
222 self.repo['D']+'^2', 243 self.repo['D']+'^2',
223 'tag_C^{}', 244 'tag_C^{}',
224 ] 245 ]
225 ) 246 )
226 self.assertEqual(ret, map(binascii.unhexlify, [ 247 self.assertEqual(ret, map(binascii.unhexlify, [
227 self.repo['D'], 248 self.repo['D'],
228 self.repo['A'], 249 self.repo['A'],
229 self.repo['B'], 250 self.repo['B'],
230 self.repo['E'], 251 self.repo['E'],
231 self.repo['C'], 252 self.repo['C'],
232 ])) 253 ]))
233 254
234 with self.assertRaisesRegexp(Exception, r"one of \('master', 'bananas'\)"): 255 with self.assertRaisesRegexp(Exception, r"one of \('master', 'bananas'\)"):
235 self.repo.run(self.gc.parse_commitrefs, 'master', 'bananas') 256 self.repo.run(self.gc.parse_commitrefs, 'master', 'bananas')
236 257
258 def testTags(self):
259 self.assertEqual(set(self.repo.run(self.gc.tags)),
260 {'tag_'+l for l in 'ABCDE'})
261
237 def testTree(self): 262 def testTree(self):
238 tree = self.repo.run(self.gc.tree, 'master:some/files') 263 tree = self.repo.run(self.gc.tree, 'master:some/files')
239 file1 = self.COMMIT_A['some/files/file1']['data'] 264 file1 = self.COMMIT_A['some/files/file1']['data']
240 file2 = self.COMMIT_D['some/files/file2']['data'] 265 file2 = self.COMMIT_D['some/files/file2']['data']
241 file3 = self.COMMIT_A['some/files/file3']['data'] 266 file3 = self.COMMIT_A['some/files/file3']['data']
242 self.assertEquals( 267 self.assertEquals(
243 tree['file1'], 268 tree['file1'],
244 ('100644', 'blob', git_test_utils.git_hash_data(file1))) 269 ('100644', 'blob', git_test_utils.git_hash_data(file1)))
245 self.assertEquals( 270 self.assertEquals(
246 tree['file2'], 271 tree['file2'],
(...skipping 25 matching lines...) Expand all
272 self.assertEquals( 297 self.assertEquals(
273 tree['files/file3'], 298 tree['files/file3'],
274 ('100644', 'blob', git_test_utils.git_hash_data(file3))) 299 ('100644', 'blob', git_test_utils.git_hash_data(file3)))
275 self.assertEquals( 300 self.assertEquals(
276 tree['other/file'], 301 tree['other/file'],
277 ('100644', 'blob', git_test_utils.git_hash_data(other))) 302 ('100644', 'blob', git_test_utils.git_hash_data(other)))
278 303
279 304
280 class GitMutableFunctionsTest(git_test_utils.GitRepoReadWriteTestBase, 305 class GitMutableFunctionsTest(git_test_utils.GitRepoReadWriteTestBase,
281 GitCommonTestBase): 306 GitCommonTestBase):
282 REPO = '' 307 REPO_SCHEMA = ''
283 308
284 def _intern_data(self, data): 309 def _intern_data(self, data):
285 with tempfile.TemporaryFile() as f: 310 with tempfile.TemporaryFile() as f:
286 f.write(data) 311 f.write(data)
287 f.seek(0) 312 f.seek(0)
288 return self.repo.run(self.gc.intern_f, f) 313 return self.repo.run(self.gc.intern_f, f)
289 314
290 def testInternF(self): 315 def testInternF(self):
291 data = 'CoolBobcatsBro' 316 data = 'CoolBobcatsBro'
292 data_hash = self._intern_data(data) 317 data_hash = self._intern_data(data)
(...skipping 11 matching lines...) Expand all
304 def testConfig(self): 329 def testConfig(self):
305 self.repo.git('config', '--add', 'happy.derpies', 'food') 330 self.repo.git('config', '--add', 'happy.derpies', 'food')
306 self.assertEquals(self.repo.run(self.gc.config_list, 'happy.derpies'), 331 self.assertEquals(self.repo.run(self.gc.config_list, 'happy.derpies'),
307 ['food']) 332 ['food'])
308 self.assertEquals(self.repo.run(self.gc.config_list, 'sad.derpies'), []) 333 self.assertEquals(self.repo.run(self.gc.config_list, 'sad.derpies'), [])
309 334
310 self.repo.git('config', '--add', 'happy.derpies', 'cat') 335 self.repo.git('config', '--add', 'happy.derpies', 'cat')
311 self.assertEquals(self.repo.run(self.gc.config_list, 'happy.derpies'), 336 self.assertEquals(self.repo.run(self.gc.config_list, 'happy.derpies'),
312 ['food', 'cat']) 337 ['food', 'cat'])
313 338
339 self.assertEquals('cat', self.repo.run(self.gc.config, 'dude.bob', 'cat'))
340
341 self.repo.run(self.gc.set_config, 'dude.bob', 'dog')
342
343 self.assertEquals('dog', self.repo.run(self.gc.config, 'dude.bob', 'cat'))
344
345 self.repo.run(self.gc.del_config, 'dude.bob')
346
347 # This should work without raising an exception
348 self.repo.run(self.gc.del_config, 'dude.bob')
349
350 self.assertEquals('cat', self.repo.run(self.gc.config, 'dude.bob', 'cat'))
351
352 self.assertEquals('origin/master', self.repo.run(self.gc.root))
353
354 self.repo.git('config', 'depot-tools.upstream', 'catfood')
355
356 self.assertEquals('catfood', self.repo.run(self.gc.root))
357
314 def testUpstream(self): 358 def testUpstream(self):
315 self.repo.git('commit', '--allow-empty', '-am', 'foooooo') 359 self.repo.git('commit', '--allow-empty', '-am', 'foooooo')
316 self.assertEquals(self.repo.run(self.gc.upstream, 'bobly'), None) 360 self.assertEquals(self.repo.run(self.gc.upstream, 'bobly'), None)
317 self.assertEquals(self.repo.run(self.gc.upstream, 'master'), None) 361 self.assertEquals(self.repo.run(self.gc.upstream, 'master'), None)
318 self.repo.git('checkout', '-tb', 'happybranch', 'master') 362 self.repo.git('checkout', '-tb', 'happybranch', 'master')
319 self.assertEquals(self.repo.run(self.gc.upstream, 'happybranch'), 363 self.assertEquals(self.repo.run(self.gc.upstream, 'happybranch'),
320 'master') 364 'master')
321 365
322 366
367 class GitMutableStructuredTest(git_test_utils.GitRepoReadWriteTestBase,
368 GitCommonTestBase):
369 REPO_SCHEMA = """
370 A B C D E F G
371 B H I J K
372 J L
373
374 X Y Z
375 """
376
377 COMMIT_B = {'file': {'data': 'B'}}
378 COMMIT_H = {'file': {'data': 'H'}}
379 COMMIT_I = {'file': {'data': 'I'}}
380 COMMIT_J = {'file': {'data': 'J'}}
381 COMMIT_K = {'file': {'data': 'K'}}
382 COMMIT_L = {'file': {'data': 'L'}}
383
384 def setUp(self):
385 super(GitMutableStructuredTest, self).setUp()
386 self.repo.git('branch', '--set-upstream-to', 'root_X', 'branch_Z')
387 self.repo.git('branch', '--set-upstream-to', 'branch_G', 'branch_K')
388 self.repo.git('branch', '--set-upstream-to', 'branch_K', 'branch_L')
389 self.repo.git('branch', '--set-upstream-to', 'root_A', 'branch_G')
390 self.repo.git('branch', '--set-upstream-to', 'root_X', 'root_A')
391
392 def testMergeBase(self):
393 self.repo.git('checkout', 'branch_K')
394
395 self.assertEqual(
396 self.repo['B'],
397 self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
398 )
399
400 self.assertEqual(
401 self.repo['J'],
402 self.repo.run(self.gc.get_or_create_merge_base, 'branch_L', 'branch_K')
403 )
404
405 self.assertEqual(
406 self.repo['B'], self.repo.run(self.gc.config, 'branch.branch_K.base')
407 )
408
409 # deadbeef is a bad hash, so this will result in repo['B']
410 self.repo.run(self.gc.manual_merge_base, 'branch_K', 'deadbeef')
411
412 self.assertEqual(
413 self.repo['B'],
414 self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
415 )
416
417 # but if we pick a real ancestor, then it'll work
418 self.repo.run(self.gc.manual_merge_base, 'branch_K', self.repo['I'])
419
420 self.assertEqual(
421 self.repo['I'],
422 self.repo.run(self.gc.get_or_create_merge_base, 'branch_K', 'branch_G')
423 )
424
425 self.assertEqual({'branch_K': self.repo['I'], 'branch_L': self.repo['J']},
426 self.repo.run(self.gc.branch_config_map, 'base'))
427
428 self.repo.run(self.gc.remove_merge_base, 'branch_K')
429 self.repo.run(self.gc.remove_merge_base, 'branch_L')
430
431 self.assertEqual(None,
432 self.repo.run(self.gc.config, 'branch.branch_K.base'))
433
434 self.assertEqual({}, self.repo.run(self.gc.branch_config_map, 'base'))
435
436 def testGetBranchTree(self):
437 skipped, tree = self.repo.run(self.gc.get_branch_tree)
438 self.assertEqual(skipped, {'master', 'root_X'})
439 self.assertEqual(tree, {
440 'branch_G': 'root_A',
441 'root_A': 'root_X',
442 'branch_K': 'branch_G',
443 'branch_L': 'branch_K',
444 'branch_Z': 'root_X'
445 })
446
447 topdown = list(self.gc.topo_iter(tree))
448 bottomup = list(self.gc.topo_iter(tree, top_down=False))
449
450 self.assertEqual(topdown, [
451 ('branch_Z', 'root_X'),
452 ('root_A', 'root_X'),
453 ('branch_G', 'root_A'),
454 ('branch_K', 'branch_G'),
455 ('branch_L', 'branch_K'),
456 ])
457
458 self.assertEqual(bottomup, [
459 ('branch_L', 'branch_K'),
460 ('branch_Z', 'root_X'),
461 ('branch_K', 'branch_G'),
462 ('branch_G', 'root_A'),
463 ('root_A', 'root_X'),
464 ])
465
466 def testSquashBranch(self):
467 self.repo.git('checkout', 'branch_K')
468
469 self.repo.run(self.gc.squash_current_branch, 'cool message')
470
471 lines = ['cool message', '']
472 for l in 'HIJK':
473 lines.extend((self.repo[l], l, ''))
474 lines.pop()
475 msg = '\n'.join(lines)
476
477 self.assertEquals(self.repo.run(self.gc.run, 'log', '-n1', '--format=%B'),
478 msg)
479
480 self.assertEquals(
481 self.repo.git('cat-file', 'blob', 'branch_K:file').stdout,
482 'K'
483 )
484
485 def testRebase(self):
486 graphlines = lambda: [
487 l.strip() for l in self.repo.git(
488 'log', '--graph', '--format=%s', *['branch_'+b for b in 'GKL']
489 ).stdout.splitlines()
490 ]
491 self.assertEqual(
492 graphlines(), [
493 '* G',
494 '* F',
495 '* E',
496 '* D',
497 '* C',
498 '| * L',
499 '| | * K',
500 '| |/',
501 '| * J',
502 '| * I',
503 '| * H',
504 '|/',
505 '* B',
506 '* A',
507 ]
508 )
509
510 rslt = self.repo.run(
511 self.gc.rebase, 'branch_G', 'branch_K~4', 'branch_K')
512 self.assertTrue(rslt.success)
513
514 self.assertEqual(
515 graphlines(), [
516 '* L',
517 '* J',
518 '* I',
519 '* H',
520 '| * K',
521 '| * J',
522 '| * I',
523 '| * H',
524 '| * G',
525 '| * F',
526 '| * E',
527 '| * D',
528 '| * C',
529 '|/',
530 '* B',
531 '* A',
532 ]
533 )
534
535 rslt = self.repo.run(
536 self.gc.rebase, 'branch_K', 'branch_L~1', 'branch_L', abort=True)
537 self.assertFalse(rslt.success)
538
539 self.assertFalse(self.repo.run(self.gc.in_rebase))
540
541 rslt = self.repo.run(
542 self.gc.rebase, 'branch_K', 'branch_L~1', 'branch_L', abort=False)
543 self.assertFalse(rslt.success)
544
545 self.assertTrue(self.repo.run(self.gc.in_rebase))
546
547 self.assertEqual(self.repo.git('status', '--porcelain').stdout, 'UU file\n')
548 self.repo.git('checkout', '--theirs', 'file')
549 self.repo.git('add', 'file')
550 self.repo.git('rebase', '--continue')
551
552 self.assertEqual(
553 graphlines(), [
554 '* L',
555 '* K',
556 '* J',
557 '* I',
558 '* H',
559 '* G',
560 '* F',
561 '* E',
562 '* D',
563 '* C',
564 '* B',
565 '* A',
566 ]
567 )
568
569
323 if __name__ == '__main__': 570 if __name__ == '__main__':
324 sys.exit(coverage_utils.covered_main( 571 sys.exit(coverage_utils.covered_main(
325 os.path.join(DEPOT_TOOLS_ROOT, 'git_common.py') 572 os.path.join(DEPOT_TOOLS_ROOT, 'git_common.py')
326 )) 573 ))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698