NEXUS_Visual_Weaver / tests /test_provider_runtime.py
specimba's picture
Deploy v4 review hardening
621cf5d verified
raw
history blame contribute delete
17.3 kB
from PIL import Image
from pathlib import Path
from nexus_visual_weaver.provider_runtime import (
NEMOTRON_NANO_REPO_ID,
NEMOTRON_PARSE_REPO_ID,
OPENBMB_REPO_ID,
ProviderJudgeResult,
_extract_content,
_image_data_url,
_post_json,
_safe_json_from_text,
_safe_provider_payload,
_short_error,
judge_with_minicpm,
judge_with_nemotron,
)
RUNTIME_FIXTURE_DIR = Path("tests/fixtures/runtime")
def _runtime_fixture_path(name: str) -> Path:
RUNTIME_FIXTURE_DIR.mkdir(parents=True, exist_ok=True)
return RUNTIME_FIXTURE_DIR / name
def test_minicpm_reports_missing_secret(monkeypatch) -> None:
monkeypatch.delenv("MINICPM_BASE_URL", raising=False)
monkeypatch.delenv("MINICPM_API_KEY", raising=False)
monkeypatch.delenv("OPENBMB_API_KEY", raising=False)
result = judge_with_minicpm(
prompt="gothic couture",
image_path=None,
scan={"export_gate": "pending"},
wardrobe_summary="boots and lace",
)
assert result.status == "missing_secret"
assert result.provider_state == "missing secret"
assert result.repo_id == "openbmb/MiniCPM-V-4.6"
def test_minicpm_blocks_when_artifact_missing(monkeypatch) -> None:
monkeypatch.setenv("MINICPM_BASE_URL", "http://127.0.0.1:9")
monkeypatch.setenv("MINICPM_API_KEY", "test-token")
result = judge_with_minicpm(
prompt="gothic couture",
image_path="missing.png",
scan={"export_gate": "clear"},
wardrobe_summary="boots and lace",
)
assert result.status == "no_artifact"
assert result.provider_state == "blocked"
def test_minicpm_success_with_mocked_post(monkeypatch) -> None:
image = _runtime_fixture_path("test-provider-artifact.png")
Image.new("RGB", (8, 8), color=(12, 16, 20)).save(image)
monkeypatch.setenv("MINICPM_BASE_URL", "http://example.test")
monkeypatch.setenv("MINICPM_API_KEY", "test-token")
def fake_post(url, token, payload, timeout):
assert url == "http://example.test/v1/chat/completions"
assert token == "test-token"
assert payload["messages"][0]["content"][1]["image_url"]["url"].startswith("data:image/png;base64,")
return {"choices": [{"message": {"content": '{"overall_status":"pass","footwear_check":"visible"}'}}]}
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
try:
result = judge_with_minicpm(
prompt="gothic couture",
image_path=str(image),
scan={"export_gate": "clear"},
wardrobe_summary="boots and lace",
)
finally:
image.unlink(missing_ok=True)
assert result.status == "success"
assert result.evidence["overall_status"] == "pass"
def test_nemotron_reports_missing_secret(monkeypatch) -> None:
monkeypatch.delenv("NEMOTRON_BASE_URL", raising=False)
monkeypatch.delenv("NEMOTRON_API_KEY", raising=False)
monkeypatch.delenv("NVIDIA_API_KEY", raising=False)
result = judge_with_nemotron(prompt="brief", run_packet={"id": "nw-test"})
assert result.status == "missing_secret"
assert result.provider == "NVIDIA"
assert "Nemotron" in result.message
# --- _short_error tests ---
def test_short_error_prefixes_class_name() -> None:
exc = ValueError("something went wrong")
result = _short_error(exc)
assert result.startswith("ValueError:")
assert "something went wrong" in result
def test_short_error_truncates_long_messages() -> None:
long_message = "x" * 500
exc = RuntimeError(long_message)
result = _short_error(exc)
assert len(result) <= len("RuntimeError: ") + 360
assert result.endswith("...")
def test_short_error_collapses_newlines() -> None:
exc = OSError("line one\nline two\nline three")
result = _short_error(exc)
assert "\n" not in result
assert "line one" in result
# --- _image_data_url tests ---
def test_image_data_url_returns_none_for_none_path() -> None:
assert _image_data_url(None) is None
def test_image_data_url_returns_none_for_missing_file() -> None:
assert _image_data_url("/nonexistent/path/to/image.png") is None
def test_image_data_url_encodes_png_as_base64() -> None:
image_path = _runtime_fixture_path("test-img-data-url.png")
Image.new("RGB", (4, 4), color=(0, 0, 0)).save(image_path)
try:
result = _image_data_url(str(image_path))
finally:
image_path.unlink(missing_ok=True)
assert result is not None
assert result.startswith("data:image/png;base64,")
def test_image_data_url_uses_jpeg_mime_for_jpg() -> None:
image_path = _runtime_fixture_path("test-img-data-url.jpg")
Image.new("RGB", (4, 4), color=(0, 0, 0)).save(image_path)
try:
result = _image_data_url(str(image_path))
finally:
image_path.unlink(missing_ok=True)
assert result is not None
assert result.startswith("data:image/jpeg;base64,")
def test_image_data_url_rejects_unknown_suffix() -> None:
image_path = _runtime_fixture_path("not-an-image.txt")
image_path.write_text("not an image", encoding="utf-8")
try:
assert _image_data_url(str(image_path)) is None
finally:
image_path.unlink(missing_ok=True)
def test_image_data_url_rejects_oversized_file(monkeypatch) -> None:
image_path = _runtime_fixture_path("large.png")
image_path.write_bytes(b"not actually decoded because size fails")
monkeypatch.setattr("nexus_visual_weaver.provider_runtime.MAX_PROVIDER_IMAGE_BYTES", 4)
try:
assert _image_data_url(str(image_path)) is None
finally:
image_path.unlink(missing_ok=True)
# --- _extract_content tests ---
def test_extract_content_returns_string_from_choices() -> None:
response = {"choices": [{"message": {"content": "hello world"}}]}
assert _extract_content(response) == "hello world"
def test_extract_content_returns_empty_for_no_choices() -> None:
assert _extract_content({"choices": []}) == ""
assert _extract_content({}) == ""
def test_extract_content_serializes_non_string_content() -> None:
response = {"choices": [{"message": {"content": {"key": "value"}}}]}
result = _extract_content(response)
assert "key" in result
assert "value" in result
# --- _safe_json_from_text tests ---
def test_safe_json_from_text_parses_valid_json() -> None:
text = '{"status": "pass", "score": 0.9}'
result = _safe_json_from_text(text)
assert result == {"status": "pass", "score": 0.9}
def test_safe_json_from_text_returns_empty_dict_for_empty_string() -> None:
assert _safe_json_from_text("") == {}
assert _safe_json_from_text(" ") == {}
def test_safe_json_from_text_falls_back_on_invalid_json() -> None:
text = "this is not valid json"
result = _safe_json_from_text(text)
assert "raw_summary" in result
assert "this is not valid json" in result["raw_summary"]
def test_safe_json_from_text_extracts_embedded_json() -> None:
text = 'Some prefix text {"result": "ok"} trailing text'
result = _safe_json_from_text(text)
assert result == {"result": "ok"}
def test_safe_json_from_text_truncates_fallback_to_1200_chars() -> None:
long_text = "not json " + "x" * 2000
result = _safe_json_from_text(long_text)
assert "raw_summary" in result
assert len(result["raw_summary"]) <= 1200
# --- ProviderJudgeResult.to_dict tests ---
def test_provider_judge_result_to_dict_contains_all_fields() -> None:
result = ProviderJudgeResult(
status="success",
provider_state="configured",
provider="OpenBMB",
repo_id=OPENBMB_REPO_ID,
model="MiniCPM-V-4.6",
message="judge returned evidence",
evidence={"overall_status": "pass"},
latency_seconds=1.23,
)
d = result.to_dict()
assert d["status"] == "success"
assert d["provider_state"] == "configured"
assert d["provider"] == "OpenBMB"
assert d["repo_id"] == OPENBMB_REPO_ID
assert d["model"] == "MiniCPM-V-4.6"
assert d["latency_seconds"] == 1.23
assert d["evidence"]["overall_status"] == "pass"
# --- nemotron success/failure tests ---
def test_nemotron_success_with_mocked_post(monkeypatch) -> None:
monkeypatch.setenv("NEMOTRON_BASE_URL", "http://nemotron.test")
monkeypatch.setenv("NEMOTRON_API_KEY", "nvidia-token")
def fake_post(url, token, payload, timeout):
assert "Nemotron" in payload["model"] or "nemotron" in payload["model"]
return {"choices": [{"message": {"content": '{"final_claim_status":"pass","structured_parse":"ok"}'}}]}
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
result = judge_with_nemotron(
prompt="gothic couture brief",
run_packet={"checkpoint": {"checkpoint_id": "nw-test-123"}},
minicpm_result={"status": "success"},
)
assert result.status == "success"
assert result.provider == "NVIDIA"
assert result.evidence["final_claim_status"] == "pass"
assert result.latency_seconds is not None
def test_nemotron_failed_api_call_returns_failed_status(monkeypatch) -> None:
import urllib.error
monkeypatch.setenv("NEMOTRON_BASE_URL", "http://nemotron.test")
monkeypatch.setenv("NEMOTRON_API_KEY", "nvidia-token")
def fake_post(url, token, payload, timeout):
raise urllib.error.URLError("connection refused")
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
result = judge_with_nemotron(
prompt="brief",
run_packet={"id": "nw-fail"},
)
assert result.status == "failed"
assert result.provider_state == "failed"
assert "URLError" in result.message or "connection" in result.message.lower()
assert result.evidence.get("configured") is True
def test_minicpm_failed_api_call_returns_failed_status(monkeypatch) -> None:
import urllib.error
image_path = _runtime_fixture_path("test-minicpm-fail.png")
Image.new("RGB", (4, 4), color=(0, 0, 0)).save(image_path)
monkeypatch.setenv("MINICPM_BASE_URL", "http://minicpm.test")
monkeypatch.setenv("MINICPM_API_KEY", "test-token")
def fake_post(url, token, payload, timeout):
raise urllib.error.URLError("network unreachable")
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
try:
result = judge_with_minicpm(
prompt="gothic couture",
image_path=str(image_path),
scan={"export_gate": "clear"},
wardrobe_summary="platform boots",
)
finally:
image_path.unlink(missing_ok=True)
assert result.status == "failed"
assert result.provider_state == "failed"
assert result.provider == "OpenBMB"
assert result.evidence.get("configured") is True
def test_nemotron_uses_parse_repo_id_for_parse_model(monkeypatch) -> None:
monkeypatch.setenv("NEMOTRON_BASE_URL", "http://nemotron.test")
monkeypatch.setenv("NEMOTRON_API_KEY", "nvidia-token")
monkeypatch.setenv("NEMOTRON_MODEL", "nvidia/NVIDIA-Nemotron-Parse-v1.2")
def fake_post(url, token, payload, timeout):
return {"choices": [{"message": {"content": "{}"}}]}
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
result = judge_with_nemotron(prompt="brief", run_packet={})
assert result.repo_id == NEMOTRON_PARSE_REPO_ID
def test_nemotron_uses_nano_repo_id_for_non_parse_model(monkeypatch) -> None:
monkeypatch.setenv("NEMOTRON_BASE_URL", "http://nemotron.test")
monkeypatch.setenv("NEMOTRON_API_KEY", "nvidia-token")
monkeypatch.setenv("NEMOTRON_MODEL", "nvidia/NVIDIA-Nemotron-3-Nano-4B-GGUF")
def fake_post(url, token, payload, timeout):
return {"choices": [{"message": {"content": "{}"}}]}
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
result = judge_with_nemotron(prompt="brief", run_packet={})
assert result.repo_id == NEMOTRON_NANO_REPO_ID
def test_minicpm_uses_openbmb_api_key_as_fallback(monkeypatch) -> None:
monkeypatch.setenv("MINICPM_BASE_URL", "http://minicpm.test")
monkeypatch.delenv("MINICPM_API_KEY", raising=False)
monkeypatch.setenv("OPENBMB_API_KEY", "openbmb-fallback-token")
image_path = _runtime_fixture_path("test-openbmb-key.png")
Image.new("RGB", (4, 4), color=(0, 0, 0)).save(image_path)
captured = {}
def fake_post(url, token, payload, timeout):
captured["token"] = token
return {"choices": [{"message": {"content": '{"status": "ok"}'}}]}
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
try:
result = judge_with_minicpm(
prompt="test",
image_path=str(image_path),
scan={},
wardrobe_summary="",
)
finally:
image_path.unlink(missing_ok=True)
assert result.status == "success"
assert captured["token"] == "openbmb-fallback-token"
def test_nemotron_uses_nvidia_api_key_as_fallback(monkeypatch) -> None:
monkeypatch.setenv("NEMOTRON_BASE_URL", "http://nemotron.test")
monkeypatch.delenv("NEMOTRON_API_KEY", raising=False)
monkeypatch.setenv("NVIDIA_API_KEY", "nvidia-fallback-token")
captured = {}
def fake_post(url, token, payload, timeout):
captured["token"] = token
return {"choices": [{"message": {"content": "{}"}}]}
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
result = judge_with_nemotron(prompt="brief", run_packet={})
assert result.status == "success"
assert captured["token"] == "nvidia-fallback-token"
def test_safe_provider_payload_redacts_sensitive_nested_keys() -> None:
result = _safe_provider_payload(
{
"checkpoint": "ok",
"HF_TOKEN": "should-not-leak",
"nested": {"raw_payload": "hidden", "items": [{"base64_image": "hidden"}, {"safe": "visible"}]},
}
)
assert result["checkpoint"] == "ok"
assert result["HF_TOKEN"] == "[redacted]"
assert result["nested"]["raw_payload"] == "[redacted]"
assert result["nested"]["items"][0]["base64_image"] == "[redacted]"
assert result["nested"]["items"][1]["safe"] == "visible"
def test_nemotron_redacts_run_packet_before_provider_call(monkeypatch) -> None:
monkeypatch.setenv("NEMOTRON_BASE_URL", "http://localhost:8001")
monkeypatch.setenv("NEMOTRON_API_KEY", "nvidia-token")
captured = {}
def fake_post(url, token, payload, timeout):
captured["content"] = payload["messages"][0]["content"]
return {"choices": [{"message": {"content": '{"final_claim_status":"pass"}'}}]}
monkeypatch.setattr("nexus_visual_weaver.provider_runtime._post_json", fake_post)
result = judge_with_nemotron(
prompt="brief",
run_packet={"safe": "visible", "api_key": "hidden-key", "nested": {"payload_bytes": "hidden-bytes"}},
minicpm_result={"status": "success", "authorization": "hidden-auth"},
)
assert result.status == "success"
assert "visible" in captured["content"]
assert "hidden-key" not in captured["content"]
assert "hidden-bytes" not in captured["content"]
assert "hidden-auth" not in captured["content"]
assert "[redacted]" in captured["content"]
def test_post_json_rejects_unsupported_url_schemes_before_urlopen(monkeypatch) -> None:
called = False
def fake_urlopen(*args, **kwargs):
nonlocal called
called = True
raise AssertionError("urlopen should not be called for invalid schemes")
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
for url in ["file:///tmp/payload.json", "ftp://example.test/api", "http:///missing-host"]:
try:
_post_json(url, "token", {"ok": True}, 1.0)
except ValueError as exc:
assert "Invalid URL" in str(exc)
else:
raise AssertionError(f"{url} should have been rejected")
assert called is False
def test_post_json_rejects_plain_http_non_loopback_before_urlopen(monkeypatch) -> None:
called = False
def fake_urlopen(*args, **kwargs):
nonlocal called
called = True
raise AssertionError("urlopen should not be called for plaintext remote provider URLs")
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
try:
_post_json("http://example.test/v1/chat/completions", "token", {"ok": True}, 1.0)
except ValueError as exc:
assert "HTTPS" in str(exc)
assert "loopback" in str(exc)
else:
raise AssertionError("remote http provider URL should have been rejected")
assert called is False
def test_post_json_allows_loopback_http_for_local_tests(monkeypatch) -> None:
class FakeResponse:
def __enter__(self):
return self
def __exit__(self, exc_type, exc, tb):
return False
def read(self):
return b'{"ok": true}'
def fake_urlopen(request, timeout):
assert request.full_url == "http://127.0.0.1:8000/v1/chat/completions"
return FakeResponse()
monkeypatch.setattr("urllib.request.urlopen", fake_urlopen)
assert _post_json("http://127.0.0.1:8000/v1/chat/completions", "token", {"ok": True}, 1.0) == {"ok": True}