test: stress_http переписан на реальный VM-путь (PUT на ВМ → /api/upload_refs)

This commit is contained in:
“Naeel”
2026-08-26 20:51:39 +03:00
parent 533aa99592
commit c4997b06d3
4 changed files with 34 additions and 16 deletions
+31 -12
View File
@@ -1,19 +1,23 @@
"""HTTP-стресс против contracts-flask (standalone, не pytest).
Создаёт параллельную нагрузку на /upload большими файлами + /health,
замеряет RPS, ошибки, таймауты. Цель — «разогреть» сервис и выявить
Реальный путь загрузки (VM-буфер):
1) PUT файла на ВМ WebDAV (мимо шлюза кластера ~64KB);
2) POST /api/upload_refs — бэк сам тянет файл с ВМ (egress).
Замеряет RPS, ошибки, таймауты. Цель — «разогреть» сервис и выявить
деградацию/обрывы (шлюз, OOM, SQLite).
Запуск:
python tests/load/stress_http.py --url http://127.0.0.1:5000 \
--n 1000 --threads 32 --size 100000
Запуск (локально):
python tests/load/stress_http.py --url http://127.0.0.1:5000 --n 1000 --threads 32 --size 100000
Пример против прода (осторожно):
python tests/load/stress_http.py --url https://contractor.pythonk8s.dev.nubes.ru \
--n 200 --threads 16 --size 500000
--file "/mnt/y/MY/Nubes/примеры_договоров_для_ИИ/спецификация-XXX001-03700.docx" \
--n 200 --threads 16
"""
import argparse
import time
import uuid
from concurrent.futures import ThreadPoolExecutor
import httpx
@@ -22,6 +26,7 @@ import httpx
def main():
ap = argparse.ArgumentParser(description="HTTP-стресс contracts-flask")
ap.add_argument("--url", default="http://127.0.0.1:5000")
ap.add_argument("--vm-url", default="https://contracts.kube5s.ru/contracts-upload/", help="ВМ WebDAV-буфер (PUT файла)")
ap.add_argument("--n", type=int, default=1000, help="число запросов")
ap.add_argument("--threads", type=int, default=32, help="параллельных потоков")
ap.add_argument("--size", type=int, default=100000, help="размер файла в байтах (если не задан --file)")
@@ -50,12 +55,25 @@ def main():
with httpx.Client(timeout=30) as c:
if args.health_only:
r = c.get(f"{args.url}/health")
else:
r = c.post(
f"{args.url}/upload",
files={"files": (fname, payload, "application/octet-stream")},
)
if r.status_code == 200:
if r.status_code == 200:
ok += 1
else:
err += 1
return
# Фаза 1: PUT файла на ВМ WebDAV (мимо шлюза ~64KB)
token = uuid.uuid4().hex
vm_url = args.vm_url.rstrip("/") + "/" + token + "_0"
r1 = c.put(vm_url, content=payload, headers={"Content-Type": "application/octet-stream"})
if not r1.is_success:
err += 1
return
# Фаза 2: POST /api/upload_refs — бэк тянет файл с ВМ (egress)
body = {
"batch_id": token,
"files": [{"name": fname, "size": real_size, "url": vm_url}],
}
r2 = c.post(f"{args.url}/api/upload_refs", json=body)
if r2.status_code == 200:
ok += 1
else:
err += 1
@@ -70,6 +88,7 @@ def main():
elapsed = time.time() - t0
print(f"url={args.url}")
print(f"vm_url={args.vm_url}")
print(f"n={args.n} threads={args.threads} size={real_size}B file={args.file or '(gen)'} health_only={args.health_only}")
print(f"ok={ok} err={err} timeouts={slow} elapsed={elapsed:.1f}s rps={args.n / elapsed:.1f}")