| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 gclient_scm.py.""" | 6 """Unit tests for gclient_scm.py.""" |
| 7 | 7 |
| 8 # pylint: disable=E1101,E1103,W0403 |
| 9 |
| 8 # Import before super_mox to keep valid references. | 10 # Import before super_mox to keep valid references. |
| 9 from os import rename | 11 from os import rename |
| 10 from shutil import rmtree | 12 from shutil import rmtree |
| 11 import StringIO | |
| 12 from subprocess import Popen, PIPE, STDOUT | 13 from subprocess import Popen, PIPE, STDOUT |
| 13 import tempfile | 14 import tempfile |
| 14 import unittest | 15 import unittest |
| 15 import __builtin__ | 16 import __builtin__ |
| 16 | 17 |
| 17 # Fixes include path. | 18 # Fixes include path. |
| 18 from super_mox import mox, StdoutCheck, TestCaseUtils, SuperMoxTestBase | 19 from super_mox import mox, StdoutCheck, TestCaseUtils, SuperMoxTestBase |
| 19 | 20 |
| 20 import sys | 21 import sys |
| 21 import gclient_scm | 22 import gclient_scm |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 55 gclient_scm.scm.SVN.current_version = None | 56 gclient_scm.scm.SVN.current_version = None |
| 56 # Absolute path of the fake checkout directory. | 57 # Absolute path of the fake checkout directory. |
| 57 self.base_path = join(self.root_dir, self.relpath) | 58 self.base_path = join(self.root_dir, self.relpath) |
| 58 | 59 |
| 59 def tearDown(self): | 60 def tearDown(self): |
| 60 SuperMoxTestBase.tearDown(self) | 61 SuperMoxTestBase.tearDown(self) |
| 61 | 62 |
| 62 | 63 |
| 63 class SVNWrapperTestCase(BaseTestCase): | 64 class SVNWrapperTestCase(BaseTestCase): |
| 64 class OptionsObject(object): | 65 class OptionsObject(object): |
| 65 def __init__(self, verbose=False, revision=None): | 66 def __init__(self, verbose=False, revision=None): |
| 66 self.verbose = verbose | 67 self.verbose = verbose |
| 67 self.revision = revision | 68 self.revision = revision |
| 68 self.manually_grab_svn_rev = True | 69 self.manually_grab_svn_rev = True |
| 69 self.deps_os = None | 70 self.deps_os = None |
| 70 self.force = False | 71 self.force = False |
| 71 self.reset = False | 72 self.reset = False |
| 72 self.nohooks = False | 73 self.nohooks = False |
| 73 | 74 |
| 74 def Options(self, *args, **kwargs): | 75 def Options(self, *args, **kwargs): |
| 75 return self.OptionsObject(*args, **kwargs) | 76 return self.OptionsObject(*args, **kwargs) |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 items = [ | 202 items = [ |
| 202 ('~ ', 'a'), | 203 ('~ ', 'a'), |
| 203 ] | 204 ] |
| 204 gclient_scm.scm.SVN.CaptureStatus(self.base_path).AndReturn(items) | 205 gclient_scm.scm.SVN.CaptureStatus(self.base_path).AndReturn(items) |
| 205 file_path = join(self.base_path, 'a') | 206 file_path = join(self.base_path, 'a') |
| 206 gclient_scm.os.path.exists(file_path).AndReturn(True) | 207 gclient_scm.os.path.exists(file_path).AndReturn(True) |
| 207 gclient_scm.os.path.isfile(file_path).AndReturn(False) | 208 gclient_scm.os.path.isfile(file_path).AndReturn(False) |
| 208 gclient_scm.os.path.islink(file_path).AndReturn(False) | 209 gclient_scm.os.path.islink(file_path).AndReturn(False) |
| 209 gclient_scm.os.path.isdir(file_path).AndReturn(True) | 210 gclient_scm.os.path.isdir(file_path).AndReturn(True) |
| 210 gclient_scm.gclient_utils.RemoveDirectory(file_path) | 211 gclient_scm.gclient_utils.RemoveDirectory(file_path) |
| 211 file_list1 = [] | |
| 212 gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, | 212 gclient_scm.scm.SVN.RunAndGetFileList(options.verbose, |
| 213 ['update', '--revision', 'BASE'], | 213 ['update', '--revision', 'BASE'], |
| 214 cwd=self.base_path, | 214 cwd=self.base_path, |
| 215 file_list=mox.IgnoreArg()) | 215 file_list=mox.IgnoreArg()) |
| 216 | 216 |
| 217 self.mox.ReplayAll() | 217 self.mox.ReplayAll() |
| 218 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, | 218 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, |
| 219 relpath=self.relpath) | 219 relpath=self.relpath) |
| 220 file_list2 = [] | 220 file_list2 = [] |
| 221 scm.revert(options, self.args, file_list2) | 221 scm.revert(options, self.args, file_list2) |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 gclient_scm.scm.SVN.CaptureInfo(file_info['URL']).AndReturn(file_info) | 333 gclient_scm.scm.SVN.CaptureInfo(file_info['URL']).AndReturn(file_info) |
| 334 | 334 |
| 335 self.mox.ReplayAll() | 335 self.mox.ReplayAll() |
| 336 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, | 336 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir, |
| 337 relpath=self.relpath) | 337 relpath=self.relpath) |
| 338 scm.updatesingle(options, ['DEPS'], files_list) | 338 scm.updatesingle(options, ['DEPS'], files_list) |
| 339 self.checkstdout('\n_____ %s at 42\n' % self.relpath) | 339 self.checkstdout('\n_____ %s at 42\n' % self.relpath) |
| 340 | 340 |
| 341 def testUpdateSingleCheckoutSVN14(self): | 341 def testUpdateSingleCheckoutSVN14(self): |
| 342 options = self.Options(verbose=True) | 342 options = self.Options(verbose=True) |
| 343 file_info = { | |
| 344 'URL': self.url, | |
| 345 'Revision': 42, | |
| 346 } | |
| 347 | 343 |
| 348 # Checks to make sure that we support svn co --depth. | 344 # Checks to make sure that we support svn co --depth. |
| 349 gclient_scm.scm.SVN.current_version = None | 345 gclient_scm.scm.SVN.current_version = None |
| 350 gclient_scm.scm.SVN.Capture(['--version'] | 346 gclient_scm.scm.SVN.Capture(['--version'] |
| 351 ).AndReturn('svn, version 1.4.4 (r25188)') | 347 ).AndReturn('svn, version 1.4.4 (r25188)') |
| 352 gclient_scm.os.path.exists(self.base_path).AndReturn(True) | 348 gclient_scm.os.path.exists(self.base_path).AndReturn(True) |
| 353 | 349 |
| 354 # When checking out a single file with svn 1.4, we use svn export | 350 # When checking out a single file with svn 1.4, we use svn export |
| 355 files_list = self.mox.CreateMockAnything() | 351 files_list = self.mox.CreateMockAnything() |
| 356 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader( | 352 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader( |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 459 file_list = [] | 455 file_list = [] |
| 460 scm.update(options, self.args, file_list) | 456 scm.update(options, self.args, file_list) |
| 461 self.checkstdout( | 457 self.checkstdout( |
| 462 ('________ found .hg directory; skipping %s\n' % self.relpath)) | 458 ('________ found .hg directory; skipping %s\n' % self.relpath)) |
| 463 | 459 |
| 464 | 460 |
| 465 class GitWrapperTestCase(GCBaseTestCase, StdoutCheck, TestCaseUtils, | 461 class GitWrapperTestCase(GCBaseTestCase, StdoutCheck, TestCaseUtils, |
| 466 unittest.TestCase): | 462 unittest.TestCase): |
| 467 """This class doesn't use pymox.""" | 463 """This class doesn't use pymox.""" |
| 468 class OptionsObject(object): | 464 class OptionsObject(object): |
| 469 def __init__(self, verbose=False, revision=None): | 465 def __init__(self, verbose=False, revision=None): |
| 470 self.verbose = verbose | 466 self.verbose = verbose |
| 471 self.revision = revision | 467 self.revision = revision |
| 472 self.manually_grab_svn_rev = True | 468 self.manually_grab_svn_rev = True |
| 473 self.deps_os = None | 469 self.deps_os = None |
| 474 self.force = False | 470 self.force = False |
| 475 self.reset = False | 471 self.reset = False |
| 476 self.nohooks = False | 472 self.nohooks = False |
| 477 | 473 |
| 478 sample_git_import = """blob | 474 sample_git_import = """blob |
| 479 mark :1 | 475 mark :1 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 from :3 | 512 from :3 |
| 517 M 100644 :4 a | 513 M 100644 :4 a |
| 518 M 100644 :5 b | 514 M 100644 :5 b |
| 519 | 515 |
| 520 reset refs/heads/master | 516 reset refs/heads/master |
| 521 from :3 | 517 from :3 |
| 522 """ | 518 """ |
| 523 def Options(self, *args, **kwargs): | 519 def Options(self, *args, **kwargs): |
| 524 return self.OptionsObject(*args, **kwargs) | 520 return self.OptionsObject(*args, **kwargs) |
| 525 | 521 |
| 526 def CreateGitRepo(self, git_import, path): | 522 @staticmethod |
| 523 def CreateGitRepo(git_import, path): |
| 527 """Do it for real.""" | 524 """Do it for real.""" |
| 528 try: | 525 try: |
| 529 Popen(['git', 'init', '-q'], stdout=PIPE, stderr=STDOUT, | 526 Popen(['git', 'init', '-q'], stdout=PIPE, stderr=STDOUT, |
| 530 cwd=path).communicate() | 527 cwd=path).communicate() |
| 531 except OSError: | 528 except OSError: |
| 532 # git is not available, skip this test. | 529 # git is not available, skip this test. |
| 533 return False | 530 return False |
| 534 Popen(['git', 'fast-import', '--quiet'], stdin=PIPE, stdout=PIPE, | 531 Popen(['git', 'fast-import', '--quiet'], stdin=PIPE, stdout=PIPE, |
| 535 stderr=STDOUT, cwd=path).communicate(input=git_import) | 532 stderr=STDOUT, cwd=path).communicate(input=git_import) |
| 536 Popen(['git', 'checkout', '-q'], stdout=PIPE, stderr=STDOUT, | 533 Popen(['git', 'checkout', '-q'], stdout=PIPE, stderr=STDOUT, |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 ('\n________ running \'git diff --name-status ' | 684 ('\n________ running \'git diff --name-status ' |
| 688 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\n') % | 685 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\n') % |
| 689 join(self.root_dir, '.')) | 686 join(self.root_dir, '.')) |
| 690 | 687 |
| 691 def testStatus2New(self): | 688 def testStatus2New(self): |
| 692 if not self.enabled: | 689 if not self.enabled: |
| 693 return | 690 return |
| 694 options = self.Options() | 691 options = self.Options() |
| 695 expected_file_list = [] | 692 expected_file_list = [] |
| 696 for f in ['a', 'b']: | 693 for f in ['a', 'b']: |
| 697 file_path = join(self.base_path, f) | 694 file_path = join(self.base_path, f) |
| 698 open(file_path, 'a').writelines('touched\n') | 695 open(file_path, 'a').writelines('touched\n') |
| 699 expected_file_list.extend([file_path]) | 696 expected_file_list.extend([file_path]) |
| 700 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, | 697 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, |
| 701 relpath=self.relpath) | 698 relpath=self.relpath) |
| 702 file_list = [] | 699 file_list = [] |
| 703 scm.status(options, self.args, file_list) | 700 scm.status(options, self.args, file_list) |
| 704 expected_file_list = [join(self.base_path, x) for x in ['a', 'b']] | 701 expected_file_list = [join(self.base_path, x) for x in ['a', 'b']] |
| 705 self.assertEquals(sorted(file_list), expected_file_list) | 702 self.assertEquals(sorted(file_list), expected_file_list) |
| 706 self.checkstdout( | 703 self.checkstdout( |
| 707 ('\n________ running \'git diff --name-status ' | 704 ('\n________ running \'git diff --name-status ' |
| 708 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\nM\tb\n') % | 705 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\nM\tb\n') % |
| 709 join(self.root_dir, '.')) | 706 join(self.root_dir, '.')) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 751 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n' | 748 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n' |
| 752 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n') | 749 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n') |
| 753 | 750 |
| 754 def testUpdateUnstagedConflict(self): | 751 def testUpdateUnstagedConflict(self): |
| 755 if not self.enabled: | 752 if not self.enabled: |
| 756 return | 753 return |
| 757 options = self.Options() | 754 options = self.Options() |
| 758 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, | 755 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, |
| 759 relpath=self.relpath) | 756 relpath=self.relpath) |
| 760 file_path = join(self.base_path, 'b') | 757 file_path = join(self.base_path, 'b') |
| 761 f = open(file_path, 'w').writelines('conflict\n') | 758 open(file_path, 'w').writelines('conflict\n') |
| 762 exception = ( | 759 exception = ( |
| 763 "error: Your local changes to 'b' would be overwritten by merge. " | 760 "error: Your local changes to 'b' would be overwritten by merge. " |
| 764 "Aborting.\n" | 761 "Aborting.\n" |
| 765 "Please, commit your changes or stash them before you can merge.\n") | 762 "Please, commit your changes or stash them before you can merge.\n") |
| 766 self.assertRaisesError(exception, scm.update, options, (), []) | 763 self.assertRaisesError(exception, scm.update, options, (), []) |
| 767 self.checkstdout('\n_____ . at refs/heads/master\n') | 764 self.checkstdout('\n_____ . at refs/heads/master\n') |
| 768 | 765 |
| 769 def testUpdateConflict(self): | 766 def testUpdateConflict(self): |
| 770 if not self.enabled: | 767 if not self.enabled: |
| 771 return | 768 return |
| 772 options = self.Options() | 769 options = self.Options() |
| 773 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, | 770 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, |
| 774 relpath=self.relpath) | 771 relpath=self.relpath) |
| 775 file_path = join(self.base_path, 'b') | 772 file_path = join(self.base_path, 'b') |
| 776 f = open(file_path, 'w').writelines('conflict\n') | 773 open(file_path, 'w').writelines('conflict\n') |
| 774 # pylint: disable=W0212 |
| 777 scm._Run(['commit', '-am', 'test'], options) | 775 scm._Run(['commit', '-am', 'test'], options) |
| 778 __builtin__.raw_input = lambda x: 'y' | 776 __builtin__.raw_input = lambda x: 'y' |
| 779 exception = ('Conflict while rebasing this branch.\n' | 777 exception = ('Conflict while rebasing this branch.\n' |
| 780 'Fix the conflict and run gclient again.\n' | 778 'Fix the conflict and run gclient again.\n' |
| 781 'See \'man git-rebase\' for details.\n') | 779 'See \'man git-rebase\' for details.\n') |
| 782 self.assertRaisesError(exception, scm.update, options, (), []) | 780 self.assertRaisesError(exception, scm.update, options, (), []) |
| 783 exception = ('\n____ . at refs/heads/master\n' | 781 exception = ('\n____ . at refs/heads/master\n' |
| 784 '\tYou have unstaged changes.\n' | 782 '\tYou have unstaged changes.\n' |
| 785 '\tPlease commit, stash, or reset.\n') | 783 '\tPlease commit, stash, or reset.\n') |
| 786 self.assertRaisesError(exception, scm.update, options, (), []) | 784 self.assertRaisesError(exception, scm.update, options, (), []) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, | 816 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir, |
| 819 relpath=self.relpath) | 817 relpath=self.relpath) |
| 820 rev_info = scm.revinfo(options, (), None) | 818 rev_info = scm.revinfo(options, (), None) |
| 821 self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458') | 819 self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458') |
| 822 | 820 |
| 823 | 821 |
| 824 if __name__ == '__main__': | 822 if __name__ == '__main__': |
| 825 unittest.main() | 823 unittest.main() |
| 826 | 824 |
| 827 # vim: ts=2:sw=2:tw=80:et: | 825 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |