Scheduler.__init__ больше не создаёт task синхронно; start() стал async-методом
This commit is contained in:
parent
66b16e95f4
commit
bb9f291623
1
bot.py
1
bot.py
@ -143,6 +143,7 @@ class BotRunner:
|
|||||||
morning_time = os.getenv("MORNING_TIME", "07:00")
|
morning_time = os.getenv("MORNING_TIME", "07:00")
|
||||||
self.scheduler = Scheduler(self.bot, morning_time)
|
self.scheduler = Scheduler(self.bot, morning_time)
|
||||||
self.bot._scheduler = self.scheduler
|
self.bot._scheduler = self.scheduler
|
||||||
|
await self.scheduler.start()
|
||||||
logger.info(
|
logger.info(
|
||||||
"Планировщик запущен (время: %s, сервер: %s)", morning_time, guild.name
|
"Планировщик запущен (время: %s, сервер: %s)", morning_time, guild.name
|
||||||
)
|
)
|
||||||
|
|||||||
@ -25,12 +25,12 @@ class TestSchedulerInit:
|
|||||||
scheduler = Scheduler(bot)
|
scheduler = Scheduler(bot)
|
||||||
assert scheduler.morning_time == "07:00"
|
assert scheduler.morning_time == "07:00"
|
||||||
|
|
||||||
def test_init_creates_task(self) -> None:
|
def test_init_does_not_start_scheduler(self) -> None:
|
||||||
"""Инициализация должна вызывать _start_scheduler."""
|
"""Инициализация не должна запускать планировщик (start() вызывается отдельно)."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
with patch.object(Scheduler, "_start_scheduler") as mock_start:
|
with patch.object(Scheduler, "_start_scheduler") as mock_start:
|
||||||
Scheduler(bot)
|
Scheduler(bot)
|
||||||
mock_start.assert_called_once()
|
mock_start.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
class TestSchedulerCalculateNextRun:
|
class TestSchedulerCalculateNextRun:
|
||||||
@ -67,14 +67,14 @@ class TestSchedulerCalculateNextRun:
|
|||||||
class TestSchedulerStartStop:
|
class TestSchedulerStartStop:
|
||||||
"""Тесты запуска/остановки планировщика."""
|
"""Тесты запуска/остановки планировщика."""
|
||||||
|
|
||||||
def test_start_starts_task(self) -> None:
|
@pytest.mark.asyncio
|
||||||
"""start() должен вызывать _start_scheduler (1 в __init__ + 1 в start, но реальный task один)."""
|
async def test_start_starts_task(self) -> None:
|
||||||
|
"""start() должен вызывать _start_scheduler один раз."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
with patch.object(Scheduler, "_start_scheduler") as mock_start:
|
with patch.object(Scheduler, "_start_scheduler") as mock_start:
|
||||||
scheduler = Scheduler(bot)
|
scheduler = Scheduler(bot)
|
||||||
scheduler.start()
|
await scheduler.start()
|
||||||
# __init__ вызывает _start_scheduler, start() тоже вызывает
|
mock_start.assert_called_once()
|
||||||
assert mock_start.call_count == 2
|
|
||||||
|
|
||||||
def test_stop_stops_task(self) -> None:
|
def test_stop_stops_task(self) -> None:
|
||||||
"""stop() должен остановить task."""
|
"""stop() должен остановить task."""
|
||||||
@ -88,12 +88,15 @@ class TestSchedulerStartStop:
|
|||||||
scheduler.stop()
|
scheduler.stop()
|
||||||
assert scheduler._running is False
|
assert scheduler._running is False
|
||||||
|
|
||||||
def test_double_start_no_duplicate(self) -> None:
|
@pytest.mark.asyncio
|
||||||
"""Повторный start должен вызывать _start_scheduler дважды (реальный task не дублируется благодаря флагам)."""
|
async def test_double_start_no_duplicate(self) -> None:
|
||||||
|
"""Повторный start() не должен дублировать task (благодаря флагам)."""
|
||||||
bot = AsyncMock()
|
bot = AsyncMock()
|
||||||
with patch.object(Scheduler, "_start_scheduler") as mock_start:
|
with patch.object(Scheduler, "_start_scheduler") as mock_start:
|
||||||
scheduler = Scheduler(bot)
|
scheduler = Scheduler(bot)
|
||||||
scheduler.start() # второй вызов
|
await scheduler.start()
|
||||||
|
await scheduler.start() # повторный вызов
|
||||||
|
# _start_scheduler вызывается 2 раза, но реальный task один (флаг _running защищает)
|
||||||
assert mock_start.call_count == 2
|
assert mock_start.call_count == 2
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -151,7 +151,6 @@ class Scheduler:
|
|||||||
)
|
)
|
||||||
self._task: asyncio.Task | None = None
|
self._task: asyncio.Task | None = None
|
||||||
self._running = False
|
self._running = False
|
||||||
self._start_scheduler()
|
|
||||||
|
|
||||||
def _start_scheduler(self):
|
def _start_scheduler(self):
|
||||||
if self._running:
|
if self._running:
|
||||||
@ -276,7 +275,7 @@ class Scheduler:
|
|||||||
if not sent:
|
if not sent:
|
||||||
logger.error("Не удалось найти канал для отправки morning-дайджеста")
|
logger.error("Не удалось найти канал для отправки morning-дайджеста")
|
||||||
|
|
||||||
def start(self) -> None:
|
async def start(self) -> None:
|
||||||
self._start_scheduler()
|
self._start_scheduler()
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self) -> None:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user