Skip to content

Commit

Permalink
Merge pull request #157 from nicoddemus/fix-windows
Browse files Browse the repository at this point in the history
Fix windows
  • Loading branch information
nicoddemus committed Nov 9, 2017
2 parents 72601dc + 2d30cde commit e5f9547
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 23 deletions.
17 changes: 11 additions & 6 deletions py/_path/local.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,14 +781,15 @@ def _gethomedir(cls):
# """
# special class constructors for local filesystem paths
# """
@classmethod
def get_temproot(cls):
""" return the system's temporary directory
(where tempfiles are usually created in)
"""
import tempfile
return py.path.local(tempfile.gettempdir())
get_temproot = classmethod(get_temproot)

@classmethod
def mkdtemp(cls, rootdir=None):
""" return a Path object pointing to a fresh new temporary directory
(which we created ourself).
Expand All @@ -797,7 +798,6 @@ def mkdtemp(cls, rootdir=None):
if rootdir is None:
rootdir = cls.get_temproot()
return cls(py.error.checked_call(tempfile.mkdtemp, dir=str(rootdir)))
mkdtemp = classmethod(mkdtemp)

def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3,
lock_timeout = 172800): # two days
Expand Down Expand Up @@ -827,7 +827,9 @@ def create_lockfile(path):
if hasattr(lockfile, 'mksymlinkto'):
lockfile.mksymlinkto(str(mypid))
else:
lockfile.write(str(mypid), 'wx')
fd = py.error.checked_call(os.open, str(lockfile), os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o644)
with os.fdopen(fd, 'w') as f:
f.write(str(mypid))
return lockfile

def atexit_remove_lockfile(lockfile):
Expand Down Expand Up @@ -862,12 +864,15 @@ def try_remove_lockfile():
if lock_timeout:
lockfile = create_lockfile(udir)
atexit_remove_lockfile(lockfile)
except (py.error.EEXIST, py.error.ENOENT):
except (py.error.EEXIST, py.error.ENOENT, py.error.EBUSY):
# race condition (1): another thread/process created the dir
# in the meantime - try again
# race condition (2): another thread/process spuriously acquired
# lock treating empty directory as candidate
# for removal - try again
# race condition (3): another thread/process tried to create the lock at
# the same time (happened in Python 3.3 on Windows)
# https://ci.appveyor.com/project/pytestbot/py/build/1.0.21/job/ffi85j4c0lqwsfwa
if lastmax == maxnum:
raise
lastmax = maxnum
Expand Down Expand Up @@ -898,7 +903,7 @@ def is_garbage(path):
# try acquiring lock to remove directory as exclusive user
if lock_timeout:
create_lockfile(path)
except (py.error.EEXIST, py.error.ENOENT):
except (py.error.EEXIST, py.error.ENOENT, py.error.EBUSY):
path_time = get_mtime(path)
if not path_time:
# assume directory doesn't exist now
Expand All @@ -908,7 +913,7 @@ def is_garbage(path):
# and lock timeout hasn't expired yet
continue

# path dir locked for exlusive use
# path dir locked for exclusive use
# and scheduled for removal to avoid another thread/process
# treating it as a new directory or removal candidate
garbage_path = rootdir.join(garbage_prefix + str(uuid.uuid4()))
Expand Down
8 changes: 1 addition & 7 deletions testing/code/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,7 @@ def test_assert_within_finally():
i = 42
""")
s = excinfo.exconly()
assert re.search("division.+by zero", s) is not None

#def g():
# A.f()
#excinfo = getexcinfo(TypeError, g)
#msg = getmsg(excinfo)
#assert msg.find("must be called with A") != -1
assert re.search("ZeroDivisionError:.*division", s) is not None


def test_assert_multiline_1():
Expand Down
5 changes: 4 additions & 1 deletion testing/log/test_log.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import py
import sys

from py._log.log import default_keywordmapper
import pytest

callcapture = py.io.StdCapture.call

default_keywordmapper = pytest.importorskip('py._log.log.default_keywordmapper')

def setup_module(mod):
mod._oldstate = default_keywordmapper.getstate()

Expand All @@ -13,6 +15,7 @@ def teardown_module(mod):

class TestLogProducer:
def setup_method(self, meth):
from py._log.log import default_keywordmapper
default_keywordmapper.setstate(_oldstate)

def test_getstate_setstate(self):
Expand Down
10 changes: 10 additions & 0 deletions testing/log/test_warning.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import sys
from distutils.version import LooseVersion

