- console_commands/logs.py — чтение последних строк лога (tail -20) - console_commands/reload.py — горячая перезагрузка всех cogs - console_commands/trigger_morning.py — ручной запуск morning-дайджеста - logs доступна через admin.py (docker exec) и интерактивный терминал - reload и trigger morning доступны через интерактивный терминал - сохранён bot._scheduler для доступа к планировщику - обновлены __init__.py, admin.py, README.md, ISSUES.md - добавлены тесты: test_console_logs.py (4), test_console_reload.py (2), test_console_trigger_morning.py (3) - итого 243 теста
88 lines
2.8 KiB
Python
88 lines
2.8 KiB
Python
"""Тесты для console_commands/logs.py."""
|
||
import importlib
|
||
from pathlib import Path
|
||
from unittest.mock import MagicMock
|
||
|
||
|
||
class TestLogsCommand:
|
||
"""Тесты консольной команды logs."""
|
||
|
||
def _get_module(self):
|
||
"""Импортировать модуль logs."""
|
||
return importlib.import_module("console_commands.logs")
|
||
|
||
def _get_logs_func(self):
|
||
"""Импортировать функцию logs."""
|
||
from console_commands.logs import logs
|
||
return logs
|
||
|
||
def test_logs_no_file(self, capfd):
|
||
"""Выводит сообщение если файл лога не существует."""
|
||
stop_event = MagicMock()
|
||
stop_event.is_set.return_value = False
|
||
bot = MagicMock()
|
||
|
||
mod = self._get_module()
|
||
original = mod.LOG_FILE
|
||
try:
|
||
mod.LOG_FILE = Path("/nonexistent/bot.log")
|
||
self._get_logs_func()(stop_event, bot)
|
||
finally:
|
||
mod.LOG_FILE = original
|
||
|
||
captured = capfd.readouterr()
|
||
assert "не найден" in captured.out
|
||
|
||
def test_logs_reads_last_lines(self, capfd, tmp_path):
|
||
"""Выводит последние N строк лога."""
|
||
log_file = tmp_path / "bot.log"
|
||
lines = [f"Line {i}\n" for i in range(30)]
|
||
log_file.write_text("".join(lines))
|
||
|
||
stop_event = MagicMock()
|
||
stop_event.is_set.return_value = False
|
||
bot = MagicMock()
|
||
|
||
mod = self._get_module()
|
||
original = mod.LOG_FILE
|
||
try:
|
||
mod.LOG_FILE = log_file
|
||
self._get_logs_func()(stop_event, bot, lines=5)
|
||
finally:
|
||
mod.LOG_FILE = original
|
||
|
||
captured = capfd.readouterr()
|
||
assert "Line 25" in captured.out
|
||
assert "Line 29" in captured.out
|
||
assert "Line 1" not in captured.out
|
||
|
||
def test_logs_fewer_lines_than_requested(self, capfd, tmp_path):
|
||
"""Если строк меньше N, выводит все."""
|
||
log_file = tmp_path / "bot.log"
|
||
log_file.write_text("Line 1\nLine 2\n")
|
||
|
||
stop_event = MagicMock()
|
||
stop_event.is_set.return_value = False
|
||
bot = MagicMock()
|
||
|
||
mod = self._get_module()
|
||
original = mod.LOG_FILE
|
||
try:
|
||
mod.LOG_FILE = log_file
|
||
self._get_logs_func()(stop_event, bot, lines=10)
|
||
finally:
|
||
mod.LOG_FILE = original
|
||
|
||
captured = capfd.readouterr()
|
||
assert "Line 1" in captured.out
|
||
assert "Line 2" in captured.out
|
||
|
||
def test_logs_stop_event(self):
|
||
"""Не выполняется если stop_event установлен."""
|
||
stop_event = MagicMock()
|
||
stop_event.is_set.return_value = True
|
||
bot = MagicMock()
|
||
|
||
result = self._get_logs_func()(stop_event, bot)
|
||
assert result is None
|