- Added methods to delete audio moderation records and retrieve all audio records in async_db.py. - Enhanced AudioRepository with functionality to delete audio records by file name and retrieve all audio message records. - Improved logging for audio record operations to enhance monitoring and debugging capabilities. - Updated related handlers to ensure proper integration of new audio management features.
151 lines
5.6 KiB
Python
151 lines
5.6 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Скрипт для тестирования rate limiting решения
|
||
"""
|
||
import asyncio
|
||
import time
|
||
from unittest.mock import AsyncMock, MagicMock
|
||
from aiogram.types import Message, User, Chat
|
||
|
||
from helper_bot.utils.rate_limiter import send_with_rate_limit
|
||
from helper_bot.utils.rate_limit_monitor import rate_limit_monitor, get_rate_limit_summary
|
||
|
||
|
||
async def test_rate_limiting():
|
||
"""Тестирует rate limiting с имитацией отправки сообщений"""
|
||
|
||
print("🚀 Начинаем тестирование rate limiting...")
|
||
|
||
# Создаем мок объекты
|
||
mock_bot = MagicMock()
|
||
mock_user = User(id=123, is_bot=False, first_name="Test")
|
||
mock_chat = Chat(id=456, type="private")
|
||
|
||
# Создаем Message с bot в конструкторе
|
||
mock_message = Message(
|
||
message_id=1,
|
||
date=int(time.time()),
|
||
chat=mock_chat,
|
||
from_user=mock_user,
|
||
content_type="text",
|
||
bot=mock_bot
|
||
)
|
||
|
||
# Настраиваем мок для send_voice
|
||
mock_bot.send_voice = AsyncMock(return_value=MagicMock(message_id=1))
|
||
|
||
# Функция для отправки голосового сообщения
|
||
async def send_voice_test():
|
||
return await mock_bot.send_voice(
|
||
chat_id=mock_chat.id,
|
||
voice="test_voice_id"
|
||
)
|
||
|
||
print("📊 Отправляем 5 сообщений подряд...")
|
||
|
||
# Отправляем несколько сообщений подряд
|
||
start_time = time.time()
|
||
for i in range(5):
|
||
print(f" Отправка сообщения {i+1}/5...")
|
||
try:
|
||
result = await send_with_rate_limit(send_voice_test, mock_chat.id)
|
||
print(f" ✅ Сообщение {i+1} отправлено успешно")
|
||
except Exception as e:
|
||
print(f" ❌ Ошибка при отправке сообщения {i+1}: {e}")
|
||
|
||
end_time = time.time()
|
||
total_time = end_time - start_time
|
||
|
||
print(f"\n⏱️ Общее время выполнения: {total_time:.2f} секунд")
|
||
print(f"📈 Среднее время на сообщение: {total_time/5:.2f} секунд")
|
||
|
||
# Показываем статистику
|
||
print("\n📊 Статистика rate limiting:")
|
||
summary = get_rate_limit_summary()
|
||
for key, value in summary.items():
|
||
if isinstance(value, float):
|
||
print(f" {key}: {value:.2f}")
|
||
else:
|
||
print(f" {key}: {value}")
|
||
|
||
# Показываем детальную статистику
|
||
print("\n🔍 Детальная статистика:")
|
||
global_stats = rate_limit_monitor.get_global_stats()
|
||
print(f" Всего запросов: {global_stats.total_requests}")
|
||
print(f" Успешных: {global_stats.successful_requests}")
|
||
print(f" Неудачных: {global_stats.failed_requests}")
|
||
print(f" Процент успеха: {global_stats.success_rate:.1%}")
|
||
print(f" Среднее время ожидания: {global_stats.average_wait_time:.2f}с")
|
||
|
||
# Проверяем что rate limiting работает
|
||
if total_time > 8: # Должно занять больше 8 секунд (5 сообщений * 1.6с минимум)
|
||
print("\n✅ Rate limiting работает корректно - сообщения отправляются с задержкой")
|
||
else:
|
||
print("\n⚠️ Rate limiting может работать некорректно - сообщения отправлены слишком быстро")
|
||
|
||
print("\n🎉 Тестирование завершено!")
|
||
|
||
|
||
async def test_error_handling():
|
||
"""Тестирует обработку ошибок"""
|
||
|
||
print("\n🧪 Тестируем обработку ошибок...")
|
||
|
||
# Создаем мок который будет падать с RetryAfter
|
||
from aiogram.exceptions import TelegramRetryAfter
|
||
|
||
mock_bot = MagicMock()
|
||
mock_chat = Chat(id=789, type="private")
|
||
|
||
call_count = 0
|
||
async def failing_send():
|
||
nonlocal call_count
|
||
call_count += 1
|
||
if call_count <= 2:
|
||
raise TelegramRetryAfter(
|
||
method=MagicMock(),
|
||
message="Flood control exceeded",
|
||
retry_after=1
|
||
)
|
||
return MagicMock(message_id=call_count)
|
||
|
||
mock_bot.send_voice = failing_send
|
||
|
||
print("📤 Отправляем сообщение с имитацией RetryAfter ошибки...")
|
||
|
||
start_time = time.time()
|
||
try:
|
||
result = await send_with_rate_limit(failing_send, mock_chat.id)
|
||
end_time = time.time()
|
||
print(f"✅ Сообщение отправлено после {call_count} попыток за {end_time - start_time:.2f}с")
|
||
except Exception as e:
|
||
print(f"❌ Ошибка: {e}")
|
||
|
||
print("🎯 Тест обработки ошибок завершен!")
|
||
|
||
|
||
async def main():
|
||
"""Основная функция"""
|
||
print("🔧 Тестирование решения Flood Control")
|
||
print("=" * 50)
|
||
|
||
# Сбрасываем статистику
|
||
rate_limit_monitor.reset_stats()
|
||
|
||
# Запускаем тесты
|
||
await test_rate_limiting()
|
||
await test_error_handling()
|
||
|
||
print("\n" + "=" * 50)
|
||
print("📋 Итоговая статистика:")
|
||
summary = get_rate_limit_summary()
|
||
for key, value in summary.items():
|
||
if isinstance(value, float):
|
||
print(f" {key}: {value:.2f}")
|
||
else:
|
||
print(f" {key}: {value}")
|
||
|
||
|
||
if __name__ == "__main__":
|
||
asyncio.run(main())
|