chore(publication): close pre-integration release blockers

This commit is contained in:
Alexandre Teixeira
2026-10-05 01:37:49 +01:00
parent 3d3aee2093
commit dab660543b
77 changed files with 4074 additions and 83103 deletions
+1 -1
View File
@@ -89,7 +89,7 @@ a status code. `scripts/odysseus-smoke --areas` prints the current list.
| Email | the fixture inbox lists, opens with its body, and the unread count drops on mark-read |
| Memory | a fact is listed, found by search, and gone after delete |
| Uploads | an attachment reads back byte for byte |
| Cookbook | hardware is detected and recommendations come back sized against it; state persists |
| Cookbook | hardware is detected; a fresh install's recommendation request returns the explicit empty-catalog Rescan guidance; state persists |
| Settings | a preference written on one session is still there after a new login |
## What is not covered, and why
+32 -8
View File
@@ -1,12 +1,22 @@
"""Cookbook: hardware is detected and the recommendations are sized against it.
"""Cookbook: hardware is detected and a fresh install says how to get a catalog.
What the README advertises here is hardware-aware recommendation, and
that is exactly the part that runs offline. Downloading and serving a
model is left to the gap list: it needs tmux, a GPU runtime and several
gigabytes over the network.
No model catalog ships with the app: the bundled lists are empty, and
rows only arrive when Rescan sends `refresh_catalog` while online. So a
fresh data dir that was never refreshed must answer a recommendation
request with an explicit empty-catalog message, not an empty table or a
server error. Ranking itself is covered by the unit tests against an
authored fixture catalog. Downloading and serving a model is left to the
gap list: it needs tmux, a GPU runtime and several gigabytes over the
network.
"""
from __future__ import annotations
from pathlib import Path
import pytest
from src.constants import DATA_DIR
SYSTEM_PATH = "/api/hwfit/system"
MODELS_PATH = "/api/hwfit/models"
STATE_PATH = "/api/cookbook/state"
@@ -14,6 +24,10 @@ GPUS_PATH = "/api/cookbook/gpus"
STATE_MARKER = "odysseusSmokeMarker"
# Everything that can give the instance a catalog: the user catalog and the
# two caches a Rescan writes, all under the instance's data dir.
CATALOG_FILES = ("hf_models.json", "hf_collection_models.json", "mlx_community_models.json")
def test_hardware_is_detected(client):
response = client.get(SYSTEM_PATH)
@@ -28,14 +42,24 @@ def test_hardware_is_detected(client):
assert gpus.json().get("ok") is True, gpus.text
def test_recommendations_fit_the_detected_hardware(client):
def test_fresh_install_explains_how_to_populate_the_catalog(client):
catalog_dir = Path(DATA_DIR) / "hwfit"
present = [name for name in CATALOG_FILES if (catalog_dir / name).exists()]
if present:
pytest.skip(f"not a fresh install: {catalog_dir} already holds {present}")
response = client.get(MODELS_PATH)
assert response.status_code == 200, response.text
body = response.json()
system = body.get("system") or {}
assert system.get("cpu_name"), body
recommended = body.get("models") or body.get("recommendations") or []
assert recommended, f"no model recommendation for this hardware: {list(body)}"
assert body.get("models") == [], body
error = body.get("error") or ""
assert "Model catalog is empty" in error, body
assert "Rescan" in error, body
# A plain request never refreshes, so nothing was fetched behind our back.
assert "catalog_refresh" not in body, body
assert not any((catalog_dir / name).exists() for name in CATALOG_FILES)
def test_cookbook_state_persists(client):