File size: 1,453 Bytes
7acbd80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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()