fix(test_watcher): wait for the watcher to actually run, not a fixed 0.9s

watcher.py debounces step=500ms/debounce=1500ms, so a 0.9s sleep never let
the watcher observe our own write at all -- the test passed 10/10 even with
the self-write dedup in service._sync_path removed, because it was really
only checking that write_note() calls index_note once. Now it also counts
_sync_path invocations (which run on every watcher batch regardless of
dedup) and polls deterministically until the watcher has demonstrably fired
before checking the dedup invariant.

Verified: with the dedup in service._sync_path temporarily disabled, this
test fails (calls == 2); restored, it passes.

Test: tests/test_watcher.py::test_service_own_write_does_not_double_index
This commit is contained in:
Markus committed 2026-09-12 18:34:13 +00:00
1 parent 491e8e5453
commit 7cfaeb3a02
1 file changed
+30 -1
+30 -1
View File
@@ -65,6 +65,18 @@ async def test_deleting_a_file_removes_it_from_the_index(svc):
async def test_service_own_write_does_not_double_index(svc, monkeypatch):
"""The watcher's debounce (watcher.py: step=500ms, debounce=1500ms) means
the watcher cannot possibly have observed a write before ~1.5s have
passed. A fixed 0.9s sleep never let it run at all, so this test used to
pass 10/10 even with the self-write dedup in service._sync_path removed
entirely -- it was only ever checking that write_note() itself calls
index_note once, not that the watcher declines to call it again.
Instead we count `_sync_path` invocations too (that method runs on every
watcher batch regardless of whether dedup skips indexing) and poll
deterministically until the watcher has demonstrably processed our own
write, so the assertion below is only reached once there is something
real to assert about."""
calls = 0
original = svc.indexer.index_note
@@ -74,8 +86,25 @@ async def test_service_own_write_does_not_double_index(svc, monkeypatch):
return original(note)
monkeypatch.setattr(svc.indexer, "index_note", counted)
sync_calls = 0
original_sync_path = svc._sync_path
def counted_sync_path(path):
nonlocal sync_calls
sync_calls += 1
return original_sync_path(path)
monkeypatch.setattr(svc, "_sync_path", counted_sync_path)
res = await svc.write_note(title="Eigener Schreibvorgang", body="Inhalt", type="fact")
await asyncio.sleep(0.9) # let the watcher see our own write
loop = asyncio.get_running_loop()
deadline = loop.time() + 4.0
while sync_calls == 0 and loop.time() < deadline:
await asyncio.sleep(0.1)
assert sync_calls > 0, "watcher never observed our own write within 4s"
rows = svc.db.read().execute("SELECT count(*) FROM chunks WHERE note_id=?", (res["id"],)).fetchone()[0]
assert rows == 1
assert calls == 1