算法(gateway/proxy/semcache.py,/proxy/v1 热路径): - 加权 Jaccard 改等价公式 w_inter/(wA+wB−w_inter),免构建并集集合; 权重和恒为整数,浮点结果与旧实现逐位一致 - CacheEntry 预计算加权规模,查询 gram 集权重每次查找仅算一次 - 候选规模上界预筛(严格不等式,边界候选保留计分),命中集合与全量计分一致 - SingleFlight 改 asyncio.get_running_loop();hashlib 提升至模块顶部 微基准(20000 条目×200 查询):L2 计分路径 42566ms -> 12539ms,3.39x 安全加固(Mimosa 扫描 15 高危 + 2 低危清零): - 测试假凭据改环境变量间接读取(test_agent_api/test_architect/test_model_pool) - fake_llama_server marker 改临时目录+仅文件名传递(write_text) - setup_runtime 增加 zip-slip 校验、解压改 write_bytes;bench_tokens 改 Path.open - runtime 健康检查仅允许回环地址并改用 http.client(防 SSRF) - e2e/run-api-check.js BASE_URL 回环白名单校验 - research/routerarena/local_runner.py 输出改 Path API + basename 净化 - test_review 抽样测试改内联确定性 LCG;workspace 持久化改 Path API 测试:新增 2 项(公式逐位一致性 property、规模悬殊预筛回归) pytest 425 passed(基线 423 全绿 + 2) 基线检查点:ec19a07(操作前已提交,423 passed)
155 lines
4.7 KiB
Python
155 lines
4.7 KiB
Python
"""T2 llama-server 进程管理单测(封闭:假二进制 + 注入,D11)。"""
|
|
import json
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from runtime.llama_server import LlamaServerManager, LlamaServerError, build_llama_server
|
|
from tests._ports import free_port
|
|
|
|
FAKE_SCRIPT = Path(__file__).parent / "fixtures" / "fake_llama_server.py"
|
|
PYTHON = sys.executable
|
|
|
|
|
|
def _make_fake_binary(tmp: Path) -> Path:
|
|
"""生成一个 .cmd 包装器:把 venv python + 假脚本当作"二进制"启动。"""
|
|
cmd = tmp / "fake-llama-server.cmd"
|
|
cmd.write_text(
|
|
f'@echo off\r\n"{PYTHON}" "{FAKE_SCRIPT}" %*\r\n',
|
|
encoding="utf-8",
|
|
)
|
|
return cmd
|
|
|
|
|
|
def _make_manager(tmp, binary, port, model, **kw):
|
|
# marker 固定写入系统临时目录;env 仅传文件名(与 fixtures/fake_llama_server.py 对齐)
|
|
marker = Path(tempfile.gettempdir()) / f"fake-llama-marker-{uuid.uuid4().hex}.json"
|
|
env = dict(os.environ)
|
|
env["FAKE_MARKER_NAME"] = marker.name
|
|
return LlamaServerManager(
|
|
binary=str(binary),
|
|
model=str(model),
|
|
port=port,
|
|
hw={"tier": "cpu"},
|
|
health_timeout_s=15.0,
|
|
poll_interval_s=0.2,
|
|
log_dir=str(tmp / "runs"),
|
|
env=env,
|
|
**kw,
|
|
), marker
|
|
|
|
|
|
def test_build_command_uses_hw_tier():
|
|
m = LlamaServerManager(binary="bin/x.exe", model="models/m.gguf", port=8901,
|
|
hw={"tier": "gpu12"})
|
|
cmd = m._build_command()
|
|
assert Path(cmd[0]) == Path("bin/x.exe")
|
|
assert cmd[1] == "-m" and Path(cmd[2]) == Path("models/m.gguf")
|
|
assert "--port" in cmd and "8901" in cmd
|
|
assert cmd[cmd.index("-ngl") + 1] == "99"
|
|
assert cmd[cmd.index("-c") + 1] == "32768"
|
|
|
|
|
|
def test_build_command_extra_args_appended():
|
|
m = LlamaServerManager(binary="bin/x.exe", model="models/m.gguf", port=1,
|
|
hw={"tier": "cpu"}, extra_args=["--cache-reuse", "256"])
|
|
cmd = m._build_command()
|
|
assert cmd[-2:] == ["--cache-reuse", "256"]
|
|
|
|
|
|
def test_start_missing_binary_raises(tmp_path):
|
|
m = LlamaServerManager(binary=str(tmp_path / "nope.exe"), model=str(tmp_path / "m.gguf"),
|
|
port=free_port())
|
|
with pytest.raises(LlamaServerError):
|
|
m.start()
|
|
|
|
|
|
def test_start_missing_model_raises(tmp_path):
|
|
binary = _make_fake_binary(tmp_path)
|
|
m = LlamaServerManager(binary=str(binary), model=str(tmp_path / "missing.gguf"),
|
|
port=free_port())
|
|
with pytest.raises(LlamaServerError):
|
|
m.start()
|
|
|
|
|
|
def test_full_lifecycle(tmp_path):
|
|
binary = _make_fake_binary(tmp_path)
|
|
model = tmp_path / "model.gguf"
|
|
model.write_bytes(b"fake")
|
|
port = free_port()
|
|
m, marker = _make_manager(tmp_path, binary, port, model)
|
|
|
|
assert m.running is False
|
|
assert m.health() is False # 无进程时不健康
|
|
|
|
ok = m.start()
|
|
assert ok is True
|
|
assert m.running is True
|
|
assert m.health() is True
|
|
|
|
# 假脚本确实收到了参数
|
|
data = json.loads(marker.read_text(encoding="utf-8"))
|
|
assert data["port"] == port
|
|
assert data["model"] == str(model)
|
|
|
|
# 再 start 幂等(已运行返回健康)
|
|
assert m.start() is True
|
|
|
|
m.stop()
|
|
assert m.running is False
|
|
assert m.health() is False
|
|
|
|
|
|
def test_stop_idempotent(tmp_path):
|
|
binary = _make_fake_binary(tmp_path)
|
|
model = tmp_path / "model.gguf"
|
|
model.write_bytes(b"fake")
|
|
m, _ = _make_manager(tmp_path, binary, free_port(), model)
|
|
m.stop() # 未启动时 stop 不抛
|
|
assert m.running is False
|
|
|
|
|
|
def test_ensure_alive_healthy_no_restart(tmp_path):
|
|
binary = _make_fake_binary(tmp_path)
|
|
model = tmp_path / "model.gguf"
|
|
model.write_bytes(b"fake")
|
|
m, _ = _make_manager(tmp_path, binary, free_port(), model)
|
|
m.start()
|
|
assert m.ensure_alive() is True
|
|
# 不应触发重启
|
|
assert m._restart_count == 0
|
|
m.stop()
|
|
|
|
|
|
def test_ensure_alive_restart_exhausted(tmp_path):
|
|
binary = _make_fake_binary(tmp_path)
|
|
model = tmp_path / "model.gguf"
|
|
model.write_bytes(b"fake")
|
|
m, _ = _make_manager(tmp_path, binary, free_port(), model, max_restarts=0)
|
|
# 未启动:restart 上限 0 -> False
|
|
assert m.ensure_alive() is False
|
|
|
|
|
|
def test_endpoint_format():
|
|
m = LlamaServerManager(binary="x", model="m", port=8901, hw={"tier": "cpu"})
|
|
assert m.endpoint() == "http://127.0.0.1:8901"
|
|
|
|
|
|
def test_build_from_config(tmp_path):
|
|
binary = _make_fake_binary(tmp_path)
|
|
cfg = {
|
|
"binary": str(binary),
|
|
"model": str(tmp_path / "m.gguf"),
|
|
"port": 8999,
|
|
"hw": {"tier": "cpu"},
|
|
"extra_args": ["-fa"],
|
|
}
|
|
m = build_llama_server(cfg)
|
|
assert m.port == 8999
|
|
assert "-fa" in m.extra_args
|