"""CPU-testable contracts for the experimental Jetson support path.""" from __future__ import annotations import importlib.metadata import json import sys import tomllib from pathlib import Path from types import SimpleNamespace import pytest import yaml from scripts import jetson_support from scripts import run_conditional_gate from scripts import setup_jetson ROOT = Path(__file__).parents[1] def test_host_evidence_is_allow_listed(monkeypatch, tmp_path): tegra = tmp_path / "nv_tegra_release" tegra.write_text("# R36 (release), REVISION: 4.3\nserial=secret\n") os_release = tmp_path / "os-release" os_release.write_text( 'ID=ubuntu\nVERSION_ID="22.04"\nPRETTY_NAME="Ubuntu 22.04"\nSECRET=value\n' ) monkeypatch.setattr(jetson_support.platform, "machine", lambda: "aarch64") monkeypatch.setattr(jetson_support.platform, "python_version", lambda: "3.10.12") monkeypatch.setattr(jetson_support, "_capture", lambda command, **kwargs: "6.2+b17") facts = jetson_support.collect_host_facts( tegra_release=tegra, os_release=os_release, ) assert facts == { "architecture": "aarch64", "python_version": "3.10.12", "os": { "id": "ubuntu", "version_id": "22.04", "pretty_name": "Ubuntu 22.04", }, "l4t_release": "# R36 (release), REVISION: 4.3", "jetpack_package": "6.2+b17", } assert "secret" not in json.dumps(facts).lower() def test_runtime_evidence_reports_cuda_without_device_identity(monkeypatch): properties = SimpleNamespace(name="Orin", total_memory=64 * 1024**3) fake_cuda = SimpleNamespace( is_available=lambda: True, device_count=lambda: 1, get_device_properties=lambda _index: properties, get_device_capability=lambda _index: (8, 7), ) fake_torch = SimpleNamespace( __version__="2.8.0a0+nv25.06", version=SimpleNamespace(cuda="12.6"), cuda=fake_cuda, ) monkeypatch.setitem(sys.modules, "torch", fake_torch) def missing_package(_name): raise importlib.metadata.PackageNotFoundError monkeypatch.setattr(jetson_support.importlib.metadata, "version", missing_package) facts = jetson_support.collect_runtime_facts() assert facts["cuda_available"] is True assert facts["device_name"] == "Orin" assert facts["compute_capability"] == [8, 7] assert facts["total_memory_gb"] == 64.0 assert set(facts) == { "torch_imported", "torch_version", "torch_cuda_version", "cuda_available", "cuda_device_count", "device_name", "compute_capability", "total_memory_gb", "bitsandbytes_version", } def test_report_validation_blocks_non_jetson_or_non_cuda_and_warns_on_bnb(): report = { "host": {"architecture": "x86_64", "l4t_release": None}, "runtime": { "torch_imported": True, "torch_cuda_version": None, "cuda_available": False, "bitsandbytes_version": "0.47.0", }, } errors, warnings = jetson_support.validate_report(report) assert len(errors) == 3 assert any("ARM64" in error for error in errors) assert any("Jetson L4T" in error for error in errors) assert any("not a CUDA build" in error for error in errors) assert warnings and "unsupported" in warnings[0] def test_gate_evidence_and_issue_body_cannot_copy_arbitrary_fields(tmp_path): evidence = tmp_path / "gate.json" evidence.write_text(json.dumps({ "gate": "jetson-runtime", "status": "passed", "git_sha": "a" * 40, "counts": {"tests": 1, "token": "nested-secret"}, "token": "must-not-escape", "hostname": "must-not-escape", })) summary = jetson_support._gate_summary(evidence) body = jetson_support.issue_body({"gate_evidence": summary}) assert summary == { "gate": "jetson-runtime", "status": "passed", "git_sha": "a" * 40, "counts": {"tests": 1}, } assert "must-not-escape" not in body assert "nested-secret" not in body assert "excludes environment variables" in body def test_dependency_export_rejects_torch_and_bitsandbytes(tmp_path): requirements = tmp_path / "requirements.txt" requirements.write_text("transformers==4.56.0\npytest==8.4.1\n") setup_jetson._require_exclusions(requirements) for forbidden in ( "torch==2.8.0", "torch @ https://example.invalid/torch.whl", "bitsandbytes[diagnostics]==0.47.0", ): requirements.write_text(forbidden + "\n") with pytest.raises(RuntimeError, match="forbidden packages"): setup_jetson._require_exclusions(requirements) def test_jetson_bootstrap_preserves_vendor_runtime_and_uses_locked_no_deps( monkeypatch, tmp_path, ): project = tmp_path / "project" (project / "scripts").mkdir(parents=True) (project / "scripts" / "jetson_support.py").write_text("# fixture\n") (project / "uv.lock").write_text("# fixture\n") venv = tmp_path / "jetson-venv" commands: list[list[str]] = [] def fake_run(command, *, cwd): command = list(command) commands.append(command) if command[1:4] == ["-m", "venv", "--system-site-packages"]: (venv / "bin").mkdir(parents=True) (venv / "pyvenv.cfg").write_text("include-system-site-packages = true\n") if "--output-file" in command: output = Path(command[command.index("--output-file") + 1]) output.write_text("transformers==4.56.0\n") monkeypatch.setattr(setup_jetson, "_run", fake_run) setup_jetson.prepare( project=project, venv=venv, python="vendor-python", uv_python="tool-python", reuse=False, ) assert commands[0][0] == "vendor-python" assert "--check" in commands[0] export = next(command for command in commands if "export" in command) assert export.count("--no-emit-package") == 2 assert "torch" in export and "bitsandbytes" in export installs = [command for command in commands if "install" in command] assert len(installs) == 2 assert all("--no-deps" in command for command in installs) assert any("check" in command for command in commands) def test_bootstrap_rejects_unsafe_or_non_vendor_reusable_targets(tmp_path): project = tmp_path / "project" project.mkdir() with pytest.raises(ValueError, match="unsafe"): setup_jetson._require_safe_target(project, project) existing = tmp_path / "existing" existing.mkdir() (existing / "pyvenv.cfg").write_text("include-system-site-packages = false\n") with pytest.raises(ValueError, match="does not expose JetPack"): setup_jetson._require_new_or_reusable_venv(existing, reuse=True) def test_bitsandbytes_is_opt_in_for_quantization_only(): metadata = tomllib.loads((ROOT / "pyproject.toml").read_text()) base = metadata["project"]["dependencies"] extras = metadata["project"]["optional-dependencies"] assert not any(value.startswith("bitsandbytes") for value in base) assert extras["quantization"] == ["bitsandbytes>=0.46.1"] def test_jetson_issue_form_requires_reproducible_sanitized_hardware_evidence(): form = yaml.safe_load( (ROOT / ".github" / "ISSUE_TEMPLATE" / "jetson-runtime.yml").read_text(), ) fields = {value.get("id"): value for value in form["body"] if value.get("id")} assert set(fields) == { "device", "jetpack", "commit", "reproduction", "expected", "actual", "evidence", "confirmations", } assert all(value.get("validations", {}).get("required") for value in fields.values()) confirmations = fields["confirmations"]["attributes"]["options"] assert all(option["required"] for option in confirmations) assert any("secrets" in option["label"] for option in confirmations) def test_jetson_conditional_prerequisites_are_physical_and_cuda(monkeypatch, tmp_path): fake_torch = SimpleNamespace(cuda=SimpleNamespace(is_available=lambda: True)) monkeypatch.setitem(sys.modules, "torch", fake_torch) monkeypatch.setattr(run_conditional_gate.platform, "machine", lambda: "aarch64") tegra = tmp_path / "nv_tegra_release" tegra.write_text("# R36\n") monkeypatch.setattr(run_conditional_gate, "JETSON_RELEASE", tegra) assert run_conditional_gate.missing_prerequisites("jetson-runtime") == [] monkeypatch.setattr(run_conditional_gate.platform, "machine", lambda: "x86_64") fake_torch.cuda.is_available = lambda: False tegra.unlink() assert run_conditional_gate.missing_prerequisites("jetson-runtime") == [ "a CUDA-capable PyTorch runtime", "an ARM64 host", "a Jetson L4T runtime", ]