Skip to content

Commit

Permalink
test, gitpython-developers#525: allow disabling freeze errors separately
Browse files Browse the repository at this point in the history
+ cmd: use DEVNULL for non PIPEs; no open-file.
+ TCs: some unitestize-assertions on base & remote TCs.
  • Loading branch information
ankostis committed Oct 12, 2016
1 parent c485e66 commit c6b0a0a
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 69 deletions.
4 changes: 2 additions & 2 deletions git/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,9 @@ def execute(self, command,
bufsize=-1,
stdin=istream,
stderr=PIPE,
stdout=PIPE if with_stdout else open(os.devnull, 'wb'),
stdout=PIPE if with_stdout else subprocess.DEVNULL,
shell=shell is not None and shell or self.USE_SHELL,
close_fds=(is_posix), # unsupported on windows
close_fds=is_posix, # unsupported on windows
universal_newlines=universal_newlines,
creationflags=PROC_CREATIONFLAGS,
**subprocess_kwargs
Expand Down
27 changes: 13 additions & 14 deletions git/test/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from git.objects.util import get_object_type_by_name
from gitdb.util import hex_to_bin
from git.compat import is_win
from git.util import HIDE_WINDOWS_KNOWN_ERRORS


class TestBase(TestBase):
Expand All @@ -42,7 +41,7 @@ def tearDown(self):
def test_base_object(self):
# test interface of base object classes
types = (Blob, Tree, Commit, TagObject)
assert len(types) == len(self.type_tuples)
self.assertEqual(len(types), len(self.type_tuples))

s = set()
num_objs = 0
Expand All @@ -56,12 +55,12 @@ def test_base_object(self):
item = obj_type(self.rorepo, binsha, 0, path)
# END handle index objects
num_objs += 1
assert item.hexsha == hexsha
assert item.type == typename
self.assertEqual(item.hexsha, hexsha)
self.assertEqual(item.type, typename)
assert item.size
assert item == item
assert not item != item
assert str(item) == item.hexsha
self.assertEqual(item, item)
self.assertNotEqual(not item, item)
self.assertEqual(str(item), item.hexsha)
assert repr(item)
s.add(item)

Expand All @@ -79,16 +78,16 @@ def test_base_object(self):

tmpfilename = tempfile.mktemp(suffix='test-stream')
with open(tmpfilename, 'wb+') as tmpfile:
assert item == item.stream_data(tmpfile)
self.assertEqual(item, item.stream_data(tmpfile))
tmpfile.seek(0)
assert tmpfile.read() == data
self.assertEqual(tmpfile.read(), data)
os.remove(tmpfilename)
# END for each object type to create

# each has a unique sha
assert len(s) == num_objs
assert len(s | s) == num_objs
assert num_index_objs == 2
self.assertEqual(len(s), num_objs)
self.assertEqual(len(s | s), num_objs)
self.assertEqual(num_index_objs, 2)

def test_get_object_type_by_name(self):
for tname in base.Object.TYPES:
Expand All @@ -99,7 +98,7 @@ def test_get_object_type_by_name(self):

def test_object_resolution(self):
# objects must be resolved to shas so they compare equal
assert self.rorepo.head.reference.object == self.rorepo.active_branch.object
self.assertEqual(self.rorepo.head.reference.object, self.rorepo.active_branch.object)

@with_rw_repo('HEAD', bare=True)
def test_with_bare_rw_repo(self, bare_rw_repo):
Expand All @@ -111,7 +110,7 @@ def test_with_rw_repo(self, rw_repo):
assert not rw_repo.config_reader("repository").getboolean("core", "bare")
assert os.path.isdir(os.path.join(rw_repo.working_tree_dir, 'lib'))

@skipIf(HIDE_WINDOWS_KNOWN_ERRORS, "FIXME: Freezes!")
#@skipIf(HIDE_WINDOWS_FREEZE_ERRORS, "FIXME: Freezes! sometimes...")
def test_with_rw_remote_and_rw_repo(self):
with rw_and_rw_remote_repos(self.rorepo, '0.1.6') as (rw_repo, rw_remote_repo):
assert not rw_repo.config_reader("repository").getboolean("core", "bare")
Expand Down
111 changes: 58 additions & 53 deletions git/test/test_remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,10 @@
# 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 (
TestBase,
with_rw_repo,
rw_and_rw_remote_repos,
fixture,
GIT_DAEMON_PORT,
assert_raises
)
import random
import tempfile
from unittest.case import skipIf

