Enhance error handling and state management in access card and session modules

- Updated the `render_access_panel` function to conditionally hide LLM errors when the Ollama model is operational, improving user experience by reducing unnecessary error visibility.
- Introduced a new `_notes_from_disk` function to streamline the retrieval of notes from disk, enhancing state management during GPU environment checks.
- Refactored error handling in the `_bind_access` function to ensure that stack and GPU environment errors are accurately recorded and managed, improving robustness in session state updates.
- Added tests to validate the new behavior of error handling and state management, ensuring that LLM errors are appropriately suppressed when conditions are met.
This commit is contained in:
Leonid Pershin
2026-08-21 20:20:49 +03:00
parent f8f8dcc93e
commit 79cb0a7e25
6 changed files with 156 additions and 22 deletions
+24
View File
@@ -42,3 +42,27 @@ def test_access_panel_red_when_killer_failed(monkeypatch):
)
panel = render_access_panel(_Cfg(), tunneled=True)
assert panel.border_style == "red"
def test_access_panel_hides_stale_llm_error_when_ollama_ok(monkeypatch):
monkeypatch.setattr(
"gpu_rent.access_card.load_state",
lambda: type(
"S",
(),
{
"notes": {
"llm_error": "Ollama /api/tags без моделей",
"stack_vm": [
{
"name": "ollama",
"ok": True,
"detail": "1 models (huihui_ai/qwen2.5-vl-abliterated:7b)",
}
],
}
},
)(),
)
panel = render_access_panel(_Cfg(), tunneled=True)
assert panel.border_style != "red"
+48
View File
@@ -181,3 +181,51 @@ def test_lock_busy(monkeypatch):
monkeypatch.setattr("gpu_rent.lock.os.getpid", lambda: 99)
with pytest.raises(GpuRentError, match="уже работает"):
SessionLock().__enter__()
def test_bind_access_keeps_provision_llm_notes(monkeypatch):
"""In-memory SessionState must not resurrect llm_error after provision_llm saved."""
from gpu_rent.ready import ServiceCheck
from gpu_rent.state import load_state
def fake_provision(cfg, host, log, **kw):
st = load_state()
st.notes = dict(st.notes or {})
st.notes["llm_runtime"] = "ollama"
st.notes.pop("llm_error", None)
save_state(st)
monkeypatch.setattr("gpu_rent.session.connect", lambda cfg: object())
monkeypatch.setattr("gpu_rent.session.compute_quotas", lambda conn: {"gpu": 1})
monkeypatch.setattr("gpu_rent.session.pick_existing_server", lambda conn: Server())
_mock_bind(monkeypatch)
monkeypatch.setattr("gpu_rent.session.provision_vm", fake_provision)
monkeypatch.setattr(
"gpu_rent.session.verify_stack_on_vm",
lambda cfg, host, log, **kw: [
ServiceCheck("swarmui", True, "HTTP 200"),
ServiceCheck("ollama", True, "1 models (qwen)"),
],
)
monkeypatch.setattr(
"gpu_rent.session.create_gpu_server",
lambda *a, **k: (_ for _ in ()).throw(AssertionError("must not create")),
)
save_state(
SessionState(
server_id="s1",
floating_ip="203.0.113.9",
bootstrapped=True,
phase="ready_cloud",
notes={
"llm_error": "Ollama /api/tags без моделей из ollama-models.yaml",
"llm_runtime": "none",
},
)
)
state = cmd_up(_cfg(monkeypatch), yes=True)
assert state.notes.get("llm_error") is None
assert state.notes.get("llm_runtime") == "ollama"
disk = load_state()
assert disk.notes.get("llm_error") is None
assert disk.notes.get("llm_runtime") == "ollama"
+18
View File
@@ -259,3 +259,21 @@ def test_jit_fail_strips_sage_extra_args(tmp_path, monkeypatch):
assert marker["pip_ok"] is True
assert marker["jit_ok"] is False
assert "--use-sage-attention" not in backends.read_text(encoding="utf-8")
def test_triton_jit_ok_runs_a_py_file(tmp_path, monkeypatch):
mod = _load()
py = tmp_path / "python"
py.write_text("", encoding="utf-8")
seen: list[list[str]] = []
def fake_output(cmd, **kw):
seen.append(list(cmd))
return "triton JIT ok\n"
monkeypatch.setattr(mod.subprocess, "check_output", fake_output)
assert mod.triton_jit_ok(py) is True
assert seen
assert seen[0][0] == str(py)
assert seen[0][1].endswith(".py")
assert "-c" not in seen[0]