Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: enforce tmp working directory #9149

Merged
merged 3 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import contextlib
import logging
import os
import re
Expand Down Expand Up @@ -41,6 +42,8 @@
from tests.helpers import isolated_environment
from tests.helpers import mock_clone
from tests.helpers import mock_download
from tests.helpers import switch_working_directory
from tests.helpers import with_working_directory


if TYPE_CHECKING:
Expand All @@ -49,12 +52,14 @@

from _pytest.config import Config as PyTestConfig
from _pytest.config.argparsing import Parser
from _pytest.tmpdir import TempPathFactory
from pytest_mock import MockerFixture

from poetry.poetry import Poetry
from tests.types import FixtureCopier
from tests.types import FixtureDirGetter
from tests.types import ProjectFactory
from tests.types import SetProjectContext


def pytest_addoption(parser: Parser) -> None:
Expand Down Expand Up @@ -525,3 +530,34 @@ def venv_flags_default() -> dict[str, bool]:
def httpretty_windows_mock_urllib3_wait_for_socket(mocker: MockerFixture) -> None:
# this is a workaround for https://github.com/gabrielfalcao/HTTPretty/issues/442
mocker.patch("urllib3.util.wait.select_wait_for_socket", returns=True)


@pytest.fixture(autouse=True)
def tmp_working_directory(tmp_path: Path) -> Iterator[Path]:
with switch_working_directory(tmp_path):
yield tmp_path


@pytest.fixture(autouse=True, scope="session")
def tmp_session_working_directory(tmp_path_factory: TempPathFactory) -> Iterator[Path]:
tmp_path = tmp_path_factory.mktemp("session-working-directory")
with switch_working_directory(tmp_path):
yield tmp_path


@pytest.fixture
def set_project_context(
tmp_working_directory: Path, tmp_path: Path, fixture_dir: FixtureDirGetter
) -> SetProjectContext:
@contextlib.contextmanager
def project_context(project: str | Path, in_place: bool = False) -> Iterator[Path]:
if isinstance(project, str):
project = fixture_dir(project)

with with_working_directory(
source=project,
target=tmp_path.joinpath(project.name) if not in_place else None,
) as path:
yield path

return project_context
58 changes: 33 additions & 25 deletions tests/console/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
if TYPE_CHECKING:
from pytest_mock import MockerFixture

from tests.types import SetProjectContext


class FooCommand(Command):
name = "foo"
Expand Down Expand Up @@ -85,44 +87,50 @@ def test_application_execute_plugin_command_with_plugins_disabled(


@pytest.mark.parametrize("disable_cache", [True, False])
def test_application_verify_source_cache_flag(disable_cache: bool) -> None:
app = Application()
def test_application_verify_source_cache_flag(
disable_cache: bool, set_project_context: SetProjectContext
) -> None:
with set_project_context("sample_project"):
app = Application()

tester = ApplicationTester(app)
command = "debug info"
tester = ApplicationTester(app)
command = "debug info"

if disable_cache:
command = f"{command} --no-cache"
if disable_cache:
command = f"{command} --no-cache"

assert not app._poetry
assert not app._poetry

tester.execute(command)
tester.execute(command)

assert app.poetry.pool.repositories
assert app.poetry.pool.repositories

for repo in app.poetry.pool.repositories:
assert isinstance(repo, CachedRepository)
assert repo._disable_cache == disable_cache
for repo in app.poetry.pool.repositories:
assert isinstance(repo, CachedRepository)
assert repo._disable_cache == disable_cache


@pytest.mark.parametrize("disable_cache", [True, False])
def test_application_verify_cache_flag_at_install(
mocker: MockerFixture, disable_cache: bool
mocker: MockerFixture,
disable_cache: bool,
set_project_context: SetProjectContext,
) -> None:
app = Application()
with set_project_context("sample_project"):
app = Application()

tester = ApplicationTester(app)
command = "install --dry-run"
tester = ApplicationTester(app)
command = "install --dry-run"

if disable_cache:
command = f"{command} --no-cache"
if disable_cache:
command = f"{command} --no-cache"

spy = mocker.spy(Authenticator, "__init__")
spy = mocker.spy(Authenticator, "__init__")

tester.execute(command)
tester.execute(command)

assert spy.call_count == 2
for call in spy.mock_calls:
(name, args, kwargs) = call
assert "disable_cache" in kwargs
assert disable_cache is kwargs["disable_cache"]
assert spy.call_count == 2
for call in spy.mock_calls:
(name, args, kwargs) = call
assert "disable_cache" in kwargs
assert disable_cache is kwargs["disable_cache"]
29 changes: 29 additions & 0 deletions tests/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,3 +338,32 @@ def redirect_request_callback(
status=status_code,
body=redirect_request_callback,
)


@contextlib.contextmanager
def switch_working_directory(path: Path, remove: bool = False) -> Iterator[Path]:
Secrus marked this conversation as resolved.
Show resolved Hide resolved
original_cwd = Path.cwd()
os.chdir(path)

with contextlib.suppress(Exception) as exception:
yield path

os.chdir(original_cwd)

if remove:
shutil.rmtree(path, ignore_errors=True)

if exception is not None:
raise exception


@contextlib.contextmanager
def with_working_directory(source: Path, target: Path | None = None) -> Iterator[Path]:
use_copy = target is not None

if use_copy:
assert target is not None
shutil.copytree(source, target)

with switch_working_directory(target or source, remove=use_copy) as path:
yield path
Loading
Loading