Skip to content

Commit 101ea34

Browse files
handle test folder cleanup being unable to create a cleanup lock
1 parent c94b2b2 commit 101ea34

File tree

3 files changed

+19
-5
lines changed

3 files changed

+19
-5
lines changed

changelog/4181.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Handle race condi

src/_pytest/pathlib.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -182,9 +182,15 @@ def cleanup_on_exit(lock_path=lock_path, original_pid=pid):
182182
return register(cleanup_on_exit)
183183

184184

185-
def delete_a_numbered_dir(path):
186-
"""removes a numbered directory"""
187-
create_cleanup_lock(path)
185+
def maybe_delete_a_numbered_dir(path):
186+
"""removes a numbered directory if its lock can be obtained"""
187+
try:
188+
create_cleanup_lock(path)
189+
except (OSError, EnvironmentError):
190+
# known races:
191+
# * other process did a cleanup at the same time
192+
# * deletable folder was found
193+
return
188194
parent = path.parent
189195

190196
garbage = parent.joinpath("garbage-{}".format(uuid.uuid4()))
@@ -214,7 +220,7 @@ def ensure_deletable(path, consider_lock_dead_if_created_before):
214220
def try_cleanup(path, consider_lock_dead_if_created_before):
215221
"""tries to cleanup a folder if we can ensure its deletable"""
216222
if ensure_deletable(path, consider_lock_dead_if_created_before):
217-
delete_a_numbered_dir(path)
223+
maybe_delete_a_numbered_dir(path)
218224

219225

220226
def cleanup_candidates(root, prefix, keep):

testing/test_tmpdir.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import six
55

66
import pytest
7+
from _pytest import pathlib
78
from _pytest.pathlib import Path
89

910

@@ -284,11 +285,17 @@ def test_rmtree(self, tmp_path):
284285
rmtree(adir, force=True)
285286
assert not adir.exists()
286287

287-
def test_cleanup_symlink(self, tmp_path):
288+
def test_cleanup_ignores_symlink(self, tmp_path):
288289
the_symlink = tmp_path / (self.PREFIX + "current")
289290
attempt_symlink_to(the_symlink, tmp_path / (self.PREFIX + "5"))
290291
self._do_cleanup(tmp_path)
291292

293+
def test_removal_accepts_lock(self, tmp_path):
294+
folder = pathlib.make_numbered_dir(root=tmp_path, prefix=self.PREFIX)
295+
pathlib.create_cleanup_lock(folder)
296+
pathlib.maybe_delete_a_numbered_dir(folder)
297+
assert folder.is_dir()
298+
292299

293300
def attempt_symlink_to(path, to_path):
294301
"""Try to make a symlink from "path" to "to_path", skipping in case this platform

0 commit comments

Comments
 (0)