from git import (
RemoteProgress,
FetchInfo,
Expand All @@ -25,14 +21,19 @@
Remote,
GitCommandError
)
from git.util import IterableList, rmtree
from git.cmd import Git
from git.compat import string_types
import tempfile
from git.test.lib import (
TestBase,
with_rw_repo,
rw_and_rw_remote_repos,
fixture,
GIT_DAEMON_PORT,
assert_raises
)
from git.util import IterableList, rmtree, HIDE_WINDOWS_FREEZE_ERRORS
import os.path as osp
import random
from unittest.case import skipIf
from git.util import HIDE_WINDOWS_KNOWN_ERRORS
from git.cmd import Git


# assure we have repeatable results
random.seed(0)
Expand Down Expand Up @@ -213,7 +214,7 @@ def get_info(res, remote, name):
new_remote_branch.rename("other_branch_name")
res = fetch_and_test(remote)
other_branch_info = get_info(res, remote, new_remote_branch)
assert other_branch_info.ref.commit == new_branch_info.ref.commit
self.assertEqual(other_branch_info.ref.commit, new_branch_info.ref.commit)

# remove new branch
Head.delete(new_remote_branch.repo, new_remote_branch)
Expand All @@ -223,34 +224,37 @@ def get_info(res, remote, name):

# prune stale tracking branches
stale_refs = remote.stale_refs
assert len(stale_refs) == 2 and isinstance(stale_refs[0], RemoteReference)
self.assertEqual(len(stale_refs), 2)
self.assertIsInstance(stale_refs[0], RemoteReference)
RemoteReference.delete(rw_repo, *stale_refs)

# test single branch fetch with refspec including target remote
res = fetch_and_test(remote, refspec="master:refs/remotes/%s/master" % remote)
assert len(res) == 1 and get_info(res, remote, 'master')
self.assertEqual(len(res), 1)
self.assertTrue(get_info(res, remote, 'master'))

# ... with respec and no target
res = fetch_and_test(remote, refspec='master')
assert len(res) == 1
self.assertEqual(len(res), 1)

# ... multiple refspecs ... works, but git command returns with error if one ref is wrong without
# doing anything. This is new in later binaries
# res = fetch_and_test(remote, refspec=['master', 'fred'])
# assert len(res) == 1
# self.assertEqual(len(res), 1)

# add new tag reference
rtag = TagReference.create(remote_repo, "1.0-RV_hello.there")
res = fetch_and_test(remote, tags=True)
tinfo = res[str(rtag)]
assert isinstance(tinfo.ref, TagReference) and tinfo.ref.commit == rtag.commit
self.assertIsInstance(tinfo.ref, TagReference)
self.assertEqual(tinfo.ref.commit, rtag.commit)
assert tinfo.flags & tinfo.NEW_TAG

# adjust tag commit
Reference.set_object(rtag, rhead.commit.parents[0].parents[0])
res = fetch_and_test(remote, tags=True)
tinfo = res[str(rtag)]
assert tinfo.commit == rtag.commit
self.assertEqual(tinfo.commit, rtag.commit)
assert tinfo.flags & tinfo.TAG_UPDATE

# delete remote tag - local one will stay
Expand Down Expand Up @@ -326,7 +330,7 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo):

# force rejected pull
res = remote.push('+%s' % lhead.reference)
assert res[0].flags & PushInfo.ERROR == 0
self.assertEqual(res[0].flags & PushInfo.ERROR, 0)
assert res[0].flags & PushInfo.FORCED_UPDATE
self._do_test_push_result(res, remote)

Expand All @@ -352,7 +356,8 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo):

# push force this tag
res = remote.push("+%s" % new_tag.path)
assert res[-1].flags & PushInfo.ERROR == 0 and res[-1].flags & PushInfo.FORCED_UPDATE
self.assertEqual(res[-1].flags & PushInfo.ERROR, 0)
self.assertTrue(res[-1].flags & PushInfo.FORCED_UPDATE)

