From fce0942cb7d81dbdbae70e50b0164fead7e8bc49 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Tue, 15 Sep 2026 16:11:26 +0200 Subject: fix(node): purge the audit log past its retention AuditStore.cleanup was never called, so audit.db kept every entry. The daemon now runs it at start and daily. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01XuNrwLf5EFWCMHzfoEvnpm --- packages/meshbay-node/tests/test_audit.py | 41 ++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'packages/meshbay-node/tests/test_audit.py') diff --git a/packages/meshbay-node/tests/test_audit.py b/packages/meshbay-node/tests/test_audit.py index 8755be2..b5b98b5 100644 --- a/packages/meshbay-node/tests/test_audit.py +++ b/packages/meshbay-node/tests/test_audit.py @@ -1,10 +1,13 @@ """Tests for the node audit store (legal compliance IP/action logging).""" +import asyncio +import inspect import time import pytest - from meshbay_node.audit import AuditStore +from meshbay_node.config import Config, HubConfig, KeystoreConfig, NodeConfig +from meshbay_node.daemon import NodeDaemon @pytest.fixture @@ -95,3 +98,39 @@ async def test_cleanup_old_entries(audit): deleted = await audit.cleanup(retention_days=365) assert deleted == 1 assert await audit.entry_count() == 1 + + +@pytest.mark.asyncio +async def test_daemon_purges_the_audit_log(audit, tmp_path): + """The daemon runs the retention itself: at start, then on its interval.""" + daemon = NodeDaemon(Config( + hub=HubConfig(url="http://localhost:9999", username="testuser"), + node=NodeConfig(), groups=[], + keystore=KeystoreConfig(path=tmp_path / "keystore.enc"), + data_dir=tmp_path / "data")) + daemon._audit_store = audit + + async def backdated(event): + await audit.log_event(user_id="u1", event=event) + await audit._db.execute( + "UPDATE audit_log SET timestamp = ? WHERE event = ?", + (time.time() - 400 * 86400, event)) + await audit._db.commit() + + await backdated("old") + await audit.log_event(user_id="u2", event="recent") + task = asyncio.create_task(daemon._purge_audit_log(interval=0.05)) + try: + await asyncio.sleep(0.02) + assert [e.event for e in await audit.get_entries()] == ["recent"] + await backdated("later") + await asyncio.sleep(0.1) + assert [e.event for e in await audit.get_entries()] == ["recent"] + finally: + task.cancel() + await asyncio.gather(task, return_exceptions=True) + + +def test_daemon_starts_the_purge(): + source = inspect.getsource(NodeDaemon) + assert "create_task(self._purge_audit_log())" in source -- cgit v1.2.3