From 6729080571facbbde8fe4c188ec777dd8babb872 Mon Sep 17 00:00:00 2001 From: Rassaby Ludovic Date: Tue, 14 Oct 2025 13:28:43 +0400 Subject: [PATCH] Add connectivity error simulation tests for TP4 validation --- .github/workflows/test-connectivity.yml | 73 +++++++++++++++++ backend/test_connectivity.py | 103 ++++++++++++++++++++++++ backend/test_error_simulation.py | 37 +++++++++ test-connectivity.bat | 41 ++++++++++ test-connectivity.sh | 41 ++++++++++ 5 files changed, 295 insertions(+) create mode 100644 .github/workflows/test-connectivity.yml create mode 100644 backend/test_connectivity.py create mode 100644 backend/test_error_simulation.py create mode 100644 test-connectivity.bat create mode 100644 test-connectivity.sh diff --git a/.github/workflows/test-connectivity.yml b/.github/workflows/test-connectivity.yml new file mode 100644 index 0000000..96595dc --- /dev/null +++ b/.github/workflows/test-connectivity.yml @@ -0,0 +1,73 @@ +name: 🔍 Tests de ConnectivitĂ© - Simulation d'Erreurs + +on: + push: + branches: [ main, develop ] + pull_request: + branches: [ main ] + workflow_dispatch: # Permet de dĂ©clencher manuellement + +jobs: + connectivity-test: + runs-on: ubuntu-latest + + steps: + - name: đŸ“„ Checkout code + uses: actions/checkout@v4 + + - name: 🐳 Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: 🚀 Start services (DB + Backend) + run: | + echo "DĂ©marrage des services..." + docker compose up -d db backend + sleep 15 + + - name: 🔍 Test 1: Backend accessible + run: | + echo "Test de connectivitĂ© au backend..." + docker compose run --rm test python -c " + import requests + try: + response = requests.get('http://backend:8000/health', timeout=5) + print('✅ Backend accessible - Status:', response.status_code) + except Exception as e: + print('❌ Backend inaccessible:', e) + exit(1) + " + + - name: ❌ Test 2: Simulation d'erreur (doit Ă©chouer) + run: | + echo "Simulation d'erreur de connectivitĂ©..." + docker compose run --rm test python -c " + import requests + print('🔍 Test de connectivitĂ© Ă  un port inexistant...') + try: + response = requests.get('http://backend:9999/health', timeout=2) + print('❌ Connexion inattendue - ce test devrait Ă©chouer') + exit(1) + except Exception as e: + print('❌ Erreur de connectivitĂ© simulĂ©e dĂ©tectĂ©e:', e) + print('✅ La dĂ©tection automatique d erreur fonctionne!') + exit(1) # Force l'Ă©chec pour dĂ©montrer la dĂ©tection + " + continue-on-error: true + + - name: đŸ§Ș Test 3: Tests pytest avec erreurs intentionnelles + run: | + echo "Lancement des tests de connectivitĂ© avec pytest..." + docker compose run --rm test pytest test_connectivity.py -v + continue-on-error: true + + - name: 📊 Show test results + if: always() + run: | + echo "📋 RĂ©sultats des tests de connectivitĂ©:" + docker compose logs backend | tail -20 + + - name: đŸ§č Cleanup + if: always() + run: | + docker compose down -v + docker system prune -f diff --git a/backend/test_connectivity.py b/backend/test_connectivity.py new file mode 100644 index 0000000..1bed572 --- /dev/null +++ b/backend/test_connectivity.py @@ -0,0 +1,103 @@ +import pytest +import requests +import os +import time + +# Configuration +BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8000") + +class TestConnectivity: + """Tests de connectivitĂ© pour valider la dĂ©tection automatique d'erreurs""" + + def test_backend_health_with_retry(self): + """Test de santĂ© du backend avec retry - devrait passer""" + max_retries = 3 + for attempt in range(max_retries): + try: + response = requests.get(f"{BASE_URL}/health", timeout=5) + assert response.status_code == 200 + assert response.json()["status"] == "healthy" + print(f"✅ Backend accessible (tentative {attempt + 1})") + return + except requests.exceptions.RequestException as e: + print(f"⚠ Tentative {attempt + 1} Ă©chouĂ©e: {e}") + if attempt < max_retries - 1: + time.sleep(2) + else: + raise + + def test_backend_connection_timeout(self): + """Test de timeout de connexion - simule une erreur de connectivitĂ©""" + # Ce test va Ă©chouer intentionnellement pour dĂ©montrer la dĂ©tection d'erreur + try: + # Tentative de connexion Ă  un port inexistant pour simuler une erreur + response = requests.get("http://localhost:9999/health", timeout=2) + assert False, "Cette ligne ne devrait jamais ĂȘtre atteinte" + except requests.exceptions.ConnectionError: + # C'est l'erreur attendue - on la laisse passer pour dĂ©montrer la dĂ©tection + print("❌ Erreur de connectivitĂ© dĂ©tectĂ©e (comportement attendu)") + raise Exception("Erreur de connectivitĂ© simulĂ©e pour tester la CI") + + def test_database_connectivity(self): + """Test de connectivitĂ© Ă  la base de donnĂ©es via l'API""" + try: + response = requests.get(f"{BASE_URL}/rooms", timeout=5) + assert response.status_code == 200 + assert isinstance(response.json(), list) + print("✅ Base de donnĂ©es accessible via l'API") + except requests.exceptions.RequestException as e: + print(f"❌ Erreur de connectivitĂ© base de donnĂ©es: {e}") + raise + + def test_api_response_time_under_load(self): + """Test de performance sous charge - simule une surcharge""" + start_time = time.time() + + # Faire plusieurs requĂȘtes simultanĂ©es pour simuler une charge + responses = [] + for i in range(5): + try: + response = requests.get(f"{BASE_URL}/health", timeout=10) + responses.append(response) + except requests.exceptions.RequestException as e: + print(f"❌ RequĂȘte {i+1} Ă©chouĂ©e: {e}") + raise + + end_time = time.time() + total_time = end_time - start_time + + # Si le temps de rĂ©ponse est trop long, on considĂšre cela comme une erreur + if total_time > 10: + print(f"❌ Temps de rĂ©ponse trop long: {total_time:.2f}s") + raise Exception(f"Performance dĂ©gradĂ©e dĂ©tectĂ©e: {total_time:.2f}s") + + print(f"✅ Performance acceptable: {total_time:.2f}s") + assert total_time < 10 + +# Test pour simuler une erreur de configuration +def test_misconfigured_endpoint(): + """Test d'un endpoint mal configurĂ© - simule une erreur de configuration""" + # Ce test va Ă©chouer pour dĂ©montrer la dĂ©tection d'erreur + try: + response = requests.get(f"{BASE_URL}/nonexistent-endpoint", timeout=5) + if response.status_code == 404: + print("❌ Endpoint inexistant dĂ©tectĂ© (comportement attendu)") + raise Exception("Endpoint mal configurĂ© dĂ©tectĂ© pour tester la CI") + except requests.exceptions.RequestException as e: + print(f"❌ Erreur de requĂȘte: {e}") + raise Exception("Erreur de configuration dĂ©tectĂ©e pour tester la CI") + +# Test de simulation d'erreur rĂ©seau +def test_network_simulation(): + """Test de simulation d'erreur rĂ©seau - dĂ©montre la dĂ©tection automatique""" + # Simulation d'une panne rĂ©seau temporaire + print("🔍 Simulation d'une panne rĂ©seau...") + + # Ce test va Ă©chouer intentionnellement + try: + # Tentative de connexion Ă  un serveur inexistant + response = requests.get("http://192.168.999.999:8000/health", timeout=1) + assert False, "Connexion impossible - erreur rĂ©seau simulĂ©e" + except requests.exceptions.RequestException: + print("❌ Panne rĂ©seau simulĂ©e dĂ©tectĂ©e (comportement attendu)") + raise Exception("Erreur rĂ©seau simulĂ©e pour valider la dĂ©tection automatique") diff --git a/backend/test_error_simulation.py b/backend/test_error_simulation.py new file mode 100644 index 0000000..16571d0 --- /dev/null +++ b/backend/test_error_simulation.py @@ -0,0 +1,37 @@ +import pytest +import requests +import os + +# Configuration +BASE_URL = os.getenv("API_BASE_URL", "http://localhost:8000") + +def test_backend_accessible(): + """Test que le backend est accessible - devrait passer""" + response = requests.get(f"{BASE_URL}/health", timeout=5) + assert response.status_code == 200 + assert response.json()["status"] == "healthy" + print("✅ Backend accessible") + +def test_simulated_connectivity_error(): + """Test qui simule une erreur de connectivitĂ© - va Ă©chouer intentionnellement""" + # Ce test va Ă©chouer pour dĂ©montrer la dĂ©tection automatique d'erreur + try: + # Tentative de connexion Ă  un port inexistant + response = requests.get("http://backend:9999/health", timeout=2) + assert False, "Cette connexion ne devrait pas rĂ©ussir" + except requests.exceptions.ConnectionError as e: + print("❌ Erreur de connectivitĂ© simulĂ©e dĂ©tectĂ©e") + # On force l'Ă©chec pour dĂ©montrer la dĂ©tection automatique + raise Exception("Erreur de connectivitĂ© simulĂ©e pour valider la dĂ©tection automatique") + +def test_nonexistent_endpoint(): + """Test d'un endpoint inexistant - va Ă©chouer intentionnellement""" + try: + response = requests.get(f"{BASE_URL}/nonexistent-endpoint", timeout=5) + if response.status_code == 404: + print("❌ Endpoint inexistant dĂ©tectĂ©") + # On force l'Ă©chec pour dĂ©montrer la dĂ©tection automatique + raise Exception("Endpoint inexistant dĂ©tectĂ© pour valider la dĂ©tection automatique") + except requests.exceptions.RequestException as e: + print(f"❌ Erreur de requĂȘte: {e}") + raise Exception("Erreur de requĂȘte dĂ©tectĂ©e pour valider la dĂ©tection automatique") diff --git a/test-connectivity.bat b/test-connectivity.bat new file mode 100644 index 0000000..99eab5b --- /dev/null +++ b/test-connectivity.bat @@ -0,0 +1,41 @@ +@echo off +chcp 65001 >nul +echo Test de connectivite - Simulation d'erreurs +echo ========================================== + +echo Verification de l'etat des services... +docker compose ps + +echo. +echo Demarrage des tests de connectivite... +echo (Ces tests vont simuler des erreurs pour valider la detection automatique) + +echo. +echo Test 1: Backend accessible +docker compose run --rm test python -c " +import requests +try: + response = requests.get('http://backend:8000/health', timeout=5) + print('✅ Backend accessible') +except Exception as e: + print('❌ Backend inaccessible:', e) +" + +echo. +echo Test 2: Simulation d'erreur de connectivite +docker compose run --rm test python -c " +import requests +try: + response = requests.get('http://backend:8000/nonexistent', timeout=5) + print('❌ Erreur attendue: endpoint inexistant') +except Exception as e: + print('❌ Erreur de connectivite simulee:', e) +" + +echo. +echo Test 3: Test avec pytest (avec erreurs intentionnelles) +docker compose run --rm test pytest test_connectivity.py -v + +echo. +echo Tests de connectivite termines ! +echo Les erreurs ci-dessus sont intentionnelles pour valider la detection automatique. diff --git a/test-connectivity.sh b/test-connectivity.sh new file mode 100644 index 0000000..7563d83 --- /dev/null +++ b/test-connectivity.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +echo "🔍 Test de connectivitĂ© - Simulation d'erreurs" +echo "==============================================" + +echo "📊 VĂ©rification de l'Ă©tat des services..." +docker compose ps + +echo "" +echo "🚀 DĂ©marrage des tests de connectivitĂ©..." +echo "(Ces tests vont simuler des erreurs pour valider la dĂ©tection automatique)" + +echo "" +echo "đŸ§Ș Test 1: Backend accessible" +docker compose run --rm test python -c " +import requests +try: + response = requests.get('http://backend:8000/health', timeout=5) + print('✅ Backend accessible') +except Exception as e: + print('❌ Backend inaccessible:', e) +" + +echo "" +echo "đŸ§Ș Test 2: Simulation d'erreur de connectivitĂ©" +docker compose run --rm test python -c " +import requests +try: + response = requests.get('http://backend:8000/nonexistent', timeout=5) + print('❌ Erreur attendue: endpoint inexistant') +except Exception as e: + print('❌ Erreur de connectivitĂ© simulĂ©e:', e) +" + +echo "" +echo "đŸ§Ș Test 3: Test avec pytest (avec erreurs intentionnelles)" +docker compose run --rm test pytest test_connectivity.py -v + +echo "" +echo "✅ Tests de connectivitĂ© terminĂ©s !" +echo "Les erreurs ci-dessus sont intentionnelles pour valider la dĂ©tection automatique."