diff --git a/tests/test_wireguard.py b/tests/test_wireguard.py index ba792f7..b5ae07a 100644 --- a/tests/test_wireguard.py +++ b/tests/test_wireguard.py @@ -6,6 +6,7 @@ to its pre-call state. """ import subprocess +from pathlib import Path import pytest @@ -59,14 +60,20 @@ def test_enable_requires_wg_config(tmp_path): wireguard.set_tunnel_enabled(True, conf_path=tmp_path / "furtka-gw.conf") -def test_enable_surfaces_clean_error_on_unreadable_conf_dir(tmp_path): - restricted = tmp_path / "restricted" - restricted.mkdir(mode=0o000) - try: - with pytest.raises(wireguard.WireguardError, match="could not access"): - wireguard.set_tunnel_enabled(True, wg=WG, conf_path=restricted / "furtka-gw.conf") - finally: - restricted.chmod(0o700) +def test_enable_surfaces_clean_error_on_unreadable_conf_dir(tmp_path, monkeypatch): + # Simulated rather than via a 0o000 directory: CI runs as root, which + # ignores directory permissions. + def denied(self, *a, **kw): + raise PermissionError(13, "Permission denied", str(self)) + + monkeypatch.setattr(Path, "mkdir", denied) + + def must_not_reload(action): + raise AssertionError("systemctl must not run when the conf can't be written") + + conf_path = tmp_path / "restricted" / "furtka-gw.conf" + with pytest.raises(wireguard.WireguardError, match="could not access"): + wireguard.set_tunnel_enabled(True, wg=WG, conf_path=conf_path, reload=must_not_reload) def test_default_conf_path_uses_env_override(monkeypatch, tmp_path): @@ -157,20 +164,23 @@ def test_status_not_configured(tmp_path): assert s == {"configured": False, "latest_handshake": None} -def test_status_survives_unreadable_conf_path(tmp_path): +def test_status_survives_unreadable_conf_path(tmp_path, monkeypatch): """Regression: an inaccessible parent directory raises PermissionError even for a path that doesn't exist yet — confirmed by actually hitting this against a real box's /etc/wireguard/ as a non-root user, which crashed the whole /api/gateway/status request with a raw traceback. A read-only status check must degrade to "not configured", never 500. """ - restricted = tmp_path / "restricted" - restricted.mkdir(mode=0o000) - try: - s = wireguard.status(conf_path=restricted / "furtka-gw.conf") - assert s == {"configured": False, "latest_handshake": None} - finally: - restricted.chmod(0o700) # so tmp_path cleanup can remove it + + # Simulated rather than via a 0o000 directory: CI runs as root, which + # ignores directory permissions. + def denied(self): + raise PermissionError(13, "Permission denied", str(self)) + + monkeypatch.setattr(Path, "is_file", denied) + + s = wireguard.status(conf_path=tmp_path / "restricted" / "furtka-gw.conf") + assert s == {"configured": False, "latest_handshake": None} def test_status_configured_reports_handshake(tmp_path):