from gpu_rent.tunnel import decide_watch, tunnel_forwards def test_decide_ok_active(): d = decide_watch("ACTIVE", tunnel_alive=True) assert d.kind == "ok" def test_decide_reconnect_when_tunnel_dead(): d = decide_watch("ACTIVE", tunnel_alive=False) assert d.kind == "reconnect" def test_decide_unshelve_expired(): for st in ("EXPIRED", "SHELVED", "SHELVED_OFFLOADED"): d = decide_watch(st, tunnel_alive=True) assert d.kind == "unshelve", st def test_decide_exit_error(): d = decide_watch("ERROR", tunnel_alive=True) assert d.kind == "exit" def test_decide_exit_missing(): d = decide_watch(None, tunnel_alive=False) assert d.kind == "exit" def test_decide_soft_fail_keeps_tunnel(): d = decide_watch("SOFT_FAIL", tunnel_alive=True) assert d.kind == "ok" assert "soft-fail" in d.detail def test_tunnel_forwards_swarm_only(): class Cfg: swarmui_local_port = 17801 llm_runtime = "none" ollama_local_port = 17811 enable_swarmui = True assert tunnel_forwards(Cfg()) == [(17801, 7801)] def test_tunnel_forwards_prefers_cfg_over_stale_notes(): """tunnel_forwards uses cfg only — notes must not add Ollama.""" class Cfg: swarmui_local_port = 17801 llm_runtime = "none" ollama_local_port = 17811 enable_swarmui = True assert tunnel_forwards(Cfg()) == [(17801, 7801)] def test_resolve_llm_uses_cfg_only(monkeypatch): from gpu_rent.access_card import resolve_llm_runtime class Cfg: llm_runtime = "none" monkeypatch.setattr( "gpu_rent.access_card.load_state", lambda: type("S", (), {"notes": {"llm_runtime": "ollama"}})(), ) # Stale notes must not override live cfg=none assert resolve_llm_runtime(Cfg()) == "none" class Cfg2: llm_runtime = "ollama" assert resolve_llm_runtime(Cfg2()) == "ollama"