perf: search.py N+1 batching + k constant extraction (T106)
This commit is contained in:
@@ -16,6 +16,7 @@ Verifies the FastAPI ``/search`` route that wraps T93's
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -133,3 +134,30 @@ def test_result_links_navigate_to_chat(client, tmp_path):
|
||||
# The link target is chat-level (memories don't carry an event_id
|
||||
# column today, so we don't deep-link to a specific turn).
|
||||
assert 'href="/chats/chat_a"' in resp.text
|
||||
|
||||
|
||||
def test_search_results_use_batched_lookups(client, tmp_path):
|
||||
"""T106: hydration must not fan out to per-row ``get_bot``/
|
||||
``get_chat``/``get_scene`` calls.
|
||||
|
||||
The previous implementation called each helper once per result row
|
||||
(worst case 50 rows x 3 helpers = 150 individual queries). The
|
||||
batched implementation collects distinct ids and issues at most one
|
||||
query per entity kind via ``WHERE id IN (...)``, so the per-row
|
||||
helpers should not be invoked at all when there are matches.
|
||||
|
||||
We seed two chats (so both ``get_bot`` and ``get_chat`` would have
|
||||
been hit pre-T106) and assert each helper sees zero per-row calls.
|
||||
"""
|
||||
_seed_two_chats_with_memories(tmp_path / "test.db")
|
||||
with (
|
||||
patch("chat.web.search.get_bot") as mock_get_bot,
|
||||
patch("chat.web.search.get_chat") as mock_get_chat,
|
||||
patch("chat.web.search.get_scene") as mock_get_scene,
|
||||
):
|
||||
resp = client.get("/search?q=rabbit")
|
||||
assert resp.status_code == 200
|
||||
# Batched IN-list queries replace the per-row helpers entirely.
|
||||
assert mock_get_bot.call_count == 0
|
||||
assert mock_get_chat.call_count == 0
|
||||
assert mock_get_scene.call_count == 0
|
||||
|
||||
Reference in New Issue
Block a user