diff options
author | Randy Döring <30527984+radoering@users.noreply.github.com> | 2023-03-12 18:23:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-12 10:23:07 -0700 |
commit | d48565f2a7a3096fd45bf11ca194ea095bdae9ac (patch) | |
tree | 1fc1d6df98424cf971b2cffc06495e61b77e6923 /tests | |
parent | e2a9ee59e58c48a663bb435dbeb36a160272f695 (diff) | |
download | virtualenv-d48565f2a7a3096fd45bf11ca194ea095bdae9ac.tar.gz |
Make `ReentrantFileLock` thread-safe and, thereby, fix race condition in `virtualenv.cli_run` (#2517)
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/test_util.py | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/tests/unit/test_util.py b/tests/unit/test_util.py index d2a5906..81f8ff7 100644 --- a/tests/unit/test_util.py +++ b/tests/unit/test_util.py @@ -1,3 +1,9 @@ +import concurrent.futures +import traceback + +import pytest + +from virtualenv.util.lock import ReentrantFileLock from virtualenv.util.subprocess import run_cmd @@ -6,3 +12,25 @@ def test_run_fail(tmp_path): assert err assert not out assert code + + +def test_reentrant_file_lock_is_thread_safe(tmp_path): + lock = ReentrantFileLock(tmp_path) + target_file = tmp_path / "target" + target_file.touch() + + def recreate_target_file(): + with lock.lock_for_key("target"): + target_file.unlink() + target_file.touch() + + with concurrent.futures.ThreadPoolExecutor() as executor: + tasks = [] + for _ in range(4): + tasks.append(executor.submit(recreate_target_file)) + concurrent.futures.wait(tasks) + for task in tasks: + try: + task.result() + except Exception: + pytest.fail(traceback.format_exc()) |