from __future__ import annotations
import json
import subprocess
import sys
import tempfile
from pathlib import Path
import pytest
SCRIPTS_DIR = Path(__file__).resolve().parents[4] / "scripts"
MANIFEST_DIR = Path(__file__).resolve().parents[4] / "compat" / "downstream"
MANIFEST_PATH = MANIFEST_DIR / "manifest.toml"
ISOLATED_RUNNER = SCRIPTS_DIR / "run_isolated_downstream.py"
DOWNSTREAM_RUNNER = SCRIPTS_DIR / "run_downstream_compat.py"
def _run_isolated(package: str, wheel_dir: str, timeout: int = 30) -> dict:
cmd = [
sys.executable, str(ISOLATED_RUNNER),
"--package", package,
"--wheel-dir", wheel_dir,
"--timeout", str(timeout),
]
result = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout + 60)
output = result.stdout.strip()
if output:
try:
return json.loads(output)
except json.JSONDecodeError:
pass
return {"status": "error", "raw_output": result.stdout[:500], "returncode": result.returncode}
def _run_downstream(wheel_dir: str, packages: str | None = None) -> dict:
cmd = [
sys.executable, str(DOWNSTREAM_RUNNER),
"--wheel-dir", wheel_dir,
]
if packages:
cmd.extend(["--packages", packages])
result = subprocess.run(cmd, capture_output=True, text=True, timeout=120)
output = result.stdout.strip()
if output:
try:
return json.loads(output)
except json.JSONDecodeError:
pass
return {"status": "error", "raw_output": result.stdout[:500], "returncode": result.returncode}
class TestIsolatedRunnerFailClosed:
def test_unknown_package_fails(self):
with tempfile.TemporaryDirectory() as tmpdir:
Path(tmpdir, "eggfetch-0.1.0-py3-none-any.whl").touch()
Path(tmpdir, "httpx-0.28.1-py3-none-any.whl").touch()
result = _run_isolated("nonexistent-pkg-xyz", tmpdir)
is_json_error = (
result.get("status") == "error"
and ("not found" in result.get("error", "").lower()
or "fail-closed" in result.get("error", "").lower())
)
is_crash = result.get("returncode", 0) != 0
assert is_json_error or is_crash, (
f"Expected fail-closed behavior, got: {result}"
)
def test_missing_command_required_package(self):
pass
def test_zero_tests_required_package_fails(self):
pass
class TestDownstreamRunnerFailClosed:
def test_unknown_package_selection_fails(self):
with tempfile.TemporaryDirectory() as tmpdir:
Path(tmpdir, "eggfetch-0.1.0-py3-none-any.whl").touch()
Path(tmpdir, "httpx-0.28.1-py3-none-any.whl").touch()
result = _run_downstream(tmpdir, packages="nonexistent-pkg-xyz")
is_json_error = (
result.get("status") == "error"
and any("no packages matched" in e.lower() or "fail-closed" in e.lower()
for e in result.get("errors", []))
)
is_crash = result.get("returncode", 0) != 0
assert is_json_error or is_crash, (
f"Expected fail-closed behavior, got: {result}"
)
def test_empty_selection_fails(self):
with tempfile.TemporaryDirectory() as tmpdir:
Path(tmpdir, "eggfetch-0.1.0-py3-none-any.whl").touch()
Path(tmpdir, "httpx-0.28.1-py3-none-any.whl").touch()
result = _run_downstream(tmpdir, packages="totally-fake-package")
assert result["status"] == "error"
def test_missing_wheel_directory_fails(self):
result = _run_downstream("/tmp/nonexistent-wheel-dir-abc123")
assert result["status"] == "error"
class TestManifestSchemaV2:
def test_manifest_has_schema_version_2(self):
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
with open(MANIFEST_PATH, "rb") as f:
data = tomllib.load(f)
assert data["portfolio"]["schema-version"] in ("2", "3")
assert data["portfolio"]["status"] in ("phase-6", "phase-7", "phase-8")
def test_required_packages_are_not_import_only(self):
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
with open(MANIFEST_PATH, "rb") as f:
data = tomllib.load(f)
EXEMPT = {"anthropic", "groq"}
errors = []
for pkg in data.get("package", []):
if pkg.get("usage") != "required":
continue
if pkg["name"] in EXEMPT:
continue
cmd = pkg.get("test-command", "")
if "print" in cmd and "import" in cmd and "-c" in cmd:
if "assert" not in cmd and "MockTransport" not in cmd and "Client" not in cmd:
errors.append(f"{pkg['name']}: import-only test command for required package")
assert not errors, "\n".join(errors)
def test_all_required_entries_have_source_type(self):
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
with open(MANIFEST_PATH, "rb") as f:
data = tomllib.load(f)
errors = []
for pkg in data.get("package", []):
if pkg.get("usage") != "required":
continue
if not pkg.get("source-type"):
errors.append(f"{pkg['name']}: missing source-type")
if not pkg.get("source-locator"):
errors.append(f"{pkg['name']}: missing source-locator")
assert not errors, "\n".join(errors)
def test_required_entries_have_source_hash(self):
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
with open(MANIFEST_PATH, "rb") as f:
data = tomllib.load(f)
errors = []
for pkg in data.get("package", []):
if pkg.get("usage") != "required":
continue
source_hash = pkg.get("source-hash", "")
if not source_hash:
errors.append(f"{pkg['name']}: missing source-hash")
elif len(source_hash) != 64 or not all(c in "0123456789abcdef" for c in source_hash):
errors.append(f"{pkg['name']}: source-hash is not a valid SHA-256: {source_hash!r}")
assert not errors, "\n".join(errors)
def test_required_entries_have_category_ids(self):
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
with open(MANIFEST_PATH, "rb") as f:
data = tomllib.load(f)
errors = []
for pkg in data.get("package", []):
if pkg.get("usage") != "required":
continue
cat_ids = pkg.get("category-ids")
if not isinstance(cat_ids, list) or len(cat_ids) == 0:
errors.append(f"{pkg['name']}: missing or empty category-ids")
assert not errors, "\n".join(errors)
def test_informational_entries_are_import_only(self):
try:
import tomllib
except ModuleNotFoundError:
import tomli as tomllib
with open(MANIFEST_PATH, "rb") as f:
data = tomllib.load(f)
errors = []
for pkg in data.get("package", []):
if pkg.get("usage") != "informational":
continue
cmd = pkg.get("test-command", "")
if not cmd:
errors.append(f"{pkg['name']}: informational package missing test-command")
assert not errors, "\n".join(errors)