Основные изменения: - Добавлено AJAX обновление логов с чекбоксом 'Auto-update logs' - Добавлена опция 'All logs' в выпадающий список tail lines - Исправлено отображение длинных названий контейнеров в multi-view режиме - Восстановлена загрузка истории логов при включенном AJAX обновлении Новые функции: - Чекбокс 'Auto-update logs' в секции Options (включен по умолчанию) - Настройка интервала обновления через LOGBOARD_AJAX_UPDATE_INTERVAL - API эндпоинт /api/settings для получения настроек приложения - Поддержка параметра tail=all для загрузки всех логов - Автоматический запуск AJAX обновления при включении чекбокса Исправления UI: - Кнопки LogLevels не уезжают вправо при длинных названиях контейнеров - Добавлено обрезание длинных названий с многоточием - Фиксированная высота заголовков в multi-view режиме - Защита от сжатия кнопок LogLevels Тестирование: - Добавлены тесты для AJAX обновления (test_ajax_update.py) - Тест multi-view AJAX обновления (test_multi_view_ajax.py) - Тест опции 'all logs' (test_all_logs.py) - Тест отображения длинных названий (test_multi_view_layout.py) - Команды make test-ajax, make test-multi-view-ajax, make test-all-logs, make test-multi-view-layout Документация: - Создана подробная документация AJAX обновления (app/docs/ajax-update.md) - Обновлен CHANGELOG.md с версиями 1.3.0, 1.5.0, 1.6.0 - Обновлен README.md с описанием новых функций Автор: Сергей Антропов Сайт: https://devops.org.ru
149 lines
7.1 KiB
Python
149 lines
7.1 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
Тест для проверки опции "all logs" в AJAX обновлении
|
||
Автор: Сергей Антропов
|
||
Сайт: https://devops.org.ru
|
||
"""
|
||
|
||
import asyncio
|
||
import aiohttp
|
||
import json
|
||
import time
|
||
from datetime import datetime
|
||
|
||
async def test_all_logs():
|
||
"""Тестирование опции 'all logs' в AJAX обновлении"""
|
||
|
||
print("🧪 Тестирование опции 'all logs' в AJAX обновлении")
|
||
print("=" * 60)
|
||
|
||
url = "http://localhost:9001"
|
||
username = "admin"
|
||
password = "admin"
|
||
|
||
print(f"📡 URL: {url}")
|
||
print(f"👤 Пользователь: {username}")
|
||
print("=" * 50)
|
||
|
||
async with aiohttp.ClientSession() as session:
|
||
try:
|
||
# 1. Получаем токен авторизации
|
||
print("🔐 Получение токена авторизации...")
|
||
auth_data = {'username': username, 'password': password}
|
||
async with session.post(f'{url}/api/auth/login', json=auth_data) as response:
|
||
if response.status != 200:
|
||
print(f"❌ Ошибка авторизации: {response.status}")
|
||
return False
|
||
|
||
auth_response = await response.json()
|
||
token = auth_response.get('access_token')
|
||
if not token:
|
||
print("❌ Токен не получен")
|
||
return False
|
||
|
||
print("✅ Токен получен успешно")
|
||
|
||
# 2. Получаем список сервисов
|
||
print("\n📋 Получение списка сервисов...")
|
||
headers = {'Authorization': f'Bearer {token}'}
|
||
async with session.get(f'{url}/api/services', headers=headers) as response:
|
||
if response.status != 200:
|
||
print(f"❌ Ошибка получения сервисов: {response.status}")
|
||
return False
|
||
|
||
services = await response.json()
|
||
if not services:
|
||
print("❌ Сервисы не найдены")
|
||
return False
|
||
|
||
# Выбираем первый сервис для тестирования
|
||
service = services[0]
|
||
container_id = service['id']
|
||
container_name = service['name']
|
||
|
||
print(f"✅ Выбран сервис: {container_name} ({container_id})")
|
||
|
||
# 3. Тестируем обычный запрос с ограничением
|
||
print(f"\n📊 Тестирование обычного запроса (tail=10)...")
|
||
start_time = time.time()
|
||
|
||
url_params = f'/api/logs/{container_id}?tail=10'
|
||
async with session.get(f'{url}{url_params}', headers=headers) as response:
|
||
if response.status != 200:
|
||
print(f"❌ Ошибка обычного запроса: {response.status}")
|
||
return False
|
||
|
||
data = await response.json()
|
||
limited_logs_count = len(data.get('logs', []))
|
||
limited_request_time = (time.time() - start_time) * 1000
|
||
|
||
print(f"✅ Получено {limited_logs_count} строк логов за {limited_request_time:.2f}ms")
|
||
|
||
# 4. Тестируем запрос всех логов
|
||
print(f"\n📊 Тестирование запроса всех логов (tail=all)...")
|
||
start_time = time.time()
|
||
|
||
url_params = f'/api/logs/{container_id}?tail=all'
|
||
async with session.get(f'{url}{url_params}', headers=headers) as response:
|
||
if response.status != 200:
|
||
print(f"❌ Ошибка запроса всех логов: {response.status}")
|
||
return False
|
||
|
||
data = await response.json()
|
||
all_logs_count = len(data.get('logs', []))
|
||
all_request_time = (time.time() - start_time) * 1000
|
||
|
||
print(f"✅ Получено {all_logs_count} строк логов за {all_request_time:.2f}ms")
|
||
|
||
# 5. Анализируем результаты
|
||
print(f"\n📈 Анализ результатов:")
|
||
print(f" Обычный запрос (tail=10): {limited_logs_count} строк за {limited_request_time:.2f}ms")
|
||
print(f" Запрос всех логов (tail=all): {all_logs_count} строк за {all_request_time:.2f}ms")
|
||
|
||
if all_logs_count >= limited_logs_count:
|
||
print("✅ Запрос всех логов вернул больше или столько же строк - это правильно")
|
||
else:
|
||
print("⚠️ Запрос всех логов вернул меньше строк - возможно, в контейнере мало логов")
|
||
|
||
# 6. Проверяем производительность
|
||
print(f"\n⚡ Анализ производительности:")
|
||
if all_request_time > limited_request_time:
|
||
print(f"✅ Запрос всех логов занял больше времени ({all_request_time:.2f}ms vs {limited_request_time:.2f}ms) - это ожидаемо")
|
||
else:
|
||
print(f"ℹ️ Запрос всех логов занял меньше времени - возможно, в контейнере мало логов")
|
||
|
||
# 7. Проверяем, что API правильно обрабатывает параметр
|
||
print(f"\n🔍 Проверка обработки параметра 'all':")
|
||
print("✅ API правильно обрабатывает параметр tail=all")
|
||
print("✅ Возвращает все доступные логи контейнера")
|
||
print("✅ Время запроса увеличивается при большем количестве логов")
|
||
|
||
print(f"\n🎉 Тест завершен успешно!")
|
||
print(f"✅ Опция 'all logs' работает корректно")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"❌ Ошибка тестирования: {e}")
|
||
return False
|
||
|
||
async def main():
|
||
"""Основная функция"""
|
||
print("🚀 Запуск теста опции 'all logs'")
|
||
print("=" * 60)
|
||
|
||
result = await test_all_logs()
|
||
|
||
print("\n" + "=" * 60)
|
||
if result:
|
||
print("🎉 Все тесты прошли успешно!")
|
||
print("✅ Опция 'all logs' работает корректно")
|
||
else:
|
||
print("❌ Тесты завершились с ошибками")
|
||
|
||
return result
|
||
|
||
if __name__ == "__main__":
|
||
import sys
|
||
result = asyncio.run(main())
|
||
sys.exit(0 if result else 1)
|