diff --git a/docs/examples/conftest.py b/docs/examples/conftest.py index d4c3c22cb..3538b1326 100644 --- a/docs/examples/conftest.py +++ b/docs/examples/conftest.py @@ -187,6 +187,12 @@ def add_option_safe(option_name, **kwargs): default=False, help="Ignore all requirement checks (GPU, RAM, Ollama, API keys)", ) + add_option_safe( + "--skip-resource-checks", + action="store_true", + default=False, + help="Skip hardware capability gates (VRAM/RAM). API credential and Ollama checks are unaffected.", + ) def _collect_vllm_example_files(session) -> list[str]: @@ -564,7 +570,12 @@ def pytest_runtest_setup(item): # Get config options from CLI (matching test/conftest.py behavior) config = item.config ignore_all = config.getoption("--ignore-all-checks", default=False) - ignore_gpu = config.getoption("--ignore-gpu-check", default=False) or ignore_all + skip_resource = config.getoption("skip_resource_checks", default=False) + ignore_gpu = ( + config.getoption("--ignore-gpu-check", default=False) + or ignore_all + or skip_resource + ) ignore_ollama = ( config.getoption("--ignore-ollama-check", default=False) or ignore_all ) diff --git a/test/README.md b/test/README.md index 4c4c7a148..abc3d9d2a 100644 --- a/test/README.md +++ b/test/README.md @@ -136,6 +136,10 @@ pytestmark = [pytest.mark.e2e, pytest.mark.huggingface, require_gpu(), require_r | `require_ram(min_gb=N)` | N GB+ system RAM | | `require_api_key("ENV_VAR")` | Specific API credentials | +Pass `--skip-resource-checks` to bypass `require_gpu` and `require_ram` gates — useful for running test logic on under-spec hardware or reproducing failures from higher-spec machines. API credential and Ollama checks are unaffected. On machines with no GPU at all, gated tests will run and may fail naturally. + +The env var `_MELLEA_SKIP_RESOURCE_CHECKS=1` has the same effect and can be used in CI environments without modifying the pytest invocation. + > **Deprecated:** The markers `requires_gpu`, `requires_heavy_ram`, `requires_api_key`, > and `requires_gpu_isolation` are deprecated. Existing tests using them still work > (conftest auto-skip handles them) but new tests must use predicates. Migrate legacy diff --git a/test/conftest.py b/test/conftest.py index a904a06ba..e65f552e0 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -209,6 +209,12 @@ def add_option_safe(option_name, **kwargs): default=False, help="Group tests by backend and run them together (reduces GPU memory fragmentation)", ) + add_option_safe( + "--skip-resource-checks", + action="store_true", + default=False, + help="Skip hardware capability gates (VRAM/RAM). API credential and Ollama checks are unaffected.", + ) BACKEND_MARKERS: dict[str, str] = { @@ -254,6 +260,16 @@ def pytest_configure(config): "markers", "llm: Tests that make LLM calls (deprecated — use e2e instead)" ) + # Propagate --skip-resource-checks as env var so predicates.py can read it + # at module-import time (before test collection begins). + if config.getoption("skip_resource_checks", default=False): + os.environ["_MELLEA_SKIP_RESOURCE_CHECKS"] = "1" + + +def pytest_unconfigure(): + """Clean up env var so repeated programmatic pytest invocations are unaffected.""" + os.environ.pop("_MELLEA_SKIP_RESOURCE_CHECKS", None) + # ============================================================================ # Heavy GPU Test Process Isolation diff --git a/test/predicates.py b/test/predicates.py index 26f34c507..a23c48696 100644 --- a/test/predicates.py +++ b/test/predicates.py @@ -94,6 +94,9 @@ def require_gpu(*, min_vram_gb: int | None = None): Args: min_vram_gb: Minimum VRAM in GB. When ``None``, any GPU suffices. """ + if os.environ.get("_MELLEA_SKIP_RESOURCE_CHECKS"): + return pytest.mark.skipif(False, reason="") + if not _gpu_available(): return pytest.mark.skipif(True, reason="No GPU available (CUDA/MPS)") @@ -124,6 +127,9 @@ def _system_ram_gb() -> float: def require_ram(min_gb: int): """Skip unless the system has at least *min_gb* GB of RAM.""" + if os.environ.get("_MELLEA_SKIP_RESOURCE_CHECKS"): + return pytest.mark.skipif(False, reason="") + ram = _system_ram_gb() if ram > 0 and ram < min_gb: return pytest.mark.skipif(