Fix test
This commit is contained in:
+33
-25
@@ -4,6 +4,7 @@
|
|||||||
Использование:
|
Использование:
|
||||||
python load_test.py --n 5
|
python load_test.py --n 5
|
||||||
python load_test.py --n 10 --url https://example.com --time 15
|
python load_test.py --n 10 --url https://example.com --time 15
|
||||||
|
python load_test.py --n 10 --parallel 3 # не более 3 одновременных запусков
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
@@ -11,14 +12,13 @@ import sys
|
|||||||
import time
|
import time
|
||||||
import argparse
|
import argparse
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
|
||||||
sys.path.insert(0, str(Path(__file__).parent))
|
sys.path.insert(0, str(Path(__file__).parent))
|
||||||
|
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
from config.settings import settings
|
|
||||||
from core.logger import setup_logger
|
from core.logger import setup_logger
|
||||||
from managers.proxy_manager import ProxyManager
|
from managers.proxy_manager import ProxyManager
|
||||||
from services.browser_service import BrowserService
|
from services.browser_service import BrowserService
|
||||||
@@ -47,30 +47,35 @@ async def run_one_browser(
|
|||||||
url: str,
|
url: str,
|
||||||
visit_time: int,
|
visit_time: int,
|
||||||
results: List[BrowserResult],
|
results: List[BrowserResult],
|
||||||
|
launch_sem: asyncio.Semaphore,
|
||||||
) -> None:
|
) -> None:
|
||||||
t0 = time.perf_counter()
|
# Семафор ограничивает сколько браузеров стартует одновременно.
|
||||||
try:
|
# Когда браузер поднялся (AsyncCamoufox.__aenter__ завершён), семафор освобождается
|
||||||
result = await browser_service.visit_page(url, reading_time=visit_time)
|
# и следующий браузер может начать запуск. Так избегаем race на ресурсы ОС.
|
||||||
duration = time.perf_counter() - t0
|
async with launch_sem:
|
||||||
results.append(BrowserResult(
|
t0 = time.perf_counter()
|
||||||
index=index,
|
try:
|
||||||
success=result.success,
|
result = await browser_service.visit_page(url, reading_time=visit_time)
|
||||||
duration=duration,
|
duration = time.perf_counter() - t0
|
||||||
error=result.error,
|
results.append(BrowserResult(
|
||||||
final_url=result.final_url,
|
index=index,
|
||||||
))
|
success=result.success,
|
||||||
status = "OK" if result.success else f"FAIL: {result.error}"
|
duration=duration,
|
||||||
print(f" [Browser {index:>2}] {status} — {duration:.1f}s | RAM: {_mem_mb():.0f} MB")
|
error=result.error,
|
||||||
except Exception as e:
|
final_url=result.final_url,
|
||||||
duration = time.perf_counter() - t0
|
))
|
||||||
results.append(BrowserResult(index=index, success=False, duration=duration, error=str(e)))
|
status = "OK" if result.success else f"FAIL: {result.error}"
|
||||||
print(f" [Browser {index:>2}] EXCEPTION: {e} — {duration:.1f}s")
|
print(f" [Browser {index:>2}] {status} — {duration:.1f}s | RAM: {_mem_mb():.0f} MB")
|
||||||
|
except Exception as e:
|
||||||
|
duration = time.perf_counter() - t0
|
||||||
|
results.append(BrowserResult(index=index, success=False, duration=duration, error=str(e)))
|
||||||
|
print(f" [Browser {index:>2}] EXCEPTION: {e} — {duration:.1f}s")
|
||||||
|
|
||||||
|
|
||||||
async def run_load_test(n: int, url: str, visit_time: int) -> None:
|
async def run_load_test(n: int, url: str, visit_time: int, parallel: int) -> None:
|
||||||
print(f"\n{'='*60}")
|
print(f"\n{'='*60}")
|
||||||
print(f" Нагрузочный тест")
|
print(f" Нагрузочный тест")
|
||||||
print(f" Браузеров: {n} | URL: {url} | Время: {visit_time}s")
|
print(f" Браузеров: {n} | Одновременный запуск: {parallel} | URL: {url} | Время: {visit_time}s")
|
||||||
|
|
||||||
# Инфо о системе
|
# Инфо о системе
|
||||||
mem = psutil.virtual_memory()
|
mem = psutil.virtual_memory()
|
||||||
@@ -91,13 +96,14 @@ async def run_load_test(n: int, url: str, visit_time: int) -> None:
|
|||||||
|
|
||||||
ram_before = _mem_mb()
|
ram_before = _mem_mb()
|
||||||
print(f" RAM до старта: {ram_before:.0f} MB")
|
print(f" RAM до старта: {ram_before:.0f} MB")
|
||||||
print(f"\n Запускаем {n} браузеров...\n")
|
print(f"\n Запускаем {n} браузеров (волнами по {parallel})...\n")
|
||||||
|
|
||||||
|
launch_sem = asyncio.Semaphore(parallel)
|
||||||
wall_start = time.perf_counter()
|
wall_start = time.perf_counter()
|
||||||
|
|
||||||
tasks = [
|
tasks = [
|
||||||
asyncio.create_task(
|
asyncio.create_task(
|
||||||
run_one_browser(i + 1, browser_service, url, visit_time, results)
|
run_one_browser(i + 1, browser_service, url, visit_time, results, launch_sem)
|
||||||
)
|
)
|
||||||
for i in range(n)
|
for i in range(n)
|
||||||
]
|
]
|
||||||
@@ -137,13 +143,15 @@ async def run_load_test(n: int, url: str, visit_time: int) -> None:
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
parser = argparse.ArgumentParser(description="Load test: N параллельных браузеров")
|
parser = argparse.ArgumentParser(description="Load test: N параллельных браузеров")
|
||||||
parser.add_argument("--n", type=int, default=3, help="Число параллельных браузеров (по умолчанию: 3)")
|
parser.add_argument("--n", type=int, default=3, help="Всего браузеров (по умолчанию: 3)")
|
||||||
|
parser.add_argument("--parallel", type=int, default=2, help="Макс. одновременных запусков (по умолчанию: 2)")
|
||||||
parser.add_argument("--url", type=str, default="https://httpbin.org/headers", help="URL для посещения")
|
parser.add_argument("--url", type=str, default="https://httpbin.org/headers", help="URL для посещения")
|
||||||
parser.add_argument("--time", type=int, default=10, dest="visit_time", help="Время посещения в секундах (по умолчанию: 10)")
|
parser.add_argument("--time", type=int, default=10, dest="visit_time", help="Время посещения в секундах (по умолчанию: 10)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
parallel = min(args.parallel, args.n)
|
||||||
try:
|
try:
|
||||||
asyncio.run(run_load_test(args.n, args.url, args.visit_time))
|
asyncio.run(run_load_test(args.n, args.url, args.visit_time, parallel))
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
print("\nПрервано.")
|
print("\nПрервано.")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user