Hermes-agent
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import asyncio
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
import pytest
|
||||
|
||||
from gateway.config import PlatformConfig
|
||||
from plugins.platforms.discord.adapter import DiscordAdapter
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_discord_bot_task_runtime_exit_notifies_gateway_for_reconnect(monkeypatch):
|
||||
"""A post-ready discord.py websocket task crash must not leave the gateway split-brained.
|
||||
|
||||
Regression: producers stayed systemd-active while Discord stopped responding after
|
||||
a runtime ClientOSError/ConnectionResetError. The adapter must mark Discord as a
|
||||
retryable fatal platform error and notify the gateway supervisor so the existing
|
||||
reconnect watcher can replace the dead adapter.
|
||||
"""
|
||||
adapter = DiscordAdapter(PlatformConfig(enabled=True, token="token"))
|
||||
adapter._running = True
|
||||
adapter._ready_event.set()
|
||||
adapter._notify_fatal_error = AsyncMock()
|
||||
|
||||
async def crash():
|
||||
raise ConnectionResetError("Cannot write to closing transport")
|
||||
|
||||
task = asyncio.create_task(crash())
|
||||
await asyncio.sleep(0)
|
||||
|
||||
adapter._handle_bot_task_done(task)
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert adapter.has_fatal_error is True
|
||||
assert adapter.fatal_error_retryable is True
|
||||
assert adapter.fatal_error_code == "discord_gateway_task_exited"
|
||||
assert adapter.fatal_error_message is not None
|
||||
assert "Cannot write to closing transport" in adapter.fatal_error_message
|
||||
adapter._notify_fatal_error.assert_awaited_once()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_discord_bot_task_done_ignored_during_intentional_disconnect():
|
||||
adapter = DiscordAdapter(PlatformConfig(enabled=True, token="token"))
|
||||
adapter._running = True
|
||||
adapter._ready_event.set()
|
||||
adapter._disconnecting = True
|
||||
adapter._notify_fatal_error = AsyncMock()
|
||||
|
||||
async def stop_cleanly():
|
||||
return None
|
||||
|
||||
task = asyncio.create_task(stop_cleanly())
|
||||
await asyncio.sleep(0)
|
||||
|
||||
adapter._handle_bot_task_done(task)
|
||||
await asyncio.sleep(0)
|
||||
|
||||
assert adapter.has_fatal_error is False
|
||||
adapter._notify_fatal_error.assert_not_awaited()
|
||||
Reference in New Issue
Block a user