""" 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"