# delete tag - have to do it using refspec
res = remote.push(":%s" % new_tag.path)
Expand Down Expand Up @@ -388,7 +393,7 @@ def _assert_push_and_pull(self, remote, rw_repo, remote_repo):
TagReference.delete(rw_repo, new_tag, other_tag)
remote.push(":%s" % other_tag.path)

@skipIf(HIDE_WINDOWS_KNOWN_ERRORS, "FIXME: Freezes!")
@skipIf(HIDE_WINDOWS_FREEZE_ERRORS, "FIXME: Freezes!")
def test_base(self):
with rw_and_rw_remote_repos(self.rorepo, '0.1.6') as (rw_repo, remote_repo):
num_remotes = 0
Expand All @@ -397,7 +402,7 @@ def test_base(self):

for remote in rw_repo.remotes:
num_remotes += 1
assert remote == remote
self.assertEqual(remote, remote)
assert str(remote) != repr(remote)
remote_set.add(remote)
remote_set.add(remote) # should already exist
Expand All @@ -406,7 +411,7 @@ def test_base(self):
refs = remote.refs
assert refs
for ref in refs:
assert ref.remote_name == remote.name
self.assertEqual(ref.remote_name, remote.name)
assert ref.remote_head
# END for each ref

Expand All @@ -415,8 +420,8 @@ def test_base(self):
for opt in ("url",):
val = getattr(remote, opt)
reader = remote.config_reader
assert reader.get(opt) == val
assert reader.get_value(opt, None) == val
self.assertEqual(reader.get(opt), val)
self.assertEqual(reader.get_value(opt, None), val)

# unable to write with a reader
self.failUnlessRaises(IOError, reader.set, opt, "test")
Expand All @@ -425,20 +430,20 @@ def test_base(self):
with remote.config_writer as writer:
new_val = "myval"
writer.set(opt, new_val)
assert writer.get(opt) == new_val
self.assertEqual(writer.get(opt), new_val)
writer.set(opt, val)
assert writer.get(opt) == val
assert getattr(remote, opt) == val
self.assertEqual(writer.get(opt), val)
self.assertEqual(getattr(remote, opt), val)
# END for each default option key

# RENAME
other_name = "totally_other_name"
prev_name = remote.name
assert remote.rename(other_name) == remote
self.assertEqual(remote.rename(other_name), remote)
assert prev_name != remote.name
# multiple times
for _ in range(2):
assert remote.rename(prev_name).name == prev_name
self.assertEqual(remote.rename(prev_name).name, prev_name)
# END for each rename ( back to prev_name )

# PUSH/PULL TESTING
Expand All @@ -457,10 +462,10 @@ def test_base(self):

assert ran_fetch_test
assert num_remotes
assert num_remotes == len(remote_set)
self.assertEqual(num_remotes, len(remote_set))

origin = rw_repo.remote('origin')
assert origin == rw_repo.remotes.origin
self.assertEqual(origin, rw_repo.remotes.origin)

# Verify we can handle prunes when fetching
# stderr lines look like this: x [deleted] (none) -> origin/experiment-2012
Expand All @@ -478,14 +483,14 @@ def test_base(self):
# end
# end for each branch
assert num_deleted > 0
assert len(rw_repo.remotes.origin.fetch(prune=True)) == 1, "deleted everything but master"
self.assertEqual(len(rw_repo.remotes.origin.fetch(prune=True)), 1, "deleted everything but master")

@with_rw_repo('HEAD', bare=True)
def test_creation_and_removal(self, bare_rw_repo):
new_name = "test_new_one"
arg_list = (new_name, "git@server:hello.git")
remote = Remote.create(bare_rw_repo, *arg_list)
assert remote.name == "test_new_one"
self.assertEqual(remote.name, "test_new_one")
assert remote in bare_rw_repo.remotes
assert remote.exists()

Expand Down Expand Up @@ -520,7 +525,7 @@ def test_fetch_info(self):
remote_info_line_fmt % "local/master",
fetch_info_line_fmt % 'remote-tracking branch')
assert not fi.ref.is_valid()
assert fi.ref.name == "local/master"
self.assertEqual(fi.ref.name, "local/master")

# handles non-default refspecs: One can specify a different path in refs/remotes
# or a special path just in refs/something for instance
Expand All @@ -547,23 +552,23 @@ def test_fetch_info(self):
fetch_info_line_fmt % 'tag')

