Add a health check for the daemon and RPC endpoint (#34)
* Add a health check for the daemon and RPC endpoint SeafileClient.is_healthy() checks seaf-cli status and makes a real RPC call (get_repo_list) against the daemon's Unix socket - neither needs the Seafile server, so it works without a token or password. healthcheck.py exposes it as a plain script for Docker's HEALTHCHECK. Each check is a fresh process spawned by the Docker daemon as root, unlike the long-lived start.py process, so it drops to the seafile user with runuser before touching the RPC socket - the one place that mechanism still belongs after the earlier in-process privilege drop. Verified against the real image: healthcheck.py exits 0 once the real daemon is up (through the actual main() entrypoint, not a test fixture) and nonzero when no daemon has been started. * Assert the return value in the daemon-down health check test Copilot review: the test checked the RPC call was skipped but not what is_healthy() actually returned in that case. --------- Co-authored-by: Maxim Shulga <maxim.shulga@alludo.com>
This commit is contained in:
1 parent
ba5ad177b7
commit
28db575c92
7 files changed
+133
-4
No files matched your search
@@ -0,0 +1,40 @@
|
||||
"""The container HEALTHCHECK must reflect both the daemon and its RPC socket."""
|
||||
|
||||
import pytest
|
||||
|
||||
from dsc.client import SeafileClient
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client():
|
||||
return SeafileClient("seafile.example", "user", "pw", "/dsc", token="tok-en")
|
||||
|
||||
|
||||
def test_healthy_when_daemon_and_rpc_both_respond(client, monkeypatch):
|
||||
monkeypatch.setattr(type(client), "daemon_ready", True)
|
||||
monkeypatch.setattr(client.rpc, "get_repo_list", lambda a, b: [])
|
||||
assert client.is_healthy() is True
|
||||
|
||||
|
||||
def test_unhealthy_when_the_daemon_is_not_ready(client, monkeypatch):
|
||||
monkeypatch.setattr(type(client), "daemon_ready", False)
|
||||
assert client.is_healthy() is False
|
||||
|
||||
|
||||
def test_unhealthy_when_the_rpc_socket_raises(client, monkeypatch):
|
||||
monkeypatch.setattr(type(client), "daemon_ready", True)
|
||||
|
||||
def broken(a, b):
|
||||
raise ConnectionError("socket gone")
|
||||
|
||||
monkeypatch.setattr(client.rpc, "get_repo_list", broken)
|
||||
assert client.is_healthy() is False
|
||||
|
||||
|
||||
def test_rpc_is_not_checked_when_the_daemon_is_already_down(client, monkeypatch):
|
||||
"""A dead daemon means a dead socket too; no need to touch it."""
|
||||
monkeypatch.setattr(type(client), "daemon_ready", False)
|
||||
called = []
|
||||
monkeypatch.setattr(client.rpc, "get_repo_list", lambda a, b: called.append(1))
|
||||
assert client.is_healthy() is False
|
||||
assert not called
|
||||
Reference in new issue
Block a user