Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
"""Cron media-send timeout resolution and failure-reason formatting.
|
||||
|
||||
Covers two salvaged fixes:
|
||||
|
||||
- PR #87965 (@AiwendilInTheWoods): an argument-less exception (notably
|
||||
TimeoutError from ``future.result(timeout=...)``) has an empty ``str()``,
|
||||
which used to render "failed to send media <path>: " with no reason at
|
||||
all — in both the log line and the delivery error recorded on the run.
|
||||
- PR #87967 (@AiwendilInTheWoods): the per-attachment send timeout was a
|
||||
hardcoded 30s; large attachments (long TTS audio, big exports) failed on
|
||||
slow uplinks with no way to raise it. Now resolved via
|
||||
HERMES_CRON_MEDIA_SEND_TIMEOUT → cron.media_send_timeout_seconds → 300s.
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
from cron.scheduler import (
|
||||
_DEFAULT_MEDIA_SEND_TIMEOUT,
|
||||
_get_media_send_timeout,
|
||||
_send_media_via_adapter,
|
||||
)
|
||||
|
||||
|
||||
class TestMediaSendTimeoutResolution:
|
||||
def test_default(self, monkeypatch):
|
||||
monkeypatch.delenv("HERMES_CRON_MEDIA_SEND_TIMEOUT", raising=False)
|
||||
monkeypatch.setattr("cron.scheduler.load_config", lambda: {})
|
||||
assert _get_media_send_timeout() == _DEFAULT_MEDIA_SEND_TIMEOUT == 300
|
||||
|
||||
def test_env_wins(self, monkeypatch):
|
||||
monkeypatch.setenv("HERMES_CRON_MEDIA_SEND_TIMEOUT", "45")
|
||||
monkeypatch.setattr(
|
||||
"cron.scheduler.load_config",
|
||||
lambda: {"cron": {"media_send_timeout_seconds": 900}},
|
||||
)
|
||||
assert _get_media_send_timeout() == 45
|
||||
|
||||
def test_config_value(self, monkeypatch):
|
||||
monkeypatch.delenv("HERMES_CRON_MEDIA_SEND_TIMEOUT", raising=False)
|
||||
monkeypatch.setattr(
|
||||
"cron.scheduler.load_config",
|
||||
lambda: {"cron": {"media_send_timeout_seconds": 900}},
|
||||
)
|
||||
assert _get_media_send_timeout() == 900
|
||||
|
||||
@pytest.mark.parametrize("bad", ["abc", "-5", "0", ""])
|
||||
def test_invalid_env_falls_back(self, monkeypatch, bad):
|
||||
monkeypatch.setenv("HERMES_CRON_MEDIA_SEND_TIMEOUT", bad)
|
||||
monkeypatch.setattr("cron.scheduler.load_config", lambda: {})
|
||||
assert _get_media_send_timeout() == _DEFAULT_MEDIA_SEND_TIMEOUT
|
||||
|
||||
def test_invalid_config_falls_back(self, monkeypatch):
|
||||
monkeypatch.delenv("HERMES_CRON_MEDIA_SEND_TIMEOUT", raising=False)
|
||||
monkeypatch.setattr(
|
||||
"cron.scheduler.load_config",
|
||||
lambda: {"cron": {"media_send_timeout_seconds": "nope"}},
|
||||
)
|
||||
assert _get_media_send_timeout() == _DEFAULT_MEDIA_SEND_TIMEOUT
|
||||
|
||||
|
||||
class TestEmptyReasonFallback:
|
||||
def _run(self, tmp_path, monkeypatch, exc):
|
||||
"""Drive _send_media_via_adapter into its generic except handler."""
|
||||
media = tmp_path / "clip.mp3"
|
||||
media.write_bytes(b"x")
|
||||
|
||||
monkeypatch.setattr(
|
||||
"gateway.platforms.base.BasePlatformAdapter.filter_media_delivery_paths",
|
||||
staticmethod(lambda files, session_key="": [(str(media), False)]),
|
||||
)
|
||||
|
||||
def boom(coro, loop):
|
||||
coro.close()
|
||||
raise exc
|
||||
|
||||
monkeypatch.setattr("agent.async_utils.safe_schedule_threadsafe", boom)
|
||||
|
||||
class _Adapter:
|
||||
async def send_voice(self, **kw): # pragma: no cover - never awaited
|
||||
pass
|
||||
|
||||
errors = _send_media_via_adapter(
|
||||
_Adapter(), "C123", [(str(media), False)], None, loop=object(),
|
||||
job={"id": "job-x"},
|
||||
)
|
||||
assert len(errors) == 1
|
||||
return errors[0]
|
||||
|
||||
def test_timeout_error_names_the_class(self, tmp_path, monkeypatch):
|
||||
# TimeoutError() has an empty str() — the recorded reason must not
|
||||
# be blank (the trailing-colon-nothing log from the field report).
|
||||
err = self._run(tmp_path, monkeypatch, TimeoutError())
|
||||
assert err.rstrip() != f"failed to send media {tmp_path / 'clip.mp3'}:"
|
||||
assert "TimeoutError" in err
|
||||
|
||||
def test_exception_with_message_keeps_it(self, tmp_path, monkeypatch):
|
||||
err = self._run(tmp_path, monkeypatch, RuntimeError("bridge closed"))
|
||||
assert "bridge closed" in err
|
||||
Reference in New Issue
Block a user