100 lines
3.2 KiB
Python
100 lines
3.2 KiB
Python
"""Opt-in fixtures for the live-Gitea integration tests.
|
|
|
|
Tests in this directory are marked ``integration`` and skipped unless
|
|
``AEGIS_INTEGRATION=1``. The default test run never touches Docker.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import re
|
|
from collections.abc import Iterator
|
|
from dataclasses import dataclass, field
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from tests.integration.harness import (
|
|
GiteaInstance,
|
|
HarnessError,
|
|
start_gitea,
|
|
stop_gitea,
|
|
unique,
|
|
)
|
|
|
|
_HERE = Path(__file__).parent.resolve()
|
|
ENABLE_ENV = "AEGIS_INTEGRATION"
|
|
|
|
|
|
def integration_enabled() -> bool:
|
|
"""Return True when the opt-in env var is set."""
|
|
return os.environ.get(ENABLE_ENV) == "1"
|
|
|
|
|
|
def pytest_configure(config: pytest.Config) -> None:
|
|
"""Register the ``integration`` marker (idempotent with pyproject)."""
|
|
config.addinivalue_line(
|
|
"markers", "integration: live Gitea in Docker, opt-in via AEGIS_INTEGRATION=1"
|
|
)
|
|
|
|
|
|
def _is_integration(item: pytest.Item) -> bool:
|
|
try:
|
|
return _HERE in Path(str(item.path)).resolve().parents
|
|
except (OSError, ValueError): # pragma: no cover - defensive
|
|
return False
|
|
|
|
|
|
def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
|
|
"""Mark and (unless opted in) skip every test under tests/integration."""
|
|
selected = [item for item in items if _is_integration(item)]
|
|
skip = pytest.mark.skip(reason=f"live Gitea tests need {ENABLE_ENV}=1 and Docker")
|
|
for item in selected:
|
|
item.add_marker(pytest.mark.integration)
|
|
if not integration_enabled():
|
|
item.add_marker(skip)
|
|
if selected and len(selected) == len(items):
|
|
# An integration-only run covers almost none of src/, so the unit-test
|
|
# coverage gate does not apply to it.
|
|
# pytest-cov reads its options from the early-config namespace.
|
|
for namespace in (config.option, config.known_args_namespace):
|
|
if getattr(namespace, "cov_fail_under", None) is not None:
|
|
namespace.cov_fail_under = 0
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def gitea() -> Iterator[GiteaInstance]:
|
|
"""A throwaway Gitea in Docker, shared by the whole session."""
|
|
try:
|
|
instance = start_gitea()
|
|
except HarnessError as exc:
|
|
pytest.fail(f"integration harness could not start Gitea: {exc}", pytrace=False)
|
|
try:
|
|
yield instance
|
|
finally:
|
|
stop_gitea(instance)
|
|
|
|
|
|
@pytest.fixture
|
|
def unique_name(request: pytest.FixtureRequest) -> str:
|
|
"""A unique, Gitea-safe name derived from the test name."""
|
|
slug = re.sub(r"[^a-z0-9]+", "-", request.node.name.lower()).strip("-")[:16].strip("-")
|
|
return unique(slug or "t")
|
|
|
|
|
|
@dataclass
|
|
class RegularUser:
|
|
"""A non-admin user with its own full-scope token."""
|
|
|
|
login: str
|
|
password: str = field(repr=False)
|
|
token: str = field(repr=False)
|
|
|
|
|
|
@pytest.fixture(scope="session")
|
|
def regular_user(gitea: GiteaInstance) -> RegularUser:
|
|
"""A non-admin user plus a full-scope token minted for that user."""
|
|
login, password = gitea.create_user(gitea.unique("it-user"))
|
|
token = gitea.mint_token(login, password, ["all"])
|
|
return RegularUser(login=login, password=password, token=token)
|