Enhance logging functionality in CLI and tunnel operations. Updated gpu-rent logs to provide a complete journal output, including cloud-init logs by default. Added log digest printing for better visibility during VM operations, especially on failure scenarios. Improved error handling and added tests for new log digest features.
This commit is contained in:
@@ -145,6 +145,7 @@ def _stub_tunnel(monkeypatch) -> None:
|
||||
monkeypatch.setattr("gpu_rent.tunnel.load_state", lambda: st)
|
||||
monkeypatch.setattr("gpu_rent.tunnel.save_state", lambda s: None)
|
||||
monkeypatch.setattr("gpu_rent.access_card.print_access_card", lambda *a, **k: None)
|
||||
monkeypatch.setattr("gpu_rent.vm_logs.print_log_digest", lambda *a, **k: None)
|
||||
monkeypatch.setattr("gpu_rent.local_watchdog.watchdog_installed", lambda: False)
|
||||
monkeypatch.setattr("gpu_rent.local_watchdog.clear_lease", lambda: None)
|
||||
|
||||
|
||||
@@ -15,11 +15,42 @@ def test_stop_after_failed_up_calls_cmd_stop(monkeypatch):
|
||||
monkeypatch.setattr("gpu_rent.cli.ok", lambda *_a, **_k: None)
|
||||
monkeypatch.setattr("gpu_rent.cli.err", lambda *_a, **_k: None)
|
||||
monkeypatch.setattr("gpu_rent.cli.log", lambda *_a, **_k: None)
|
||||
monkeypatch.setattr(
|
||||
"gpu_rent.state.load_state",
|
||||
lambda: SimpleNamespace(floating_ip=None),
|
||||
)
|
||||
|
||||
_stop_after_failed_up(SimpleNamespace(), RuntimeError("boom"))
|
||||
assert calls == [{"no_pull": True, "destroy_disks": False}]
|
||||
|
||||
|
||||
def test_stop_after_failed_up_prints_digest_when_fip(monkeypatch):
|
||||
calls: list[dict] = []
|
||||
digests: list[str] = []
|
||||
|
||||
def fake_stop(cfg, *, no_pull=False, log=None, destroy_disks=False):
|
||||
calls.append({"no_pull": no_pull})
|
||||
return SimpleNamespace()
|
||||
|
||||
monkeypatch.setattr("gpu_rent.cli.cmd_stop", fake_stop)
|
||||
monkeypatch.setattr("gpu_rent.cli.warn", lambda *_a, **_k: None)
|
||||
monkeypatch.setattr("gpu_rent.cli.ok", lambda *_a, **_k: None)
|
||||
monkeypatch.setattr("gpu_rent.cli.err", lambda *_a, **_k: None)
|
||||
monkeypatch.setattr("gpu_rent.cli.log", lambda *_a, **_k: None)
|
||||
monkeypatch.setattr(
|
||||
"gpu_rent.state.load_state",
|
||||
lambda: SimpleNamespace(floating_ip="10.0.0.1"),
|
||||
)
|
||||
monkeypatch.setattr(
|
||||
"gpu_rent.vm_logs.print_log_digest",
|
||||
lambda cfg, host, **kw: digests.append(host),
|
||||
)
|
||||
|
||||
_stop_after_failed_up(SimpleNamespace(enable_swarmui=True, llm_runtime="none"), RuntimeError("boom"))
|
||||
assert digests == ["10.0.0.1"]
|
||||
assert calls == [{"no_pull": True}]
|
||||
|
||||
|
||||
def test_up_stop_on_fail_default_true(monkeypatch, tmp_path):
|
||||
monkeypatch.setenv("HOME", str(tmp_path))
|
||||
monkeypatch.setenv("USERPROFILE", str(tmp_path))
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
"""Unit tests for vm_logs digest / CLI log command builders."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from gpu_rent.vm_logs import (
|
||||
DIGEST_LINES,
|
||||
KILLER_UNIT,
|
||||
build_logs_remote_cmd,
|
||||
fetch_unit_logs,
|
||||
resolve_unit_alias,
|
||||
units_for,
|
||||
)
|
||||
|
||||
|
||||
class _Cfg:
|
||||
def __init__(self, *, enable_swarmui: bool = True, llm_runtime: str = "none"):
|
||||
self.enable_swarmui = enable_swarmui
|
||||
self.llm_runtime = llm_runtime
|
||||
|
||||
|
||||
def test_units_for_swarm_and_ollama():
|
||||
assert units_for(_Cfg(enable_swarmui=True, llm_runtime="ollama")) == [
|
||||
"swarmui",
|
||||
"ollama",
|
||||
KILLER_UNIT,
|
||||
]
|
||||
|
||||
|
||||
def test_units_for_swarm_only():
|
||||
assert units_for(_Cfg(enable_swarmui=True, llm_runtime="none")) == [
|
||||
"swarmui",
|
||||
KILLER_UNIT,
|
||||
]
|
||||
|
||||
|
||||
def test_units_for_llm_only():
|
||||
assert units_for(_Cfg(enable_swarmui=False, llm_runtime="ollama")) == [
|
||||
"ollama",
|
||||
KILLER_UNIT,
|
||||
]
|
||||
|
||||
|
||||
def test_digest_cmd_has_journal_no_cloud_init():
|
||||
units = units_for(_Cfg(enable_swarmui=True, llm_runtime="ollama"))
|
||||
cmd = build_logs_remote_cmd(
|
||||
lines=DIGEST_LINES,
|
||||
include_cloud_init=False,
|
||||
journal_units=units,
|
||||
)
|
||||
assert "cloud-init" not in cmd
|
||||
assert "journalctl -u swarmui" in cmd
|
||||
assert "journalctl -u ollama" in cmd
|
||||
assert f"journalctl -u {KILLER_UNIT}" in cmd
|
||||
assert f"-n {DIGEST_LINES}" in cmd
|
||||
assert "systemctl is-active swarmui" in cmd
|
||||
|
||||
|
||||
def test_full_logs_cmd_includes_cloud_init():
|
||||
cmd = build_logs_remote_cmd(
|
||||
lines=80,
|
||||
include_cloud_init=True,
|
||||
journal_units=["swarmui", "ollama", KILLER_UNIT],
|
||||
)
|
||||
assert "cloud-init-output.log" in cmd
|
||||
assert "journalctl -u swarmui" in cmd
|
||||
|
||||
|
||||
def test_resolve_unit_alias():
|
||||
assert resolve_unit_alias(None) == "all"
|
||||
assert resolve_unit_alias("swarm") == "swarmui"
|
||||
assert resolve_unit_alias("killer") == KILLER_UNIT
|
||||
with pytest.raises(ValueError, match="неизвестный"):
|
||||
resolve_unit_alias("bogus")
|
||||
|
||||
|
||||
def test_fetch_unit_logs_uses_ssh(monkeypatch):
|
||||
calls: list[tuple] = []
|
||||
|
||||
def fake_ssh(cfg, host, command, check=False, timeout=60):
|
||||
calls.append((host, command, check, timeout))
|
||||
return "active\nok"
|
||||
|
||||
monkeypatch.setattr("gpu_rent.vm_logs.run_ssh", fake_ssh)
|
||||
cfg = _Cfg(enable_swarmui=True, llm_runtime="none")
|
||||
out = fetch_unit_logs(cfg, "1.2.3.4", units_for(cfg), lines=20)
|
||||
assert out == "active\nok"
|
||||
assert calls[0][0] == "1.2.3.4"
|
||||
assert "cloud-init" not in calls[0][1]
|
||||
assert "journalctl -u swarmui" in calls[0][1]
|
||||
assert f"journalctl -u {KILLER_UNIT}" in calls[0][1]
|
||||
assert "journalctl -u ollama" not in calls[0][1]
|
||||
Reference in New Issue
Block a user