From 7842e92ebaf3fc3380cc8d704afa3841f333748c Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Thu, 15 Sep 2016 00:59:36 +0200 Subject: test, deps: FIX `mock` deps on py3. + Del extra spaces, import os.path as osp --- git/test/lib/asserts.py | 5 ++++- git/test/test_commit.py | 22 +++++++++++++--------- git/test/test_git.py | 6 +++++- 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/asserts.py b/git/test/lib/asserts.py index 60a888b3..9edc49e0 100644 --- a/git/test/lib/asserts.py +++ b/git/test/lib/asserts.py @@ -16,7 +16,10 @@ from nose.tools import ( assert_false ) -from mock import patch +try: + from unittest.mock import patch +except ImportError: + from mock import patch __all__ = ['assert_instance_of', 'assert_not_instance_of', 'assert_none', 'assert_not_none', diff --git a/git/test/test_commit.py b/git/test/test_commit.py index c0599503..805221ac 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -34,7 +34,11 @@ import re import os from datetime import datetime from git.objects.util import tzoffset, utc -from mock import Mock + +try: + from unittest.mock import Mock +except ImportError: + from mock import Mock def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False): @@ -343,9 +347,9 @@ JzJMZDRLQLFvnzqZuCjE cstream = BytesIO() cmt._serialize(cstream) assert re.search(r"^gpgsig $", cstream.getvalue().decode('ascii'), re.MULTILINE) - + self.assert_gpgsig_deserialization(cstream) - + cstream.seek(0) cmt.gpgsig = None cmt._deserialize(cstream) @@ -355,27 +359,27 @@ JzJMZDRLQLFvnzqZuCjE cstream = BytesIO() cmt._serialize(cstream) assert not re.search(r"^gpgsig ", cstream.getvalue().decode('ascii'), re.MULTILINE) - + def assert_gpgsig_deserialization(self, cstream): assert 'gpgsig' in 'precondition: need gpgsig' - + class RepoMock: def __init__(self, bytestr): self.bytestr = bytestr - + @property def odb(self): class ODBMock: def __init__(self, bytestr): self.bytestr = bytestr - + def stream(self, *args): stream = Mock(spec_set=['read'], return_value=self.bytestr) stream.read.return_value = self.bytestr return ('binsha', 'typename', 'size', stream) - + return ODBMock(self.bytestr) - + repo_mock = RepoMock(cstream.getvalue()) for field in Commit.__slots__: c = Commit(repo_mock, b'x' * 20) diff --git a/git/test/test_git.py b/git/test/test_git.py index b46ac72d..59796a3d 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -6,7 +6,6 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php import os import sys -import mock import subprocess from git.test.lib import ( @@ -28,6 +27,11 @@ from gitdb.test.lib import with_rw_directory from git.compat import PY3 +try: + from unittest import mock +except ImportError: + import mock + class TestGit(TestBase): -- cgit v1.2.3 From 51bf7cbe8216d9a1da723c59b6feece0b1a34589 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 25 Sep 2016 18:08:16 +0200 Subject: win: GC.collect on all TC.tearDown to fix appveyor hang runs + Fixed the hangs at `test_git:TestGit.test_handle_process_output()`. [travisci skip] --- git/test/lib/helper.py | 2 ++ git/test/performance/test_commit.py | 4 ++++ git/test/test_base.py | 4 ++++ git/test/test_diff.py | 8 ++++++-- git/test/test_docs.py | 7 ++++++- git/test/test_git.py | 4 ++++ git/test/test_remote.py | 4 ++++ git/test/test_repo.py | 4 ++++ git/test/test_submodule.py | 4 ++++ 9 files changed, 38 insertions(+), 3 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 8be2881c..9488005f 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -299,6 +299,8 @@ class TestBase(TestCase): Dynamically add a read-only repository to our actual type. This way each test type has its own repository """ + import gc + gc.collect() cls.rorepo = Repo(GIT_REPO) @classmethod diff --git a/git/test/performance/test_commit.py b/git/test/performance/test_commit.py index b59c747e..c60dc2fc 100644 --- a/git/test/performance/test_commit.py +++ b/git/test/performance/test_commit.py @@ -17,6 +17,10 @@ from git.test.test_commit import assert_commit_serialization class TestPerformance(TestBigRepoRW): + def tearDown(self): + import gc + gc.collect() + # ref with about 100 commits in its history ref_100 = '0.1.6' diff --git a/git/test/test_base.py b/git/test/test_base.py index 7b71a77e..c17e04e7 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -27,6 +27,10 @@ from gitdb.util import hex_to_bin class TestBase(TestBase): + def tearDown(self): + import gc + gc.collect() + type_tuples = (("blob", "8741fc1d09d61f02ffd8cded15ff603eff1ec070", "blob.py"), ("tree", "3a6a5e3eeed3723c09f1ef0399f81ed6b8d82e79", "directory"), ("commit", "4251bd59fb8e11e40c40548cba38180a9536118c", None), diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 9fdb26a2..8735dfc4 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -28,6 +28,10 @@ from git import ( class TestDiff(TestBase): + def tearDown(self): + import gc + gc.collect() + def _assert_diff_format(self, diffs): # verify that the format of the diff is sane for diff in diffs: @@ -107,12 +111,12 @@ class TestDiff(TestBase): def test_diff_of_modified_files_not_added_to_the_index(self): output = StringProcessAdapter(fixture('diff_abbrev-40_full-index_M_raw_no-color')) diffs = Diff._index_from_raw_format(self.rorepo, output.stdout) - + assert len(diffs) == 1, 'one modification' assert len(list(diffs.iter_change_type('M'))) == 1, 'one modification' assert diffs[0].change_type == 'M' assert diffs[0].b_blob is None - + def test_binary_diff(self): for method, file_name in ((Diff._index_from_patch_format, 'diff_patch_binary'), (Diff._index_from_raw_format, 'diff_raw_binary')): diff --git a/git/test/test_docs.py b/git/test/test_docs.py index b297363d..2cd355b2 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -11,6 +11,11 @@ from gitdb.test.lib import with_rw_directory class Tutorials(TestBase): + + def tearDown(self): + import gc + gc.collect() + @with_rw_directory def test_init_repo_object(self, rw_dir): # [1-test_init_repo_object] @@ -64,7 +69,7 @@ class Tutorials(TestBase): assert repo.head.ref == repo.heads.master # head is a symbolic reference pointing to master assert repo.tags['0.3.5'] == repo.tag('refs/tags/0.3.5') # you can access tags in various ways too assert repo.refs.master == repo.heads['master'] # .refs provides access to all refs, i.e. heads ... - + if 'TRAVIS' not in os.environ: assert repo.refs['origin/master'] == repo.remotes.origin.refs.master # ... remotes ... assert repo.refs['0.3.5'] == repo.tags['0.3.5'] # ... and tags diff --git a/git/test/test_git.py b/git/test/test_git.py index 59796a3d..534539d7 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -40,6 +40,10 @@ class TestGit(TestBase): super(TestGit, cls).setUpClass() cls.git = Git(cls.rorepo.working_dir) + def tearDown(self): + import gc + gc.collect() + @patch.object(Git, 'execute') def test_call_process_calls_execute(self, git): git.return_value = '' diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 3c2e622d..70c4a596 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -101,6 +101,10 @@ class TestRemoteProgress(RemoteProgress): class TestRemote(TestBase): + def tearDown(self): + import gc + gc.collect() + def _print_fetchhead(self, repo): fp = open(os.path.join(repo.git_dir, "FETCH_HEAD")) fp.close() diff --git a/git/test/test_repo.py b/git/test/test_repo.py index d04a0f66..abc4a704 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -64,6 +64,10 @@ def flatten(lol): class TestRepo(TestBase): + def tearDown(self): + import gc + gc.collect() + @raises(InvalidGitRepositoryError) def test_new_should_raise_on_invalid_repo_location(self): Repo(tempfile.gettempdir()) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 17ce605a..881dd7e6 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -49,6 +49,10 @@ prog = TestRootProgress() class TestSubmodule(TestBase): + def tearDown(self): + import gc + gc.collect() + k_subm_current = "c15a6e1923a14bc760851913858a3942a4193cdb" k_subm_changed = "394ed7006ee5dc8bddfd132b64001d5dfc0ffdd3" k_no_subm_tag = "0.1.6" -- cgit v1.2.3 From 082851e0afd3a58790fe3c2434f6d070f97c69c1 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sun, 25 Sep 2016 18:55:15 +0200 Subject: apveyor: simplify test. --- git/test/test_util.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'git/test') diff --git a/git/test/test_util.py b/git/test/test_util.py index c6ca6920..a47697c0 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -90,7 +90,7 @@ class TestUtils(TestBase): wait_lock = BlockingLockFile(my_file, 0.05, wait_time) self.failUnlessRaises(IOError, wait_lock._obtain_lock) elapsed = time.time() - start - assert elapsed <= wait_time + 0.02 # some extra time it may cost + assert elapsed <= wait_time + 0.02, elapsed # some extra time it may cost def test_user_id(self): assert '@' in get_user_id() -- cgit v1.2.3 From 7ec2f8a4f26cec3fbbe1fb447058acaf508b39c0 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 01:36:57 +0200 Subject: apveyor, #519: FIX incomplete Popen pump + The code in `_read_lines_from_fno()` was reading the stream only once per invocation, so when input was larger than `mmap.PAGESIZE`, bytes were forgotten in the stream. + Replaced buffer-building code with iterate-on-file-descriptors. + Also set deamon-threads. --- git/test/test_git.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'git/test') diff --git a/git/test/test_git.py b/git/test/test_git.py index 534539d7..82ed2ace 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -238,9 +238,11 @@ class TestGit(TestBase): stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - shell=False) + shell=False, + creationflags=Git.CREATE_NO_WINDOW if sys.platform == 'win32' else 0, + ) handle_process_output(proc, counter_stdout, counter_stderr, lambda proc: proc.wait()) - assert count[1] == line_count - assert count[2] == line_count + self.assertEqual(count[1], line_count) + self.assertEqual(count[2], line_count) -- cgit v1.2.3 From fa70623a651d2a0b227202cad1e526e3eeebfa00 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 11:08:57 +0200 Subject: test, #519: FIX appveyor conda & failures in py2.6 `assertRaisesRegexp` --- git/test/test_git.py | 1 - git/test/test_index.py | 10 +++++++--- git/test/test_repo.py | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) (limited to 'git/test') diff --git a/git/test/test_git.py b/git/test/test_git.py index 82ed2ace..f8318595 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -239,7 +239,6 @@ class TestGit(TestBase): stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, - creationflags=Git.CREATE_NO_WINDOW if sys.platform == 'win32' else 0, ) handle_process_output(proc, counter_stdout, counter_stderr, lambda proc: proc.wait()) diff --git a/git/test/test_index.py b/git/test/test_index.py index 178a59d2..2ea787a4 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -135,7 +135,7 @@ class TestIndex(TestBase): raise AssertionError("CMP Failed: Missing entries in index: %s, missing in tree: %s" % (bset - iset, iset - bset)) # END assertion message - + @with_rw_repo('0.1.6') def test_index_lock_handling(self, rw_repo): def add_bad_blob(): @@ -147,7 +147,8 @@ class TestIndex(TestBase): except Exception as ex: msg_py3 = "required argument is not an integer" msg_py2 = "cannot convert argument to integer" - assert msg_py2 in str(ex) or msg_py3 in str(ex) + ## msg_py26 ="unsupported operand type(s) for &: 'str' and 'long'" + assert msg_py2 in str(ex) or msg_py3 in str(ex), str(ex) ## 2nd time should not fail due to stray lock file try: @@ -157,6 +158,9 @@ class TestIndex(TestBase): @with_rw_repo('0.1.6') def test_index_file_from_tree(self, rw_repo): + if sys.version_info < (2, 7): + ## Skipped, not `assertRaisesRegexp` in py2.6 + return common_ancestor_sha = "5117c9c8a4d3af19a9958677e45cda9269de1541" cur_sha = "4b43ca7ff72d5f535134241e7c797ddc9c7a3573" other_sha = "39f85c4358b7346fee22169da9cad93901ea9eb9" @@ -576,7 +580,7 @@ class TestIndex(TestBase): if sys.platform != "win32": for target in ('/etc/nonexisting', '/etc/passwd', '/etc'): basename = "my_real_symlink" - + link_file = os.path.join(rw_repo.working_tree_dir, basename) os.symlink(target, link_file) entries = index.reset(new_commit).add([link_file], fprogress=self._fprogress_add) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index abc4a704..b516402a 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -110,7 +110,7 @@ class TestRepo(TestBase): # try from invalid revision that does not exist self.failUnlessRaises(BadName, self.rorepo.tree, 'hello world') - + def test_pickleable(self): pickle.loads(pickle.dumps(self.rorepo)) @@ -318,6 +318,9 @@ class TestRepo(TestBase): @patch.object(Git, '_call_process') def test_should_display_blame_information(self, git): + if sys.version_info < (2, 7): + ## Skipped, not `assertRaisesRegexp` in py2.6 + return git.return_value = fixture('blame') b = self.rorepo.blame('master', 'lib/git.py') assert_equal(13, len(b)) -- cgit v1.2.3 From 7bbaac26906863b9a09158346218457befb2821a Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 12:32:28 +0200 Subject: test, #519: Popen() universal_newlin.es NoWindow in Winfoes + More win-fixes: + Do not check unicode files in < py3. + util, #519: x4 timeout of lock-file blocking, failing in Appveyor. --- git/test/test_base.py | 3 +++ git/test/test_git.py | 2 ++ git/test/test_util.py | 7 ++++++- 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'git/test') diff --git a/git/test/test_base.py b/git/test/test_base.py index c17e04e7..22006470 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -7,6 +7,7 @@ import os import sys import tempfile +from unittest import skipIf import git.objects.base as base from git.test.lib import ( @@ -116,6 +117,8 @@ class TestBase(TestBase): assert rw_remote_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib')) + @skipIf(sys.version_info < (3, ) and os.name == 'nt', + "Unicode woes, see https://github.com/gitpython-developers/GitPython/pull/519") @with_rw_repo('0.1.6') def test_add_unicode(self, rw_repo): filename = u"שלום.txt" diff --git a/git/test/test_git.py b/git/test/test_git.py index f8318595..935673b1 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -239,6 +239,8 @@ class TestGit(TestBase): stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, + universal_newlines=True, + creationflags=Git.CREATE_NO_WINDOW if sys.platform == 'win32' else 0, ) handle_process_output(proc, counter_stdout, counter_stderr, lambda proc: proc.wait()) diff --git a/git/test/test_util.py b/git/test/test_util.py index a47697c0..2e53df50 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -27,6 +27,7 @@ from git.cmd import dashify from git.compat import string_types import time +import sys class TestIterableMember(object): @@ -90,7 +91,11 @@ class TestUtils(TestBase): wait_lock = BlockingLockFile(my_file, 0.05, wait_time) self.failUnlessRaises(IOError, wait_lock._obtain_lock) elapsed = time.time() - start - assert elapsed <= wait_time + 0.02, elapsed # some extra time it may cost + # More extra time costs, but... + extra_time = 0.2 + if sys.platform == 'win32': + extra_time *= 4 + self.assertLess(elapsed, wait_time + 0.02) def test_user_id(self): assert '@' in get_user_id() -- cgit v1.2.3 From 45f8f20bdf1447fbfebd19a07412d337626ed6b0 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 19:42:42 +0200 Subject: Win, #519: FIX WinHangs: Popen() CREATE_NEW_PROCESS_GROUP to allow kill + FIXED most hangs BUT no more `git-daemon` un-killable! + Use logger for utils to replace stray print(). --- git/test/lib/helper.py | 12 +++++++----- git/test/test_git.py | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 9488005f..b59f518b 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -5,12 +5,12 @@ # the BSD License: http://www.opensource.org/licenses/bsd-license.php from __future__ import print_function import os -import sys from unittest import TestCase import time import tempfile import shutil import io +import logging from git import Repo, Remote, GitCommandError, Git from git.compat import string_types @@ -25,6 +25,8 @@ __all__ = ( 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', 'GIT_REPO', 'GIT_DAEMON_PORT' ) +log = logging.getLogger('git.util') + #{ Routines @@ -120,7 +122,7 @@ def with_rw_repo(working_tree_ref, bare=False): try: return func(self, rw_repo) except: - print("Keeping repo after failure: %s" % repo_dir, file=sys.stderr) + log.info("Keeping repo after failure: %s", repo_dir) repo_dir = None raise finally: @@ -218,7 +220,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref): # on some platforms ? if gd is not None: os.kill(gd.proc.pid, 15) - print(str(e)) + log.warning('git-ls-remote failed due to: %s(%s)', type(e), e) if os.name == 'nt': msg = "git-daemon needs to run this test, but windows does not have one. " msg += 'Otherwise, run: git-daemon "%s"' % temp_dir @@ -239,8 +241,8 @@ def with_rw_and_rw_remote_repo(working_tree_ref): try: return func(self, rw_repo, rw_remote_repo) except: - print("Keeping repos after failure: repo_dir = %s, remote_repo_dir = %s" - % (repo_dir, remote_repo_dir), file=sys.stderr) + log.info("Keeping repos after failure: repo_dir = %s, remote_repo_dir = %s", + repo_dir, remote_repo_dir) repo_dir = remote_repo_dir = None raise finally: diff --git a/git/test/test_git.py b/git/test/test_git.py index 935673b1..ea62de03 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -21,7 +21,8 @@ from git import ( Git, GitCommandError, GitCommandNotFound, - Repo + Repo, + cmd ) from gitdb.test.lib import with_rw_directory @@ -240,7 +241,7 @@ class TestGit(TestBase): stderr=subprocess.PIPE, shell=False, universal_newlines=True, - creationflags=Git.CREATE_NO_WINDOW if sys.platform == 'win32' else 0, + creationflags=cmd.PROC_CREATIONFLAGS, ) handle_process_output(proc, counter_stdout, counter_stderr, lambda proc: proc.wait()) -- cgit v1.2.3 From 29eb301700c41f0af7d57d923ad069cbdf636381 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 19:44:35 +0200 Subject: win, #519: proc.terminate() instead of kill(SIGTERM) + test_diff: replace asserts with unittest-asserts. --- git/test/lib/helper.py | 5 ++-- git/test/test_diff.py | 75 ++++++++++++++++++++++++++------------------------ 2 files changed, 41 insertions(+), 39 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index b59f518b..75d4e6fb 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -219,7 +219,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref): # Of course we expect it to work here already, but maybe there are timing constraints # on some platforms ? if gd is not None: - os.kill(gd.proc.pid, 15) + gd.proc.terminate() log.warning('git-ls-remote failed due to: %s(%s)', type(e), e) if os.name == 'nt': msg = "git-daemon needs to run this test, but windows does not have one. " @@ -246,9 +246,8 @@ def with_rw_and_rw_remote_repo(working_tree_ref): repo_dir = remote_repo_dir = None raise finally: - # gd.proc.kill() ... no idea why that doesn't work if gd is not None: - os.kill(gd.proc.pid, 15) + gd.proc.terminate() os.chdir(prev_cwd) rw_repo.git.clear_cache() diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 8735dfc4..cab72d2a 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -70,9 +70,10 @@ class TestDiff(TestBase): self.failUnlessRaises(GitCommandError, r.git.cherry_pick, 'master') # Now do the actual testing - this should just work - assert len(r.index.diff(None)) == 2 + self.assertEqual(len(r.index.diff(None)), 2) - assert len(r.index.diff(None, create_patch=True)) == 0, "This should work, but doesn't right now ... it's OK" + self.assertEqual(len(r.index.diff(None, create_patch=True)), 0, + "This should work, but doesn't right now ... it's OK") def test_list_from_string_new_mode(self): output = StringProcessAdapter(fixture('diff_new_mode')) @@ -100,41 +101,43 @@ class TestDiff(TestBase): output = StringProcessAdapter(fixture('diff_rename_raw')) diffs = Diff._index_from_raw_format(self.rorepo, output.stdout) - assert len(diffs) == 1 + self.assertEqual(len(diffs), 1) diff = diffs[0] - assert diff.renamed_file - assert diff.renamed - assert diff.rename_from == 'this' - assert diff.rename_to == 'that' - assert len(list(diffs.iter_change_type('R'))) == 1 + self.assertIsNotNone(diff.renamed_file) + self.assertIsNotNone(diff.renamed) + self.assertEqual(diff.rename_from, 'this') + self.assertEqual(diff.rename_to, 'that') + self.assertEqual(len(list(diffs.iter_change_type('R'))), 1) def test_diff_of_modified_files_not_added_to_the_index(self): output = StringProcessAdapter(fixture('diff_abbrev-40_full-index_M_raw_no-color')) diffs = Diff._index_from_raw_format(self.rorepo, output.stdout) - assert len(diffs) == 1, 'one modification' - assert len(list(diffs.iter_change_type('M'))) == 1, 'one modification' - assert diffs[0].change_type == 'M' - assert diffs[0].b_blob is None + self.assertEqual(len(diffs), 1, 'one modification') + self.assertEqual(len(list(diffs.iter_change_type('M'))), 1, 'one modification') + self.assertEqual(diffs[0].change_type, 'M') + self.assertIsNone(diffs[0].b_blob,) def test_binary_diff(self): for method, file_name in ((Diff._index_from_patch_format, 'diff_patch_binary'), (Diff._index_from_raw_format, 'diff_raw_binary')): res = method(None, StringProcessAdapter(fixture(file_name)).stdout) - assert len(res) == 1 - assert len(list(res.iter_change_type('M'))) == 1 + self.assertEqual(len(res), 1) + self.assertEqual(len(list(res.iter_change_type('M'))), 1) if res[0].diff: - assert res[0].diff == b"Binary files a/rps and b/rps differ\n", "in patch mode, we get a diff text" - assert str(res[0]), "This call should just work" + self.assertEqual(res[0].diff, + b"Binary files a/rps and b/rps differ\n", + "in patch mode, we get a diff text") + self.assertIsNotNone(str(res[0]), "This call should just work") # end for each method to test def test_diff_index(self): output = StringProcessAdapter(fixture('diff_index_patch')) res = Diff._index_from_patch_format(None, output.stdout) - assert len(res) == 6 + self.assertEqual(len(res), 6) for dr in res: - assert dr.diff.startswith(b'@@') - assert str(dr), "Diff to string conversion should be possible" + self.assertTrue(dr.diff.startswith(b'@@'), dr) + self.assertIsNotNone(str(dr), "Diff to string conversion should be possible") # end for each diff dr = res[3] @@ -143,24 +146,24 @@ class TestDiff(TestBase): def test_diff_index_raw_format(self): output = StringProcessAdapter(fixture('diff_index_raw')) res = Diff._index_from_raw_format(None, output.stdout) - assert res[0].deleted_file - assert res[0].b_path is None + self.assertIsNotNone(res[0].deleted_file) + self.assertIsNone(res[0].b_path,) def test_diff_initial_commit(self): initial_commit = self.rorepo.commit('33ebe7acec14b25c5f84f35a664803fcab2f7781') # Without creating a patch... diff_index = initial_commit.diff(NULL_TREE) - assert diff_index[0].b_path == 'CHANGES' - assert diff_index[0].new_file - assert diff_index[0].diff == '' + self.assertEqual(diff_index[0].b_path, 'CHANGES') + self.assertIsNotNone(diff_index[0].new_file) + self.assertEqual(diff_index[0].diff, '') # ...and with creating a patch diff_index = initial_commit.diff(NULL_TREE, create_patch=True) - assert diff_index[0].a_path is None, repr(diff_index[0].a_path) - assert diff_index[0].b_path == 'CHANGES', repr(diff_index[0].b_path) - assert diff_index[0].new_file - assert diff_index[0].diff == fixture('diff_initial') + self.assertIsNone(diff_index[0].a_path, repr(diff_index[0].a_path)) + self.assertEqual(diff_index[0].b_path, 'CHANGES', repr(diff_index[0].b_path)) + self.assertIsNotNone(diff_index[0].new_file) + self.assertEqual(diff_index[0].diff, fixture('diff_initial')) def test_diff_unsafe_paths(self): output = StringProcessAdapter(fixture('diff_patch_unsafe_paths')) @@ -206,8 +209,8 @@ class TestDiff(TestBase): def test_diff_with_spaces(self): data = StringProcessAdapter(fixture('diff_file_with_spaces')) diff_index = Diff._index_from_patch_format(self.rorepo, data.stdout) - assert diff_index[0].a_path is None, repr(diff_index[0].a_path) - assert diff_index[0].b_path == u'file with spaces', repr(diff_index[0].b_path) + self.assertIsNone(diff_index[0].a_path, repr(diff_index[0].a_path)) + self.assertEqual(diff_index[0].b_path, u'file with spaces', repr(diff_index[0].b_path)) def test_diff_interface(self): # test a few variations of the main diff routine @@ -236,12 +239,12 @@ class TestDiff(TestBase): diff_set = set() diff_set.add(diff_index[0]) diff_set.add(diff_index[0]) - assert len(diff_set) == 1 - assert diff_index[0] == diff_index[0] - assert not (diff_index[0] != diff_index[0]) + self.assertEqual(len(diff_set), 1) + self.assertEqual(diff_index[0], diff_index[0]) + self.assertFalse(diff_index[0] != diff_index[0]) for dr in diff_index: - assert str(dr), "Diff to string conversion should be possible" + self.assertIsNotNone(str(dr), "Diff to string conversion should be possible") # END diff index checking # END for each patch option # END for each path option @@ -252,11 +255,11 @@ class TestDiff(TestBase): # can iterate in the diff index - if not this indicates its not working correctly # or our test does not span the whole range of possibilities for key, value in assertion_map.items(): - assert value, "Did not find diff for %s" % key + self.assertIsNotNone(value, "Did not find diff for %s" % key) # END for each iteration type # test path not existing in the index - should be ignored c = self.rorepo.head.commit cp = c.parents[0] diff_index = c.diff(cp, ["does/not/exist"]) - assert len(diff_index) == 0 + self.assertEqual(len(diff_index), 0) -- cgit v1.2.3 From f495e94028bfddc264727ffc464cd694ddd05ab8 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 20:41:41 +0200 Subject: src, #519: collect all is_() calls --- git/test/lib/helper.py | 8 ++++---- git/test/test_base.py | 5 +++-- git/test/test_git.py | 4 ++-- git/test/test_index.py | 8 ++++---- git/test/test_submodule.py | 4 ++-- git/test/test_util.py | 5 ++--- 6 files changed, 17 insertions(+), 17 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 75d4e6fb..7cc1dcae 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -13,7 +13,7 @@ import io import logging from git import Repo, Remote, GitCommandError, Git -from git.compat import string_types +from git.compat import string_types, is_win osp = os.path.dirname @@ -73,7 +73,7 @@ def _mktemp(*args): prefixing /private/ will lead to incorrect paths on OSX.""" tdir = tempfile.mktemp(*args) # See :note: above to learn why this is comented out. - # if sys.platform == 'darwin': + # if is_darwin(): # tdir = '/private' + tdir return tdir @@ -83,7 +83,7 @@ def _rmtree_onerror(osremove, fullpath, exec_info): Handle the case on windows that read-only files cannot be deleted by os.remove by setting it to mode 777, then retry deletion. """ - if os.name != 'nt' or osremove is not os.remove: + if is_win() or osremove is not os.remove: raise os.chmod(fullpath, 0o777) @@ -221,7 +221,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref): if gd is not None: gd.proc.terminate() log.warning('git-ls-remote failed due to: %s(%s)', type(e), e) - if os.name == 'nt': + if is_win(): msg = "git-daemon needs to run this test, but windows does not have one. " msg += 'Otherwise, run: git-daemon "%s"' % temp_dir raise AssertionError(msg) diff --git a/git/test/test_base.py b/git/test/test_base.py index 22006470..cf92997f 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -24,6 +24,7 @@ from git import ( ) from git.objects.util import get_object_type_by_name from gitdb.util import hex_to_bin +from git.compat import is_win class TestBase(TestBase): @@ -117,7 +118,7 @@ class TestBase(TestBase): assert rw_remote_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib')) - @skipIf(sys.version_info < (3, ) and os.name == 'nt', + @skipIf(sys.version_info < (3,) and is_win(), "Unicode woes, see https://github.com/gitpython-developers/GitPython/pull/519") @with_rw_repo('0.1.6') def test_add_unicode(self, rw_repo): @@ -134,7 +135,7 @@ class TestBase(TestBase): open(file_path, "wb").write(b'something') - if os.name == 'nt': + if is_win(): # on windows, there is no way this works, see images on # https://github.com/gitpython-developers/GitPython/issues/147#issuecomment-68881897 # Therefore, it must be added using the python implementation diff --git a/git/test/test_git.py b/git/test/test_git.py index ea62de03..2ef15523 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -26,7 +26,7 @@ from git import ( ) from gitdb.test.lib import with_rw_directory -from git.compat import PY3 +from git.compat import PY3, is_darwin try: from unittest import mock @@ -214,7 +214,7 @@ class TestGit(TestBase): try: remote.fetch() except GitCommandError as err: - if sys.version_info[0] < 3 and sys.platform == 'darwin': + if sys.version_info[0] < 3 and is_darwin(): assert 'ssh-origin' in str(err) assert err.status == 128 else: diff --git a/git/test/test_index.py b/git/test/test_index.py index 2ea787a4..b83201c9 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -27,7 +27,7 @@ from git import ( GitCommandError, CheckoutError, ) -from git.compat import string_types +from git.compat import string_types, is_win from gitdb.util import hex_to_bin import os import sys @@ -577,7 +577,7 @@ class TestIndex(TestBase): assert len(entries) == 1 and entries[0].hexsha != null_hex_sha # add symlink - if sys.platform != "win32": + if not is_win(): for target in ('/etc/nonexisting', '/etc/passwd', '/etc'): basename = "my_real_symlink" @@ -630,7 +630,7 @@ class TestIndex(TestBase): index.checkout(fake_symlink_path) # on windows we will never get symlinks - if os.name == 'nt': + if is_win(): # simlinks should contain the link as text ( which is what a # symlink actually is ) open(fake_symlink_path, 'rb').read() == link_target @@ -711,7 +711,7 @@ class TestIndex(TestBase): assert fkey not in index.entries index.add(files, write=True) - if os.name != 'nt': + if is_win(): hp = hook_path('pre-commit', index.repo.git_dir) hpd = os.path.dirname(hp) if not os.path.isdir(hpd): diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 881dd7e6..5906b06c 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -17,7 +17,7 @@ from git.exc import ( from git.objects.submodule.base import Submodule from git.objects.submodule.root import RootModule, RootUpdateProgress from git.util import to_native_path_linux, join_path_native -from git.compat import string_types +from git.compat import string_types, is_win from git.repo.fun import ( find_git_dir, touch @@ -26,7 +26,7 @@ from git.repo.fun import ( # Change the configuration if possible to prevent the underlying memory manager # to keep file handles open. On windows we get problems as they are not properly # closed due to mmap bugs on windows (as it appears) -if sys.platform == 'win32': +if is_win(): try: import smmap.util smmap.util.MapRegion._test_read_into_memory = True diff --git a/git/test/test_util.py b/git/test/test_util.py index 2e53df50..76a5e0e9 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -24,10 +24,9 @@ from git.objects.util import ( parse_date, ) from git.cmd import dashify -from git.compat import string_types +from git.compat import string_types, is_win import time -import sys class TestIterableMember(object): @@ -93,7 +92,7 @@ class TestUtils(TestBase): elapsed = time.time() - start # More extra time costs, but... extra_time = 0.2 - if sys.platform == 'win32': + if is_win(): extra_time *= 4 self.assertLess(elapsed, wait_time + 0.02) -- cgit v1.2.3 From aa3f2fa76844e1700ba37723acf603428b20ef74 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 21:31:21 +0200 Subject: src, #519: Improve daemon launch so Win does not stuck + Retrofit try...finally blocks to ensure killing the daemon - now vulnerable also on Windows due to Popen() + CREATE_NEW_PROCESS_GROUP - BUT `test_base.test_with_rw_remote_and_rw_repo()` TC fails in MINGW due to invalid remote-URL in fetching-repo's config. Another day. - NEXT FREEZE to solve: test-diff_interface() under MINGW! --- git/test/lib/helper.py | 69 +++++++++++++++++++++++++++----------------------- 1 file changed, 38 insertions(+), 31 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 7cc1dcae..9e6be3e3 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -14,6 +14,7 @@ import logging from git import Repo, Remote, GitCommandError, Git from git.compat import string_types, is_win +import textwrap osp = os.path.dirname @@ -201,43 +202,45 @@ def with_rw_and_rw_remote_repo(working_tree_ref): d_remote.config_writer.set('url', remote_repo_url) temp_dir = osp(_mktemp()) - # On windows, this will fail ... we deal with failures anyway and default to telling the user to do it + # On MINGW-git, daemon exists, in Cygwin-git, this will fail. + gd = Git().daemon(temp_dir, enable='receive-pack', listen='127.0.0.1', port=GIT_DAEMON_PORT, + as_process=True) try: - gd = Git().daemon(temp_dir, enable='receive-pack', listen='127.0.0.1', port=GIT_DAEMON_PORT, - as_process=True) # yes, I know ... fortunately, this is always going to work if sleep time is just large enough time.sleep(0.5) - except Exception: - gd = None # end - # try to list remotes to diagnoes whether the server is up - try: - rw_repo.git.ls_remote(d_remote) - except GitCommandError as e: - # We assume in good faith that we didn't start the daemon - but make sure we kill it anyway - # Of course we expect it to work here already, but maybe there are timing constraints - # on some platforms ? - if gd is not None: - gd.proc.terminate() - log.warning('git-ls-remote failed due to: %s(%s)', type(e), e) - if is_win(): - msg = "git-daemon needs to run this test, but windows does not have one. " - msg += 'Otherwise, run: git-daemon "%s"' % temp_dir - raise AssertionError(msg) - else: - msg = 'Please start a git-daemon to run this test, execute: git daemon --enable=receive-pack "%s"' - msg += 'You can also run the daemon on a different port by passing --port=' - msg += 'and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to ' - msg %= temp_dir + # try to list remotes to diagnoes whether the server is up + try: + rw_repo.git.ls_remote(d_remote) + except GitCommandError as e: + # We assume in good faith that we didn't start the daemon - but make sure we kill it anyway + # Of course we expect it to work here already, but maybe there are timing constraints + # on some platforms ? + if gd is not None: + gd.proc.terminate() + log.warning('git(%s) ls-remote failed due to:%s', + rw_repo.git_dir, e) + if is_win(): + msg = textwrap.dedent(""" + MINGW yet has problems with paths, CYGWIN additionally is missing `git-daemon` + needed to run this test. Anyhow, try starting `git-daemon` manually:""") + else: + msg = "Please try starting `git-daemon` manually:" + + msg += textwrap.dedent(""" + git daemon --enable=receive-pack '%s' + You can also run the daemon on a different port by passing --port=" + and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to + """ % temp_dir) raise AssertionError(msg) - # END make assertion - # END catch ls remote error + # END make assertion + # END catch ls remote error + + # adjust working dir + prev_cwd = os.getcwd() + os.chdir(rw_repo.working_dir) - # adjust working dir - prev_cwd = os.getcwd() - os.chdir(rw_repo.working_dir) - try: try: return func(self, rw_repo, rw_remote_repo) except: @@ -245,11 +248,15 @@ def with_rw_and_rw_remote_repo(working_tree_ref): repo_dir, remote_repo_dir) repo_dir = remote_repo_dir = None raise + finally: + os.chdir(prev_cwd) + finally: if gd is not None: gd.proc.terminate() - os.chdir(prev_cwd) + import gc + gc.collect() rw_repo.git.clear_cache() rw_remote_repo.git.clear_cache() if repo_dir: -- cgit v1.2.3 From 618e6259ef03a4b25415bae31a7540ac5eb2e38a Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 22:20:33 +0200 Subject: test, #519: Try appveyor advice for never-ending builds + see http://help.appveyor.com/discussions/problems/5334-nosetests-finsih-bu-build-stuck-and-next-job-dealys-to-start + Use `io.DEFAULT_BUFFER_SIZE`. + test_commit: replace asserts with unittest-asserts. - TRY Popen() NO universal_newlines: NO, reverted in next commits. + [travisci skip] --- git/test/lib/helper.py | 2 +- git/test/test_commit.py | 94 ++++++++++++++++++++++++++----------------------- git/test/test_git.py | 1 - 3 files changed, 50 insertions(+), 47 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 9e6be3e3..d92d76e2 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -253,7 +253,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref): finally: if gd is not None: - gd.proc.terminate() + gd.proc.kill() import gc gc.collect() diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 805221ac..2f5270d4 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -61,14 +61,14 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False) stream.seek(0) istream = rwrepo.odb.store(IStream(Commit.type, streamlen, stream)) - assert istream.hexsha == cm.hexsha.encode('ascii') + assert_equal(istream.hexsha, cm.hexsha.encode('ascii')) nc = Commit(rwrepo, Commit.NULL_BIN_SHA, cm.tree, cm.author, cm.authored_date, cm.author_tz_offset, cm.committer, cm.committed_date, cm.committer_tz_offset, cm.message, cm.parents, cm.encoding) - assert nc.parents == cm.parents + assert_equal(nc.parents, cm.parents) stream = BytesIO() nc._serialize(stream) ns += 1 @@ -82,7 +82,7 @@ def assert_commit_serialization(rwrepo, commit_id, print_performance_info=False) nc.binsha = rwrepo.odb.store(istream).binsha # if it worked, we have exactly the same contents ! - assert nc.hexsha == cm.hexsha + assert_equal(nc.hexsha, cm.hexsha) # END check commits elapsed = time.time() - st @@ -103,10 +103,10 @@ class TestCommit(TestBase): assert_equal("Sebastian Thiel", commit.author.name) assert_equal("byronimo@gmail.com", commit.author.email) - assert commit.author == commit.committer + self.assertEqual(commit.author, commit.committer) assert isinstance(commit.authored_date, int) and isinstance(commit.committed_date, int) assert isinstance(commit.author_tz_offset, int) and isinstance(commit.committer_tz_offset, int) - assert commit.message == "Added missing information to docstrings of commit and stats module\n" + self.assertEqual(commit.message, "Added missing information to docstrings of commit and stats module\n") def test_stats(self): commit = self.rorepo.commit('33ebe7acec14b25c5f84f35a664803fcab2f7781') @@ -129,20 +129,20 @@ class TestCommit(TestBase): # assure data is parsed properly michael = Actor._from_string("Michael Trier ") - assert commit.author == michael - assert commit.committer == michael - assert commit.authored_date == 1210193388 - assert commit.committed_date == 1210193388 - assert commit.author_tz_offset == 14400, commit.author_tz_offset - assert commit.committer_tz_offset == 14400, commit.committer_tz_offset - assert commit.message == "initial project\n" + self.assertEqual(commit.author, michael) + self.assertEqual(commit.committer, michael) + self.assertEqual(commit.authored_date, 1210193388) + self.assertEqual(commit.committed_date, 1210193388) + self.assertEqual(commit.author_tz_offset, 14400, commit.author_tz_offset) + self.assertEqual(commit.committer_tz_offset, 14400, commit.committer_tz_offset) + self.assertEqual(commit.message, "initial project\n") def test_unicode_actor(self): # assure we can parse unicode actors correctly name = u"Üäöß ÄußÉ" - assert len(name) == 9 + self.assertEqual(len(name), 9) special = Actor._from_string(u"%s " % name) - assert special.name == name + self.assertEqual(special.name, name) assert isinstance(special.name, text_type) def test_traversal(self): @@ -156,44 +156,44 @@ class TestCommit(TestBase): # basic branch first, depth first dfirst = start.traverse(branch_first=False) bfirst = start.traverse(branch_first=True) - assert next(dfirst) == p0 - assert next(dfirst) == p00 + self.assertEqual(next(dfirst), p0) + self.assertEqual(next(dfirst), p00) - assert next(bfirst) == p0 - assert next(bfirst) == p1 - assert next(bfirst) == p00 - assert next(bfirst) == p10 + self.assertEqual(next(bfirst), p0) + self.assertEqual(next(bfirst), p1) + self.assertEqual(next(bfirst), p00) + self.assertEqual(next(bfirst), p10) # at some point, both iterations should stop - assert list(bfirst)[-1] == first + self.assertEqual(list(bfirst)[-1], first) stoptraverse = self.rorepo.commit("254d04aa3180eb8b8daf7b7ff25f010cd69b4e7d").traverse(as_edge=True) l = list(stoptraverse) - assert len(l[0]) == 2 + self.assertEqual(len(l[0]), 2) # ignore self - assert next(start.traverse(ignore_self=False)) == start + self.assertEqual(next(start.traverse(ignore_self=False)), start) # depth - assert len(list(start.traverse(ignore_self=False, depth=0))) == 1 + self.assertEqual(len(list(start.traverse(ignore_self=False, depth=0))), 1) # prune - assert next(start.traverse(branch_first=1, prune=lambda i, d: i == p0)) == p1 + self.assertEqual(next(start.traverse(branch_first=1, prune=lambda i, d: i == p0)), p1) # predicate - assert next(start.traverse(branch_first=1, predicate=lambda i, d: i == p1)) == p1 + self.assertEqual(next(start.traverse(branch_first=1, predicate=lambda i, d: i == p1)), p1) # traversal should stop when the beginning is reached self.failUnlessRaises(StopIteration, next, first.traverse()) # parents of the first commit should be empty ( as the only parent has a null # sha ) - assert len(first.parents) == 0 + self.assertEqual(len(first.parents), 0) def test_iteration(self): # we can iterate commits all_commits = Commit.list_items(self.rorepo, self.rorepo.head) assert all_commits - assert all_commits == list(self.rorepo.iter_commits()) + self.assertEqual(all_commits, list(self.rorepo.iter_commits())) # this includes merge commits mcomit = self.rorepo.commit('d884adc80c80300b4cc05321494713904ef1df2d') @@ -240,7 +240,7 @@ class TestCommit(TestBase): list(rw_repo.iter_commits(rw_repo.head.ref)) # should fail unless bug is fixed def test_count(self): - assert self.rorepo.tag('refs/tags/0.1.5').commit.count() == 143 + self.assertEqual(self.rorepo.tag('refs/tags/0.1.5').commit.count(), 143) def test_list(self): # This doesn't work anymore, as we will either attempt getattr with bytes, or compare 20 byte string @@ -270,7 +270,7 @@ class TestCommit(TestBase): piter = c.iter_parents(skip=skip) first_parent = next(piter) assert first_parent != c - assert first_parent == c.parents[0] + self.assertEqual(first_parent, c.parents[0]) # END for each def test_name_rev(self): @@ -283,7 +283,7 @@ class TestCommit(TestBase): assert_commit_serialization(rwrepo, '0.1.6') def test_serialization_unicode_support(self): - assert Commit.default_encoding.lower() == 'utf-8' + self.assertEqual(Commit.default_encoding.lower(), 'utf-8') # create a commit with unicode in the message, and the author's name # Verify its serialization and deserialization @@ -292,10 +292,10 @@ class TestCommit(TestBase): assert isinstance(cmt.author.name, text_type) # same here cmt.message = u"üäêèß" - assert len(cmt.message) == 5 + self.assertEqual(len(cmt.message), 5) cmt.author.name = u"äüß" - assert len(cmt.author.name) == 3 + self.assertEqual(len(cmt.author.name), 3) cstream = BytesIO() cmt._serialize(cstream) @@ -305,8 +305,8 @@ class TestCommit(TestBase): ncmt = Commit(self.rorepo, cmt.binsha) ncmt._deserialize(cstream) - assert cmt.author.name == ncmt.author.name - assert cmt.message == ncmt.message + self.assertEqual(cmt.author.name, ncmt.author.name) + self.assertEqual(cmt.message, ncmt.message) # actually, it can't be printed in a shell as repr wants to have ascii only # it appears cmt.author.__repr__() @@ -315,8 +315,8 @@ class TestCommit(TestBase): cmt = self.rorepo.commit() cmt._deserialize(open(fixture_path('commit_invalid_data'), 'rb')) - assert cmt.author.name == u'E.Azer Ko�o�o�oculu', cmt.author.name - assert cmt.author.email == 'azer@kodfabrik.com', cmt.author.email + self.assertEqual(cmt.author.name, u'E.Azer Ko�o�o�oculu', cmt.author.name) + self.assertEqual(cmt.author.email, 'azer@kodfabrik.com', cmt.author.email) def test_gpgsig(self): cmt = self.rorepo.commit() @@ -339,7 +339,7 @@ BX/otlTa8pNE3fWYBxURvfHnMY4i3HQT7Bc1QjImAhMnyo2vJk4ORBJIZ1FTNIhJ JzJMZDRLQLFvnzqZuCjE =przd -----END PGP SIGNATURE-----""" - assert cmt.gpgsig == fixture_sig + self.assertEqual(cmt.gpgsig, fixture_sig) cmt.gpgsig = "" assert cmt.gpgsig != fixture_sig @@ -353,7 +353,7 @@ JzJMZDRLQLFvnzqZuCjE cstream.seek(0) cmt.gpgsig = None cmt._deserialize(cstream) - assert cmt.gpgsig == "" + self.assertEqual(cmt.gpgsig, "") cmt.gpgsig = None cstream = BytesIO() @@ -387,9 +387,13 @@ JzJMZDRLQLFvnzqZuCjE def test_datetimes(self): commit = self.rorepo.commit('4251bd5') - assert commit.authored_date == 1255018625 - assert commit.committed_date == 1255026171 - assert commit.authored_datetime == datetime(2009, 10, 8, 18, 17, 5, tzinfo=tzoffset(-7200)), commit.authored_datetime # noqa - assert commit.authored_datetime == datetime(2009, 10, 8, 16, 17, 5, tzinfo=utc), commit.authored_datetime - assert commit.committed_datetime == datetime(2009, 10, 8, 20, 22, 51, tzinfo=tzoffset(-7200)) - assert commit.committed_datetime == datetime(2009, 10, 8, 18, 22, 51, tzinfo=utc), commit.committed_datetime + self.assertEqual(commit.authored_date, 1255018625) + self.assertEqual(commit.committed_date, 1255026171) + self.assertEqual(commit.authored_datetime, + datetime(2009, 10, 8, 18, 17, 5, tzinfo=tzoffset(-7200)), commit.authored_datetime) # noqa + self.assertEqual(commit.authored_datetime, + datetime(2009, 10, 8, 16, 17, 5, tzinfo=utc), commit.authored_datetime) + self.assertEqual(commit.committed_datetime, + datetime(2009, 10, 8, 20, 22, 51, tzinfo=tzoffset(-7200))) + self.assertEqual(commit.committed_datetime, + datetime(2009, 10, 8, 18, 22, 51, tzinfo=utc), commit.committed_datetime) diff --git a/git/test/test_git.py b/git/test/test_git.py index 2ef15523..a6213c58 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -240,7 +240,6 @@ class TestGit(TestBase): stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, - universal_newlines=True, creationflags=cmd.PROC_CREATIONFLAGS, ) -- cgit v1.2.3 From 6a3c95b408162c78b9a4230bb4f7274a94d0add4 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Mon, 26 Sep 2016 23:20:58 +0200 Subject: test, #519: No remote TCs, git-daemon cannot die@! --- git/test/test_base.py | 1 + git/test/test_remote.py | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'git/test') diff --git a/git/test/test_base.py b/git/test/test_base.py index cf92997f..f139798b 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -112,6 +112,7 @@ class TestBase(TestBase): assert not rw_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib')) + @skipIf(is_win(), "git-daemon proc stuck on Appveyor!") @with_rw_and_rw_remote_repo('0.1.6') def test_with_rw_remote_and_rw_repo(self, rw_repo, rw_remote_repo): assert not rw_repo.config_reader("repository").getboolean("core", "bare") diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 70c4a596..0060b5a6 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -26,7 +26,8 @@ from git import ( GitCommandError ) from git.util import IterableList -from git.compat import string_types +from git.compat import string_types, is_win +from unittest import skipIf import tempfile import shutil import os @@ -99,6 +100,7 @@ class TestRemoteProgress(RemoteProgress): assert self._num_progress_messages +@skipIf(is_win(), "git-daemon proc stuck on Appveyor!") class TestRemote(TestBase): def tearDown(self): @@ -407,7 +409,7 @@ class TestRemote(TestBase): # OPTIONS # cannot use 'fetch' key anymore as it is now a method - for opt in ("url", ): + for opt in ("url",): val = getattr(remote, opt) reader = remote.config_reader assert reader.get(opt) == val -- cgit v1.2.3 From c572a8d95d8fa184eb58b15b7ff96d01ef1f9ec3 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 27 Sep 2016 00:09:20 +0200 Subject: Win, #519: FIX undead Git-daemon on Windows + On MINGW-git, daemon exists but if invoked as 'git daemon', DAEMON CANNOT DIE! + So, launch `git-daemon` on Apveyor, but - remote TCs fail due to paths problems. + Updated README instructions on Windows. + Restore disabled remote TCs on Windows. + Disable failures on daemon-tests only the last moment (raise SkipTest) so when ready, it will also pass. --- git/test/lib/helper.py | 36 ++++++++++++++++++++++++++++++------ git/test/test_base.py | 1 - git/test/test_remote.py | 4 +--- 3 files changed, 31 insertions(+), 10 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index d92d76e2..0a845a3f 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -140,6 +140,28 @@ def with_rw_repo(working_tree_ref, bare=False): return argument_passer +def launch_git_daemon(temp_dir, ip, port): + if is_win(): + ## On MINGW-git, daemon exists in .\Git\mingw64\libexec\git-core\, + # but if invoked as 'git daemon', it detaches from parent `git` cmd, + # and then CANNOT DIE! + # So, invoke it as a single command. + ## Cygwin-git has no daemon. + # + daemon_cmd = ['git-daemon', temp_dir, + '--enable=receive-pack', + '--listen=%s' % ip, + '--port=%s' % port] + gd = Git().execute(daemon_cmd, as_process=True) + else: + gd = Git().daemon(temp_dir, + enable='receive-pack', + listen=ip, + port=port, + as_process=True) + return gd + + def with_rw_and_rw_remote_repo(working_tree_ref): """ Same as with_rw_repo, but also provides a writable remote repository from which the @@ -167,6 +189,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref): assert isinstance(working_tree_ref, string_types), "Decorator requires ref name for working tree checkout" def argument_passer(func): + def remote_repo_creator(self): remote_repo_dir = _mktemp("remote_repo_%s" % func.__name__) repo_dir = _mktemp("remote_clone_non_bare_repo") @@ -202,9 +225,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref): d_remote.config_writer.set('url', remote_repo_url) temp_dir = osp(_mktemp()) - # On MINGW-git, daemon exists, in Cygwin-git, this will fail. - gd = Git().daemon(temp_dir, enable='receive-pack', listen='127.0.0.1', port=GIT_DAEMON_PORT, - as_process=True) + gd = launch_git_daemon(temp_dir, '127.0.0.1', GIT_DAEMON_PORT) try: # yes, I know ... fortunately, this is always going to work if sleep time is just large enough time.sleep(0.5) @@ -223,8 +244,10 @@ def with_rw_and_rw_remote_repo(working_tree_ref): rw_repo.git_dir, e) if is_win(): msg = textwrap.dedent(""" - MINGW yet has problems with paths, CYGWIN additionally is missing `git-daemon` - needed to run this test. Anyhow, try starting `git-daemon` manually:""") + MINGW yet has problems with paths, and `git-daemon.exe` must be in PATH + (look into .\Git\mingw64\libexec\git-core\); + CYGWIN has no daemon, but if one exists, it gets along fine (has also paths problems) + Anyhow, alternatively try starting `git-daemon` manually:""") else: msg = "Please try starting `git-daemon` manually:" @@ -233,7 +256,8 @@ def with_rw_and_rw_remote_repo(working_tree_ref): You can also run the daemon on a different port by passing --port=" and setting the environment variable GIT_PYTHON_TEST_GIT_DAEMON_PORT to """ % temp_dir) - raise AssertionError(msg) + from nose import SkipTest + raise SkipTest(msg) if is_win else AssertionError(msg) # END make assertion # END catch ls remote error diff --git a/git/test/test_base.py b/git/test/test_base.py index f139798b..cf92997f 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -112,7 +112,6 @@ class TestBase(TestBase): assert not rw_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib')) - @skipIf(is_win(), "git-daemon proc stuck on Appveyor!") @with_rw_and_rw_remote_repo('0.1.6') def test_with_rw_remote_and_rw_repo(self, rw_repo, rw_remote_repo): assert not rw_repo.config_reader("repository").getboolean("core", "bare") diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 0060b5a6..2716d5b9 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -26,8 +26,7 @@ from git import ( GitCommandError ) from git.util import IterableList -from git.compat import string_types, is_win -from unittest import skipIf +from git.compat import string_types import tempfile import shutil import os @@ -100,7 +99,6 @@ class TestRemoteProgress(RemoteProgress): assert self._num_progress_messages -@skipIf(is_win(), "git-daemon proc stuck on Appveyor!") class TestRemote(TestBase): def tearDown(self): -- cgit v1.2.3 From e61439b3018b0b9a8eb43e59d0d7cf32041e2fed Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 27 Sep 2016 16:05:58 +0200 Subject: src: constify is_() calls + TCs: unittest-asserts for git-tests. --- git/test/lib/helper.py | 8 ++++---- git/test/test_base.py | 4 ++-- git/test/test_git.py | 37 +++++++++++++++++++------------------ git/test/test_index.py | 6 +++--- git/test/test_submodule.py | 2 +- git/test/test_util.py | 2 +- 6 files changed, 30 insertions(+), 29 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 0a845a3f..7f4e81e0 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -74,7 +74,7 @@ def _mktemp(*args): prefixing /private/ will lead to incorrect paths on OSX.""" tdir = tempfile.mktemp(*args) # See :note: above to learn why this is comented out. - # if is_darwin(): + # if is_darwin: # tdir = '/private' + tdir return tdir @@ -84,7 +84,7 @@ def _rmtree_onerror(osremove, fullpath, exec_info): Handle the case on windows that read-only files cannot be deleted by os.remove by setting it to mode 777, then retry deletion. """ - if is_win() or osremove is not os.remove: + if is_win or osremove is not os.remove: raise os.chmod(fullpath, 0o777) @@ -141,7 +141,7 @@ def with_rw_repo(working_tree_ref, bare=False): def launch_git_daemon(temp_dir, ip, port): - if is_win(): + if is_win: ## On MINGW-git, daemon exists in .\Git\mingw64\libexec\git-core\, # but if invoked as 'git daemon', it detaches from parent `git` cmd, # and then CANNOT DIE! @@ -242,7 +242,7 @@ def with_rw_and_rw_remote_repo(working_tree_ref): gd.proc.terminate() log.warning('git(%s) ls-remote failed due to:%s', rw_repo.git_dir, e) - if is_win(): + if is_win: msg = textwrap.dedent(""" MINGW yet has problems with paths, and `git-daemon.exe` must be in PATH (look into .\Git\mingw64\libexec\git-core\); diff --git a/git/test/test_base.py b/git/test/test_base.py index cf92997f..fa0bebca 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -118,7 +118,7 @@ class TestBase(TestBase): assert rw_remote_repo.config_reader("repository").getboolean("core", "bare") assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib')) - @skipIf(sys.version_info < (3,) and is_win(), + @skipIf(sys.version_info < (3,) and is_win, "Unicode woes, see https://github.com/gitpython-developers/GitPython/pull/519") @with_rw_repo('0.1.6') def test_add_unicode(self, rw_repo): @@ -135,7 +135,7 @@ class TestBase(TestBase): open(file_path, "wb").write(b'something') - if is_win(): + if is_win: # on windows, there is no way this works, see images on # https://github.com/gitpython-developers/GitPython/issues/147#issuecomment-68881897 # Therefore, it must be added using the python implementation diff --git a/git/test/test_git.py b/git/test/test_git.py index a6213c58..36bbbb10 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -85,7 +85,7 @@ class TestGit(TestBase): # order is undefined res = self.git.transform_kwargs(**{'s': True, 't': True}) - assert ['-s', '-t'] == res or ['-t', '-s'] == res + self.assertEqual(set(['-s', '-t']), set(res)) def test_it_executes_git_to_shell_and_returns_result(self): assert_match('^git version [\d\.]{2}.*$', self.git.execute(["git", "version"])) @@ -117,7 +117,7 @@ class TestGit(TestBase): g.stdin.write(b"b2339455342180c7cc1e9bba3e9f181f7baa5167\n") g.stdin.flush() obj_info_two = g.stdout.readline() - assert obj_info == obj_info_two + self.assertEqual(obj_info, obj_info_two) # read data - have to read it in one large chunk size = int(obj_info.split()[2]) @@ -127,18 +127,19 @@ class TestGit(TestBase): # now we should be able to read a new object g.stdin.write(b"b2339455342180c7cc1e9bba3e9f181f7baa5167\n") g.stdin.flush() - assert g.stdout.readline() == obj_info + self.assertEqual(g.stdout.readline(), obj_info) # same can be achived using the respective command functions hexsha, typename, size = self.git.get_object_header(hexsha) hexsha, typename_two, size_two, data = self.git.get_object_data(hexsha) - assert typename == typename_two and size == size_two + self.assertEqual(typename, typename_two) + self.assertEqual(size, size_two) def test_version(self): v = self.git.version_info - assert isinstance(v, tuple) + self.assertIsInstance(v, tuple) for n in v: - assert isinstance(n, int) + self.assertIsInstance(n, int) # END verify number types def test_cmd_override(self): @@ -174,28 +175,28 @@ class TestGit(TestBase): def test_env_vars_passed_to_git(self): editor = 'non_existant_editor' with mock.patch.dict('os.environ', {'GIT_EDITOR': editor}): - assert self.git.var("GIT_EDITOR") == editor + self.assertEqual(self.git.var("GIT_EDITOR"), editor) @with_rw_directory def test_environment(self, rw_dir): # sanity check - assert self.git.environment() == {} + self.assertEqual(self.git.environment(), {}) # make sure the context manager works and cleans up after itself with self.git.custom_environment(PWD='/tmp'): - assert self.git.environment() == {'PWD': '/tmp'} + self.assertEqual(self.git.environment(), {'PWD': '/tmp'}) - assert self.git.environment() == {} + self.assertEqual(self.git.environment(), {}) old_env = self.git.update_environment(VARKEY='VARVALUE') # The returned dict can be used to revert the change, hence why it has # an entry with value 'None'. - assert old_env == {'VARKEY': None} - assert self.git.environment() == {'VARKEY': 'VARVALUE'} + self.assertEqual(old_env, {'VARKEY': None}) + self.assertEqual(self.git.environment(), {'VARKEY': 'VARVALUE'}) new_env = self.git.update_environment(**old_env) - assert new_env == {'VARKEY': 'VARVALUE'} - assert self.git.environment() == {} + self.assertEqual(new_env, {'VARKEY': 'VARVALUE'}) + self.assertEqual(self.git.environment(), {}) path = os.path.join(rw_dir, 'failing-script.sh') stream = open(path, 'wt') @@ -214,11 +215,11 @@ class TestGit(TestBase): try: remote.fetch() except GitCommandError as err: - if sys.version_info[0] < 3 and is_darwin(): - assert 'ssh-origin' in str(err) - assert err.status == 128 + if sys.version_info[0] < 3 and is_darwin: + self.assertIn('ssh-orig, ' in str(err)) + self.assertEqual(err.status, 128) else: - assert 'FOO' in str(err) + self.assertIn('FOO', str(err)) # end # end # end if select.poll exists diff --git a/git/test/test_index.py b/git/test/test_index.py index b83201c9..2a8df798 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -577,7 +577,7 @@ class TestIndex(TestBase): assert len(entries) == 1 and entries[0].hexsha != null_hex_sha # add symlink - if not is_win(): + if not is_win: for target in ('/etc/nonexisting', '/etc/passwd', '/etc'): basename = "my_real_symlink" @@ -630,7 +630,7 @@ class TestIndex(TestBase): index.checkout(fake_symlink_path) # on windows we will never get symlinks - if is_win(): + if is_win: # simlinks should contain the link as text ( which is what a # symlink actually is ) open(fake_symlink_path, 'rb').read() == link_target @@ -711,7 +711,7 @@ class TestIndex(TestBase): assert fkey not in index.entries index.add(files, write=True) - if is_win(): + if is_win: hp = hook_path('pre-commit', index.repo.git_dir) hpd = os.path.dirname(hp) if not os.path.isdir(hpd): diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 5906b06c..9307bab2 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -26,7 +26,7 @@ from git.repo.fun import ( # Change the configuration if possible to prevent the underlying memory manager # to keep file handles open. On windows we get problems as they are not properly # closed due to mmap bugs on windows (as it appears) -if is_win(): +if is_win: try: import smmap.util smmap.util.MapRegion._test_read_into_memory = True diff --git a/git/test/test_util.py b/git/test/test_util.py index 76a5e0e9..9fc159df 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -92,7 +92,7 @@ class TestUtils(TestBase): elapsed = time.time() - start # More extra time costs, but... extra_time = 0.2 - if is_win(): + if is_win: extra_time *= 4 self.assertLess(elapsed, wait_time + 0.02) -- cgit v1.2.3 From 434505f1b6f882978de17009854d054992b827cf Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 27 Sep 2016 21:06:27 +0200 Subject: TCs: unittestize many test-docs assertions --- git/test/test_docs.py | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'git/test') diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 2cd355b2..85c647dd 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -58,28 +58,28 @@ class Tutorials(TestBase): # repository paths # [7-test_init_repo_object] - assert os.path.isdir(cloned_repo.working_tree_dir) # directory with your work files - assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir) # directory containing the git repository - assert bare_repo.working_tree_dir is None # bare repositories have no working tree + assert os.path.isdir(cloned_repo.working_tree_dir) # directory with your work files + assert cloned_repo.git_dir.startswith(cloned_repo.working_tree_dir) # directory containing the git repository + assert bare_repo.working_tree_dir is None # bare repositories have no working tree # ![7-test_init_repo_object] # heads, tags and references # heads are branches in git-speak # [8-test_init_repo_object] - assert repo.head.ref == repo.heads.master # head is a symbolic reference pointing to master - assert repo.tags['0.3.5'] == repo.tag('refs/tags/0.3.5') # you can access tags in various ways too - assert repo.refs.master == repo.heads['master'] # .refs provides access to all refs, i.e. heads ... + self.assertEqual(repo.head.ref, repo.heads.master) # head is a sym-ref pointing to master + self.assertEqual(repo.tags['0.3.5'], repo.tag('refs/tags/0.3.5')) # you can access tags in various ways too + self.assertEqual(repo.refs.master, repo.heads['master']) # .refs provides all refs, ie heads ... if 'TRAVIS' not in os.environ: - assert repo.refs['origin/master'] == repo.remotes.origin.refs.master # ... remotes ... - assert repo.refs['0.3.5'] == repo.tags['0.3.5'] # ... and tags + self.assertEqual(repo.refs['origin/master'], repo.remotes.origin.refs.master) # ... remotes ... + self.assertEqual(repo.refs['0.3.5'], repo.tags['0.3.5']) # ... and tags # ![8-test_init_repo_object] # create a new head/branch # [9-test_init_repo_object] new_branch = cloned_repo.create_head('feature') # create a new branch ... assert cloned_repo.active_branch != new_branch # which wasn't checked out yet ... - assert new_branch.commit == cloned_repo.active_branch.commit # and which points to the checked-out commit + self.assertEqual(new_branch.commit, cloned_repo.active_branch.commit) # pointing to the checked-out commit # It's easy to let a branch point to the previous commit, without affecting anything else # Each reference provides access to the git object it points to, usually commits assert new_branch.set_commit('HEAD~1').commit == cloned_repo.active_branch.commit.parents[0] @@ -89,7 +89,7 @@ class Tutorials(TestBase): # [10-test_init_repo_object] past = cloned_repo.create_tag('past', ref=new_branch, message="This is a tag-object pointing to %s" % new_branch.name) - assert past.commit == new_branch.commit # the tag points to the specified commit + self.assertEqual(past.commit, new_branch.commit) # the tag points to the specified commit assert past.tag.message.startswith("This is") # and its object carries the message provided now = cloned_repo.create_tag('now') # This is a tag-reference. It may not carry meta-data @@ -110,7 +110,7 @@ class Tutorials(TestBase): file_count += item.type == 'blob' tree_count += item.type == 'tree' assert file_count and tree_count # we have accumulated all directories and files - assert len(tree.blobs) + len(tree.trees) == len(tree) # a tree is iterable itself to traverse its children + self.assertEqual(len(tree.blobs) + len(tree.trees), len(tree)) # a tree is iterable on its children # ![11-test_init_repo_object] # remotes allow handling push, pull and fetch operations @@ -122,8 +122,8 @@ class Tutorials(TestBase): print(op_code, cur_count, max_count, cur_count / (max_count or 100.0), message or "NO MESSAGE") # end - assert len(cloned_repo.remotes) == 1 # we have been cloned, so there should be one remote - assert len(bare_repo.remotes) == 0 # this one was just initialized + self.assertEqual(len(cloned_repo.remotes), 1) # we have been cloned, so should be one remote + self.assertEqual(len(bare_repo.remotes), 0) # this one was just initialized origin = bare_repo.create_remote('origin', url=cloned_repo.working_tree_dir) assert origin.exists() for fetch_info in origin.fetch(progress=MyProgressPrinter()): @@ -138,8 +138,8 @@ class Tutorials(TestBase): # index # [13-test_init_repo_object] - assert new_branch.checkout() == cloned_repo.active_branch # checking out a branch adjusts the working tree - assert new_branch.commit == past.commit # Now the past is checked out + self.assertEqual(new_branch.checkout(), cloned_repo.active_branch) # checking out branch adjusts the wtree + self.assertEqual(new_branch.commit, past.commit) # Now the past is checked out new_file_path = os.path.join(cloned_repo.working_tree_dir, 'my-new-file') open(new_file_path, 'wb').close() # create new file in working tree @@ -244,17 +244,17 @@ class Tutorials(TestBase): # ![8-test_references_and_objects] # [9-test_references_and_objects] - assert hct.type == 'tree' # preset string type, being a class attribute + self.assertEqual(hct.type, 'tree') # preset string type, being a class attribute assert hct.size > 0 # size in bytes assert len(hct.hexsha) == 40 assert len(hct.binsha) == 20 # ![9-test_references_and_objects] # [10-test_references_and_objects] - assert hct.path == '' # root tree has no path + self.assertEqual(hct.path, '') # root tree has no path assert hct.trees[0].path != '' # the first contained item has one though - assert hct.mode == 0o40000 # trees have the mode of a linux directory - assert hct.blobs[0].mode == 0o100644 # blobs have a specific mode though comparable to a standard linux fs + self.assertEqual(hct.mode, 0o40000) # trees have the mode of a linux directory + self.assertEqual(hct.blobs[0].mode, 0o100644) # blobs have specific mode, comparable to a standard linux fs # ![10-test_references_and_objects] # [11-test_references_and_objects] @@ -311,14 +311,14 @@ class Tutorials(TestBase): # ![18-test_references_and_objects] # [19-test_references_and_objects] - assert tree['smmap'] == tree / 'smmap' # access by index and by sub-path + self.assertEqual(tree['smmap'], tree / 'smmap') # access by index and by sub-path for entry in tree: # intuitive iteration of tree members print(entry) blob = tree.trees[0].blobs[0] # let's get a blob in a sub-tree assert blob.name assert len(blob.path) < len(blob.abspath) - assert tree.trees[0].name + '/' + blob.name == blob.path # this is how the relative blob path is generated - assert tree[blob.path] == blob # you can use paths like 'dir/file' in tree[...] + self.assertEqual(tree.trees[0].name + '/' + blob.name, blob.path) # this is how relative blob path generated + self.assertEqual(tree[blob.path], blob) # you can use paths like 'dir/file' in tree # ![19-test_references_and_objects] # [20-test_references_and_objects] @@ -331,7 +331,7 @@ class Tutorials(TestBase): assert repo.tree() == repo.head.commit.tree past = repo.commit('HEAD~5') assert repo.tree(past) == repo.tree(past.hexsha) - assert repo.tree('v0.8.1').type == 'tree' # yes, you can provide any refspec - works everywhere + self.assertEqual(repo.tree('v0.8.1').type, 'tree') # yes, you can provide any refspec - works everywhere # ![21-test_references_and_objects] # [22-test_references_and_objects] @@ -351,7 +351,7 @@ class Tutorials(TestBase): index.remove(['LICENSE']) # remove an existing one assert os.path.isfile(os.path.join(repo.working_tree_dir, 'LICENSE')) # working tree is untouched - assert index.commit("my commit message").type == 'commit' # commit changed index + self.assertEqual(index.commit("my commit message").type, 'commit') # commit changed index repo.active_branch.commit = repo.commit('HEAD~1') # forget last commit from git import Actor @@ -378,7 +378,7 @@ class Tutorials(TestBase): assert origin == empty_repo.remotes.origin == empty_repo.remotes['origin'] origin.fetch() # assure we actually have data. fetch() returns useful information # Setup a local tracking branch of a remote branch - empty_repo.create_head('master', origin.refs.master) # create local branch "master" from remote branch "master" + empty_repo.create_head('master', origin.refs.master) # create local branch "master" from remote "master" empty_repo.heads.master.set_tracking_branch(origin.refs.master) # set local "master" to track remote "master empty_repo.heads.master.checkout() # checkout local "master" to working tree # Three above commands in one: @@ -455,19 +455,19 @@ class Tutorials(TestBase): assert len(sms) == 1 sm = sms[0] - assert sm.name == 'gitdb' # git-python has gitdb as single submodule ... - assert sm.children()[0].name == 'smmap' # ... which has smmap as single submodule + self.assertEqual(sm.name, 'gitdb') # git-python has gitdb as single submodule ... + self.assertEqual(sm.children()[0].name, 'smmap') # ... which has smmap as single submodule # The module is the repository referenced by the submodule assert sm.module_exists() # the module is available, which doesn't have to be the case. assert sm.module().working_tree_dir.endswith('gitdb') # the submodule's absolute path is the module's path assert sm.abspath == sm.module().working_tree_dir - assert len(sm.hexsha) == 40 # Its sha defines the commit to checkout + self.assertEqual(len(sm.hexsha), 40) # Its sha defines the commit to checkout assert sm.exists() # yes, this submodule is valid and exists # read its configuration conveniently assert sm.config_reader().get_value('path') == sm.path - assert len(sm.children()) == 1 # query the submodule hierarchy + self.assertEqual(len(sm.children()), 1) # query the submodule hierarchy # ![1-test_submodules] @with_rw_directory -- cgit v1.2.3 From 137ee6ef22c4e6480f95972ef220d1832cdc709a Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 27 Sep 2016 22:07:19 +0200 Subject: Win, #519: FIX with_rw_directory() to remove read-only dirs + Stop using gitdb's respective helper. + Fix files chmod(555) which CANNOT DELETE on Windows (but do on Linux). --- git/test/lib/helper.py | 53 +++++++++++++++++++++++++++++++-------------- git/test/performance/lib.py | 4 ++-- git/test/test_commit.py | 2 +- git/test/test_config.py | 2 +- git/test/test_diff.py | 2 +- git/test/test_docs.py | 6 +++-- git/test/test_git.py | 9 +++----- git/test/test_index.py | 9 ++++---- git/test/test_reflog.py | 5 ++--- git/test/test_remote.py | 5 ++--- git/test/test_repo.py | 13 +++++------ git/test/test_submodule.py | 2 +- 12 files changed, 64 insertions(+), 48 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 7f4e81e0..6d840027 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -4,15 +4,16 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php from __future__ import print_function + import os from unittest import TestCase import time import tempfile -import shutil import io import logging from git import Repo, Remote, GitCommandError, Git +from git.util import rmtree from git.compat import string_types, is_win import textwrap @@ -23,7 +24,8 @@ GIT_DAEMON_PORT = os.environ.get("GIT_PYTHON_TEST_GIT_DAEMON_PORT", "9418") __all__ = ( 'fixture_path', 'fixture', 'absolute_project_path', 'StringProcessAdapter', - 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', 'GIT_REPO', 'GIT_DAEMON_PORT' + 'with_rw_directory', 'with_rw_repo', 'with_rw_and_rw_remote_repo', 'TestBase', 'TestCase', + 'GIT_REPO', 'GIT_DAEMON_PORT' ) log = logging.getLogger('git.util') @@ -79,16 +81,31 @@ def _mktemp(*args): return tdir -def _rmtree_onerror(osremove, fullpath, exec_info): - """ - Handle the case on windows that read-only files cannot be deleted by - os.remove by setting it to mode 777, then retry deletion. - """ - if is_win or osremove is not os.remove: - raise +def with_rw_directory(func): + """Create a temporary directory which can be written to, remove it if the + test succeeds, but leave it otherwise to aid additional debugging""" - os.chmod(fullpath, 0o777) - os.remove(fullpath) + def wrapper(self): + path = tempfile.mktemp(prefix=func.__name__) + os.mkdir(path) + keep = False + try: + try: + return func(self, path) + except Exception: + log.info.write("Test %s.%s failed, output is at %r\n", + type(self).__name__, func.__name__, path) + keep = True + raise + finally: + # Need to collect here to be sure all handles have been closed. It appears + # a windows-only issue. In fact things should be deleted, as well as + # memory maps closed, once objects go out of scope. For some reason + # though this is not the case here unless we collect explicitly. + import gc + gc.collect() + if not keep: + rmtree(path) def with_rw_repo(working_tree_ref, bare=False): @@ -129,8 +146,11 @@ def with_rw_repo(working_tree_ref, bare=False): finally: os.chdir(prev_cwd) rw_repo.git.clear_cache() + rw_repo = None + import gc + gc.collect() if repo_dir is not None: - shutil.rmtree(repo_dir, onerror=_rmtree_onerror) + rmtree(repo_dir) # END rm test repo if possible # END cleanup # END rw repo creator @@ -279,14 +299,15 @@ def with_rw_and_rw_remote_repo(working_tree_ref): if gd is not None: gd.proc.kill() - import gc - gc.collect() rw_repo.git.clear_cache() rw_remote_repo.git.clear_cache() + rw_repo = rw_remote_repo = None + import gc + gc.collect() if repo_dir: - shutil.rmtree(repo_dir, onerror=_rmtree_onerror) + rmtree(repo_dir) if remote_repo_dir: - shutil.rmtree(remote_repo_dir, onerror=_rmtree_onerror) + rmtree(remote_repo_dir) if gd is not None: gd.proc.wait() diff --git a/git/test/performance/lib.py b/git/test/performance/lib.py index bb3f7a99..eebbfd76 100644 --- a/git/test/performance/lib.py +++ b/git/test/performance/lib.py @@ -4,7 +4,6 @@ from git.test.lib import ( TestBase ) from gitdb.test.lib import skip_on_travis_ci -import shutil import tempfile import logging @@ -16,6 +15,7 @@ from git.db import ( from git import ( Repo ) +from git.util import rmtree #{ Invvariants k_env_git_repo = "GIT_PYTHON_TEST_GIT_REPO_BASE" @@ -86,7 +86,7 @@ class TestBigRepoRW(TestBigRepoR): def tearDown(self): super(TestBigRepoRW, self).tearDown() if self.gitrwrepo is not None: - shutil.rmtree(self.gitrwrepo.working_dir) + rmtree(self.gitrwrepo.working_dir) self.gitrwrepo.git.clear_cache() self.gitrwrepo = None self.puregitrwrepo.git.clear_cache() diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 2f5270d4..33f8081c 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -19,7 +19,7 @@ from git import ( Actor, ) from gitdb import IStream -from gitdb.test.lib import with_rw_directory +from git.test.lib import with_rw_directory from git.compat import ( string_types, text_type diff --git a/git/test/test_config.py b/git/test/test_config.py index c0889c1a..d47349fa 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -9,7 +9,7 @@ from git.test.lib import ( fixture_path, assert_equal, ) -from gitdb.test.lib import with_rw_directory +from git.test.lib import with_rw_directory from git import ( GitConfigParser ) diff --git a/git/test/test_diff.py b/git/test/test_diff.py index cab72d2a..57c6bc79 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -15,7 +15,7 @@ from git.test.lib import ( ) -from gitdb.test.lib import with_rw_directory +from git.test.lib import with_rw_directory from git import ( Repo, diff --git a/git/test/test_docs.py b/git/test/test_docs.py index 85c647dd..a6e92543 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -7,7 +7,7 @@ import os from git.test.lib import TestBase -from gitdb.test.lib import with_rw_directory +from git.test.lib.helper import with_rw_directory class Tutorials(TestBase): @@ -210,7 +210,7 @@ class Tutorials(TestBase): master = head.reference # retrieve the reference the head points to master.commit # from here you use it as any other reference # ![3-test_references_and_objects] - +# # [4-test_references_and_objects] log = master.log() log[0] # first (i.e. oldest) reflog entry @@ -448,6 +448,8 @@ class Tutorials(TestBase): git.for_each_ref() # '-' becomes '_' when calling it # ![31-test_references_and_objects] + repo.git.clear_cache() + def test_submodules(self): # [1-test_submodules] repo = self.rorepo diff --git a/git/test/test_git.py b/git/test/test_git.py index 36bbbb10..a676d7f7 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -24,7 +24,7 @@ from git import ( Repo, cmd ) -from gitdb.test.lib import with_rw_directory +from git.test.lib import with_rw_directory from git.compat import PY3, is_darwin @@ -174,7 +174,7 @@ class TestGit(TestBase): def test_env_vars_passed_to_git(self): editor = 'non_existant_editor' - with mock.patch.dict('os.environ', {'GIT_EDITOR': editor}): + with mock.patch.dict('os.environ', {'GIT_EDITOR': editor}): # @UndefinedVariable self.assertEqual(self.git.var("GIT_EDITOR"), editor) @with_rw_directory @@ -203,7 +203,7 @@ class TestGit(TestBase): stream.write("#!/usr/bin/env sh\n" + "echo FOO\n") stream.close() - os.chmod(path, 0o555) + os.chmod(path, 0o777) rw_repo = Repo.init(os.path.join(rw_dir, 'repo')) remote = rw_repo.create_remote('ssh-origin', "ssh://git@server/foo") @@ -220,9 +220,6 @@ class TestGit(TestBase): self.assertEqual(err.status, 128) else: self.assertIn('FOO', str(err)) - # end - # end - # end if select.poll exists def test_handle_process_output(self): from git.cmd import handle_process_output diff --git a/git/test/test_index.py b/git/test/test_index.py index 2a8df798..0e2bc98c 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -11,7 +11,7 @@ from git.test.lib import ( fixture, with_rw_repo ) -from git.util import Actor +from git.util import Actor, rmtree from git.exc import ( HookExecutionError, InvalidGitRepositoryError @@ -32,7 +32,6 @@ from gitdb.util import hex_to_bin import os import sys import tempfile -import shutil from stat import ( S_ISLNK, ST_MODE @@ -46,7 +45,7 @@ from git.index.typ import ( IndexEntry ) from git.index.fun import hook_path -from gitdb.test.lib import with_rw_directory +from git.test.lib import with_rw_directory class TestIndex(TestBase): @@ -387,7 +386,7 @@ class TestIndex(TestBase): assert not open(test_file, 'rb').read().endswith(append_data) # checkout directory - shutil.rmtree(os.path.join(rw_repo.working_tree_dir, "lib")) + rmtree(os.path.join(rw_repo.working_tree_dir, "lib")) rval = index.checkout('lib') assert len(list(rval)) > 1 @@ -719,7 +718,7 @@ class TestIndex(TestBase): with open(hp, "wt") as fp: fp.write("#!/usr/bin/env sh\necho stdout; echo stderr 1>&2; exit 1") # end - os.chmod(hp, 0o544) + os.chmod(hp, 0o744) try: index.commit("This should fail") except HookExecutionError as err: diff --git a/git/test/test_reflog.py b/git/test/test_reflog.py index 3571e083..dffedf3b 100644 --- a/git/test/test_reflog.py +++ b/git/test/test_reflog.py @@ -7,11 +7,10 @@ from git.refs import ( RefLogEntry, RefLog ) -from git.util import Actor +from git.util import Actor, rmtree from gitdb.util import hex_to_bin import tempfile -import shutil import os @@ -104,4 +103,4 @@ class TestRefLog(TestBase): # END for each reflog # finally remove our temporary data - shutil.rmtree(tdir) + rmtree(tdir) diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 2716d5b9..05de4ae2 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -25,10 +25,9 @@ from git import ( Remote, GitCommandError ) -from git.util import IterableList +from git.util import IterableList, rmtree from git.compat import string_types import tempfile -import shutil import os import random @@ -285,7 +284,7 @@ class TestRemote(TestBase): # and only provides progress information to ttys res = fetch_and_test(other_origin) finally: - shutil.rmtree(other_repo_dir) + rmtree(other_repo_dir) # END test and cleanup def _assert_push_and_pull(self, remote, rw_repo, remote_repo): diff --git a/git/test/test_repo.py b/git/test/test_repo.py index b516402a..3e030a05 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -34,18 +34,17 @@ from git import ( GitCommandError ) from git.repo.fun import touch -from git.util import join_path_native +from git.util import join_path_native, rmtree from git.exc import ( BadObject, ) from gitdb.util import bin_to_hex from git.compat import string_types -from gitdb.test.lib import with_rw_directory +from git.test.lib import with_rw_directory import os import sys import tempfile -import shutil import itertools from io import BytesIO @@ -200,7 +199,7 @@ class TestRepo(TestBase): self._assert_empty_repo(rc) try: - shutil.rmtree(clone_path) + rmtree(clone_path) except OSError: # when relative paths are used, the clone may actually be inside # of the parent directory @@ -211,9 +210,9 @@ class TestRepo(TestBase): rc = Repo.clone_from(r.git_dir, clone_path) self._assert_empty_repo(rc) - shutil.rmtree(git_dir_abs) + rmtree(git_dir_abs) try: - shutil.rmtree(clone_path) + rmtree(clone_path) except OSError: # when relative paths are used, the clone may actually be inside # of the parent directory @@ -231,7 +230,7 @@ class TestRepo(TestBase): self._assert_empty_repo(r) finally: try: - shutil.rmtree(del_dir_abs) + rmtree(del_dir_abs) except OSError: pass os.chdir(prev_cwd) diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index 9307bab2..dcfe9216 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -9,7 +9,7 @@ from git.test.lib import ( TestBase, with_rw_repo ) -from gitdb.test.lib import with_rw_directory +from git.test.lib import with_rw_directory from git.exc import ( InvalidGitRepositoryError, RepositoryDirtyError -- cgit v1.2.3 From 467416356a96148bcb01feb771f6ea20e5215727 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Tue, 27 Sep 2016 23:57:53 +0200 Subject: test: Start using `ddt` library for TCs + DataDriven TCs for identifying which separate case failed. + appveyor: rework matrix, conda3.4 cannot install in develop mode --- git/test/test_diff.py | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'git/test') diff --git a/git/test/test_diff.py b/git/test/test_diff.py index 57c6bc79..a8960297 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -24,8 +24,10 @@ from git import ( DiffIndex, NULL_TREE, ) +import ddt +@ddt.ddt class TestDiff(TestBase): def tearDown(self): @@ -118,18 +120,20 @@ class TestDiff(TestBase): self.assertEqual(diffs[0].change_type, 'M') self.assertIsNone(diffs[0].b_blob,) - def test_binary_diff(self): - for method, file_name in ((Diff._index_from_patch_format, 'diff_patch_binary'), - (Diff._index_from_raw_format, 'diff_raw_binary')): - res = method(None, StringProcessAdapter(fixture(file_name)).stdout) - self.assertEqual(len(res), 1) - self.assertEqual(len(list(res.iter_change_type('M'))), 1) - if res[0].diff: - self.assertEqual(res[0].diff, - b"Binary files a/rps and b/rps differ\n", - "in patch mode, we get a diff text") - self.assertIsNotNone(str(res[0]), "This call should just work") - # end for each method to test + @ddt.data( + (Diff._index_from_patch_format, 'diff_patch_binary'), + (Diff._index_from_raw_format, 'diff_raw_binary') + ) + def test_binary_diff(self, case): + method, file_name = case + res = method(None, StringProcessAdapter(fixture(file_name)).stdout) + self.assertEqual(len(res), 1) + self.assertEqual(len(list(res.iter_change_type('M'))), 1) + if res[0].diff: + self.assertEqual(res[0].diff, + b"Binary files a/rps and b/rps differ\n", + "in patch mode, we get a diff text") + self.assertIsNotNone(str(res[0]), "This call should just work") def test_diff_index(self): output = StringProcessAdapter(fixture('diff_index_patch')) -- cgit v1.2.3 From a5db3d3c49ebe559cb80983d7bb855d4adf1b887 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Wed, 28 Sep 2016 01:05:38 +0200 Subject: io, dif: #519: FIX DIFF freeze when reading from GIL + CAUSE: In Windows, Diffs freeze while reading Popen streams, probably buffers smaller; good-thin(TM) in this case because reading a Popen-proc from the launching-thread freezes GIL. The alternative to use `proc.communicate()` also relies on big buffers. + SOLUTION: Use `cmd.handle_process_output()` to consume Diff-proc streams. + Retroffited `handle_process_output()` code to support also byte-streams, both Threading(Windows) and Select/Poll (Posix) paths updated. - TODO: Unfortunately, `Diff._index_from_patch_format()` still slurps input; need to re-phrase header-regexes linewise to resolve it. --- git/test/test_diff.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'git/test') diff --git a/git/test/test_diff.py b/git/test/test_diff.py index a8960297..d34d84e3 100644 --- a/git/test/test_diff.py +++ b/git/test/test_diff.py @@ -79,7 +79,7 @@ class TestDiff(TestBase): def test_list_from_string_new_mode(self): output = StringProcessAdapter(fixture('diff_new_mode')) - diffs = Diff._index_from_patch_format(self.rorepo, output.stdout) + diffs = Diff._index_from_patch_format(self.rorepo, output) self._assert_diff_format(diffs) assert_equal(1, len(diffs)) @@ -87,7 +87,7 @@ class TestDiff(TestBase): def test_diff_with_rename(self): output = StringProcessAdapter(fixture('diff_rename')) - diffs = Diff._index_from_patch_format(self.rorepo, output.stdout) + diffs = Diff._index_from_patch_format(self.rorepo, output) self._assert_diff_format(diffs) assert_equal(1, len(diffs)) @@ -102,7 +102,7 @@ class TestDiff(TestBase): assert isinstance(str(diff), str) output = StringProcessAdapter(fixture('diff_rename_raw')) - diffs = Diff._index_from_raw_format(self.rorepo, output.stdout) + diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1) diff = diffs[0] self.assertIsNotNone(diff.renamed_file) @@ -113,7 +113,7 @@ class TestDiff(TestBase): def test_diff_of_modified_files_not_added_to_the_index(self): output = StringProcessAdapter(fixture('diff_abbrev-40_full-index_M_raw_no-color')) - diffs = Diff._index_from_raw_format(self.rorepo, output.stdout) + diffs = Diff._index_from_raw_format(self.rorepo, output) self.assertEqual(len(diffs), 1, 'one modification') self.assertEqual(len(list(diffs.iter_change_type('M'))), 1, 'one modification') @@ -126,7 +126,7 @@ class TestDiff(TestBase): ) def test_binary_diff(self, case): method, file_name = case - res = method(None, StringProcessAdapter(fixture(file_name)).stdout) + res = method(None, StringProcessAdapter(fixture(file_name))) self.assertEqual(len(res), 1) self.assertEqual(len(list(res.iter_change_type('M'))), 1) if res[0].diff: @@ -137,7 +137,7 @@ class TestDiff(TestBase): def test_diff_index(self): output = StringProcessAdapter(fixture('diff_index_patch')) - res = Diff._index_from_patch_format(None, output.stdout) + res = Diff._index_from_patch_format(None, output) self.assertEqual(len(res), 6) for dr in res: self.assertTrue(dr.diff.startswith(b'@@'), dr) @@ -149,7 +149,7 @@ class TestDiff(TestBase): def test_diff_index_raw_format(self): output = StringProcessAdapter(fixture('diff_index_raw')) - res = Diff._index_from_raw_format(None, output.stdout) + res = Diff._index_from_raw_format(None, output) self.assertIsNotNone(res[0].deleted_file) self.assertIsNone(res[0].b_path,) @@ -171,7 +171,7 @@ class TestDiff(TestBase): def test_diff_unsafe_paths(self): output = StringProcessAdapter(fixture('diff_patch_unsafe_paths')) - res = Diff._index_from_patch_format(None, output.stdout) + res = Diff._index_from_patch_format(None, output) # The "Additions" self.assertEqual(res[0].b_path, u'path/ starting with a space') @@ -207,12 +207,12 @@ class TestDiff(TestBase): for fixture_name in fixtures: diff_proc = StringProcessAdapter(fixture(fixture_name)) - Diff._index_from_patch_format(self.rorepo, diff_proc.stdout) + Diff._index_from_patch_format(self.rorepo, diff_proc) # END for each fixture def test_diff_with_spaces(self): data = StringProcessAdapter(fixture('diff_file_with_spaces')) - diff_index = Diff._index_from_patch_format(self.rorepo, data.stdout) + diff_index = Diff._index_from_patch_format(self.rorepo, data) self.assertIsNone(diff_index[0].a_path, repr(diff_index[0].a_path)) self.assertEqual(diff_index[0].b_path, u'file with spaces', repr(diff_index[0].b_path)) -- cgit v1.2.3 From cf2335af23fb693549d6c4e72b65f97afddc5f64 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Wed, 28 Sep 2016 01:47:49 +0200 Subject: Win, hook, #519: Consume Hook Popen-proc out of GIL + HookException thrown on Popen, and were missed on Windows. + No SHELL on Popen?? + Minor fixes: + Try harder to delete trees - no remorses. + Simplify exception reprs. + Unittest-ize test_index assertions. --- git/test/test_index.py | 156 +++++++++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 71 deletions(-) (limited to 'git/test') diff --git a/git/test/test_index.py b/git/test/test_index.py index 0e2bc98c..c78890ae 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -55,9 +55,9 @@ class TestIndex(TestBase): self._reset_progress() def _assert_fprogress(self, entries): - assert len(entries) == len(self._fprogress_map) + self.assertEqual(len(entries), len(self._fprogress_map)) for path, call_count in self._fprogress_map.items(): - assert call_count == 2 + self.assertEqual(call_count, 2) # END for each item in progress map self._reset_progress() @@ -107,14 +107,14 @@ class TestIndex(TestBase): # test stage index_merge = IndexFile(self.rorepo, fixture_path("index_merge")) - assert len(index_merge.entries) == 106 + self.assertEqual(len(index_merge.entries), 106) assert len(list(e for e in index_merge.entries.values() if e.stage != 0)) # write the data - it must match the original tmpfile = tempfile.mktemp() index_merge.write(tmpfile) fp = open(tmpfile, 'rb') - assert fp.read() == fixture("index_merge") + self.assertEqual(fp.read(), fixture("index_merge")) fp.close() os.remove(tmpfile) @@ -206,13 +206,13 @@ class TestIndex(TestBase): assert (blob.path, 0) in three_way_index.entries num_blobs += 1 # END for each blob - assert num_blobs == len(three_way_index.entries) + self.assertEqual(num_blobs, len(three_way_index.entries)) @with_rw_repo('0.1.6') def test_index_merge_tree(self, rw_repo): # A bit out of place, but we need a different repo for this: - assert self.rorepo != rw_repo and not (self.rorepo == rw_repo) - assert len(set((self.rorepo, self.rorepo, rw_repo, rw_repo))) == 2 + self.assertNotEqual(self.rorepo, rw_repo) + self.assertEqual(len(set((self.rorepo, self.rorepo, rw_repo, rw_repo))), 2) # SINGLE TREE MERGE # current index is at the (virtual) cur_commit @@ -225,7 +225,7 @@ class TestIndex(TestBase): assert manifest_entry.binsha != rw_repo.index.entries[manifest_key].binsha rw_repo.index.reset(rw_repo.head) - assert rw_repo.index.entries[manifest_key].binsha == manifest_entry.binsha + self.assertEqual(rw_repo.index.entries[manifest_key].binsha, manifest_entry.binsha) # FAKE MERGE ############# @@ -243,7 +243,7 @@ class TestIndex(TestBase): index = rw_repo.index index.entries[manifest_key] = IndexEntry.from_base(manifest_fake_entry) index.write() - assert rw_repo.index.entries[manifest_key].hexsha == Diff.NULL_HEX_SHA + self.assertEqual(rw_repo.index.entries[manifest_key].hexsha, Diff.NULL_HEX_SHA) # write an unchanged index ( just for the fun of it ) rw_repo.index.write() @@ -267,7 +267,8 @@ class TestIndex(TestBase): # now make a proper three way merge with unmerged entries unmerged_tree = IndexFile.from_tree(rw_repo, parent_commit, tree, next_commit) unmerged_blobs = unmerged_tree.unmerged_blobs() - assert len(unmerged_blobs) == 1 and list(unmerged_blobs.keys())[0] == manifest_key[0] + self.assertEqual(len(unmerged_blobs), 1) + self.assertEqual(list(unmerged_blobs.keys())[0], manifest_key[0]) @with_rw_repo('0.1.6') def test_index_file_diffing(self, rw_repo): @@ -289,11 +290,11 @@ class TestIndex(TestBase): # diff against same index is 0 diff = index.diff() - assert len(diff) == 0 + self.assertEqual(len(diff), 0) # against HEAD as string, must be the same as it matches index diff = index.diff('HEAD') - assert len(diff) == 0 + self.assertEqual(len(diff), 0) # against previous head, there must be a difference diff = index.diff(cur_head_commit) @@ -303,7 +304,7 @@ class TestIndex(TestBase): adiff = index.diff(str(cur_head_commit), R=True) odiff = index.diff(cur_head_commit, R=False) # now its not reversed anymore assert adiff != odiff - assert odiff == diff # both unreversed diffs against HEAD + self.assertEqual(odiff, diff) # both unreversed diffs against HEAD # against working copy - its still at cur_commit wdiff = index.diff(None) @@ -319,8 +320,8 @@ class TestIndex(TestBase): rev_head_parent = 'HEAD~1' assert index.reset(rev_head_parent) is index - assert cur_branch == rw_repo.active_branch - assert cur_commit == rw_repo.head.commit + self.assertEqual(cur_branch, rw_repo.active_branch) + self.assertEqual(cur_commit, rw_repo.head.commit) # there must be differences towards the working tree which is in the 'future' assert index.diff(None) @@ -333,8 +334,8 @@ class TestIndex(TestBase): fp.close() index.reset(rev_head_parent, working_tree=True) assert not index.diff(None) - assert cur_branch == rw_repo.active_branch - assert cur_commit == rw_repo.head.commit + self.assertEqual(cur_branch, rw_repo.active_branch) + self.assertEqual(cur_commit, rw_repo.head.commit) fp = open(file_path, 'rb') try: assert fp.read() != new_data @@ -358,7 +359,7 @@ class TestIndex(TestBase): # individual file os.remove(test_file) rval = index.checkout(test_file, fprogress=self._fprogress) - assert list(rval)[0] == 'CHANGES' + self.assertEqual(list(rval)[0], 'CHANGES') self._assert_fprogress([test_file]) assert os.path.exists(test_file) @@ -374,9 +375,11 @@ class TestIndex(TestBase): try: index.checkout(test_file) except CheckoutError as e: - assert len(e.failed_files) == 1 and e.failed_files[0] == os.path.basename(test_file) - assert (len(e.failed_files) == len(e.failed_reasons)) and isinstance(e.failed_reasons[0], string_types) - assert len(e.valid_files) == 0 + self.assertEqual(len(e.failed_files), 1) + self.assertEqual(e.failed_files[0], os.path.basename(test_file)) + self.assertEqual(len(e.failed_files), len(e.failed_reasons)) + self.assertIsInstance(e.failed_reasons[0], string_types) + self.assertEqual(len(e.valid_files), 0) assert open(test_file, 'rb').read().endswith(append_data) else: raise AssertionError("Exception CheckoutError not thrown") @@ -414,7 +417,7 @@ class TestIndex(TestBase): writer.set_value("user", "name", uname) writer.set_value("user", "email", umail) writer.release() - assert writer.get_value("user", "name") == uname + self.assertEqual(writer.get_value("user", "name"), uname) # remove all of the files, provide a wild mix of paths, BaseIndexEntries, # IndexEntries @@ -437,21 +440,21 @@ class TestIndex(TestBase): # END mixed iterator deleted_files = index.remove(mixed_iterator(), working_tree=False) assert deleted_files - assert self._count_existing(rw_repo, deleted_files) == len(deleted_files) - assert len(index.entries) == 0 + self.assertEqual(self._count_existing(rw_repo, deleted_files), len(deleted_files)) + self.assertEqual(len(index.entries), 0) # reset the index to undo our changes index.reset() - assert len(index.entries) == num_entries + self.assertEqual(len(index.entries), num_entries) # remove with working copy deleted_files = index.remove(mixed_iterator(), working_tree=True) assert deleted_files - assert self._count_existing(rw_repo, deleted_files) == 0 + self.assertEqual(self._count_existing(rw_repo, deleted_files), 0) # reset everything index.reset(working_tree=True) - assert self._count_existing(rw_repo, deleted_files) == len(deleted_files) + self.assertEqual(self._count_existing(rw_repo, deleted_files), len(deleted_files)) # invalid type self.failUnlessRaises(TypeError, index.remove, [1]) @@ -468,14 +471,14 @@ class TestIndex(TestBase): new_commit = index.commit(commit_message, head=False) assert cur_commit != new_commit - assert new_commit.author.name == uname - assert new_commit.author.email == umail - assert new_commit.committer.name == uname - assert new_commit.committer.email == umail - assert new_commit.message == commit_message - assert new_commit.parents[0] == cur_commit - assert len(new_commit.parents) == 1 - assert cur_head.commit == cur_commit + self.assertEqual(new_commit.author.name, uname) + self.assertEqual(new_commit.author.email, umail) + self.assertEqual(new_commit.committer.name, uname) + self.assertEqual(new_commit.committer.email, umail) + self.assertEqual(new_commit.message, commit_message) + self.assertEqual(new_commit.parents[0], cur_commit) + self.assertEqual(len(new_commit.parents), 1) + self.assertEqual(cur_head.commit, cur_commit) # commit with other actor cur_commit = cur_head.commit @@ -484,15 +487,15 @@ class TestIndex(TestBase): my_committer = Actor(u"Committing Frèderic Çaufl€", "committer@example.com") commit_actor = index.commit(commit_message, author=my_author, committer=my_committer) assert cur_commit != commit_actor - assert commit_actor.author.name == u"Frèderic Çaufl€" - assert commit_actor.author.email == "author@example.com" - assert commit_actor.committer.name == u"Committing Frèderic Çaufl€" - assert commit_actor.committer.email == "committer@example.com" - assert commit_actor.message == commit_message - assert commit_actor.parents[0] == cur_commit - assert len(new_commit.parents) == 1 - assert cur_head.commit == commit_actor - assert cur_head.log()[-1].actor == my_committer + self.assertEqual(commit_actor.author.name, u"Frèderic Çaufl€") + self.assertEqual(commit_actor.author.email, "author@example.com") + self.assertEqual(commit_actor.committer.name, u"Committing Frèderic Çaufl€") + self.assertEqual(commit_actor.committer.email, "committer@example.com") + self.assertEqual(commit_actor.message, commit_message) + self.assertEqual(commit_actor.parents[0], cur_commit) + self.assertEqual(len(new_commit.parents), 1) + self.assertEqual(cur_head.commit, commit_actor) + self.assertEqual(cur_head.log()[-1].actor, my_committer) # commit with author_date and commit_date cur_commit = cur_head.commit @@ -501,25 +504,25 @@ class TestIndex(TestBase): new_commit = index.commit(commit_message, author_date="2006-04-07T22:13:13", commit_date="2005-04-07T22:13:13") assert cur_commit != new_commit print(new_commit.authored_date, new_commit.committed_date) - assert new_commit.message == commit_message - assert new_commit.authored_date == 1144447993 - assert new_commit.committed_date == 1112911993 + self.assertEqual(new_commit.message, commit_message) + self.assertEqual(new_commit.authored_date, 1144447993) + self.assertEqual(new_commit.committed_date, 1112911993) # same index, no parents commit_message = "index without parents" commit_no_parents = index.commit(commit_message, parent_commits=list(), head=True) - assert commit_no_parents.message == commit_message - assert len(commit_no_parents.parents) == 0 - assert cur_head.commit == commit_no_parents + self.assertEqual(commit_no_parents.message, commit_message) + self.assertEqual(len(commit_no_parents.parents), 0) + self.assertEqual(cur_head.commit, commit_no_parents) # same index, multiple parents commit_message = "Index with multiple parents\n commit with another line" commit_multi_parent = index.commit(commit_message, parent_commits=(commit_no_parents, new_commit)) - assert commit_multi_parent.message == commit_message - assert len(commit_multi_parent.parents) == 2 - assert commit_multi_parent.parents[0] == commit_no_parents - assert commit_multi_parent.parents[1] == new_commit - assert cur_head.commit == commit_multi_parent + self.assertEqual(commit_multi_parent.message, commit_message) + self.assertEqual(len(commit_multi_parent.parents), 2) + self.assertEqual(commit_multi_parent.parents[0], commit_no_parents) + self.assertEqual(commit_multi_parent.parents[1], new_commit) + self.assertEqual(cur_head.commit, commit_multi_parent) # re-add all files in lib # get the lib folder back on disk, but get an index without it @@ -538,17 +541,17 @@ class TestIndex(TestBase): entries = index.reset(new_commit).add([os.path.join('lib', 'git', '*.py')], fprogress=self._fprogress_add) self._assert_entries(entries) self._assert_fprogress(entries) - assert len(entries) == 14 + self.assertEqual(len(entries), 14) # same file entries = index.reset(new_commit).add( [os.path.join(rw_repo.working_tree_dir, 'lib', 'git', 'head.py')] * 2, fprogress=self._fprogress_add) self._assert_entries(entries) - assert entries[0].mode & 0o644 == 0o644 + self.assertEqual(entries[0].mode & 0o644, 0o644) # would fail, test is too primitive to handle this case # self._assert_fprogress(entries) self._reset_progress() - assert len(entries) == 2 + self.assertEqual(len(entries), 2) # missing path self.failUnlessRaises(OSError, index.reset(new_commit).add, ['doesnt/exist/must/raise']) @@ -558,7 +561,8 @@ class TestIndex(TestBase): entries = index.reset(new_commit).add([old_blob], fprogress=self._fprogress_add) self._assert_entries(entries) self._assert_fprogress(entries) - assert index.entries[(old_blob.path, 0)].hexsha == old_blob.hexsha and len(entries) == 1 + self.assertEqual(index.entries[(old_blob.path, 0)].hexsha, old_blob.hexsha) + self.assertEqual(len(entries), 1) # mode 0 not allowed null_hex_sha = Diff.NULL_HEX_SHA @@ -573,7 +577,8 @@ class TestIndex(TestBase): [BaseIndexEntry((0o10644, null_bin_sha, 0, new_file_relapath))], fprogress=self._fprogress_add) self._assert_entries(entries) self._assert_fprogress(entries) - assert len(entries) == 1 and entries[0].hexsha != null_hex_sha + self.assertEqual(len(entries), 1) + self.assertNotEquals(entries[0].hexsha, null_hex_sha) # add symlink if not is_win: @@ -585,11 +590,12 @@ class TestIndex(TestBase): entries = index.reset(new_commit).add([link_file], fprogress=self._fprogress_add) self._assert_entries(entries) self._assert_fprogress(entries) - assert len(entries) == 1 and S_ISLNK(entries[0].mode) - assert S_ISLNK(index.entries[index.entry_key("my_real_symlink", 0)].mode) + self.assertEqual(len(entries), 1) + self.assertTrue(S_ISLNK(entries[0].mode)) + self.assertTrue(S_ISLNK(index.entries[index.entry_key("my_real_symlink", 0)].mode)) # we expect only the target to be written - assert index.repo.odb.stream(entries[0].binsha).read().decode('ascii') == target + self.assertEqual(index.repo.odb.stream(entries[0].binsha).read().decode('ascii'), target) os.remove(link_file) # end for each target @@ -604,7 +610,8 @@ class TestIndex(TestBase): self._assert_entries(entries) self._assert_fprogress(entries) assert entries[0].hexsha != null_hex_sha - assert len(entries) == 1 and S_ISLNK(entries[0].mode) + self.assertEqual(len(entries), 1) + self.assertTrue(S_ISLNK(entries[0].mode)) # assure this also works with an alternate method full_index_entry = IndexEntry.from_base(BaseIndexEntry((0o120000, entries[0].binsha, 0, entries[0].path))) @@ -654,7 +661,7 @@ class TestIndex(TestBase): # files into directory - dry run paths = ['LICENSE', 'VERSION', 'doc'] rval = index.move(paths, dry_run=True) - assert len(rval) == 2 + self.assertEqual(len(rval), 2) assert os.path.exists(paths[0]) # again, no dry run @@ -722,11 +729,18 @@ class TestIndex(TestBase): try: index.commit("This should fail") except HookExecutionError as err: - assert err.status == 1 - assert err.command == hp - assert err.stdout == 'stdout\n' - assert err.stderr == 'stderr\n' - assert str(err) + if is_win: + self.assertIsInstance(err.status, WindowsError) + self.assertEqual(err.command, hp) + self.assertIsNone(err.stdout) + self.assertIsNone(err.stderr) + assert str(err) + else: + self.assertEqual(err.status, 1) + self.assertEqual(err.command, hp) + self.assertEqual(err.stdout, 'stdout\n') + self.assertEqual(err.stderr, 'stderr\n') + assert str(err) else: raise AssertionError("Should have cought a HookExecutionError") # end exception handling @@ -766,7 +780,7 @@ class TestIndex(TestBase): count += 1 index = rw_repo.index.reset(commit) orig_tree = commit.tree - assert index.write_tree() == orig_tree + self.assertEqual(index.write_tree(), orig_tree) # END for each commit def test_index_new(self): -- cgit v1.2.3 From f11fdf1d9d22a198511b02f3ca90146cfa5deb5c Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Wed, 28 Sep 2016 14:43:47 +0200 Subject: remote, #519: FIX1-of-2 double-decoding push-infos + When `universal_lines==True` (515a6b9ccf8) must tel `handle_process_output` to stop decoding strings. --- git/test/lib/helper.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 6d840027..949e474f 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -258,8 +258,10 @@ def with_rw_and_rw_remote_repo(working_tree_ref): # We assume in good faith that we didn't start the daemon - but make sure we kill it anyway # Of course we expect it to work here already, but maybe there are timing constraints # on some platforms ? - if gd is not None: + try: gd.proc.terminate() + except Exception as ex: + log.debug("Ignoring %r while terminating proc after %r.", ex, e) log.warning('git(%s) ls-remote failed due to:%s', rw_repo.git_dir, e) if is_win: @@ -296,8 +298,10 @@ def with_rw_and_rw_remote_repo(working_tree_ref): os.chdir(prev_cwd) finally: - if gd is not None: + try: gd.proc.kill() + except: + pass ## Either it has died (and we're here), or it won't die, again here... rw_repo.git.clear_cache() rw_remote_repo.git.clear_cache() -- cgit v1.2.3 From 44c6d0b368bc1ec6cd0a97b01678b38788c9bd9c Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Wed, 28 Sep 2016 05:46:50 +0200 Subject: Proc, #519: Rework error-exc msgs & log thread-pumps errors + No WindowsError exception. + Add `test_exc.py` for unicode issues. + Single-arg for decoding-streams in pump-func. --- git/test/test_exc.py | 142 +++++++++++++++++++++++++++++++++++++++++++++++++ git/test/test_git.py | 6 ++- git/test/test_index.py | 2 +- git/test/test_util.py | 3 +- 4 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 git/test/test_exc.py (limited to 'git/test') diff --git a/git/test/test_exc.py b/git/test/test_exc.py new file mode 100644 index 00000000..7e6b023e --- /dev/null +++ b/git/test/test_exc.py @@ -0,0 +1,142 @@ +# -*- coding: utf-8 -*- +# test_exc.py +# Copyright (C) 2008, 2009, 2016 Michael Trier (mtrier@gmail.com) and contributors +# +# This module is part of GitPython and is released under +# the BSD License: http://www.opensource.org/licenses/bsd-license.php + + +import re + +import ddt +from git.exc import ( + CommandError, + GitCommandNotFound, + GitCommandError, + HookExecutionError, +) +from git.test.lib import TestBase + +import itertools as itt + + +_cmd_argvs = ( + ('cmd', ), + ('θνιψοδε', ), + ('θνιψοδε', 'normal', 'argvs'), + ('cmd', 'ελληνικα', 'args'), + ('θνιψοδε', 'κι', 'αλλα', 'strange', 'args'), + ('θνιψοδε', 'κι', 'αλλα', 'non-unicode', 'args'), +) +_causes_n_substrings = ( + (None, None), # noqa: E241 + (7, "exit code(7)"), # noqa: E241 + ('Some string', "'Some string'"), # noqa: E241 + ('παλιο string', "'παλιο string'"), # noqa: E241 + (Exception("An exc."), "Exception('An exc.')"), # noqa: E241 + (Exception("Κακια exc."), "Exception('Κακια exc.')"), # noqa: E241 + (object(), " Date: Wed, 28 Sep 2016 17:10:59 +0200 Subject: remote, #519: INCOMPLETE FIX-2 double-decoding push-infos + Unicode PY2/3 issues fixed also in pump stream func. --- git/test/lib/helper.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'git/test') diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 949e474f..90d2b1e9 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -301,7 +301,8 @@ def with_rw_and_rw_remote_repo(working_tree_ref): try: gd.proc.kill() except: - pass ## Either it has died (and we're here), or it won't die, again here... + ## Either it has died (and we're here), or it won't die, again here... + pass rw_repo.git.clear_cache() rw_remote_repo.git.clear_cache() -- cgit v1.2.3 From f1d2d0683afa6328b6015c6a3aa6a6912a055756 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Wed, 28 Sep 2016 19:04:33 +0200 Subject: FIX tox/requirements --- git/test/test_index.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'git/test') diff --git a/git/test/test_index.py b/git/test/test_index.py index 08d6491d..46cc990d 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -731,9 +731,9 @@ class TestIndex(TestBase): except HookExecutionError as err: if is_win: self.assertIsInstance(err.status, OSError) - self.assertEqual(err.command, hp) - self.assertIsNone(err.stdout) - self.assertIsNone(err.stderr) + self.assertEqual(err.command, [hp]) + self.assertEqual(err.stdout, '') + self.assertEqual(err.stderr, '') assert str(err) else: self.assertEqual(err.status, 1) -- cgit v1.2.3 From 395955609dfd711cc4558e2b618450f3514b28c1 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Thu, 29 Sep 2016 01:07:41 +0200 Subject: FIX hook TC on PY3+Win & indeterministic lock timing. + Cannot `index.path` into ENV, it is bytes! + The hook TC never runs on linux! + Unblock removal of odbfile in perf-large streams TC. + Attempt to unblock removal of submodule file by intensive cleaning. more unblock files --- git/test/performance/test_streams.py | 3 +++ git/test/test_util.py | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'git/test') diff --git a/git/test/performance/test_streams.py b/git/test/performance/test_streams.py index 4b1738cd..8194547c 100644 --- a/git/test/performance/test_streams.py +++ b/git/test/performance/test_streams.py @@ -87,6 +87,9 @@ class TestObjDBPerformance(TestBigRepoR): % (size_kib, desc, cs_kib, elapsed_readchunks, size_kib / elapsed_readchunks), file=sys.stderr) # del db file so git has something to do + ostream = None + import gc + gc.collect() os.remove(db_file) # VS. CGIT diff --git a/git/test/test_util.py b/git/test/test_util.py index eae9fbc7..36fb5be3 100644 --- a/git/test/test_util.py +++ b/git/test/test_util.py @@ -90,10 +90,11 @@ class TestUtils(TestBase): wait_lock = BlockingLockFile(my_file, 0.05, wait_time) self.failUnlessRaises(IOError, wait_lock._obtain_lock) elapsed = time.time() - start - extra_time = 0.2 + extra_time = 0.02 if is_win: + # for Appveyor extra_time *= 6 # NOTE: Indeterministic failures here... - self.assertLess(elapsed, wait_time + 0.02) + self.assertLess(elapsed, wait_time + extra_time) def test_user_id(self): assert '@' in get_user_id() -- cgit v1.2.3 From d84b960982b5bad0b3c78c4a680638824924004b Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 1 Oct 2016 03:50:12 +0200 Subject: cfg_TCs, #519: FIX config resource leaks + Modify lock/read-config-file code to ansure files closed + Use `with GitConfigarser()` more systematically in TCs. + Clear any locks left hanging from pev Tcs --- git/test/test_config.py | 171 ++++++++++++++++++++++++++---------------------- 1 file changed, 93 insertions(+), 78 deletions(-) (limited to 'git/test') diff --git a/git/test/test_config.py b/git/test/test_config.py index d47349fa..b807413b 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -4,28 +4,48 @@ # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php -from git.test.lib import ( - TestCase, - fixture_path, - assert_equal, -) -from git.test.lib import with_rw_directory +import glob +import io +import os + from git import ( GitConfigParser ) from git.compat import ( string_types, -) -import io -import os + is_win,) from git.config import cp +from git.test.lib import ( + TestCase, + fixture_path, +) +from git.test.lib import with_rw_directory + +import os.path as osp + + +_tc_lock_fpaths = osp.join(osp.dirname(__file__), 'fixtures/*.lock') + + +def _rm_lock_files(): + for lfp in glob.glob(_tc_lock_fpaths): + if is_win and osp.isfile(lfp): + os.chmod(lfp, 0o777) + os.remove(lfp) class TestBase(TestCase): + def setUp(self): + _rm_lock_files() + + def tearDown(self): + for lfp in glob.glob(_tc_lock_fpaths): + if osp.isfile(lfp): + raise AssertionError('Previous TC left hanging git-lock file: %s', lfp) def _to_memcache(self, file_path): - fp = open(file_path, "rb") - sio = io.BytesIO(fp.read()) + with open(file_path, "rb") as fp: + sio = io.BytesIO(fp.read()) sio.name = file_path return sio @@ -33,51 +53,49 @@ class TestBase(TestCase): # writer must create the exact same file as the one read before for filename in ("git_config", "git_config_global"): file_obj = self._to_memcache(fixture_path(filename)) - w_config = GitConfigParser(file_obj, read_only=False) - w_config.read() # enforce reading - assert w_config._sections - w_config.write() # enforce writing - - # we stripped lines when reading, so the results differ - assert file_obj.getvalue() - self.assertEqual(file_obj.getvalue(), self._to_memcache(fixture_path(filename)).getvalue()) - - # creating an additional config writer must fail due to exclusive access - self.failUnlessRaises(IOError, GitConfigParser, file_obj, read_only=False) - - # should still have a lock and be able to make changes - assert w_config._lock._has_lock() - - # changes should be written right away - sname = "my_section" - oname = "mykey" - val = "myvalue" - w_config.add_section(sname) - assert w_config.has_section(sname) - w_config.set(sname, oname, val) - assert w_config.has_option(sname, oname) - assert w_config.get(sname, oname) == val - - sname_new = "new_section" - oname_new = "new_key" - ival = 10 - w_config.set_value(sname_new, oname_new, ival) - assert w_config.get_value(sname_new, oname_new) == ival - - file_obj.seek(0) - r_config = GitConfigParser(file_obj, read_only=True) - assert r_config.has_section(sname) - assert r_config.has_option(sname, oname) - assert r_config.get(sname, oname) == val - w_config.release() + with GitConfigParser(file_obj, read_only=False) as w_config: + w_config.read() # enforce reading + assert w_config._sections + w_config.write() # enforce writing + + # we stripped lines when reading, so the results differ + assert file_obj.getvalue() + self.assertEqual(file_obj.getvalue(), self._to_memcache(fixture_path(filename)).getvalue()) + + # creating an additional config writer must fail due to exclusive access + self.failUnlessRaises(IOError, GitConfigParser, file_obj, read_only=False) + + # should still have a lock and be able to make changes + assert w_config._lock._has_lock() + + # changes should be written right away + sname = "my_section" + oname = "mykey" + val = "myvalue" + w_config.add_section(sname) + assert w_config.has_section(sname) + w_config.set(sname, oname, val) + assert w_config.has_option(sname, oname) + assert w_config.get(sname, oname) == val + + sname_new = "new_section" + oname_new = "new_key" + ival = 10 + w_config.set_value(sname_new, oname_new, ival) + assert w_config.get_value(sname_new, oname_new) == ival + + file_obj.seek(0) + r_config = GitConfigParser(file_obj, read_only=True) + assert r_config.has_section(sname) + assert r_config.has_option(sname, oname) + assert r_config.get(sname, oname) == val # END for each filename @with_rw_directory def test_lock_reentry(self, rw_dir): fpl = os.path.join(rw_dir, 'l') - gcp = GitConfigParser(fpl, read_only=False) - with gcp as cw: - cw.set_value('include', 'some_value', 'a') + with GitConfigParser(fpl, read_only=False) as gcp: + gcp.set_value('include', 'some_value', 'a') # entering again locks the file again... with gcp as cw: cw.set_value('include', 'some_other_value', 'b') @@ -91,21 +109,21 @@ class TestBase(TestCase): def test_multi_line_config(self): file_obj = self._to_memcache(fixture_path("git_config_with_comments")) - config = GitConfigParser(file_obj, read_only=False) - ev = "ruby -e '\n" - ev += " system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n" - ev += " b = File.read(%(%A))\n" - ev += " b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\." - ev += "define.:version => (\\d+). do\\n>+ .*/) do\n" - ev += " %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n" - ev += " end\n" - ev += " File.open(%(%A), %(w)) {|f| f.write(b)}\n" - ev += " exit 1 if b.include?(%(<)*%L)'" - assert_equal(config.get('merge "railsschema"', 'driver'), ev) - assert_equal(config.get('alias', 'lg'), - "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset'" - " --abbrev-commit --date=relative") - assert len(config.sections()) == 23 + with GitConfigParser(file_obj, read_only=False) as config: + ev = "ruby -e '\n" + ev += " system %(git), %(merge-file), %(--marker-size=%L), %(%A), %(%O), %(%B)\n" + ev += " b = File.read(%(%A))\n" + ev += " b.sub!(/^<+ .*\\nActiveRecord::Schema\\.define.:version => (\\d+). do\\n=+\\nActiveRecord::Schema\\." # noqa E501 + ev += "define.:version => (\\d+). do\\n>+ .*/) do\n" + ev += " %(ActiveRecord::Schema.define(:version => #{[$1, $2].max}) do)\n" + ev += " end\n" + ev += " File.open(%(%A), %(w)) {|f| f.write(b)}\n" + ev += " exit 1 if b.include?(%(<)*%L)'" + self.assertEqual(config.get('merge "railsschema"', 'driver'), ev) + self.assertEqual(config.get('alias', 'lg'), + "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset'" + " --abbrev-commit --date=relative") + self.assertEqual(len(config.sections()), 23) def test_base(self): path_repo = fixture_path("git_config") @@ -202,22 +220,19 @@ class TestBase(TestCase): def test_rename(self): file_obj = self._to_memcache(fixture_path('git_config')) - cw = GitConfigParser(file_obj, read_only=False, merge_includes=False) - - self.failUnlessRaises(ValueError, cw.rename_section, "doesntexist", "foo") - self.failUnlessRaises(ValueError, cw.rename_section, "core", "include") + with GitConfigParser(file_obj, read_only=False, merge_includes=False) as cw: + self.failUnlessRaises(ValueError, cw.rename_section, "doesntexist", "foo") + self.failUnlessRaises(ValueError, cw.rename_section, "core", "include") - nn = "bee" - assert cw.rename_section('core', nn) is cw - assert not cw.has_section('core') - assert len(cw.items(nn)) == 4 - cw.release() + nn = "bee" + assert cw.rename_section('core', nn) is cw + assert not cw.has_section('core') + assert len(cw.items(nn)) == 4 def test_complex_aliases(self): file_obj = self._to_memcache(fixture_path('.gitconfig')) - w_config = GitConfigParser(file_obj, read_only=False) - self.assertEqual(w_config.get('alias', 'rbi'), '"!g() { git rebase -i origin/${1:-master} ; } ; g"') - w_config.release() + with GitConfigParser(file_obj, read_only=False) as w_config: + self.assertEqual(w_config.get('alias', 'rbi'), '"!g() { git rebase -i origin/${1:-master} ; } ; g"') self.assertEqual(file_obj.getvalue(), self._to_memcache(fixture_path('.gitconfig')).getvalue()) def test_empty_config_value(self): -- cgit v1.2.3 From 13d399f4460ecb17cecc59d7158a4159010b2ac5 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 1 Oct 2016 12:12:19 +0200 Subject: ci: restore ci log-level to normal, coverage on Win-Appveyor + Extract util-method to delete lock-files, also on Windows (will be needed by TCs). --- git/test/test_config.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'git/test') diff --git a/git/test/test_config.py b/git/test/test_config.py index b807413b..bd2bad0a 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -12,8 +12,7 @@ from git import ( GitConfigParser ) from git.compat import ( - string_types, - is_win,) + string_types) from git.config import cp from git.test.lib import ( TestCase, @@ -22,6 +21,7 @@ from git.test.lib import ( from git.test.lib import with_rw_directory import os.path as osp +from git.util import rmfile _tc_lock_fpaths = osp.join(osp.dirname(__file__), 'fixtures/*.lock') @@ -29,9 +29,7 @@ _tc_lock_fpaths = osp.join(osp.dirname(__file__), 'fixtures/*.lock') def _rm_lock_files(): for lfp in glob.glob(_tc_lock_fpaths): - if is_win and osp.isfile(lfp): - os.chmod(lfp, 0o777) - os.remove(lfp) + rmfile(lfp) class TestBase(TestCase): -- cgit v1.2.3 From a79cf677744e2c1721fa55f934fa07034bc54b0a Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 1 Oct 2016 12:58:54 +0200 Subject: repo-TCs, #519: FIX config resource leaks + Modify lock/read-config-file code to ensure files closed. + Use `with GitConfigarser()` more systematically in TCs. + Clear any locks left hanging from prev Tcs. + Util: mark lock-files as SHORT_LIVED; save some SSDs... --- git/test/test_config.py | 3 +- git/test/test_repo.py | 80 +++++++++++++++++++++++++++---------------------- 2 files changed, 46 insertions(+), 37 deletions(-) (limited to 'git/test') diff --git a/git/test/test_config.py b/git/test/test_config.py index bd2bad0a..154aaa24 100644 --- a/git/test/test_config.py +++ b/git/test/test_config.py @@ -11,8 +11,7 @@ import os from git import ( GitConfigParser ) -from git.compat import ( - string_types) +from git.compat import string_types from git.config import cp from git.test.lib import ( TestCase, diff --git a/git/test/test_repo.py b/git/test/test_repo.py index 3e030a05..e2c18d3f 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -4,18 +4,14 @@ # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php +import glob +from io import BytesIO +import itertools +import os import pickle +import sys +import tempfile -from git.test.lib import ( - patch, - TestBase, - with_rw_repo, - fixture, - assert_false, - assert_equal, - assert_true, - raises -) from git import ( InvalidGitRepositoryError, Repo, @@ -33,23 +29,28 @@ from git import ( BadName, GitCommandError ) -from git.repo.fun import touch -from git.util import join_path_native, rmtree +from git.compat import string_types from git.exc import ( BadObject, ) -from gitdb.util import bin_to_hex -from git.compat import string_types +from git.repo.fun import touch +from git.test.lib import ( + patch, + TestBase, + with_rw_repo, + fixture, + assert_false, + assert_equal, + assert_true, + raises +) from git.test.lib import with_rw_directory - -import os -import sys -import tempfile -import itertools -from io import BytesIO - +from git.util import join_path_native, rmtree, rmfile +from gitdb.util import bin_to_hex from nose import SkipTest +import os.path as osp + def iter_flatten(lol): for items in lol: @@ -61,9 +62,23 @@ def flatten(lol): return list(iter_flatten(lol)) +_tc_lock_fpaths = osp.join(osp.dirname(__file__), '../../.git/*.lock') + + +def _rm_lock_files(): + for lfp in glob.glob(_tc_lock_fpaths): + rmfile(lfp) + + class TestRepo(TestBase): + def setUp(self): + _rm_lock_files() + def tearDown(self): + for lfp in glob.glob(_tc_lock_fpaths): + if osp.isfile(lfp): + raise AssertionError('Previous TC left hanging git-lock file: %s', lfp) import gc gc.collect() @@ -309,10 +324,9 @@ class TestRepo(TestBase): def test_archive(self): tmpfile = tempfile.mktemp(suffix='archive-test') - stream = open(tmpfile, 'wb') - self.rorepo.archive(stream, '0.1.6', path='doc') - assert stream.tell() - stream.close() + with open(tmpfile, 'wb') as stream: + self.rorepo.archive(stream, '0.1.6', path='doc') + assert stream.tell() os.remove(tmpfile) @patch.object(Git, '_call_process') @@ -401,9 +415,8 @@ class TestRepo(TestBase): num_recently_untracked = 0 for fpath in files: - fd = open(fpath, "wb") - fd.close() - # END for each filename + with open(fpath, "wb"): + pass untracked_files = rwrepo.untracked_files num_recently_untracked = len(untracked_files) @@ -426,19 +439,16 @@ class TestRepo(TestBase): def test_config_writer(self): for config_level in self.rorepo.config_level: try: - writer = self.rorepo.config_writer(config_level) - assert not writer.read_only - writer.release() + with self.rorepo.config_writer(config_level) as writer: + self.assertFalse(writer.read_only) except IOError: # its okay not to get a writer for some configuration files if we # have no permissions pass - # END for each config level def test_config_level_paths(self): for config_level in self.rorepo.config_level: assert self.rorepo._get_config_path(config_level) - # end for each config level def test_creation_deletion(self): # just a very quick test to assure it generally works. There are @@ -448,8 +458,8 @@ class TestRepo(TestBase): tag = self.rorepo.create_tag("new_tag", "HEAD~2") self.rorepo.delete_tag(tag) - writer = self.rorepo.config_writer() - writer.release() + with self.rorepo.config_writer(): + pass remote = self.rorepo.create_remote("new_remote", "git@server:repo.git") self.rorepo.delete_remote(remote) -- cgit v1.2.3 From b8b025f719b2c3203e194580bbd0785a26c08ebd Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 1 Oct 2016 16:02:20 +0200 Subject: Win, #519: FIX repo TCs. + FIX TestRepo.test_submodule_update(): + submod: del `.git` file prior overwrite; Windows denied otherwise! + FIX TestRepo.test_untracked_files(): + In the `git add ` case, it failed with unicode args on PY2. Had to encode them with `locale.getpreferredencoding()` AND use SHELL. + cmd: add `shell` into `execute()` kwds, for overriding USE_SHELL per command. + repo: replace blocky `communicate()` in `_clone()` with thread-pumps. + test_repo.py: unittestize (almost all) assertions. + Replace open --> with open for index (base and TC). + test_index.py: Enabled a dormant assertion. --- git/test/test_index.py | 35 ++++---- git/test/test_repo.py | 213 +++++++++++++++++++++++++-------------------- git/test/test_submodule.py | 3 +- 3 files changed, 136 insertions(+), 115 deletions(-) (limited to 'git/test') diff --git a/git/test/test_index.py b/git/test/test_index.py index 46cc990d..1ffbe9e2 100644 --- a/git/test/test_index.py +++ b/git/test/test_index.py @@ -113,9 +113,8 @@ class TestIndex(TestBase): # write the data - it must match the original tmpfile = tempfile.mktemp() index_merge.write(tmpfile) - fp = open(tmpfile, 'rb') - self.assertEqual(fp.read(), fixture("index_merge")) - fp.close() + with open(tmpfile, 'rb') as fp: + self.assertEqual(fp.read(), fixture("index_merge")) os.remove(tmpfile) def _cmp_tree_index(self, tree, index): @@ -329,22 +328,19 @@ class TestIndex(TestBase): # reset the working copy as well to current head,to pull 'back' as well new_data = b"will be reverted" file_path = os.path.join(rw_repo.working_tree_dir, "CHANGES") - fp = open(file_path, "wb") - fp.write(new_data) - fp.close() + with open(file_path, "wb") as fp: + fp.write(new_data) index.reset(rev_head_parent, working_tree=True) assert not index.diff(None) self.assertEqual(cur_branch, rw_repo.active_branch) self.assertEqual(cur_commit, rw_repo.head.commit) - fp = open(file_path, 'rb') - try: + with open(file_path, 'rb') as fp: assert fp.read() != new_data - finally: - fp.close() # test full checkout test_file = os.path.join(rw_repo.working_tree_dir, "CHANGES") - open(test_file, 'ab').write(b"some data") + with open(test_file, 'ab') as fd: + fd.write(b"some data") rval = index.checkout(None, force=True, fprogress=self._fprogress) assert 'CHANGES' in list(rval) self._assert_fprogress([None]) @@ -369,9 +365,8 @@ class TestIndex(TestBase): # checkout file with modifications append_data = b"hello" - fp = open(test_file, "ab") - fp.write(append_data) - fp.close() + with open(test_file, "ab") as fp: + fp.write(append_data) try: index.checkout(test_file) except CheckoutError as e: @@ -380,7 +375,9 @@ class TestIndex(TestBase): self.assertEqual(len(e.failed_files), len(e.failed_reasons)) self.assertIsInstance(e.failed_reasons[0], string_types) self.assertEqual(len(e.valid_files), 0) - assert open(test_file, 'rb').read().endswith(append_data) + with open(test_file, 'rb') as fd: + s = fd.read() + self.assertTrue(s.endswith(append_data), s) else: raise AssertionError("Exception CheckoutError not thrown") @@ -639,9 +636,10 @@ class TestIndex(TestBase): if is_win: # simlinks should contain the link as text ( which is what a # symlink actually is ) - open(fake_symlink_path, 'rb').read() == link_target + with open(fake_symlink_path, 'rt') as fd: + self.assertEqual(fd.read(), link_target) else: - assert S_ISLNK(os.lstat(fake_symlink_path)[ST_MODE]) + self.assertTrue(S_ISLNK(os.lstat(fake_symlink_path)[ST_MODE])) # TEST RENAMING def assert_mv_rval(rval): @@ -691,7 +689,8 @@ class TestIndex(TestBase): for fid in range(3): fname = 'newfile%i' % fid - open(fname, 'wb').write(b"abcd") + with open(fname, 'wb') as fd: + fd.write(b"abcd") yield Blob(rw_repo, Blob.NULL_BIN_SHA, 0o100644, fname) # END for each new file # END path producer diff --git a/git/test/test_repo.py b/git/test/test_repo.py index e2c18d3f..a37c9be9 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -7,6 +7,7 @@ import glob from io import BytesIO import itertools +import functools as fnt import os import pickle import sys @@ -29,7 +30,12 @@ from git import ( BadName, GitCommandError ) -from git.compat import string_types +from git.compat import ( + PY3, + is_win, + string_types, + win_encode, +) from git.exc import ( BadObject, ) @@ -93,10 +99,10 @@ class TestRepo(TestBase): @with_rw_repo('0.3.2.1') def test_repo_creation_from_different_paths(self, rw_repo): r_from_gitdir = Repo(rw_repo.git_dir) - assert r_from_gitdir.git_dir == rw_repo.git_dir + self.assertEqual(r_from_gitdir.git_dir, rw_repo.git_dir) assert r_from_gitdir.git_dir.endswith('.git') assert not rw_repo.git.working_dir.endswith('.git') - assert r_from_gitdir.git.working_dir == rw_repo.git.working_dir + self.assertEqual(r_from_gitdir.git.working_dir, rw_repo.git.working_dir) def test_description(self): txt = "Test repository" @@ -110,17 +116,17 @@ class TestRepo(TestBase): def test_heads_should_populate_head_data(self): for head in self.rorepo.heads: assert head.name - assert isinstance(head.commit, Commit) + self.assertIsInstance(head.commit, Commit) # END for each head - assert isinstance(self.rorepo.heads.master, Head) - assert isinstance(self.rorepo.heads['master'], Head) + self.assertIsInstance(self.rorepo.heads.master, Head) + self.assertIsInstance(self.rorepo.heads['master'], Head) def test_tree_from_revision(self): tree = self.rorepo.tree('0.1.6') - assert len(tree.hexsha) == 40 - assert tree.type == "tree" - assert self.rorepo.tree(tree) == tree + self.assertEqual(len(tree.hexsha), 40) + self.assertEqual(tree.type, "tree") + self.assertEqual(self.rorepo.tree(tree), tree) # try from invalid revision that does not exist self.failUnlessRaises(BadName, self.rorepo.tree, 'hello world') @@ -130,13 +136,13 @@ class TestRepo(TestBase): def test_commit_from_revision(self): commit = self.rorepo.commit('0.1.4') - assert commit.type == 'commit' - assert self.rorepo.commit(commit) == commit + self.assertEqual(commit.type, 'commit') + self.assertEqual(self.rorepo.commit(commit), commit) def test_commits(self): mc = 10 commits = list(self.rorepo.iter_commits('0.1.6', max_count=mc)) - assert len(commits) == mc + self.assertEqual(len(commits), mc) c = commits[0] assert_equal('9a4b1d4d11eee3c5362a4152216376e634bd14cf', c.hexsha) @@ -153,23 +159,23 @@ class TestRepo(TestBase): assert_equal("Bumped version 0.1.6\n", c.message) c = commits[1] - assert isinstance(c.parents, tuple) + self.assertIsInstance(c.parents, tuple) def test_trees(self): mc = 30 num_trees = 0 for tree in self.rorepo.iter_trees('0.1.5', max_count=mc): num_trees += 1 - assert isinstance(tree, Tree) + self.assertIsInstance(tree, Tree) # END for each tree - assert num_trees == mc + self.assertEqual(num_trees, mc) def _assert_empty_repo(self, repo): # test all kinds of things with an empty, freshly initialized repo. # It should throw good errors # entries should be empty - assert len(repo.index.entries) == 0 + self.assertEqual(len(repo.index.entries), 0) # head is accessible assert repo.head @@ -201,7 +207,7 @@ class TestRepo(TestBase): # with specific path for path in (git_dir_rela, git_dir_abs): r = Repo.init(path=path, bare=True) - assert isinstance(r, Repo) + self.assertIsInstance(r, Repo) assert r.bare is True assert not r.has_separate_working_tree() assert os.path.isdir(r.git_dir) @@ -257,18 +263,18 @@ class TestRepo(TestBase): def test_daemon_export(self): orig_val = self.rorepo.daemon_export self.rorepo.daemon_export = not orig_val - assert self.rorepo.daemon_export == (not orig_val) + self.assertEqual(self.rorepo.daemon_export, (not orig_val)) self.rorepo.daemon_export = orig_val - assert self.rorepo.daemon_export == orig_val + self.assertEqual(self.rorepo.daemon_export, orig_val) def test_alternates(self): cur_alternates = self.rorepo.alternates # empty alternates self.rorepo.alternates = [] - assert self.rorepo.alternates == [] + self.assertEqual(self.rorepo.alternates, []) alts = ["other/location", "this/location"] self.rorepo.alternates = alts - assert alts == self.rorepo.alternates + self.assertEqual(alts, self.rorepo.alternates) self.rorepo.alternates = cur_alternates def test_repr(self): @@ -313,11 +319,11 @@ class TestRepo(TestBase): assert rwrepo.is_dirty(untracked_files=True, path="doc") is True def test_head(self): - assert self.rorepo.head.reference.object == self.rorepo.active_branch.object + self.assertEqual(self.rorepo.head.reference.object, self.rorepo.active_branch.object) def test_index(self): index = self.rorepo.index - assert isinstance(index, IndexFile) + self.assertIsInstance(index, IndexFile) def test_tag(self): assert self.rorepo.tag('refs/tags/0.1.5').commit @@ -361,7 +367,7 @@ class TestRepo(TestBase): # BINARY BLAME git.return_value = fixture('blame_binary') blames = self.rorepo.blame('master', 'rps') - assert len(blames) == 2 + self.assertEqual(len(blames), 2) def test_blame_real(self): c = 0 @@ -381,32 +387,35 @@ class TestRepo(TestBase): git.return_value = fixture('blame_incremental') blame_output = self.rorepo.blame_incremental('9debf6b0aafb6f7781ea9d1383c86939a1aacde3', 'AUTHORS') blame_output = list(blame_output) - assert len(blame_output) == 5 + self.assertEqual(len(blame_output), 5) # Check all outputted line numbers ranges = flatten([entry.linenos for entry in blame_output]) - assert ranges == flatten([range(2, 3), range(14, 15), range(1, 2), range(3, 14), range(15, 17)]), str(ranges) + self.assertEqual(ranges, flatten([range(2, 3), range(14, 15), range(1, 2), range(3, 14), range(15, 17)])) commits = [entry.commit.hexsha[:7] for entry in blame_output] - assert commits == ['82b8902', '82b8902', 'c76852d', 'c76852d', 'c76852d'], str(commits) + self.assertEqual(commits, ['82b8902', '82b8902', 'c76852d', 'c76852d', 'c76852d']) # Original filenames - assert all([entry.orig_path == u'AUTHORS' for entry in blame_output]) + self.assertSequenceEqual([entry.orig_path for entry in blame_output], [u'AUTHORS'] * len(blame_output)) # Original line numbers orig_ranges = flatten([entry.orig_linenos for entry in blame_output]) - assert orig_ranges == flatten([range(2, 3), range(14, 15), range(1, 2), range(2, 13), range(13, 15)]), str(orig_ranges) # noqa + self.assertEqual(orig_ranges, flatten([range(2, 3), range(14, 15), range(1, 2), range(2, 13), range(13, 15)])) # noqa E501 @patch.object(Git, '_call_process') def test_blame_complex_revision(self, git): git.return_value = fixture('blame_complex_revision') res = self.rorepo.blame("HEAD~10..HEAD", "README.md") - assert len(res) == 1 - assert len(res[0][1]) == 83, "Unexpected amount of parsed blame lines" + self.assertEqual(len(res), 1) + self.assertEqual(len(res[0][1]), 83, "Unexpected amount of parsed blame lines") @with_rw_repo('HEAD', bare=False) def test_untracked_files(self, rwrepo): - for (run, repo_add) in enumerate((rwrepo.index.add, rwrepo.git.add)): + for run, (repo_add, is_invoking_git) in enumerate(( + (rwrepo.index.add, False), + (rwrepo.git.add, True), + )): base = rwrepo.working_tree_dir files = (join_path_native(base, u"%i_test _myfile" % run), join_path_native(base, "%i_test_other_file" % run), @@ -424,10 +433,15 @@ class TestRepo(TestBase): num_test_untracked = 0 for utfile in untracked_files: num_test_untracked += join_path_native(base, utfile) in files - assert len(files) == num_test_untracked + self.assertEqual(len(files), num_test_untracked) + if is_win and not PY3 and is_invoking_git: + ## On Windows, shell needed when passing unicode cmd-args. + # + repo_add = fnt.partial(repo_add, shell=True) + untracked_files = [win_encode(f) for f in untracked_files] repo_add(untracked_files) - assert len(rwrepo.untracked_files) == (num_recently_untracked - len(files)) + self.assertEqual(len(rwrepo.untracked_files), (num_recently_untracked - len(files))) # end for each run def test_config_reader(self): @@ -465,8 +479,9 @@ class TestRepo(TestBase): def test_comparison_and_hash(self): # this is only a preliminary test, more testing done in test_index - assert self.rorepo == self.rorepo and not (self.rorepo != self.rorepo) - assert len(set((self.rorepo, self.rorepo))) == 1 + self.assertEqual(self.rorepo, self.rorepo) + self.assertFalse(self.rorepo != self.rorepo) + self.assertEqual(len(set((self.rorepo, self.rorepo))), 1) @with_rw_directory def test_tilde_and_env_vars_in_repo_path(self, rw_dir): @@ -505,57 +520,59 @@ class TestRepo(TestBase): # readlines no limit s = mkfull() lines = s.readlines() - assert len(lines) == 3 and lines[-1].endswith(b'\n') - assert s._stream.tell() == len(d) # must have scrubbed to the end + self.assertEqual(len(lines), 3) + self.assertTrue(lines[-1].endswith(b'\n'), lines[-1]) + self.assertEqual(s._stream.tell(), len(d)) # must have scrubbed to the end # realines line limit s = mkfull() lines = s.readlines(5) - assert len(lines) == 1 + self.assertEqual(len(lines), 1) # readlines on tiny sections s = mktiny() lines = s.readlines() - assert len(lines) == 1 and lines[0] == l1p - assert s._stream.tell() == ts + 1 + self.assertEqual(len(lines), 1) + self.assertEqual(lines[0], l1p) + self.assertEqual(s._stream.tell(), ts + 1) # readline no limit s = mkfull() - assert s.readline() == l1 - assert s.readline() == l2 - assert s.readline() == l3 - assert s.readline() == b'' - assert s._stream.tell() == len(d) + self.assertEqual(s.readline(), l1) + self.assertEqual(s.readline(), l2) + self.assertEqual(s.readline(), l3) + self.assertEqual(s.readline(), b'') + self.assertEqual(s._stream.tell(), len(d)) # readline limit s = mkfull() - assert s.readline(5) == l1p - assert s.readline() == l1[5:] + self.assertEqual(s.readline(5), l1p) + self.assertEqual(s.readline(), l1[5:]) # readline on tiny section s = mktiny() - assert s.readline() == l1p - assert s.readline() == b'' - assert s._stream.tell() == ts + 1 + self.assertEqual(s.readline(), l1p) + self.assertEqual(s.readline(), b'') + self.assertEqual(s._stream.tell(), ts + 1) # read no limit s = mkfull() - assert s.read() == d[:-1] - assert s.read() == b'' - assert s._stream.tell() == len(d) + self.assertEqual(s.read(), d[:-1]) + self.assertEqual(s.read(), b'') + self.assertEqual(s._stream.tell(), len(d)) # read limit s = mkfull() - assert s.read(5) == l1p - assert s.read(6) == l1[5:] - assert s._stream.tell() == 5 + 6 # its not yet done + self.assertEqual(s.read(5), l1p) + self.assertEqual(s.read(6), l1[5:]) + self.assertEqual(s._stream.tell(), 5 + 6) # its not yet done # read tiny s = mktiny() - assert s.read(2) == l1[:2] - assert s._stream.tell() == 2 - assert s.read() == l1[2:ts] - assert s._stream.tell() == ts + 1 + self.assertEqual(s.read(2), l1[:2]) + self.assertEqual(s._stream.tell(), 2) + self.assertEqual(s.read(), l1[2:ts]) + self.assertEqual(s._stream.tell(), ts + 1) def _assert_rev_parse_types(self, name, rev_obj): rev_parse = self.rorepo.rev_parse @@ -565,11 +582,12 @@ class TestRepo(TestBase): # tree and blob type obj = rev_parse(name + '^{tree}') - assert obj == rev_obj.tree + self.assertEqual(obj, rev_obj.tree) obj = rev_parse(name + ':CHANGES') - assert obj.type == 'blob' and obj.path == 'CHANGES' - assert rev_obj.tree['CHANGES'] == obj + self.assertEqual(obj.type, 'blob') + self.assertEqual(obj.path, 'CHANGES') + self.assertEqual(rev_obj.tree['CHANGES'], obj) def _assert_rev_parse(self, name): """tries multiple different rev-parse syntaxes with the given name @@ -585,7 +603,7 @@ class TestRepo(TestBase): # try history rev = name + "~" obj2 = rev_parse(rev) - assert obj2 == obj.parents[0] + self.assertEqual(obj2, obj.parents[0]) self._assert_rev_parse_types(rev, obj2) # history with number @@ -598,20 +616,20 @@ class TestRepo(TestBase): for pn in range(11): rev = name + "~%i" % (pn + 1) obj2 = rev_parse(rev) - assert obj2 == history[pn] + self.assertEqual(obj2, history[pn]) self._assert_rev_parse_types(rev, obj2) # END history check # parent ( default ) rev = name + "^" obj2 = rev_parse(rev) - assert obj2 == obj.parents[0] + self.assertEqual(obj2, obj.parents[0]) self._assert_rev_parse_types(rev, obj2) # parent with number for pn, parent in enumerate(obj.parents): rev = name + "^%i" % (pn + 1) - assert rev_parse(rev) == parent + self.assertEqual(rev_parse(rev), parent) self._assert_rev_parse_types(rev, parent) # END for each parent @@ -627,7 +645,7 @@ class TestRepo(TestBase): rev_parse = self.rorepo.rev_parse # try special case: This one failed at some point, make sure its fixed - assert rev_parse("33ebe").hexsha == "33ebe7acec14b25c5f84f35a664803fcab2f7781" + self.assertEqual(rev_parse("33ebe").hexsha, "33ebe7acec14b25c5f84f35a664803fcab2f7781") # start from reference num_resolved = 0 @@ -638,7 +656,7 @@ class TestRepo(TestBase): path_section = '/'.join(path_tokens[-(pt + 1):]) try: obj = self._assert_rev_parse(path_section) - assert obj.type == ref.object.type + self.assertEqual(obj.type, ref.object.type) num_resolved += 1 except (BadName, BadObject): print("failed on %s" % path_section) @@ -653,31 +671,31 @@ class TestRepo(TestBase): # it works with tags ! tag = self._assert_rev_parse('0.1.4') - assert tag.type == 'tag' + self.assertEqual(tag.type, 'tag') # try full sha directly ( including type conversion ) - assert tag.object == rev_parse(tag.object.hexsha) + self.assertEqual(tag.object, rev_parse(tag.object.hexsha)) self._assert_rev_parse_types(tag.object.hexsha, tag.object) # multiple tree types result in the same tree: HEAD^{tree}^{tree}:CHANGES rev = '0.1.4^{tree}^{tree}' - assert rev_parse(rev) == tag.object.tree - assert rev_parse(rev + ':CHANGES') == tag.object.tree['CHANGES'] + self.assertEqual(rev_parse(rev), tag.object.tree) + self.assertEqual(rev_parse(rev + ':CHANGES'), tag.object.tree['CHANGES']) # try to get parents from first revision - it should fail as no such revision # exists first_rev = "33ebe7acec14b25c5f84f35a664803fcab2f7781" commit = rev_parse(first_rev) - assert len(commit.parents) == 0 - assert commit.hexsha == first_rev + self.assertEqual(len(commit.parents), 0) + self.assertEqual(commit.hexsha, first_rev) self.failUnlessRaises(BadName, rev_parse, first_rev + "~") self.failUnlessRaises(BadName, rev_parse, first_rev + "^") # short SHA1 commit2 = rev_parse(first_rev[:20]) - assert commit2 == commit + self.assertEqual(commit2, commit) commit2 = rev_parse(first_rev[:5]) - assert commit2 == commit + self.assertEqual(commit2, commit) # todo: dereference tag into a blob 0.1.7^{blob} - quite a special one # needs a tag which points to a blob @@ -685,13 +703,13 @@ class TestRepo(TestBase): # ref^0 returns commit being pointed to, same with ref~0, and ^{} tag = rev_parse('0.1.4') for token in (('~0', '^0', '^{}')): - assert tag.object == rev_parse('0.1.4%s' % token) + self.assertEqual(tag.object, rev_parse('0.1.4%s' % token)) # END handle multiple tokens # try partial parsing max_items = 40 for i, binsha in enumerate(self.rorepo.odb.sha_iter()): - assert rev_parse(bin_to_hex(binsha)[:8 - (i % 2)].decode('ascii')).binsha == binsha + self.assertEqual(rev_parse(bin_to_hex(binsha)[:8 - (i % 2)].decode('ascii')).binsha, binsha) if i > max_items: # this is rather slow currently, as rev_parse returns an object # which requires accessing packs, it has some additional overhead @@ -712,13 +730,13 @@ class TestRepo(TestBase): self.failUnlessRaises(BadObject, rev_parse, "%s@{0}" % head.commit.hexsha) # uses HEAD.ref by default - assert rev_parse('@{0}') == head.commit + self.assertEqual(rev_parse('@{0}'), head.commit) if not head.is_detached: refspec = '%s@{0}' % head.ref.name - assert rev_parse(refspec) == head.ref.commit + self.assertEqual(rev_parse(refspec), head.ref.commit) # all additional specs work as well - assert rev_parse(refspec + "^{tree}") == head.commit.tree - assert rev_parse(refspec + ":CHANGES").type == 'blob' + self.assertEqual(rev_parse(refspec + "^{tree}"), head.commit.tree) + self.assertEqual(rev_parse(refspec + ":CHANGES").type, 'blob') # END operate on non-detached head # position doesn't exist @@ -734,13 +752,13 @@ class TestRepo(TestBase): target_type = GitCmdObjectDB if sys.version_info[:2] < (2, 5): target_type = GitCmdObjectDB - assert isinstance(self.rorepo.odb, target_type) + self.assertIsInstance(self.rorepo.odb, target_type) def test_submodules(self): - assert len(self.rorepo.submodules) == 1 # non-recursive - assert len(list(self.rorepo.iter_submodules())) >= 2 + self.assertEqual(len(self.rorepo.submodules), 1) # non-recursive + self.assertGreaterEqual(len(list(self.rorepo.iter_submodules())), 2) - assert isinstance(self.rorepo.submodule("gitdb"), Submodule) + self.assertIsInstance(self.rorepo.submodule("gitdb"), Submodule) self.failUnlessRaises(ValueError, self.rorepo.submodule, "doesn't exist") @with_rw_repo('HEAD', bare=False) @@ -753,7 +771,7 @@ class TestRepo(TestBase): # test create submodule sm = rwrepo.submodules[0] sm = rwrepo.create_submodule("my_new_sub", "some_path", join_path_native(self.rorepo.working_tree_dir, sm.path)) - assert isinstance(sm, Submodule) + self.assertIsInstance(sm, Submodule) # note: the rest of this functionality is tested in test_submodule @@ -767,12 +785,12 @@ class TestRepo(TestBase): # Create a repo and make sure it's pointing to the relocated .git directory. git_file_repo = Repo(rwrepo.working_tree_dir) - assert os.path.abspath(git_file_repo.git_dir) == real_path_abs + self.assertEqual(os.path.abspath(git_file_repo.git_dir), real_path_abs) # Test using an absolute gitdir path in the .git file. open(git_file_path, 'wb').write(('gitdir: %s\n' % real_path_abs).encode('ascii')) git_file_repo = Repo(rwrepo.working_tree_dir) - assert os.path.abspath(git_file_repo.git_dir) == real_path_abs + self.assertEqual(os.path.abspath(git_file_repo.git_dir), real_path_abs) def test_file_handle_leaks(self): def last_commit(repo, rev, path): @@ -793,7 +811,7 @@ class TestRepo(TestBase): def test_remote_method(self): self.failUnlessRaises(ValueError, self.rorepo.remote, 'foo-blue') - assert isinstance(self.rorepo.remote(name='origin'), Remote) + self.assertIsInstance(self.rorepo.remote(name='origin'), Remote) @with_rw_directory def test_empty_repo(self, rw_dir): @@ -801,7 +819,7 @@ class TestRepo(TestBase): r = Repo.init(rw_dir, mkdir=False) # It's ok not to be able to iterate a commit, as there is none self.failUnlessRaises(ValueError, r.iter_commits) - assert r.active_branch.name == 'master' + self.assertEqual(r.active_branch.name, 'master') assert not r.active_branch.is_valid(), "Branch is yet to be born" # actually, when trying to create a new branch without a commit, git itself fails @@ -841,12 +859,15 @@ class TestRepo(TestBase): # two commit merge-base res = repo.merge_base(c1, c2) - assert isinstance(res, list) and len(res) == 1 and isinstance(res[0], Commit) - assert res[0].hexsha.startswith('3936084') + self.assertIsInstance(res, list) + self.assertEqual(len(res), 1) + self.assertIsInstance(res[0], Commit) + self.assertTrue(res[0].hexsha.startswith('3936084')) for kw in ('a', 'all'): res = repo.merge_base(c1, c2, c3, **{kw: True}) - assert isinstance(res, list) and len(res) == 1 + self.assertIsInstance(res, list) + self.assertEqual(len(res), 1) # end for each keyword signalling all merge-bases to be returned # Test for no merge base - can't do as we have diff --git a/git/test/test_submodule.py b/git/test/test_submodule.py index dcfe9216..8e2829b2 100644 --- a/git/test/test_submodule.py +++ b/git/test/test_submodule.py @@ -309,7 +309,8 @@ class TestSubmodule(TestBase): # but ... we have untracked files in the child submodule fn = join_path_native(csm.module().working_tree_dir, "newfile") - open(fn, 'w').write("hi") + with open(fn, 'w') as fd: + fd.write("hi") self.failUnlessRaises(InvalidGitRepositoryError, sm.remove) # forcibly delete the child repository -- cgit v1.2.3 From 9a521681ff8614beb8e2c566cf3c475baca22169 Mon Sep 17 00:00:00 2001 From: Kostis Anagnostopoulos Date: Sat, 1 Oct 2016 18:20:13 +0200 Subject: io, #519: ALL open() --> with open() + Some cases had restructuring of code. --- git/test/fixtures/cat_file.py | 7 ++++--- git/test/lib/helper.py | 8 ++++---- git/test/test_base.py | 13 ++++++------- git/test/test_commit.py | 6 ++++-- git/test/test_docs.py | 3 ++- git/test/test_git.py | 14 ++++++-------- git/test/test_remote.py | 4 ++-- git/test/test_repo.py | 6 ++++-- 8 files changed, 32 insertions(+), 29 deletions(-) (limited to 'git/test') diff --git a/git/test/fixtures/cat_file.py b/git/test/fixtures/cat_file.py index 2f1b915a..5480e628 100644 --- a/git/test/fixtures/cat_file.py +++ b/git/test/fixtures/cat_file.py @@ -1,5 +1,6 @@ import sys -for line in open(sys.argv[1]).readlines(): - sys.stdout.write(line) - sys.stderr.write(line) +with open(sys.argv[1]) as fd: + for line in fd.readlines(): + sys.stdout.write(line) + sys.stderr.write(line) diff --git a/git/test/lib/helper.py b/git/test/lib/helper.py index 90d2b1e9..a85ac2fd 100644 --- a/git/test/lib/helper.py +++ b/git/test/lib/helper.py @@ -39,7 +39,8 @@ def fixture_path(name): def fixture(name): - return open(fixture_path(name), 'rb').read() + with open(fixture_path(name), 'rb') as fd: + return fd.read() def absolute_project_path(): @@ -373,7 +374,6 @@ class TestBase(TestCase): """ repo = repo or self.rorepo abs_path = os.path.join(repo.working_tree_dir, rela_path) - fp = open(abs_path, "w") - fp.write(data) - fp.close() + with open(abs_path, "w") as fp: + fp.write(data) return abs_path diff --git a/git/test/test_base.py b/git/test/test_base.py index fa0bebca..e5e8f173 100644 --- a/git/test/test_base.py +++ b/git/test/test_base.py @@ -77,13 +77,11 @@ class TestBase(TestBase): assert data tmpfilename = tempfile.mktemp(suffix='test-stream') - tmpfile = open(tmpfilename, 'wb+') - assert item == item.stream_data(tmpfile) - tmpfile.seek(0) - assert tmpfile.read() == data - tmpfile.close() + with open(tmpfilename, 'wb+') as tmpfile: + assert item == item.stream_data(tmpfile) + tmpfile.seek(0) + assert tmpfile.read() == data os.remove(tmpfilename) - # END stream to file directly # END for each object type to create # each has a unique sha @@ -133,7 +131,8 @@ class TestBase(TestBase): from nose import SkipTest raise SkipTest("Environment doesn't support unicode filenames") - open(file_path, "wb").write(b'something') + with open(file_path, "wb") as fp: + fp.write(b'something') if is_win: # on windows, there is no way this works, see images on diff --git a/git/test/test_commit.py b/git/test/test_commit.py index 33f8081c..66d988a3 100644 --- a/git/test/test_commit.py +++ b/git/test/test_commit.py @@ -313,14 +313,16 @@ class TestCommit(TestBase): def test_invalid_commit(self): cmt = self.rorepo.commit() - cmt._deserialize(open(fixture_path('commit_invalid_data'), 'rb')) + with open(fixture_path('commit_invalid_data'), 'rb') as fd: + cmt._deserialize(fd) self.assertEqual(cmt.author.name, u'E.Azer Ko�o�o�oculu', cmt.author.name) self.assertEqual(cmt.author.email, 'azer@kodfabrik.com', cmt.author.email) def test_gpgsig(self): cmt = self.rorepo.commit() - cmt._deserialize(open(fixture_path('commit_with_gpgsig'), 'rb')) + with open(fixture_path('commit_with_gpgsig'), 'rb') as fd: + cmt._deserialize(fd) fixture_sig = """-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) diff --git a/git/test/test_docs.py b/git/test/test_docs.py index a6e92543..8a2dff0f 100644 --- a/git/test/test_docs.py +++ b/git/test/test_docs.py @@ -53,7 +53,8 @@ class Tutorials(TestBase): # ![5-test_init_repo_object] # [6-test_init_repo_object] - repo.archive(open(join(rw_dir, 'repo.tar'), 'wb')) + with open(join(rw_dir, 'repo.tar'), 'wb') as fp: + repo.archive(fp) # ![6-test_init_repo_object] # repository paths diff --git a/git/test/test_git.py b/git/test/test_git.py index 8a0242e6..94614cd1 100644 --- a/git/test/test_git.py +++ b/git/test/test_git.py @@ -93,10 +93,9 @@ class TestGit(TestBase): def test_it_accepts_stdin(self): filename = fixture_path("cat_file_blob") - fh = open(filename, 'r') - assert_equal("70c379b63ffa0795fdbfbc128e5a2818397b7ef8", - self.git.hash_object(istream=fh, stdin=True)) - fh.close() + with open(filename, 'r') as fh: + assert_equal("70c379b63ffa0795fdbfbc128e5a2818397b7ef8", + self.git.hash_object(istream=fh, stdin=True)) @patch.object(Git, 'execute') def test_it_ignores_false_kwargs(self, git): @@ -200,10 +199,9 @@ class TestGit(TestBase): self.assertEqual(self.git.environment(), {}) path = os.path.join(rw_dir, 'failing-script.sh') - stream = open(path, 'wt') - stream.write("#!/usr/bin/env sh\n" + - "echo FOO\n") - stream.close() + with open(path, 'wt') as stream: + stream.write("#!/usr/bin/env sh\n" + "echo FOO\n") os.chmod(path, 0o777) rw_repo = Repo.init(os.path.join(rw_dir, 'repo')) diff --git a/git/test/test_remote.py b/git/test/test_remote.py index 05de4ae2..b99e49cf 100644 --- a/git/test/test_remote.py +++ b/git/test/test_remote.py @@ -105,8 +105,8 @@ class TestRemote(TestBase): gc.collect() def _print_fetchhead(self, repo): - fp = open(os.path.join(repo.git_dir, "FETCH_HEAD")) - fp.close() + with open(os.path.join(repo.git_dir, "FETCH_HEAD")): + pass def _do_test_fetch_result(self, results, remote): # self._print_fetchhead(remote.repo) diff --git a/git/test/test_repo.py b/git/test/test_repo.py index a37c9be9..349d955e 100644 --- a/git/test/test_repo.py +++ b/git/test/test_repo.py @@ -781,14 +781,16 @@ class TestRepo(TestBase): real_path_abs = os.path.abspath(join_path_native(rwrepo.working_tree_dir, '.real')) os.rename(rwrepo.git_dir, real_path_abs) git_file_path = join_path_native(rwrepo.working_tree_dir, '.git') - open(git_file_path, 'wb').write(fixture('git_file')) + with open(git_file_path, 'wb') as fp: + fp.write(fixture('git_file')) # Create a repo and make sure it's pointing to the relocated .git directory. git_file_repo = Repo(rwrepo.working_tree_dir) self.assertEqual(os.path.abspath(git_file_repo.git_dir), real_path_abs) # Test using an absolute gitdir path in the .git file. - open(git_file_path, 'wb').write(('gitdir: %s\n' % real_path_abs).encode('ascii')) + with open(git_file_path, 'wb') as fp: + fp.write(('gitdir: %s\n' % real_path_abs).encode('ascii')) git_file_repo = Repo(rwrepo.working_tree_dir) self.assertEqual(os.path.abspath(git_file_repo.git_dir), real_path_abs) -- cgit v1.2.3