logboard/app/scripts/test_all_logs.py
Sergey Antropoff 6e51f00791 feat: Добавлено AJAX обновление логов и улучшения интерфейса
Основные изменения:
- Добавлено 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
2025-08-18 19:35:47 +03:00

149 lines
7.1 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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)