assert isinstance(fi.ref, TagReference)
assert fi.ref.path == tag_path
self.assertEqual(fi.ref.path, tag_path)

# branches default to refs/remotes
fi = FetchInfo._from_line(self.rorepo,
remote_info_line_fmt % "remotename/branch",
fetch_info_line_fmt % 'branch')

assert isinstance(fi.ref, RemoteReference)
assert fi.ref.remote_name == 'remotename'
self.assertEqual(fi.ref.remote_name, 'remotename')

# but you can force it anywhere, in which case we only have a references
fi = FetchInfo._from_line(self.rorepo,
remote_info_line_fmt % "refs/something/branch",
fetch_info_line_fmt % 'branch')

assert type(fi.ref) is Reference
assert fi.ref.path == "refs/something/branch"
self.assertEqual(fi.ref.path, "refs/something/branch")

def test_uncommon_branch_names(self):
stderr_lines = fixture('uncommon_branch_prefix_stderr').decode('ascii').splitlines()
Expand All @@ -574,8 +579,8 @@ def test_uncommon_branch_names(self):
res = [FetchInfo._from_line('ShouldntMatterRepo', stderr, fetch_line)
for stderr, fetch_line in zip(stderr_lines, fetch_lines)]
assert len(res)
assert res[0].remote_ref_path == 'refs/pull/1/head'
assert res[0].ref.path == 'refs/heads/pull/1/head'
self.assertEqual(res[0].remote_ref_path, 'refs/pull/1/head')
self.assertEqual(res[0].ref.path, 'refs/heads/pull/1/head')
assert isinstance(res[0].ref, Head)

@with_rw_repo('HEAD', bare=False)
Expand All @@ -588,36 +593,36 @@ def test_multiple_urls(self, rw_repo):
remote = rw_repo.remotes[0]
# Testing setting a single URL
remote.set_url(test1)
assert list(remote.urls) == [test1]
self.assertEqual(list(remote.urls), [test1])

# Testing replacing that single URL
remote.set_url(test1)
assert list(remote.urls) == [test1]
self.assertEqual(list(remote.urls), [test1])
# Testing adding new URLs
remote.set_url(test2, add=True)
assert list(remote.urls) == [test1, test2]
self.assertEqual(list(remote.urls), [test1, test2])
remote.set_url(test3, add=True)
assert list(remote.urls) == [test1, test2, test3]
self.assertEqual(list(remote.urls), [test1, test2, test3])
# Testing removing an URL
remote.set_url(test2, delete=True)
assert list(remote.urls) == [test1, test3]
self.assertEqual(list(remote.urls), [test1, test3])
# Testing changing an URL
remote.set_url(test3, test2)
assert list(remote.urls) == [test1, test2]
self.assertEqual(list(remote.urls), [test1, test2])

# will raise: fatal: --add --delete doesn't make sense
assert_raises(GitCommandError, remote.set_url, test2, add=True, delete=True)

# Testing on another remote, with the add/delete URL
remote = rw_repo.create_remote('another', url=test1)
remote.add_url(test2)
assert list(remote.urls) == [test1, test2]
self.assertEqual(list(remote.urls), [test1, test2])
remote.add_url(test3)
assert list(remote.urls) == [test1, test2, test3]
self.assertEqual(list(remote.urls), [test1, test2, test3])
# Testing removing all the URLs
remote.delete_url(test2)
assert list(remote.urls) == [test1, test3]
self.assertEqual(list(remote.urls), [test1, test3])
remote.delete_url(test1)
assert list(remote.urls) == [test3]
self.assertEqual(list(remote.urls), [test3])
# will raise fatal: Will not delete all non-push URLs
assert_raises(GitCommandError, remote.delete_url, test3)
1 change: 1 addition & 0 deletions git/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#: so the errors marked with this var are considered "acknowledged" ones, awaiting remedy,
#: till then, we wish to hide them.
HIDE_WINDOWS_KNOWN_ERRORS = is_win and os.environ.get('HIDE_WINDOWS_KNOWN_ERRORS', True)
HIDE_WINDOWS_FREEZE_ERRORS = is_win and os.environ.get('HIDE_WINDOWS_FREEZE_ERRORS', HIDE_WINDOWS_KNOWN_ERRORS)

#{ Utility Methods

Expand Down

0 comments on commit c6b0a0a

Please sign in to comment.