Refactor history sync into history_service and update docs/tests

This commit is contained in:
2026-04-14 15:09:58 +02:00
parent 86fa271c40
commit 58bb769a35
7 changed files with 147 additions and 90 deletions

View File

@@ -378,3 +378,58 @@ class TestGetIpDetail:
assert result.country_name == "United States"
assert result.asn == "AS15169"
assert result.org == "Google"
# ---------------------------------------------------------------------------
# sync_from_fail2ban_db tests
# ---------------------------------------------------------------------------
class TestSyncFromFail2BanDb:
async def test_archives_new_records_and_returns_count(self) -> None:
from types import SimpleNamespace
fake_db = AsyncMock()
fake_rows = [
SimpleNamespace(
jail="sshd",
ip="1.2.3.4",
timeofban=1000,
bancount=1,
data="{}",
)
]
with patch(
"app.services.history_service._get_last_archive_ts",
new=AsyncMock(return_value=1000),
), patch(
"app.services.history_service.get_fail2ban_db_path",
new=AsyncMock(return_value="/tmp/fake.sqlite3"),
), patch(
"app.services.history_service.fail2ban_db_repo.get_history_page",
new=AsyncMock(return_value=(fake_rows, 1)),
) as mock_page, patch(
"app.services.history_service.archive_ban_event",
new=AsyncMock(return_value=True),
) as archive_mock:
count = await history_service.sync_from_fail2ban_db(
fake_db, "/tmp/fake.sock"
)
assert count == 1
mock_page.assert_awaited_once_with(
db_path="/tmp/fake.sqlite3",
since=1001,
page=1,
page_size=500,
)
archive_mock.assert_awaited_once_with(
db=fake_db,
jail="sshd",
ip="1.2.3.4",
timeofban=1000,
bancount=1,
data="{}",
action="ban",
)

View File

@@ -31,35 +31,26 @@ class TestHistorySyncTask:
async def test_backfill_window_is_7_5_days(self) -> None:
assert history_sync.BACKFILL_WINDOW == 648000
async def test_sync_uses_strict_since_after_restart(self) -> None:
async def test_run_sync_delegates_to_history_service(self) -> None:
fake_app = type("FakeApp", (), {})()
fake_app.state = type("FakeState", (), {})()
fake_app.state.settings = type("FakeSettings", (), {})()
fake_app.state.settings.fail2ban_socket = "/tmp/fake.sock"
fake_app.state.settings.database_path = "/tmp/fake.db"
fake_app.state.db = MagicMock()
fake_app.state.db.close = AsyncMock()
async def fake_get_history_page(*, db_path: str, since: int, page: int, page_size: int, **kwargs):
assert since == 1001
return [], 0
async def fake_get_fail2ban_db_path(socket_path: str) -> str:
return "/tmp/fake.sqlite3"
fake_db = AsyncMock()
fake_db.close = AsyncMock()
with patch(
"app.tasks.history_sync.open_db",
new_callable=AsyncMock,
return_value=fake_app.state.db,
return_value=fake_db,
), patch(
"app.tasks.history_sync._get_last_archive_ts",
new=AsyncMock(return_value=1000),
), patch(
"app.tasks.history_sync.get_fail2ban_db_path",
new=fake_get_fail2ban_db_path,
), patch(
"app.tasks.history_sync.fail2ban_db_repo.get_history_page",
new=fake_get_history_page,
):
"app.tasks.history_sync.history_service.sync_from_fail2ban_db",
new_callable=AsyncMock,
return_value=42,
) as mock_sync:
await history_sync._run_sync(fake_app)
mock_sync.assert_awaited_once_with(fake_db, "/tmp/fake.sock")
fake_db.close.assert_awaited_once()