4NK_IA_back/tests/performance/locustfile.py
root 5d8ad901d1 Initial commit: Pipeline notarial complet
- Infrastructure complète de traitement de documents notariaux
- API FastAPI d'ingestion et d'orchestration
- Pipelines Celery pour le traitement asynchrone
- Support des formats PDF, JPEG, PNG, TIFF, HEIC
- OCR avec Tesseract et correction lexicale
- Classification automatique des documents avec Ollama
- Extraction de données structurées
- Indexation dans AnythingLLM et OpenSearch
- Système de vérifications et contrôles métier
- Base de données PostgreSQL pour le métier
- Stockage objet avec MinIO
- Base de données graphe Neo4j
- Recherche plein-texte avec OpenSearch
- Supervision avec Prometheus et Grafana
- Scripts d'installation pour Debian
- Documentation complète
- Tests unitaires et de performance
- Service systemd pour le déploiement
- Scripts de déploiement automatisés
2025-09-08 22:05:22 +02:00

123 lines
5.0 KiB
Python

"""
Tests de performance avec Locust
"""
from locust import HttpUser, task, between
import random
import os
class NotariatPipelineUser(HttpUser):
"""Utilisateur simulé pour les tests de performance"""
wait_time = between(1, 3)
def on_start(self):
"""Initialisation de l'utilisateur"""
self.etude_id = f"E-{random.randint(100, 999)}"
self.utilisateur_id = f"U-{random.randint(1000, 9999)}"
self.dossier_id = f"D-2025-{random.randint(100, 999)}"
@task(3)
def import_document(self):
"""Test d'import de document"""
# Simulation d'un fichier PDF
files = {
"file": ("test_document.pdf", self._generate_fake_pdf(), "application/pdf")
}
data = {
"id_dossier": self.dossier_id,
"source": "upload",
"etude_id": self.etude_id,
"utilisateur_id": self.utilisateur_id
}
with self.client.post("/api/import", files=files, data=data, catch_response=True) as response:
if response.status_code == 200:
result = response.json()
if result.get("status") == "queued":
response.success()
else:
response.failure(f"Status non attendu: {result.get('status')}")
else:
response.failure(f"Code de statut: {response.status_code}")
@task(1)
def health_check(self):
"""Test de vérification de santé"""
with self.client.get("/api/health", catch_response=True) as response:
if response.status_code == 200:
data = response.json()
if data.get("status") in ["healthy", "degraded"]:
response.success()
else:
response.failure(f"Status de santé: {data.get('status')}")
else:
response.failure(f"Code de statut: {response.status_code}")
@task(1)
def get_documents(self):
"""Test de récupération des documents"""
params = {
"etude_id": self.etude_id,
"limit": 10
}
with self.client.get("/api/documents", params=params, catch_response=True) as response:
if response.status_code == 200:
data = response.json()
if isinstance(data, list):
response.success()
else:
response.failure("Format de réponse invalide")
else:
response.failure(f"Code de statut: {response.status_code}")
@task(1)
def admin_stats(self):
"""Test des statistiques d'administration"""
with self.client.get("/api/admin/stats", catch_response=True) as response:
if response.status_code == 200:
data = response.json()
if "documents" in data and "processing" in data:
response.success()
else:
response.failure("Données de statistiques manquantes")
else:
response.failure(f"Code de statut: {response.status_code}")
def _generate_fake_pdf(self):
"""Génération d'un faux PDF pour les tests"""
# En réalité, on utiliserait un vrai fichier PDF de test
return b"%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\n2 0 obj\n<<\n/Type /Pages\n/Kids [3 0 R]\n/Count 1\n>>\nendobj\n3 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n/MediaBox [0 0 612 792]\n/Contents 4 0 R\n>>\nendobj\n4 0 obj\n<<\n/Length 44\n>>\nstream\nBT\n/F1 12 Tf\n72 720 Td\n(Test Document) Tj\nET\nendstream\nendobj\nxref\n0 5\n0000000000 65535 f \n0000000009 00000 n \n0000000058 00000 n \n0000000115 00000 n \n0000000204 00000 n \ntrailer\n<<\n/Size 5\n/Root 1 0 R\n>>\nstartxref\n297\n%%EOF"
class HighLoadUser(HttpUser):
"""Utilisateur pour tests de charge élevée"""
wait_time = between(0.1, 0.5)
def on_start(self):
"""Initialisation pour charge élevée"""
self.etude_id = f"E-{random.randint(100, 999)}"
self.utilisateur_id = f"U-{random.randint(1000, 9999)}"
self.dossier_id = f"D-2025-{random.randint(100, 999)}"
@task(10)
def rapid_import(self):
"""Import rapide de documents"""
files = {
"file": ("rapid_test.pdf", self._generate_fake_pdf(), "application/pdf")
}
data = {
"id_dossier": f"{self.dossier_id}-{random.randint(1, 1000)}",
"source": "upload",
"etude_id": self.etude_id,
"utilisateur_id": self.utilisateur_id
}
self.client.post("/api/import", files=files, data=data)
def _generate_fake_pdf(self):
"""Génération d'un faux PDF léger"""
return b"%PDF-1.4\n1 0 obj\n<<\n/Type /Catalog\n/Pages 2 0 R\n>>\nendobj\n2 0 obj\n<<\n/Type /Pages\n/Kids [3 0 R]\n/Count 1\n>>\nendobj\n3 0 obj\n<<\n/Type /Page\n/Parent 2 0 R\n/MediaBox [0 0 612 792]\n>>\nendobj\nxref\n0 4\n0000000000 65535 f \n0000000009 00000 n \n0000000058 00000 n \n0000000115 00000 n \ntrailer\n<<\n/Size 4\n/Root 1 0 R\n>>\nstartxref\n174\n%%EOF"