Files
projectAIpopular/tests/test_sense_routes.py
T
tzt c3efa70da2 feat(sense): T-G0 语义分析器骨架(包结构/DDL/灰度门控挂载)
- gateway/sense/:config(SenseConfig:mode 灰度三态/特征门/conformal/consumers
  档位映射,mode 非法回落 collect)、errors(EmbedderDown/ArtifactMissing,D-G4 降级)、
  store(tier_observations + sense_artifacts DDL,WAL;观察写入/标签回填/
  labeled 查询/180d 清理/工件登记与 active 切换)、routes(/sense/health 透出灰度状态)
- settings DEFAULTS 增 sense 段(enabled 默认 False,mode 默认 collect——D-G7)
- api.py include_router 门控(装配失败不拖垮主应用)
- 测试 +5:门控 404/DDL 幂等/配置缺省与 mode 回落/独立挂载 health/
  观察写入-回填-计数-清理链路,全量 375 passed
2026-09-05 11:07:04 +08:00

80 lines
3.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""语义分析器骨架测试(T-G0):enabled 门控 / DDL / 独立挂载 / 配置构建。"""
import pytest
pytest.importorskip("fastapi")
from fastapi import FastAPI
from fastapi.testclient import TestClient
import gateway.api as ga
from gateway.sense.config import build_sense_config
from gateway.sense.store import SenseStore
def test_sense_disabled_by_default_404():
"""D-G7:默认 enabled=False -> 全局 app 不注册任何 /sense 路由。"""
client = TestClient(ga.app)
assert client.get("/sense/health").status_code == 404
assert client.get("/sense/admin/agreement").status_code == 404
def test_ddl_creates_tables_and_indexes(tmp_path):
"""两表 + 两索引幂等创建。"""
store = SenseStore.init_db(tmp_path / "sense.sqlite3")
tables = set(store.table_names())
assert {"tier_observations", "sense_artifacts"} <= tables
idx = set(store.index_names())
assert {"idx_obs_ts", "idx_obs_policy"} <= idx
SenseStore.init_db(tmp_path / "sense.sqlite3") # 幂等
def test_build_sense_config_defaults():
"""缺省值 + mode 非法回落 collectD-G7)。"""
cfg = build_sense_config({})
assert cfg.enabled is False
assert cfg.mode == "collect"
assert cfg.embedder.dim == 1024
assert cfg.min_labels == 500
assert cfg.tier_pool_hint("proxy", "t1") == "local-small"
assert cfg.tier_pool_hint("proxy", "t3") == "premium"
assert cfg.tier_pool_hint("client", "t2") == "budget" # 无配置兜底
bad = build_sense_config({"sense": {"mode": "turbo", "enabled": True}})
assert bad.mode == "collect"
def test_enabled_router_health(tmp_path):
"""enabled=True 独立挂载:/sense/health 透出灰度状态。"""
cfg = build_sense_config({"sense": {"enabled": True, "mode": "collect",
"db_path": str(tmp_path / "s.sqlite3")}})
app = FastAPI()
app.include_router(
__import__("gateway.sense", fromlist=["x"]).build_sense_router(cfg))
client = TestClient(app)
r = client.get("/sense/health")
assert r.status_code == 200
data = r.json()
assert data["enabled"] is True and data["mode"] == "collect"
def test_observation_roundtrip(tmp_path):
"""观察写入/标签回填/计数/留存清理(store 基础链路)。"""
store = SenseStore.init_db(tmp_path / "s.sqlite3")
store.insert_observation({
"request_id": "r1", "consumer": "pipeline", "decided_tier": "T2",
"executed_tier": "T2", "probs": '{"t1":0.2,"t2":0.6,"t3":0.2}',
"policy_version": "v0-rule", "features": '{"turns":1}'})
store.insert_observation({
"request_id": "r2", "consumer": "proxy", "decided_tier": "T1",
"executed_tier": "T1", "probs": "{}", "policy_version": "v0-rule",
"features": "{}", "outcome": "ok"})
assert store.count_labeled() == 0
store.set_true_tier("r1", "T2")
assert store.count_labeled() == 1
rows = store.labeled_rows()
assert rows[0]["request_id"] == "r1" and rows[0]["true_tier"] == "T2"
assert store.update_outcome("r2", "escalated", executed_tier="T2") is True
# 180d 清理
import time
assert store.purge_older_than(time.time() + 10) >= 2
assert store.count_labeled() == 0