#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Тест AJAX обновления в multi-view режиме Автор: Сергей Антропов Сайт: https://devops.org.ru """ import asyncio import aiohttp import json import time from datetime import datetime import os import sys async def test_multi_view_ajax(): """Тестирование AJAX обновления в multi-view режиме""" print("🔄 Тестирование AJAX обновления в multi-view режиме") print("=" * 60) # Настройки base_url = "http://localhost:9001" username = os.getenv("LOGBOARD_USER", "admin") password = os.getenv("LOGBOARD_PASS", "admin") async with aiohttp.ClientSession() as session: try: # 1. Получаем токен авторизации print("🔐 Получение токена авторизации...") auth_data = { "username": username, "password": password } async with session.post(f"{base_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"{base_url}/api/services", headers=headers) as response: if response.status != 200: print(f"❌ Ошибка получения контейнеров: {response.status}") return False containers = await response.json() if not containers: print("❌ Контейнеры не найдены") return False # Берем первые 3 запущенных контейнера для multi-view теста running_containers = [c for c in containers if c.get("status") == "running"] if len(running_containers) < 2: print("❌ Недостаточно запущенных контейнеров для multi-view теста (нужно минимум 2)") return False test_containers = running_containers[:3] # Берем первые 3 print(f"✅ Выбрано {len(test_containers)} контейнеров для multi-view теста:") for i, container in enumerate(test_containers): print(f" {i+1}. {container['name']} ({container['id'][:12]}...)") # 3. Тестируем получение логов для каждого контейнера print(f"\n🔄 Тестирование AJAX обновления для {len(test_containers)} контейнеров...") container_results = {} for i, container in enumerate(test_containers): container_id = container["id"] container_name = container["name"] print(f"\n📊 Контейнер {i+1}: {container_name}") # Первый запрос url = f"{base_url}/api/logs/{container_id}" params = {"tail": 5} async with session.get(url, headers=headers, params=params) as response: if response.status != 200: print(f" ❌ Ошибка получения логов: {response.status}") continue data = await response.json() first_count = data.get('total_lines', 0) first_timestamp = data.get('timestamp') print(f" ✅ Первый запрос: {first_count} строк, timestamp: {first_timestamp}") # Ждем немного await asyncio.sleep(1) # Второй запрос с since params = {"tail": 5, "since": first_timestamp} async with session.get(url, headers=headers, params=params) as response: if response.status != 200: print(f" ❌ Ошибка получения новых логов: {response.status}") continue data = await response.json() second_count = data.get('total_lines', 0) second_timestamp = data.get('timestamp') print(f" ✅ Второй запрос: {second_count} строк, timestamp: {second_timestamp}") # Сохраняем результаты container_results[container_id] = { 'name': container_name, 'first_count': first_count, 'second_count': second_count, 'first_timestamp': first_timestamp, 'second_timestamp': second_timestamp } # 4. Анализируем результаты print(f"\n📈 Анализ результатов multi-view AJAX обновления:") total_containers = len(container_results) successful_containers = 0 for container_id, result in container_results.items(): print(f"\n 📦 {result['name']} ({container_id[:12]}...):") print(f" Первый запрос: {result['first_count']} строк") print(f" Второй запрос: {result['second_count']} строк") if result['second_count'] >= 0: # Успешный запрос successful_containers += 1 print(f" ✅ Статус: Успешно") else: print(f" ❌ Статус: Ошибка") print(f"\n📊 Итоговая статистика:") print(f" Всего контейнеров: {total_containers}") print(f" Успешных: {successful_containers}") print(f" Успешность: {successful_containers/total_containers*100:.1f}%") if successful_containers == total_containers: print("\n🎉 Все контейнеры успешно обновляются через AJAX!") return True else: print(f"\n⚠️ {total_containers - successful_containers} контейнеров имеют проблемы") return False except Exception as e: print(f"❌ Ошибка тестирования: {e}") return False async def test_concurrent_ajax_requests(): """Тестирование одновременных AJAX запросов (имитация multi-view)""" print(f"\n⚡ Тестирование одновременных AJAX запросов") print("=" * 50) # Настройки base_url = "http://localhost:9001" username = os.getenv("LOGBOARD_USER", "admin") password = os.getenv("LOGBOARD_PASS", "admin") async with aiohttp.ClientSession() as session: try: # Получаем токен auth_data = {"username": username, "password": password} async with session.post(f"{base_url}/api/auth/login", json=auth_data) as response: auth_response = await response.json() token = auth_response.get("access_token") headers = {"Authorization": f"Bearer {token}"} # Получаем контейнеры async with session.get(f"{base_url}/api/services", headers=headers) as response: containers = await response.json() running_containers = [c for c in containers if c.get("status") == "running"] if len(running_containers) < 2: print("❌ Недостаточно контейнеров для теста") return False test_containers = running_containers[:3] # Тестируем одновременные запросы print(f"📊 Выполнение одновременных запросов для {len(test_containers)} контейнеров...") start_time = time.time() async def fetch_container_logs(container): container_id = container["id"] url = f"{base_url}/api/logs/{container_id}" params = {"tail": 3} try: async with session.get(url, headers=headers, params=params) as response: data = await response.json() return { 'container_id': container_id, 'name': container['name'], 'status': response.status, 'lines': data.get('total_lines', 0), 'success': response.status == 200 } except Exception as e: return { 'container_id': container_id, 'name': container['name'], 'status': 'error', 'lines': 0, 'success': False, 'error': str(e) } # Выполняем запросы одновременно tasks = [fetch_container_logs(container) for container in test_containers] results = await asyncio.gather(*tasks) total_time = time.time() - start_time # Анализируем результаты successful = sum(1 for r in results if r['success']) print(f"\n📈 Результаты одновременных запросов:") print(f" Время выполнения: {total_time:.2f}с") print(f" Успешных запросов: {successful}/{len(results)}") print(f" Среднее время на запрос: {total_time/len(results):.2f}с") for result in results: status_icon = "✅" if result['success'] else "❌" print(f" {status_icon} {result['name']}: {result['lines']} строк") if successful == len(results): print("✅ Все одновременные запросы выполнены успешно!") return True else: print(f"⚠️ {len(results) - successful} запросов завершились с ошибкой") return False except Exception as e: print(f"❌ Ошибка тестирования одновременных запросов: {e}") return False async def main(): """Основная функция тестирования""" print("🔄 Запуск тестов multi-view AJAX обновления") print("=" * 70) # Проверяем, что сервер запущен try: async with aiohttp.ClientSession() as session: async with session.get("http://localhost:9001/healthz") as response: if response.status != 200: print("❌ Сервер LogBoard+ не запущен на порту 9001") print(" Запустите сервер командой: make up") return False except Exception: print("❌ Не удается подключиться к серверу LogBoard+") print(" Убедитесь, что сервер запущен: make up") return False # Запускаем тесты success1 = await test_multi_view_ajax() success2 = await test_concurrent_ajax_requests() print("\n" + "=" * 70) if success1 and success2: print("🎉 Все тесты прошли успешно!") print("✅ Multi-view AJAX обновление работает корректно") return True else: print("❌ Некоторые тесты не прошли") print("🔧 Проверьте логи сервера и настройки") return False if __name__ == "__main__": result = asyncio.run(main()) sys.exit(0 if result else 1)