handle test folder cleanup being unable to create a cleanup lock
This commit is contained in:
		
							parent
							
								
									c94b2b227e
								
							
						
					
					
						commit
						ae2fc27799
					
				|  | @ -0,0 +1 @@ | ||||||
|  | Handle race condition between creation and deletion of temporary folders. | ||||||
|  | @ -182,9 +182,15 @@ def register_cleanup_lock_removal(lock_path, register=atexit.register): | ||||||
|     return register(cleanup_on_exit) |     return register(cleanup_on_exit) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def delete_a_numbered_dir(path): | def maybe_delete_a_numbered_dir(path): | ||||||
|     """removes a numbered directory""" |     """removes a numbered directory if its lock can be obtained""" | ||||||
|  |     try: | ||||||
|         create_cleanup_lock(path) |         create_cleanup_lock(path) | ||||||
|  |     except (OSError, EnvironmentError): | ||||||
|  |         #  known races: | ||||||
|  |         #  * other process did a cleanup at the same time | ||||||
|  |         #  * deletable folder was found | ||||||
|  |         return | ||||||
|     parent = path.parent |     parent = path.parent | ||||||
| 
 | 
 | ||||||
|     garbage = parent.joinpath("garbage-{}".format(uuid.uuid4())) |     garbage = parent.joinpath("garbage-{}".format(uuid.uuid4())) | ||||||
|  | @ -214,7 +220,7 @@ def ensure_deletable(path, consider_lock_dead_if_created_before): | ||||||
| def try_cleanup(path, consider_lock_dead_if_created_before): | def try_cleanup(path, consider_lock_dead_if_created_before): | ||||||
|     """tries to cleanup a folder if we can ensure its deletable""" |     """tries to cleanup a folder if we can ensure its deletable""" | ||||||
|     if ensure_deletable(path, consider_lock_dead_if_created_before): |     if ensure_deletable(path, consider_lock_dead_if_created_before): | ||||||
|         delete_a_numbered_dir(path) |         maybe_delete_a_numbered_dir(path) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def cleanup_candidates(root, prefix, keep): | def cleanup_candidates(root, prefix, keep): | ||||||
|  |  | ||||||
|  | @ -4,6 +4,7 @@ import sys | ||||||
| import six | import six | ||||||
| 
 | 
 | ||||||
| import pytest | import pytest | ||||||
|  | from _pytest import pathlib | ||||||
| from _pytest.pathlib import Path | from _pytest.pathlib import Path | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -284,11 +285,17 @@ class TestNumberedDir(object): | ||||||
|         rmtree(adir, force=True) |         rmtree(adir, force=True) | ||||||
|         assert not adir.exists() |         assert not adir.exists() | ||||||
| 
 | 
 | ||||||
|     def test_cleanup_symlink(self, tmp_path): |     def test_cleanup_ignores_symlink(self, tmp_path): | ||||||
|         the_symlink = tmp_path / (self.PREFIX + "current") |         the_symlink = tmp_path / (self.PREFIX + "current") | ||||||
|         attempt_symlink_to(the_symlink, tmp_path / (self.PREFIX + "5")) |         attempt_symlink_to(the_symlink, tmp_path / (self.PREFIX + "5")) | ||||||
|         self._do_cleanup(tmp_path) |         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): | def attempt_symlink_to(path, to_path): | ||||||
|     """Try to make a symlink from "path" to "to_path", skipping in case this platform |     """Try to make a symlink from "path" to "to_path", skipping in case this platform | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue