Skip to content

Commit

Permalink
Merge pull request conda#694 from maresb/fix-pip-test
Browse files Browse the repository at this point in the history
Fix test that fails when cache is deleted
  • Loading branch information
maresb authored Sep 13, 2024
2 parents 1473122 + c53135d commit 0e2edf6
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 40 deletions.
37 changes: 37 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import pathlib
import platform
import re
import shutil
import sys
import typing

from pathlib import Path
Expand All @@ -15,6 +17,7 @@
from docker.models.containers import Container
from ensureconda.resolve import platform_subdir

from conda_lock._vendor.poetry.locations import DEFAULT_CACHE_DIR
from conda_lock.invoke_conda import PathLike, _ensureconda


Expand Down Expand Up @@ -179,3 +182,37 @@ def install_lock():
"""Limit concurrent install operations."""
with filelock.FileLock(str(TESTS_DIR.joinpath("install.lock"))):
yield


@pytest.fixture()
def cleared_poetry_cache(tmp_path_factory, testrun_uid: str):
"""Ensure no concurrency for tests that rely on the cache being cleared"""
# testrun_uid comes from xdist <https://stackoverflow.com/a/62765653>
# The idea for using FileLock with the base temp directory comes from
# <https://pytest-xdist.readthedocs.io/en/latest/how-to.html#making-session-scoped-fixtures-execute-only-once>
root_tmp_dir = tmp_path_factory.getbasetemp().parent
testrun_lockfile = root_tmp_dir / f".conda_lock_pytest_{testrun_uid}.lock"
with filelock.FileLock(testrun_lockfile):
# Use `pytest -s` to see these messages
print(
f"Clearing {DEFAULT_CACHE_DIR} based on lock {testrun_lockfile}",
file=sys.stderr,
)
clear_poetry_cache()
yield
print(f"Releasing lock {testrun_lockfile}", file=sys.stderr)


def clear_poetry_cache() -> None:
# We are going to rmtree the cache directory. Let's be extra careful to make
# sure we only delete a directory named "pypoetry-conda-lock" or one of its
# subdirectories.
to_delete = DEFAULT_CACHE_DIR.resolve()
assert to_delete.name == "pypoetry-conda-lock" or (
to_delete.parent.name == "pypoetry-conda-lock" and to_delete.name == "Cache"
)
# Do another independent check that triggers even if we're in optimized mode
if "pypoetry-conda-lock" in to_delete.parts:
shutil.rmtree(DEFAULT_CACHE_DIR, ignore_errors=True)
else:
raise RuntimeError(f"Refusing to delete {to_delete} as it does not look right")
7 changes: 6 additions & 1 deletion tests/test_conda_lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -2752,7 +2752,12 @@ def test_parse_environment_file_with_pip_and_platform_selector():


def test_pip_full_whl_url(
tmp_path: Path, conda_exe: str, monkeypatch: "pytest.MonkeyPatch"
tmp_path: Path,
conda_exe: str,
monkeypatch: "pytest.MonkeyPatch",
# If the cache is cleared under this test, it can cause an error message:
# E FileNotFoundError: [Errno 2] No such file or directory: '/Users/runner/Library/Caches/pypoetry-conda-lock/artifacts/5a/51/bb/896565e2c84dc024b41e43536c67cef3618b17b0daa532d87a72054dca/requests-2.31.0-py3-none-any.whl'
cleared_poetry_cache: None,
):
"""Ensure that we can specify full wheel URL in the environment file."""

Expand Down
39 changes: 0 additions & 39 deletions tests/test_pip_repositories.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import base64
import os
import shutil
import sys
import tarfile

from io import BytesIO
Expand All @@ -13,9 +11,6 @@
import requests
import requests_mock

from filelock import FileLock

from conda_lock._vendor.poetry.locations import DEFAULT_CACHE_DIR
from conda_lock.conda_lock import DEFAULT_LOCKFILE_NAME, run_lock
from conda_lock.lockfile import parse_conda_lock_file
from tests.test_conda_lock import clone_test_dir
Expand Down Expand Up @@ -135,25 +130,6 @@ def configure_auth(monkeypatch):
monkeypatch.setenv("PIP_PASSWORD", _PRIVATE_REPO_PASSWORD)


@pytest.fixture()
def cleared_poetry_cache(tmp_path_factory, testrun_uid: str):
"""Ensure no concurrency for tests that rely on the cache being cleared"""
# testrun_uid comes from xdist <https://stackoverflow.com/a/62765653>
# The idea for using FileLock with the base temp directory comes from
# <https://pytest-xdist.readthedocs.io/en/latest/how-to.html#making-session-scoped-fixtures-execute-only-once>
root_tmp_dir = tmp_path_factory.getbasetemp().parent
testrun_lockfile = root_tmp_dir / f".conda_lock_pytest_{testrun_uid}.lock"
with FileLock(testrun_lockfile):
# Use `pytest -s` to see these messages
print(
f"Clearing {DEFAULT_CACHE_DIR} based on lock {testrun_lockfile}",
file=sys.stderr,
)
clear_poetry_cache()
yield
print(f"Releasing lock {testrun_lockfile}", file=sys.stderr)


def test_it_uses_pip_repositories_with_env_var_substitution(
monkeypatch: "pytest.MonkeyPatch",
conda_exe: str,
Expand Down Expand Up @@ -197,18 +173,3 @@ def test_it_uses_pip_repositories_with_env_var_substitution(
"Password environment variable was not respected, See full lock-file:\n"
+ lockfile_content
)


def clear_poetry_cache() -> None:
# We are going to rmtree the cache directory. Let's be extra careful to make
# sure we only delete a directory named "pypoetry-conda-lock" or one of its
# subdirectories.
to_delete = DEFAULT_CACHE_DIR.resolve()
assert to_delete.name == "pypoetry-conda-lock" or (
to_delete.parent.name == "pypoetry-conda-lock" and to_delete.name == "Cache"
)
# Do another independent check that triggers even if we're in optimized mode
if "pypoetry-conda-lock" in to_delete.parts:
shutil.rmtree(DEFAULT_CACHE_DIR, ignore_errors=True)
else:
raise RuntimeError(f"Refusing to delete {to_delete} as it does not look right")

0 comments on commit 0e2edf6

Please sign in to comment.