Defer removing tmpdir
This commit is contained in:
parent
326ae0cd88
commit
caf8371f74
|
@ -1,4 +1,5 @@
|
||||||
"""Support for providing temporary directories to test functions."""
|
"""Support for providing temporary directories to test functions."""
|
||||||
|
import atexit
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
@ -285,18 +286,22 @@ def tmp_path(
|
||||||
result_dict = request.node.stash[tmppath_result_key]
|
result_dict = request.node.stash[tmppath_result_key]
|
||||||
|
|
||||||
if policy == "failed" and result_dict.get("call", True):
|
if policy == "failed" and result_dict.get("call", True):
|
||||||
# We do a "best effort" to remove files, but it might not be possible due to some leaked resource,
|
|
||||||
# permissions, etc, in which case we ignore it.
|
def remove_path_and_dead_symlink():
|
||||||
rmtree(path, ignore_errors=True)
|
# ignore_errors is required because the base directory has already been gone here
|
||||||
|
# when all the testcase is passed
|
||||||
|
rmtree(path, ignore_errors=True)
|
||||||
|
|
||||||
|
# remove dead symlink
|
||||||
|
basetemp = tmp_path_factory._basetemp
|
||||||
|
if basetemp is None:
|
||||||
|
return
|
||||||
|
cleanup_dead_symlink(basetemp)
|
||||||
|
|
||||||
|
atexit.register(remove_path_and_dead_symlink)
|
||||||
|
|
||||||
del request.node.stash[tmppath_result_key]
|
del request.node.stash[tmppath_result_key]
|
||||||
|
|
||||||
# remove dead symlink
|
|
||||||
basetemp = tmp_path_factory._basetemp
|
|
||||||
if basetemp is None:
|
|
||||||
return
|
|
||||||
cleanup_dead_symlink(basetemp)
|
|
||||||
|
|
||||||
|
|
||||||
def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):
|
def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):
|
||||||
"""After each session, remove base directory if all the tests passed,
|
"""After each session, remove base directory if all the tests passed,
|
||||||
|
@ -313,9 +318,7 @@ def pytest_sessionfinish(session, exitstatus: Union[int, ExitCode]):
|
||||||
):
|
):
|
||||||
passed_dir = tmp_path_factory._basetemp
|
passed_dir = tmp_path_factory._basetemp
|
||||||
if passed_dir.exists():
|
if passed_dir.exists():
|
||||||
# We do a "best effort" to remove files, but it might not be possible due to some leaked resource,
|
atexit.register(rmtree, passed_dir)
|
||||||
# permissions, etc, in which case we ignore it.
|
|
||||||
rmtree(passed_dir, ignore_errors=True)
|
|
||||||
|
|
||||||
|
|
||||||
@hookimpl(tryfirst=True, hookwrapper=True)
|
@hookimpl(tryfirst=True, hookwrapper=True)
|
||||||
|
|
|
@ -92,136 +92,6 @@ class TestConfigTmpPath:
|
||||||
assert mytemp.exists()
|
assert mytemp.exists()
|
||||||
assert not mytemp.joinpath("hello").exists()
|
assert not mytemp.joinpath("hello").exists()
|
||||||
|
|
||||||
def test_policy_failed_removes_only_passed_dir(self, pytester: Pytester) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
def test_1(tmp_path):
|
|
||||||
assert 0 == 0
|
|
||||||
def test_2(tmp_path):
|
|
||||||
assert 0 == 1
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
pytester.makepyprojecttoml(
|
|
||||||
"""
|
|
||||||
[tool.pytest.ini_options]
|
|
||||||
tmp_path_retention_policy = "failed"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
pytester.inline_run(p)
|
|
||||||
root = pytester._test_tmproot
|
|
||||||
|
|
||||||
for child in root.iterdir():
|
|
||||||
base_dir = list(
|
|
||||||
filter(lambda x: x.is_dir() and not x.is_symlink(), child.iterdir())
|
|
||||||
)
|
|
||||||
assert len(base_dir) == 1
|
|
||||||
test_dir = list(
|
|
||||||
filter(
|
|
||||||
lambda x: x.is_dir() and not x.is_symlink(), base_dir[0].iterdir()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
# Check only the failed one remains
|
|
||||||
assert len(test_dir) == 1
|
|
||||||
assert test_dir[0].name == "test_20"
|
|
||||||
|
|
||||||
def test_policy_failed_removes_basedir_when_all_passed(
|
|
||||||
self, pytester: Pytester
|
|
||||||
) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
def test_1(tmp_path):
|
|
||||||
assert 0 == 0
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
pytester.makepyprojecttoml(
|
|
||||||
"""
|
|
||||||
[tool.pytest.ini_options]
|
|
||||||
tmp_path_retention_policy = "failed"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
pytester.inline_run(p)
|
|
||||||
root = pytester._test_tmproot
|
|
||||||
for child in root.iterdir():
|
|
||||||
# This symlink will be deleted by cleanup_numbered_dir **after**
|
|
||||||
# the test finishes because it's triggered by atexit.
|
|
||||||
# So it has to be ignored here.
|
|
||||||
base_dir = filter(lambda x: not x.is_symlink(), child.iterdir())
|
|
||||||
# Check the base dir itself is gone
|
|
||||||
assert len(list(base_dir)) == 0
|
|
||||||
|
|
||||||
# issue #10502
|
|
||||||
def test_policy_failed_removes_dir_when_skipped_from_fixture(
|
|
||||||
self, pytester: Pytester
|
|
||||||
) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def fixt(tmp_path):
|
|
||||||
pytest.skip()
|
|
||||||
|
|
||||||
def test_fixt(fixt):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
pytester.makepyprojecttoml(
|
|
||||||
"""
|
|
||||||
[tool.pytest.ini_options]
|
|
||||||
tmp_path_retention_policy = "failed"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
|
|
||||||
pytester.inline_run(p)
|
|
||||||
|
|
||||||
# Check if the whole directory is removed
|
|
||||||
root = pytester._test_tmproot
|
|
||||||
for child in root.iterdir():
|
|
||||||
base_dir = list(
|
|
||||||
filter(lambda x: x.is_dir() and not x.is_symlink(), child.iterdir())
|
|
||||||
)
|
|
||||||
assert len(base_dir) == 0
|
|
||||||
|
|
||||||
# issue #10502
|
|
||||||
def test_policy_all_keeps_dir_when_skipped_from_fixture(
|
|
||||||
self, pytester: Pytester
|
|
||||||
) -> None:
|
|
||||||
p = pytester.makepyfile(
|
|
||||||
"""
|
|
||||||
import pytest
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def fixt(tmp_path):
|
|
||||||
pytest.skip()
|
|
||||||
|
|
||||||
def test_fixt(fixt):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
pytester.makepyprojecttoml(
|
|
||||||
"""
|
|
||||||
[tool.pytest.ini_options]
|
|
||||||
tmp_path_retention_policy = "all"
|
|
||||||
"""
|
|
||||||
)
|
|
||||||
pytester.inline_run(p)
|
|
||||||
|
|
||||||
# Check if the whole directory is kept
|
|
||||||
root = pytester._test_tmproot
|
|
||||||
for child in root.iterdir():
|
|
||||||
base_dir = list(
|
|
||||||
filter(lambda x: x.is_dir() and not x.is_symlink(), child.iterdir())
|
|
||||||
)
|
|
||||||
assert len(base_dir) == 1
|
|
||||||
test_dir = list(
|
|
||||||
filter(
|
|
||||||
lambda x: x.is_dir() and not x.is_symlink(), base_dir[0].iterdir()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
assert len(test_dir) == 1
|
|
||||||
|
|
||||||
|
|
||||||
testdata = [
|
testdata = [
|
||||||
("mypath", True),
|
("mypath", True),
|
||||||
|
|
Loading…
Reference in New Issue