For strings fnmatch_lines converts it into a Source objects, splitted on newlines. This is not necessary here, and it is more consistent to use lists here in the first place.
360 lines
10 KiB
Python
360 lines
10 KiB
Python
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import print_function
|
|
|
|
import sys
|
|
|
|
import attr
|
|
import six
|
|
|
|
import pytest
|
|
from _pytest import pathlib
|
|
from _pytest.pathlib import Path
|
|
from _pytest.warnings import SHOW_PYTEST_WARNINGS_ARG
|
|
|
|
|
|
def test_tmpdir_fixture(testdir):
|
|
p = testdir.copy_example("tmpdir/tmpdir_fixture.py")
|
|
results = testdir.runpytest(p)
|
|
results.stdout.fnmatch_lines(["*1 passed*"])
|
|
|
|
|
|
def test_ensuretemp(recwarn):
|
|
d1 = pytest.ensuretemp("hello")
|
|
d2 = pytest.ensuretemp("hello")
|
|
assert d1 == d2
|
|
assert d1.check(dir=1)
|
|
|
|
|
|
@attr.s
|
|
class FakeConfig(object):
|
|
basetemp = attr.ib()
|
|
trace = attr.ib(default=None)
|
|
|
|
@property
|
|
def trace(self):
|
|
return self
|
|
|
|
def get(self, key):
|
|
return lambda *k: None
|
|
|
|
@property
|
|
def option(self):
|
|
return self
|
|
|
|
|
|
class TestTempdirHandler(object):
|
|
def test_mktemp(self, tmp_path):
|
|
|
|
from _pytest.tmpdir import TempdirFactory, TempPathFactory
|
|
|
|
config = FakeConfig(tmp_path)
|
|
t = TempdirFactory(TempPathFactory.from_config(config))
|
|
tmp = t.mktemp("world")
|
|
assert tmp.relto(t.getbasetemp()) == "world0"
|
|
tmp = t.mktemp("this")
|
|
assert tmp.relto(t.getbasetemp()).startswith("this")
|
|
tmp2 = t.mktemp("this")
|
|
assert tmp2.relto(t.getbasetemp()).startswith("this")
|
|
assert tmp2 != tmp
|
|
|
|
@pytest.mark.issue(4425)
|
|
def test_tmppath_relative_basetemp_absolute(self, tmp_path, monkeypatch):
|
|
from _pytest.tmpdir import TempPathFactory
|
|
|
|
monkeypatch.chdir(tmp_path)
|
|
config = FakeConfig("hello")
|
|
t = TempPathFactory.from_config(config)
|
|
assert t.getbasetemp().resolve() == (tmp_path / "hello").resolve()
|
|
|
|
|
|
class TestConfigTmpdir(object):
|
|
def test_getbasetemp_custom_removes_old(self, testdir):
|
|
mytemp = testdir.tmpdir.join("xyz")
|
|
p = testdir.makepyfile(
|
|
"""
|
|
def test_1(tmpdir):
|
|
pass
|
|
"""
|
|
)
|
|
testdir.runpytest(p, "--basetemp=%s" % mytemp)
|
|
mytemp.check()
|
|
mytemp.ensure("hello")
|
|
|
|
testdir.runpytest(p, "--basetemp=%s" % mytemp)
|
|
mytemp.check()
|
|
assert not mytemp.join("hello").check()
|
|
|
|
|
|
def test_basetemp(testdir):
|
|
mytemp = testdir.tmpdir.mkdir("mytemp")
|
|
p = testdir.makepyfile(
|
|
"""
|
|
import pytest
|
|
def test_1():
|
|
pytest.ensuretemp("hello")
|
|
"""
|
|
)
|
|
result = testdir.runpytest(p, "--basetemp=%s" % mytemp, SHOW_PYTEST_WARNINGS_ARG)
|
|
assert result.ret == 0
|
|
assert mytemp.join("hello").check()
|
|
|
|
|
|
def test_tmpdir_always_is_realpath(testdir):
|
|
# the reason why tmpdir should be a realpath is that
|
|
# when you cd to it and do "os.getcwd()" you will anyway
|
|
# get the realpath. Using the symlinked path can thus
|
|
# easily result in path-inequality
|
|
# XXX if that proves to be a problem, consider using
|
|
# os.environ["PWD"]
|
|
realtemp = testdir.tmpdir.mkdir("myrealtemp")
|
|
linktemp = testdir.tmpdir.join("symlinktemp")
|
|
attempt_symlink_to(linktemp, str(realtemp))
|
|
p = testdir.makepyfile(
|
|
"""
|
|
def test_1(tmpdir):
|
|
import os
|
|
assert os.path.realpath(str(tmpdir)) == str(tmpdir)
|
|
"""
|
|
)
|
|
result = testdir.runpytest("-s", p, "--basetemp=%s/bt" % linktemp)
|
|
assert not result.ret
|
|
|
|
|
|
def test_tmp_path_always_is_realpath(testdir, monkeypatch):
|
|
# for reasoning see: test_tmpdir_always_is_realpath test-case
|
|
realtemp = testdir.tmpdir.mkdir("myrealtemp")
|
|
linktemp = testdir.tmpdir.join("symlinktemp")
|
|
attempt_symlink_to(linktemp, str(realtemp))
|
|
monkeypatch.setenv("PYTEST_DEBUG_TEMPROOT", str(linktemp))
|
|
testdir.makepyfile(
|
|
"""
|
|
def test_1(tmp_path):
|
|
assert tmp_path.resolve() == tmp_path
|
|
"""
|
|
)
|
|
reprec = testdir.inline_run()
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
|
def test_tmpdir_too_long_on_parametrization(testdir):
|
|
testdir.makepyfile(
|
|
"""
|
|
import pytest
|
|
@pytest.mark.parametrize("arg", ["1"*1000])
|
|
def test_some(arg, tmpdir):
|
|
tmpdir.ensure("hello")
|
|
"""
|
|
)
|
|
reprec = testdir.inline_run()
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
|
def test_tmpdir_factory(testdir):
|
|
testdir.makepyfile(
|
|
"""
|
|
import pytest
|
|
@pytest.fixture(scope='session')
|
|
def session_dir(tmpdir_factory):
|
|
return tmpdir_factory.mktemp('data', numbered=False)
|
|
def test_some(session_dir):
|
|
assert session_dir.isdir()
|
|
"""
|
|
)
|
|
reprec = testdir.inline_run()
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
|
def test_tmpdir_fallback_tox_env(testdir, monkeypatch):
|
|
"""Test that tmpdir works even if environment variables required by getpass
|
|
module are missing (#1010).
|
|
"""
|
|
monkeypatch.delenv("USER", raising=False)
|
|
monkeypatch.delenv("USERNAME", raising=False)
|
|
testdir.makepyfile(
|
|
"""
|
|
import pytest
|
|
def test_some(tmpdir):
|
|
assert tmpdir.isdir()
|
|
"""
|
|
)
|
|
reprec = testdir.inline_run()
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
|
@pytest.fixture
|
|
def break_getuser(monkeypatch):
|
|
monkeypatch.setattr("os.getuid", lambda: -1)
|
|
# taken from python 2.7/3.4
|
|
for envvar in ("LOGNAME", "USER", "LNAME", "USERNAME"):
|
|
monkeypatch.delenv(envvar, raising=False)
|
|
|
|
|
|
@pytest.mark.usefixtures("break_getuser")
|
|
@pytest.mark.skipif(sys.platform.startswith("win"), reason="no os.getuid on windows")
|
|
def test_tmpdir_fallback_uid_not_found(testdir):
|
|
"""Test that tmpdir works even if the current process's user id does not
|
|
correspond to a valid user.
|
|
"""
|
|
|
|
testdir.makepyfile(
|
|
"""
|
|
import pytest
|
|
def test_some(tmpdir):
|
|
assert tmpdir.isdir()
|
|
"""
|
|
)
|
|
reprec = testdir.inline_run()
|
|
reprec.assertoutcome(passed=1)
|
|
|
|
|
|
@pytest.mark.usefixtures("break_getuser")
|
|
@pytest.mark.skipif(sys.platform.startswith("win"), reason="no os.getuid on windows")
|
|
def test_get_user_uid_not_found():
|
|
"""Test that get_user() function works even if the current process's
|
|
user id does not correspond to a valid user (e.g. running pytest in a
|
|
Docker container with 'docker run -u'.
|
|
"""
|
|
from _pytest.tmpdir import get_user
|
|
|
|
assert get_user() is None
|
|
|
|
|
|
@pytest.mark.skipif(not sys.platform.startswith("win"), reason="win only")
|
|
def test_get_user(monkeypatch):
|
|
"""Test that get_user() function works even if environment variables
|
|
required by getpass module are missing from the environment on Windows
|
|
(#1010).
|
|
"""
|
|
from _pytest.tmpdir import get_user
|
|
|
|
monkeypatch.delenv("USER", raising=False)
|
|
monkeypatch.delenv("USERNAME", raising=False)
|
|
assert get_user() is None
|
|
|
|
|
|
class TestNumberedDir(object):
|
|
PREFIX = "fun-"
|
|
|
|
def test_make(self, tmp_path):
|
|
from _pytest.pathlib import make_numbered_dir
|
|
|
|
for i in range(10):
|
|
d = make_numbered_dir(root=tmp_path, prefix=self.PREFIX)
|
|
assert d.name.startswith(self.PREFIX)
|
|
assert d.name.endswith(str(i))
|
|
|
|
symlink = tmp_path.joinpath(self.PREFIX + "current")
|
|
if symlink.exists():
|
|
# unix
|
|
assert symlink.is_symlink()
|
|
assert symlink.resolve() == d.resolve()
|
|
|
|
def test_cleanup_lock_create(self, tmp_path):
|
|
d = tmp_path.joinpath("test")
|
|
d.mkdir()
|
|
from _pytest.pathlib import create_cleanup_lock
|
|
|
|
lockfile = create_cleanup_lock(d)
|
|
with pytest.raises(EnvironmentError, match="cannot create lockfile in .*"):
|
|
create_cleanup_lock(d)
|
|
|
|
lockfile.unlink()
|
|
|
|
def test_lock_register_cleanup_removal(self, tmp_path):
|
|
from _pytest.pathlib import create_cleanup_lock, register_cleanup_lock_removal
|
|
|
|
lock = create_cleanup_lock(tmp_path)
|
|
|
|
registry = []
|
|
register_cleanup_lock_removal(lock, register=registry.append)
|
|
|
|
cleanup_func, = registry
|
|
|
|
assert lock.is_file()
|
|
|
|
cleanup_func(original_pid="intentionally_different")
|
|
|
|
assert lock.is_file()
|
|
|
|
cleanup_func()
|
|
|
|
assert not lock.exists()
|
|
|
|
cleanup_func()
|
|
|
|
assert not lock.exists()
|
|
|
|
def _do_cleanup(self, tmp_path):
|
|
self.test_make(tmp_path)
|
|
from _pytest.pathlib import cleanup_numbered_dir
|
|
|
|
cleanup_numbered_dir(
|
|
root=tmp_path,
|
|
prefix=self.PREFIX,
|
|
keep=2,
|
|
consider_lock_dead_if_created_before=0,
|
|
)
|
|
|
|
def test_cleanup_keep(self, tmp_path):
|
|
self._do_cleanup(tmp_path)
|
|
a, b = (x for x in tmp_path.iterdir() if not x.is_symlink())
|
|
print(a, b)
|
|
|
|
def test_cleanup_locked(self, tmp_path):
|
|
|
|
from _pytest import pathlib
|
|
|
|
p = pathlib.make_numbered_dir(root=tmp_path, prefix=self.PREFIX)
|
|
|
|
pathlib.create_cleanup_lock(p)
|
|
|
|
assert not pathlib.ensure_deletable(
|
|
p, consider_lock_dead_if_created_before=p.stat().st_mtime - 1
|
|
)
|
|
assert pathlib.ensure_deletable(
|
|
p, consider_lock_dead_if_created_before=p.stat().st_mtime + 1
|
|
)
|
|
|
|
def test_rmtree(self, tmp_path):
|
|
from _pytest.pathlib import rmtree
|
|
|
|
adir = tmp_path / "adir"
|
|
adir.mkdir()
|
|
rmtree(adir)
|
|
|
|
assert not adir.exists()
|
|
|
|
adir.mkdir()
|
|
afile = adir / "afile"
|
|
afile.write_bytes(b"aa")
|
|
|
|
rmtree(adir, force=True)
|
|
assert not adir.exists()
|
|
|
|
def test_cleanup_ignores_symlink(self, tmp_path):
|
|
the_symlink = tmp_path / (self.PREFIX + "current")
|
|
attempt_symlink_to(the_symlink, tmp_path / (self.PREFIX + "5"))
|
|
self._do_cleanup(tmp_path)
|
|
|
|
def test_removal_accepts_lock(self, tmp_path):
|
|
folder = pathlib.make_numbered_dir(root=tmp_path, prefix=self.PREFIX)
|
|
pathlib.create_cleanup_lock(folder)
|
|
pathlib.maybe_delete_a_numbered_dir(folder)
|
|
assert folder.is_dir()
|
|
|
|
|
|
def attempt_symlink_to(path, to_path):
|
|
"""Try to make a symlink from "path" to "to_path", skipping in case this platform
|
|
does not support it or we don't have sufficient privileges (common on Windows)."""
|
|
if sys.platform.startswith("win") and six.PY2:
|
|
pytest.skip("pathlib for some reason cannot make symlinks on Python 2")
|
|
try:
|
|
Path(path).symlink_to(Path(to_path))
|
|
except OSError:
|
|
pytest.skip("could not create symbolic link")
|
|
|
|
|
|
def test_tmpdir_equals_tmp_path(tmpdir, tmp_path):
|
|
assert Path(tmpdir) == tmp_path
|