haiku.rag/tests/test_vacuum_debounce.py

56 lines
1.9 KiB
Python

import asyncio
import pytest
import haiku.rag.client as client_mod
from haiku.rag.client import HaikuRAG
@pytest.mark.asyncio
async def test_schedule_vacuum_is_debounced(temp_db_path, monkeypatch):
"""Rapid writes within the throttle window schedule only one background
vacuum; once the interval elapses, a new one is scheduled."""
t = {"now": 1000.0}
monkeypatch.setattr(client_mod, "monotonic", lambda: t["now"])
async with HaikuRAG(temp_db_path, create=True) as client:
calls: list[int] = []
async def fake_vacuum(*_a, **_k):
calls.append(1)
monkeypatch.setattr(client.store, "vacuum", fake_vacuum)
for _ in range(3):
client._schedule_vacuum()
await asyncio.gather(*client._vacuum_tasks)
assert len(calls) == 1 # debounced within the interval
t["now"] += client_mod._VACUUM_MIN_INTERVAL_S + 1
client._schedule_vacuum()
await asyncio.gather(*client._vacuum_tasks)
assert len(calls) == 2 # interval elapsed -> a new vacuum scheduled
@pytest.mark.asyncio
async def test_debounced_writes_still_collapse_on_close(temp_db_path, monkeypatch):
"""Even when scheduled vacuums after the first are debounced, the writes are
marked dirty so the close-time drain runs a final collapse."""
t = {"now": 1000.0}
monkeypatch.setattr(client_mod, "monotonic", lambda: t["now"])
calls: list[int] = []
async with HaikuRAG(temp_db_path, create=True) as client:
async def fake_vacuum(*_a, **_k):
calls.append(1)
monkeypatch.setattr(client.store, "vacuum", fake_vacuum)
client._schedule_vacuum() # schedules the first background pass
client._schedule_vacuum() # debounced (no task)
await client._await_vacuum_tasks()
# one scheduled background pass + one final collapse on drain
assert len(calls) == 2
assert client._vacuum_dirty is False