perf(tests): cut test_hermes_state.py 52s -> 10s — kill sleep throttle + per-row seeding
test_hermes_state.py was the slowest file in the suite (46.7s in CI's durations cache) and therefore the LPT floor: no test slice can finish faster than its slowest file, which caps how far slicing the test matrix wider can cut the merge-gate critical path. Profiling (cProfile on the slowest tests) found the time was dead, not work: 1. time.sleep in optimize_fts_storage's inter-chunk throttle — 4.1s of a 4.6s migration test. The throttle exists so a LIVE gateway/CLI sharing the DB isn't starved of the write lock; tests run against a private tmp-path DB with no concurrent process, so the sleep protects nobody. New autouse fixture zeroes _FTS_REBUILD_MIN_PAUSE / _FTS_REBUILD_DUTY_FACTOR for this file (~20s saved). No test asserts on wall-clock pacing, so nothing weakens. 2. TestGetMessagesPagination._seed appending 3000 messages one append_message (= one commit, and off WAL one fsync) at a time — ~10s of seeding before the query under test even ran. Switched to append_messages_batch (one write transaction), the API the docstring of which exists for exactly this shape. The perf contract the seed feeds still discriminates: measured 11 progress-handler steps on the indexed path vs 855 on the forced scan path, against the unchanged 300 threshold. Measured (local, 3 runs + canonical runner): before: 187 passed in 51.8s after: 187 passed in 9.1-16.1s (canonical scripts/run_tests.sh: 14.9s) Zero production code touched; 187 tests before and after.
This commit is contained in:
parent
be1740d110
commit
169758d42f
|
|
@ -78,6 +78,24 @@ def db(tmp_path):
|
|||
session_db.close()
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def _no_fts_rebuild_throttle(monkeypatch):
|
||||
"""Zero the FTS-rebuild inter-chunk throttle for every test in this file.
|
||||
|
||||
``optimize_fts_storage`` sleeps ``max(_FTS_REBUILD_MIN_PAUSE,
|
||||
chunk_cost * _FTS_REBUILD_DUTY_FACTOR)`` between chunks so a LIVE
|
||||
gateway/CLI sharing the DB isn't starved of the write lock. Tests run
|
||||
against a private tmp-path DB with no concurrent process — the sleep
|
||||
protects nobody and was pure dead time (measured: 4.1s of a 4.6s
|
||||
migration test was time.sleep; ~20s across the file, whose total was
|
||||
~52s). The duty-cycle POLICY (sleep >= 4x chunk cost) stays covered by
|
||||
the production constants themselves; no test asserts on wall-clock
|
||||
pacing.
|
||||
"""
|
||||
monkeypatch.setattr(SessionDB, "_FTS_REBUILD_MIN_PAUSE", 0.0)
|
||||
monkeypatch.setattr(SessionDB, "_FTS_REBUILD_DUTY_FACTOR", 0.0)
|
||||
|
||||
|
||||
# =========================================================================
|
||||
# Connection lifecycle
|
||||
# =========================================================================
|
||||
|
|
@ -3564,8 +3582,19 @@ class TestGetMessagesPagination:
|
|||
|
||||
def _seed(self, db, n=10):
|
||||
db.create_session(session_id="s1", source="cli")
|
||||
for i in range(n):
|
||||
db.append_message("s1", "user" if i % 2 == 0 else "assistant", f"msg-{i}")
|
||||
# One write transaction for the whole seed: per-row append_message
|
||||
# pays a commit (and, off WAL, an fsync) per message, which at
|
||||
# n=3000 was ~10s of pure seeding before the query under test ran.
|
||||
db.append_messages_batch(
|
||||
"s1",
|
||||
[
|
||||
{
|
||||
"role": "user" if i % 2 == 0 else "assistant",
|
||||
"content": f"msg-{i}",
|
||||
}
|
||||
for i in range(n)
|
||||
],
|
||||
)
|
||||
|
||||
def test_default_returns_all_messages(self, db):
|
||||
self._seed(db)
|
||||
|
|
|
|||
Loading…
Reference in New Issue