fix: test DB isolation, Discord recovery, and over-mocked tests

Test data was bleeding into production tasks.db because
swarm.task_queue.models.DB_PATH (relative path) was never patched in
conftest.clean_database. Fixed by switching to absolute paths via
settings.repo_root and adding the missing module to the patching list.

Discord bot could leak orphaned clients on retry after ERROR state.
Added _cleanup_stale() to close stale client/task before each start()
attempt, with improved logging in the token watcher.

Rewrote test_paperclip_client.py to use httpx.MockTransport instead of
patching _get/_post/_delete — tests now exercise real HTTP status codes,
error handling, and JSON parsing. Added end-to-end test for
capture_error → create_task DB isolation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trip T
2026-03-11 20:33:59 -04:00
parent 9d9449cdcf
commit ea2dbdb4b5
8 changed files with 253 additions and 66 deletions

View File

@@ -134,6 +134,12 @@ class DiscordVendor(ChatPlatform):
logger.warning("Discord bot: no token configured, skipping start.")
return False
# Clean up any stale client/task from a previous failed attempt
# so we don't leak background tasks or hold orphaned connections.
# Must happen before the import check — the old client could exist
# from when discord.py was available.
await self._cleanup_stale()
try:
import discord
except ImportError:
@@ -163,9 +169,10 @@ class DiscordVendor(ChatPlatform):
logger.info("Discord bot connected (%d guilds).", self._guild_count)
return True
if self._state == PlatformState.ERROR:
logger.warning("Discord bot: entered ERROR state during connection.")
return False
logger.warning("Discord bot: connection timed out.")
logger.warning("Discord bot: connection timed out after 15s.")
self._state = PlatformState.ERROR
return False
@@ -176,6 +183,23 @@ class DiscordVendor(ChatPlatform):
self._client = None
return False
async def _cleanup_stale(self) -> None:
"""Close any orphaned client/task from a previous failed start."""
if self._client and not self._client.is_closed():
try:
await self._client.close()
except Exception:
pass
self._client = None
if self._task and not self._task.done():
self._task.cancel()
try:
await self._task
except (asyncio.CancelledError, Exception):
pass
self._task = None
async def stop(self) -> None:
"""Gracefully disconnect the Discord bot."""
if self._client and not self._client.is_closed():