Files
6krrt/tests/test_admin_override_binds_everywhere.py
adlee-was-taken 43645d4b59 fix: an admin availability override binds every path, and "stale" works
Sweep findings #3 and #4 (plans/admin-portal-functional-sweep.md).

#3. "stale" was inert. The models page offers active / deprecated / stale,
and only "deprecated" was ever read. The reasoning in the old docstring was
wrong rather than conservative: it said stale "already has its own filter",
meaning freshness.exclude_stale -- but that filter reads
models.availability, the catalog column, and an admin override lives in
admin_model_overrides and is never merged into those rows. Selecting
"stale" wrote a row and changed nothing.

Measured on /route before the fix: 27 candidates with a stale override set,
27 with it cleared, against 28 when a deprecated override was cleared.

Both off-states now exclude, unconditionally rather than gated on
freshness.exclude_stale / exclude_deprecated. Those settings are a policy
about catalog age; an override is an operator naming one model, and an
explicit instruction should not need a second flag to take effect.
_admin_deprecated_models is renamed _admin_excluded_models in all three
modules, since "deprecated" no longer describes what it returns.

#4. The override bound /route but nothing else. /v1/models reads
models.availability directly, so a switched-off model stayed advertised;
_resolve_pinned_provider had no check, so a client that took it from that
list was served by it as normal. The override applied to routed traffic
only, which is the opposite of what "deprecated" reads as in the portal.

Both are now closed, and /v1/models grows the same guard it already applies
under gaming mode -- with the comment there giving the reason verbatim: do
not advertise a model whose pin is about to be refused.

The new tests parametrize over both off-states rather than testing
"deprecated" and trusting "stale" to follow, since trusting that is exactly
how stale stayed inert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VRQXz5SYZYVWscxS1QqF6U
2026-09-08 18:33:50 -04:00

140 lines
5.0 KiB
Python

"""An admin availability override means the same thing on every path.
Two gaps, both measured on the live router before the fix:
* "stale" was inert. It wrote a row and changed nothing, because the filter
it was supposed to feed reads ``models.availability`` and the override
lives in ``admin_model_overrides``.
* "deprecated" bound ``/route`` but not ``/v1/models`` or a pinned request,
so a client could list the model the operator had switched off and then
be served by it.
"""
from __future__ import annotations
import sqlite3
from pathlib import Path
import pytest
from starlette.testclient import TestClient
import dispatcher
from dispatcher import Classification, app
ROOT = Path(__file__).resolve().parent.parent
SCHEMA_SQL = (ROOT / "config" / "schema.sql").read_text()
KEEP = "keep-model"
DROP = "drop-model"
@pytest.fixture
def client(tmp_path, monkeypatch):
db_path = tmp_path / "ovr.db"
conn = sqlite3.connect(db_path)
conn.executescript(SCHEMA_SQL)
import admin
admin.ensure_admin_tables(conn)
for model_id in (KEEP, DROP):
conn.execute(
"""
INSERT INTO models (
model_id, provider, base_model_id, tier, context_window,
effective_context_window, max_output_tokens,
cost_per_1m_prompt, cost_per_1m_completion,
supports_vision, supports_json_mode,
latency_class, reasoning_mode, context_variant,
access_level, availability, last_updated
) VALUES (?, 'neuralwatt', ?, 2, 262128, 192500, 16384, 1.0, 2.0,
0, 1, 'standard', 'default', 'full', 'public', 'active',
'2026-08-22T00:00:00+00:00')
""",
(model_id, model_id),
)
conn.commit()
conn.close()
monkeypatch.setattr(dispatcher.cfg.database, "path", str(db_path))
monkeypatch.setattr(dispatcher.cfg.verification, "local_llm_enabled", False)
monkeypatch.setattr(dispatcher.cfg.local_vision, "enabled", False)
monkeypatch.setattr(dispatcher.cfg.session_cache, "enabled", False)
monkeypatch.setenv("NEURALWATT_API_KEY", "test-key")
monkeypatch.setattr(
dispatcher, "classify",
lambda task, context: Classification(
task_category="coding_general", task_tier=2,
required_context_tokens=100, confidence=0.9,
),
)
return TestClient(app)
def _override(client, model_id, availability):
resp = client.post(
f"/admin/api/models/{model_id}/neuralwatt/availability",
json={"availability": availability},
)
assert resp.status_code == 200, resp.text
def _listed(client):
return {m["id"] for m in client.get("/v1/models").json()["data"]}
# --- "stale" is no longer inert -------------------------------------------
@pytest.mark.parametrize("availability", ["deprecated", "stale"])
def test_both_off_states_remove_the_model_from_v1_models(client, availability):
assert DROP in _listed(client)
_override(client, DROP, availability)
assert DROP not in _listed(client)
assert KEEP in _listed(client), "only the overridden model should go"
@pytest.mark.parametrize("availability", ["deprecated", "stale"])
def test_both_off_states_refuse_a_pinned_request(client, availability):
_override(client, DROP, availability)
resp = client.post(
"/v1/chat/completions",
json={"model": DROP, "messages": [{"role": "user", "content": "hi"}]},
)
assert resp.status_code == 503, resp.text
assert "override" in resp.text
@pytest.mark.parametrize("availability", ["deprecated", "stale"])
def test_both_off_states_drop_the_model_from_routing(client, availability):
before = client.post("/route", json={"task": "write a function"}).json()
assert before["candidates_considered"] >= 2
_override(client, DROP, availability)
after = client.post("/route", json={"task": "write a function"}).json()
assert after["candidates_considered"] == before["candidates_considered"] - 1
# --- "active" clears -------------------------------------------------------
def test_an_active_override_puts_the_model_back(client):
_override(client, DROP, "deprecated")
assert DROP not in _listed(client)
_override(client, DROP, "active")
assert DROP in _listed(client)
def test_clearing_the_override_puts_the_model_back(client):
_override(client, DROP, "stale")
assert DROP not in _listed(client)
resp = client.delete(f"/admin/api/models/{DROP}/neuralwatt/availability")
assert resp.status_code == 200, resp.text
assert DROP in _listed(client)
def test_an_unoverridden_model_is_still_pinnable(client):
"""The refusal must be scoped to the override, not to pinning."""
_override(client, DROP, "deprecated")
resp = client.post(
"/v1/chat/completions",
json={"model": KEEP, "messages": [{"role": "user", "content": "hi"}]},
)
# Reaches the provider call rather than being refused up front; the
# provider is not stubbed here, so anything but the 503 proves the point.
assert resp.status_code != 503 or "override" not in resp.text