133 lines
7.4 KiB
Python
133 lines
7.4 KiB
Python
"""Check a real extracted Linux headless candidate using Google CPU inference.
|
|
|
|
This is an installed-layout smoke test, not a broad relevance benchmark or
|
|
clean-machine certification. No GPU provider or network setup is exercised.
|
|
"""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import tarfile
|
|
import tempfile
|
|
import time
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
MAX_FILE = 256 * 1024 * 1024
|
|
|
|
|
|
def sha256(path):
|
|
with path.open("rb") as stream:
|
|
return hashlib.file_digest(stream, "sha256").hexdigest()
|
|
|
|
|
|
def extract_checked(archive_path, destination):
|
|
from package_linux import safe_name
|
|
with tarfile.open(archive_path, "r:gz") as archive:
|
|
members = archive.getmembers()
|
|
if not 1 <= len(members) <= 128 or len({item.name for item in members}) != len(members):
|
|
raise ValueError("Invalid candidate member inventory")
|
|
for member in members:
|
|
safe_name(member.name)
|
|
if not member.isfile() or not 0 < member.size <= MAX_FILE:
|
|
raise ValueError("Unexpected candidate member")
|
|
manifest_member = archive.getmember("PACKAGE.json")
|
|
if manifest_member.size > 65536:
|
|
raise ValueError("Oversized candidate manifest")
|
|
manifest = json.load(archive.extractfile(manifest_member))
|
|
records = manifest["files"]
|
|
expected = {record["path"]: record for record in records}
|
|
if (manifest.get("platform") != "linux" or manifest.get("architecture") != "x86_64"
|
|
or len(expected) != len(records) or set(expected) != {member.name for member in members} - {"PACKAGE.json"}
|
|
or sum(member.size for member in members) > 1024 * 1024 * 1024):
|
|
raise ValueError("Candidate inventory does not cover archive")
|
|
for member in members:
|
|
target = destination / member.name
|
|
if not target.resolve().is_relative_to(destination.resolve()):
|
|
raise ValueError("Candidate path escapes extraction")
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
with archive.extractfile(member) as source, target.open("xb") as output:
|
|
shutil.copyfileobj(source, output, length=65536)
|
|
if member.name != "PACKAGE.json":
|
|
record = expected[member.name]
|
|
mode = int(record["mode"], 8)
|
|
if (target.stat().st_size != record["bytes"] or sha256(target) != record["sha256"]
|
|
or mode not in {0o644, 0o755} or member.mode != mode):
|
|
raise ValueError("Candidate bytes or permissions mismatch")
|
|
target.chmod(mode)
|
|
return manifest
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--archive", type=Path, required=True)
|
|
parser.add_argument("--models", type=Path, required=True)
|
|
parser.add_argument("--output", type=Path, required=True)
|
|
args = parser.parse_args()
|
|
if os.name != "posix" or not Path("/proc/self/exe").exists():
|
|
parser.error("Run natively on Linux")
|
|
models = args.models.resolve()
|
|
environment = dict(os.environ, SEARCHI_FORCE_CPU="1", GGML_DISABLE_VULKAN="1")
|
|
environment.pop("LD_LIBRARY_PATH", None)
|
|
environment.pop("GGML_BACKEND_PATH", None)
|
|
environment.pop("SEARCHI_FFMPEG_PATH", None)
|
|
environment.pop("SEARCHI_FFPROBE_PATH", None)
|
|
timings = {}
|
|
with tempfile.TemporaryDirectory(prefix="searchi archive QA ") as directory:
|
|
root = Path(directory)
|
|
installed = root / "installed"
|
|
installed.mkdir()
|
|
manifest = extract_checked(args.archive, installed)
|
|
cli, worker = installed / "searchi", installed / "searchi-gemma-worker"
|
|
corpus = root / "corpus"
|
|
corpus.mkdir()
|
|
(corpus / "supplier.md").write_text("The supplier partnership may be ended with sixty days written notice.\n", encoding="utf-8")
|
|
(corpus / "retry.py").write_text("import time\n\ndef fetch_with_backoff(operation):\n delay = 1\n for attempt in range(5):\n try:\n return operation()\n except Exception:\n time.sleep(delay)\n delay *= 2\n", encoding="utf-8")
|
|
shutil.copy2(ROOT / "crates/searchi-semantic/tests/fixtures/digup-speech.wav", corpus / "speech.wav")
|
|
db = root / "index.sqlite"
|
|
|
|
def run(label, arguments, json_output=False):
|
|
started = time.perf_counter()
|
|
output = subprocess.run([str(cli), *map(str, arguments)], cwd=installed, env=environment,
|
|
check=True, capture_output=True, text=True, encoding="utf-8", timeout=180)
|
|
timings[label] = (time.perf_counter() - started) * 1000
|
|
return json.loads(output.stdout) if json_output else output.stdout
|
|
|
|
run("help", ["--help"])
|
|
run("index", ["index", "--db", db, "--root", corpus])
|
|
# Omit explicit decoder paths to exercise installed helper discovery.
|
|
report = run("embed", ["embed", "--db", db, "--model-dir", models,
|
|
"--embedding-worker", worker, "--cpu-threads", "1"], True)
|
|
if report["media_files"] != 1 or report["media_failures"] != 0 or report["passages"] != 2 or report["chunks"] < 3:
|
|
raise RuntimeError("Installed mixed document/code/audio indexing failed")
|
|
model_arguments = ["--model-dir", models, "--embedding-worker", worker, "--cpu-threads", "1"]
|
|
hits = run("semantic_search", ["search", "--db", db,
|
|
"Wie beenden wir die Zusammenarbeit mit dem Lieferanten?", "--json", *model_arguments], True)
|
|
if not hits or hits[0]["filename"] != "supplier.md" or "sixty days" not in hits[0]["snippet"] or not hits[0]["source"]:
|
|
raise RuntimeError("Installed Google semantic search lost the supplier passage")
|
|
code = run("code_search", ["search", "--db", db,
|
|
"recover from transient network failures with increasing delays", "--code-only", "--json", *model_arguments], True)
|
|
if not code or code[0]["filename"] != "retry.py" or code[0]["source"]["kind"] != "line":
|
|
raise RuntimeError("Installed scoped code search lost its citation")
|
|
restricted = run("strict_filter", ["search", "--db", db, "supplier cancellation",
|
|
"--extension", "pdf", "--json", *model_arguments], True)
|
|
if restricted:
|
|
raise RuntimeError("Installed semantic search violated extension filter")
|
|
evidence = {"platform": "linux-x86_64", "cpu_only": True,
|
|
"archive_sha256": sha256(args.archive), "archive_bytes": args.archive.stat().st_size,
|
|
"verified_files": len(manifest["files"]), "extraction_path_contains_spaces": True,
|
|
"automatic_media_helper_discovery": "passed", "embedding_report": report,
|
|
"semantic_top_filename": hits[0]["filename"], "code_source": code[0]["source"],
|
|
"strict_filter": "passed", "command_elapsed_ms": timings,
|
|
"timing_scope": "single deployment smoke samples; not retrieval/performance benchmarks",
|
|
"limitations": ["GPU untested", "desktop untested", "clean-machine/ABI coverage untested", "broad retrieval quality untested"]}
|
|
args.output.parent.mkdir(parents=True, exist_ok=True)
|
|
args.output.write_text(json.dumps(evidence, indent=2) + "\n", encoding="utf-8")
|
|
print(json.dumps({"passed": True, "verified_files": evidence["verified_files"], "media_files": report["media_files"]}))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|