ApiCore-Whisper: transcribe.py liest das Manifest im RAM-Arbeitsordner, dekodiert mit festem Demuxer je Endung, misst die Länge vor dem Abschreiben (TOO_LONG > 240 s, DECODE_FAILED bei Länge 0), sperrt das Netz vor dem Modell-Laden und schreibt nur Zähler auf stdout. Image: python:3.12-slim per Digest, Nutzer 1000, alle Pakete mit Hash (faster-whisper 1.2.1, av 18.1.0 wegen Inkompatibilität mit av 19), Modell faster-whisper-small auf fester Revision mit SHA-256 je Datei. CI-Workflow nur bei Änderungen unter ApiCore-Whisper/, Actions per SHA. deploy/k8s/components/voice: CronJob alle 2 Minuten mit fetch, whisper, ingest (gleiche UID, getrennte /tmp-Volumes, damit der Decoder dem Container mit den Secrets nichts unterschieben kann; whisper ohne Secrets und Umgebungsvariablen außer WHISPER_CPU_THREADS), Overlay mit Platzhalter-Digest, ConfigMap-Werte für Sprache, Policy-Tests (55). Die Anbindung des Anthropic-Schlüssels bleibt offen (Ruling 9). Refs #27 Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
"""Tests for the build-time model download (no network)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
|
|
|
import fetch_model # noqa: E402
|
|
|
|
|
|
def test_verify_accepts_the_pinned_hash(tmp_path: Path):
|
|
file = tmp_path / "a.bin"
|
|
file.write_bytes(b"model")
|
|
fetch_model.verify(file, hashlib.sha256(b"model").hexdigest())
|
|
|
|
|
|
def test_verify_rejects_a_changed_file(tmp_path: Path):
|
|
file = tmp_path / "a.bin"
|
|
file.write_bytes(b"tampered")
|
|
with pytest.raises(fetch_model.ChecksumMismatch):
|
|
fetch_model.verify(file, hashlib.sha256(b"model").hexdigest())
|
|
|
|
|
|
def test_download_refuses_plain_http(tmp_path: Path):
|
|
with pytest.raises(ValueError):
|
|
fetch_model.download("http://example.invalid/x", tmp_path / "x")
|
|
|
|
|
|
def test_every_pinned_file_has_a_sha256_and_the_revision_is_a_commit():
|
|
assert len(fetch_model.REVISION) == 40
|
|
assert set(fetch_model.FILES) >= {"model.bin", "config.json", "tokenizer.json", "vocabulary.txt"}
|
|
for digest in fetch_model.FILES.values():
|
|
assert len(digest) == 64 and int(digest, 16) >= 0
|
|
|
|
|
|
def test_fetch_all_stops_on_a_mismatch(tmp_path: Path, monkeypatch):
|
|
def fake_download(url: str, target: Path) -> None:
|
|
target.write_bytes(b"evil")
|
|
|
|
monkeypatch.setattr(fetch_model, "download", fake_download)
|
|
with pytest.raises(fetch_model.ChecksumMismatch):
|
|
fetch_model.fetch_all(tmp_path / "m", {"model.bin": hashlib.sha256(b"good").hexdigest()})
|