feat: add TunnelConfig dataclass and YAML I/O

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-21 11:31:19 +08:00
parent 113cc994b1
commit 53133ccb67
3 changed files with 151 additions and 0 deletions

19
tests/conftest.py Normal file
View File

@@ -0,0 +1,19 @@
import pytest
from autossh_mgr.config import TunnelConfig, ensure_dirs
@pytest.fixture
def config_dir(tmp_path):
ensure_dirs(tmp_path)
return tmp_path
@pytest.fixture
def sample_tunnel():
return TunnelConfig(
name="web-service",
host="relay.example.com",
user="deploy",
local_port=8080,
remote_port=18080,
)

61
tests/unit/test_config.py Normal file
View File

@@ -0,0 +1,61 @@
import pytest
import click
from autossh_mgr.config import (
TunnelConfig, ensure_dirs, load_tunnels, save_tunnels, get_tunnel
)
def test_ensure_dirs_creates_structure(tmp_path):
ensure_dirs(tmp_path)
assert (tmp_path / "tunnels.yaml").exists()
assert (tmp_path / "pids").is_dir()
assert (tmp_path / "logs").is_dir()
def test_ensure_dirs_is_idempotent(tmp_path):
ensure_dirs(tmp_path)
ensure_dirs(tmp_path) # must not raise
def test_load_tunnels_empty(config_dir):
assert load_tunnels(config_dir) == []
def test_save_and_load_roundtrip(config_dir, sample_tunnel):
save_tunnels(config_dir, [sample_tunnel])
loaded = load_tunnels(config_dir)
assert len(loaded) == 1
t = loaded[0]
assert t.name == "web-service"
assert t.host == "relay.example.com"
assert t.user == "deploy"
assert t.local_port == 8080
assert t.remote_port == 18080
assert t.port == 22
assert t.identity_file == "~/.ssh/id_ed25519"
assert t.local_host == "127.0.0.1"
assert t.remote_host == "0.0.0.0"
assert t.ssh_options == ""
def test_save_atomic_write(config_dir, sample_tunnel):
save_tunnels(config_dir, [sample_tunnel])
# No .tmp file left behind
assert not (config_dir / "tunnels.yaml.tmp").exists()
def test_get_tunnel_found(config_dir, sample_tunnel):
save_tunnels(config_dir, [sample_tunnel])
t = get_tunnel(config_dir, "web-service")
assert t.name == "web-service"
def test_get_tunnel_not_found(config_dir):
with pytest.raises(click.ClickException, match="No tunnel named 'missing'"):
get_tunnel(config_dir, "missing")
def test_get_config_dir_env_override(monkeypatch, tmp_path):
monkeypatch.setenv("AUTOSSH_MGR_CONFIG_DIR", str(tmp_path))
from autossh_mgr.config import get_config_dir
assert get_config_dir() == tmp_path