test(audit): fix critical test suite deadlocks and write exhaustive architectural report
- Fix 'Triple Bingo' history synchronization explosion during streaming - Implement stateless event buffering in ApiHookClient to prevent dropped events - Ensure 'tool_execution' events emit consistently across all LLM providers - Add hard timeouts to all background thread wait() conditions - Add thorough teardown cleanup to conftest.py's reset_ai_client fixture - Write highly detailed report_gemini.md exposing asyncio lifecycle flaws
This commit is contained in:
@@ -9,6 +9,7 @@ class ApiHookClient:
|
||||
self.base_url = base_url
|
||||
self.max_retries = max_retries
|
||||
self.retry_delay = retry_delay
|
||||
self._event_buffer: list[dict[str, Any]] = []
|
||||
|
||||
def wait_for_server(self, timeout: float = 3) -> bool:
|
||||
"""
|
||||
@@ -209,21 +210,31 @@ class ApiHookClient:
|
||||
return {"tag": tag, "shown": False, "error": str(e)}
|
||||
|
||||
def get_events(self) -> list[Any]:
|
||||
"""Fetches and clears the event queue from the server."""
|
||||
"""Fetches new events and adds them to the internal buffer."""
|
||||
try:
|
||||
res = self._make_request('GET', '/api/events')
|
||||
return res.get("events", []) if res else []
|
||||
new_events = res.get("events", []) if res else []
|
||||
if new_events:
|
||||
self._event_buffer.extend(new_events)
|
||||
return list(self._event_buffer)
|
||||
except Exception:
|
||||
return []
|
||||
return list(self._event_buffer)
|
||||
|
||||
def clear_events(self) -> None:
|
||||
"""Clears the internal event buffer and the server queue."""
|
||||
self._make_request('GET', '/api/events')
|
||||
self._event_buffer.clear()
|
||||
|
||||
def wait_for_event(self, event_type: str, timeout: float = 5) -> dict[str, Any] | None:
|
||||
"""Polls for a specific event type."""
|
||||
"""Polls for a specific event type in the internal buffer."""
|
||||
start = time.time()
|
||||
while time.time() - start < timeout:
|
||||
events = self.get_events()
|
||||
for ev in events:
|
||||
# Refresh buffer
|
||||
self.get_events()
|
||||
# Search in buffer
|
||||
for i, ev in enumerate(self._event_buffer):
|
||||
if isinstance(ev, dict) and ev.get("type") == event_type:
|
||||
return ev
|
||||
return self._event_buffer.pop(i)
|
||||
time.sleep(0.1) # Fast poll
|
||||
return None
|
||||
|
||||
|
||||
Reference in New Issue
Block a user