import pytest

import py

mypath = py.path.local(__file__).new(ext=".py")


win = sys.platform.startswith('win')
pytestmark = pytest.mark.skipif(win and LooseVersion(pytest.__version__) >= LooseVersion('3.1'),
reason='apiwarn is not compatible with pytest >= 3.1 (#162)')


@pytest.mark.xfail
def test_forwarding_to_warnings_module():
pytest.deprecated_call(py.log._apiwarn, "1.3", "..")
Expand Down
18 changes: 11 additions & 7 deletions testing/path/test_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,17 @@ def test_fspath_protocol_other_class(self, fake_fspath_obj):
assert py_path.join(fake_fspath_obj).strpath == os.path.join(
py_path.strpath, str_path)

@pytest.mark.skipif(sys.version_info[:2] == (2, 6) and sys.platform.startswith('win'),
reason='multiprocessing bug in Python 2.6/Windows prevents this test '
'from working as intended '
'(see https://bugs.python.org/issue10845 and #157).')
def test_make_numbered_dir_multiprocess_safe(self, tmpdir):
# https://github.com/pytest-dev/py/issues/30
pool = multiprocessing.Pool()
results = [pool.apply_async(batch_make_numbered_dirs, [tmpdir, 100]) for _ in range(20)]
for r in results:
assert r.get()


class TestExecutionOnWindows:
pytestmark = win32only
Expand Down Expand Up @@ -446,13 +457,6 @@ def notimpl(x, y):
assert x.relto(tmpdir)
assert x.check()

def test_make_numbered_dir_multiprocess_safe(self, tmpdir):
# https://github.com/pytest-dev/py/issues/30
pool = multiprocessing.Pool()
results = [pool.apply_async(batch_make_numbered_dirs, [tmpdir, 100]) for _ in range(20)]
for r in results:
assert r.get() == True

def test_locked_make_numbered_dir(self, tmpdir):
for i in range(10):
numdir = local.make_numbered_dir(prefix='base2.', rootdir=tmpdir,
Expand Down
7 changes: 6 additions & 1 deletion testing/path/test_svnauth.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import py
import svntestbase
from py.path import SvnAuth
import time
import sys
Expand Down Expand Up @@ -323,6 +322,12 @@ def test_log(self, setup):
assert log[0].msg == 'added foo.txt'

def test_switch(self, setup):
import pytest
try:
import xdist
pytest.skip('#160: fails under xdist')
except ImportError:
pass
wc = py.path.svnwc(setup.temppath, auth=setup.auth)
svnurl = 'svn://localhost:%s/%s' % (setup.port, setup.repopath.basename)
wc.checkout(svnurl)
Expand Down
9 changes: 8 additions & 1 deletion testing/path/test_svnwc.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
from py._path import svnwc as svncommon
from svntestbase import CommonSvnTests


pytestmark = pytest.mark.xfail(sys.platform.startswith('win'),
reason='#161 all tests in this file are failing on Windows',
run=False)


def test_make_repo(path1, tmpdir):
repo = tmpdir.join("repo")
py.process.cmdexec('svnadmin create %s' % repo)
Expand Down Expand Up @@ -106,8 +112,9 @@ def test_status_unchanged(self, path1):
assert r.join('sampledir/otherfile').basename in [item.basename
for item in s.unchanged]

@pytest.mark.xfail(reason="svn-1.7 has buggy 'status --xml' output")
def test_status_update(self, path1):
# not a mark because the global "pytestmark" will end up overwriting a mark here
pytest.xfail("svn-1.7 has buggy 'status --xml' output")
r = path1
try:
r.update(rev=1)
Expand Down
4 changes: 4 additions & 0 deletions testing/root/test_py_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

@py.test.mark.parametrize('name', [x for x in dir(py) if x[0] != '_'])
def test_dir(name):
if name == 'log' and sys.platform.startswith('win'):
py.test.skip('syslog is not available on Windows')
obj = getattr(py, name)
if hasattr(obj, '__map__'): # isinstance(obj, Module):
keys = dir(obj)
Expand Down Expand Up @@ -52,6 +54,8 @@ def recurse(p):


def check_import(modpath):
if modpath == 'py._log.log' and sys.platform.startswith('win'):
py.test.skip('syslog is not available on Windows')
py.builtin.print_("checking import", modpath)
assert __import__(modpath)

Expand Down

0 comments on commit e5f9547

Please sign in to comment.