- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
477 lines
17 KiB
Python
Executable File
477 lines
17 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Test rapide du système RPA Vision V3 après corrections
|
|
Tests de fonctionnalité réelle sans simulation
|
|
"""
|
|
|
|
import sys
|
|
import os
|
|
import tempfile
|
|
import shutil
|
|
import numpy as np
|
|
from pathlib import Path
|
|
|
|
# Ajouter le répertoire racine au path
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
|
|
def test_core_functionality():
|
|
"""Test de la fonctionnalité réelle des composants critiques"""
|
|
print("🧪 Test de fonctionnalité réelle des composants...")
|
|
|
|
# Test 1: FAISSManager avec opérations réelles
|
|
try:
|
|
from core.embedding.faiss_manager import FAISSManager
|
|
|
|
# Créer un manager réel
|
|
manager = FAISSManager(dimensions=512)
|
|
|
|
# Test d'ajout d'embedding réel
|
|
test_vector = np.random.randn(512).astype(np.float32)
|
|
faiss_id = manager.add_embedding("test_emb_1", test_vector, {"test": True})
|
|
|
|
# Test de recherche réelle
|
|
results = manager.search_similar(test_vector, k=1)
|
|
|
|
if len(results) > 0 and results[0].embedding_id == "test_emb_1":
|
|
print("✅ FAISSManager - Fonctionnalité réelle validée")
|
|
else:
|
|
print("❌ FAISSManager - Recherche échouée")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ FAISSManager: {e}")
|
|
return False
|
|
|
|
# Test 2: StorageManager avec opérations réelles sur fichiers
|
|
try:
|
|
from core.persistence import StorageManager
|
|
|
|
# Utiliser un répertoire temporaire réel
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
storage = StorageManager(base_path=temp_dir)
|
|
|
|
# Test de sauvegarde réelle d'embedding
|
|
test_embedding = np.random.randn(512).astype(np.float32)
|
|
embedding_path = storage.save_embedding(
|
|
"test_session",
|
|
"test_state",
|
|
test_embedding,
|
|
{"test_meta": "value"}
|
|
)
|
|
|
|
# Vérifier que le fichier existe réellement
|
|
if not Path(embedding_path).exists():
|
|
print("❌ StorageManager - Fichier non créé")
|
|
return False
|
|
|
|
# Test de chargement réel
|
|
loaded_embedding, loaded_metadata = storage.load_embedding(embedding_path)
|
|
|
|
# Vérifier que les données sont identiques
|
|
if not np.allclose(test_embedding, loaded_embedding):
|
|
print("❌ StorageManager - Données corrompues")
|
|
return False
|
|
|
|
print("✅ StorageManager - Fonctionnalité réelle validée")
|
|
|
|
except Exception as e:
|
|
print(f"❌ StorageManager: {e}")
|
|
return False
|
|
|
|
# Test 3: ProcessingPipeline avec données réelles
|
|
try:
|
|
from server.processing_pipeline import ProcessingPipeline
|
|
|
|
# Créer un pipeline réel
|
|
pipeline = ProcessingPipeline()
|
|
|
|
# Test avec des données réelles minimales
|
|
test_session_data = {
|
|
"session_id": "test_session_001",
|
|
"events": [
|
|
{
|
|
"type": "mouse_click",
|
|
"timestamp": 1234567890,
|
|
"x": 100,
|
|
"y": 200
|
|
}
|
|
],
|
|
"screenshots": []
|
|
}
|
|
|
|
# Valider que le pipeline peut traiter des données réelles
|
|
is_valid = pipeline.validate_session_data(test_session_data)
|
|
|
|
if is_valid:
|
|
print("✅ ProcessingPipeline - Validation réelle réussie")
|
|
else:
|
|
print("❌ ProcessingPipeline - Validation échouée")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ ProcessingPipeline: {e}")
|
|
return False
|
|
|
|
# Test 4: Modèles de données avec instanciation réelle
|
|
try:
|
|
from core.models import RawSession, ScreenState, UIElement
|
|
|
|
# Test RawSession avec données réelles
|
|
raw_session = RawSession(
|
|
session_id="test_session",
|
|
user_id="test_user",
|
|
started_at="2025-01-06T10:00:00Z",
|
|
events=[],
|
|
screenshots=[]
|
|
)
|
|
|
|
# Vérifier que l'objet est utilisable
|
|
if raw_session.session_id != "test_session":
|
|
print("❌ RawSession - Instanciation échouée")
|
|
return False
|
|
|
|
# Test UIElement avec données réelles
|
|
ui_element = UIElement(
|
|
element_id="test_element",
|
|
element_type="button",
|
|
bbox=[10, 20, 100, 50],
|
|
text="Test Button",
|
|
confidence=0.95
|
|
)
|
|
|
|
# Vérifier les propriétés calculées
|
|
if ui_element.center != (60, 45): # Centre calculé
|
|
print("❌ UIElement - Calculs échoués")
|
|
return False
|
|
|
|
print("✅ Modèles de données - Instanciation réelle validée")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Modèles de données: {e}")
|
|
return False
|
|
|
|
return True
|
|
|
|
def test_real_env_config():
|
|
"""Test de la configuration d'environnement avec chargement réel"""
|
|
print("\n🔧 Test configuration environnement réelle...")
|
|
|
|
env_path = Path(".env.local")
|
|
if not env_path.exists():
|
|
print("❌ .env.local manquant")
|
|
return False
|
|
|
|
# Test de chargement réel des variables d'environnement
|
|
try:
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
# Sauvegarder l'état actuel
|
|
original_env = dict(os.environ)
|
|
|
|
# Charger le fichier .env.local réellement
|
|
load_dotenv(env_path)
|
|
|
|
# Vérifier que les variables sont réellement chargées
|
|
auth_disabled = os.getenv("RPA_AUTH_DISABLED", "true").lower()
|
|
encryption_password = os.getenv("ENCRYPTION_PASSWORD", "")
|
|
|
|
if auth_disabled == "false":
|
|
print("✅ Authentification activée (chargée depuis .env)")
|
|
else:
|
|
print("⚠️ Authentification désactivée")
|
|
|
|
if encryption_password:
|
|
print("✅ Mot de passe de chiffrement configuré et chargé")
|
|
else:
|
|
print("❌ Mot de passe de chiffrement manquant ou vide")
|
|
return False
|
|
|
|
# Test de validation de la configuration de sécurité
|
|
try:
|
|
from core.security.security_config import SecurityConfig
|
|
|
|
# Créer une configuration réelle
|
|
security_config = SecurityConfig()
|
|
|
|
# Vérifier que la configuration est valide
|
|
if security_config.validate():
|
|
print("✅ Configuration de sécurité validée")
|
|
else:
|
|
print("⚠️ Configuration de sécurité invalide")
|
|
|
|
except Exception as e:
|
|
print(f"⚠️ SecurityConfig non disponible: {e}")
|
|
|
|
# Restaurer l'environnement original
|
|
os.environ.clear()
|
|
os.environ.update(original_env)
|
|
|
|
return True
|
|
|
|
except ImportError:
|
|
print("⚠️ python-dotenv non installé, test de base seulement")
|
|
|
|
# Test de base sans dotenv
|
|
with open(env_path, 'r') as f:
|
|
content = f.read()
|
|
|
|
if "RPA_AUTH_DISABLED=false" in content:
|
|
print("✅ Authentification activée (fichier)")
|
|
else:
|
|
print("⚠️ Authentification désactivée")
|
|
|
|
if "ENCRYPTION_PASSWORD=" in content and len(content.split("ENCRYPTION_PASSWORD=")[1].split('\n')[0].strip()) > 0:
|
|
print("✅ Mot de passe de chiffrement configuré (fichier)")
|
|
else:
|
|
print("❌ Mot de passe de chiffrement manquant")
|
|
return False
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur lors du test de configuration: {e}")
|
|
return False
|
|
|
|
def test_real_directories_and_permissions():
|
|
"""Test des répertoires avec vérification des permissions réelles"""
|
|
print("\n📁 Test des répertoires et permissions...")
|
|
|
|
dirs_to_test = [
|
|
("data/training/uploads", True), # (path, should_be_writable)
|
|
("data/training/sessions", True),
|
|
("logs", True),
|
|
("venv_v3", False), # Virtual env, just check existence
|
|
("core", False), # Core modules, read-only
|
|
]
|
|
|
|
all_ok = True
|
|
|
|
for dir_path, should_be_writable in dirs_to_test:
|
|
path_obj = Path(dir_path)
|
|
|
|
if not path_obj.exists():
|
|
print(f"❌ {dir_path} - N'existe pas")
|
|
all_ok = False
|
|
continue
|
|
|
|
if not path_obj.is_dir():
|
|
print(f"❌ {dir_path} - N'est pas un répertoire")
|
|
all_ok = False
|
|
continue
|
|
|
|
# Test des permissions réelles
|
|
if should_be_writable:
|
|
try:
|
|
# Test d'écriture réel avec un fichier temporaire
|
|
test_file = path_obj / ".test_write_permission"
|
|
test_file.write_text("test")
|
|
test_file.unlink() # Supprimer le fichier de test
|
|
print(f"✅ {dir_path} - Accessible en écriture")
|
|
except Exception as e:
|
|
print(f"❌ {dir_path} - Pas d'accès en écriture: {e}")
|
|
all_ok = False
|
|
else:
|
|
# Test de lecture seulement
|
|
try:
|
|
list(path_obj.iterdir()) # Essayer de lister le contenu
|
|
print(f"✅ {dir_path} - Accessible en lecture")
|
|
except Exception as e:
|
|
print(f"❌ {dir_path} - Pas d'accès en lecture: {e}")
|
|
all_ok = False
|
|
|
|
# Test spécifique: Vérifier que les répertoires de données peuvent stocker des fichiers réels
|
|
try:
|
|
test_data_dir = Path("data/training/uploads")
|
|
if test_data_dir.exists():
|
|
# Créer un fichier de test réaliste
|
|
test_session_file = test_data_dir / "test_session.json"
|
|
test_data = {
|
|
"session_id": "test_001",
|
|
"timestamp": "2025-01-06T10:00:00Z",
|
|
"events": []
|
|
}
|
|
|
|
import json
|
|
test_session_file.write_text(json.dumps(test_data, indent=2))
|
|
|
|
# Vérifier que le fichier peut être lu
|
|
loaded_data = json.loads(test_session_file.read_text())
|
|
|
|
if loaded_data["session_id"] == "test_001":
|
|
print("✅ Test d'écriture/lecture de données réelles réussi")
|
|
test_session_file.unlink() # Nettoyer
|
|
else:
|
|
print("❌ Test d'écriture/lecture de données échoué")
|
|
all_ok = False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Test d'écriture/lecture de données: {e}")
|
|
all_ok = False
|
|
|
|
return all_ok
|
|
|
|
def test_integration_flow():
|
|
"""Test d'un flux d'intégration réel simplifié"""
|
|
print("\n🔄 Test de flux d'intégration réel...")
|
|
|
|
try:
|
|
# Test 1: Créer une session réelle avec StorageManager
|
|
from core.persistence import StorageManager
|
|
from core.models import RawSession
|
|
|
|
with tempfile.TemporaryDirectory() as temp_dir:
|
|
storage = StorageManager(base_path=temp_dir)
|
|
|
|
# Créer une session réelle
|
|
session = RawSession(
|
|
session_id="integration_test_001",
|
|
user_id="test_user",
|
|
started_at="2025-01-06T10:00:00Z",
|
|
events=[
|
|
{
|
|
"type": "mouse_click",
|
|
"timestamp": 1234567890,
|
|
"x": 150,
|
|
"y": 250,
|
|
"button": "left"
|
|
}
|
|
],
|
|
screenshots=[]
|
|
)
|
|
|
|
# Sauvegarder la session réellement
|
|
session_path = storage.save_raw_session(session)
|
|
|
|
if not Path(session_path).exists():
|
|
print("❌ Sauvegarde de session échouée")
|
|
return False
|
|
|
|
# Charger la session et vérifier l'intégrité
|
|
loaded_session = storage.load_raw_session(session_path)
|
|
|
|
if loaded_session.session_id != session.session_id:
|
|
print("❌ Intégrité de session compromise")
|
|
return False
|
|
|
|
print("✅ Flux session: sauvegarde/chargement réussi")
|
|
|
|
# Test 2: Pipeline de traitement avec données réelles
|
|
from server.processing_pipeline import ProcessingPipeline
|
|
|
|
pipeline = ProcessingPipeline()
|
|
|
|
# Simuler un traitement réel avec validation
|
|
test_data = {
|
|
"session_id": "integration_test_002",
|
|
"events": [
|
|
{
|
|
"type": "key_press",
|
|
"timestamp": 1234567891,
|
|
"key": "Enter"
|
|
}
|
|
]
|
|
}
|
|
|
|
# Valider avec le pipeline réel
|
|
validation_result = pipeline.validate_session_data(test_data)
|
|
|
|
if not validation_result:
|
|
print("❌ Validation pipeline échouée")
|
|
return False
|
|
|
|
print("✅ Pipeline: validation de données réussie")
|
|
|
|
# Test 3: Intégration FAISS + Storage
|
|
from core.embedding.faiss_manager import FAISSManager
|
|
|
|
faiss_manager = FAISSManager(dimensions=128) # Plus petit pour le test
|
|
|
|
# Créer des embeddings réels et les stocker
|
|
embeddings_data = []
|
|
for i in range(5):
|
|
embedding = np.random.randn(128).astype(np.float32)
|
|
embedding_id = f"integration_emb_{i}"
|
|
|
|
# Ajouter à FAISS
|
|
faiss_id = faiss_manager.add_embedding(embedding_id, embedding)
|
|
embeddings_data.append((embedding_id, embedding, faiss_id))
|
|
|
|
# Test de recherche d'intégration
|
|
query_embedding = embeddings_data[2][1] # Utiliser le 3ème embedding
|
|
results = faiss_manager.search_similar(query_embedding, k=3)
|
|
|
|
if len(results) == 0:
|
|
print("❌ Recherche FAISS échouée")
|
|
return False
|
|
|
|
# Vérifier que le résultat le plus similaire est correct
|
|
if results[0].embedding_id != embeddings_data[2][0]:
|
|
print("❌ Recherche FAISS imprécise")
|
|
return False
|
|
|
|
print("✅ Intégration FAISS: recherche réussie")
|
|
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"❌ Flux d'intégration: {e}")
|
|
return False
|
|
|
|
def main():
|
|
print("🔧 RPA Vision V3 - Test Système avec Fonctionnalité Réelle")
|
|
print("=" * 60)
|
|
|
|
tests = [
|
|
("Fonctionnalité Core", test_core_functionality),
|
|
("Configuration Réelle", test_real_env_config),
|
|
("Répertoires & Permissions", test_real_directories_and_permissions),
|
|
("Flux d'Intégration", test_integration_flow)
|
|
]
|
|
|
|
results = []
|
|
for name, test_func in tests:
|
|
try:
|
|
print(f"\n🔍 Exécution: {name}")
|
|
result = test_func()
|
|
results.append((name, result))
|
|
except Exception as e:
|
|
print(f"❌ Erreur dans {name}: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
results.append((name, False))
|
|
|
|
print("\n" + "=" * 60)
|
|
print("📊 RÉSULTATS FINAUX:")
|
|
|
|
all_passed = True
|
|
for name, passed in results:
|
|
status = "✅ PASS" if passed else "❌ FAIL"
|
|
print(f" {name}: {status}")
|
|
if not passed:
|
|
all_passed = False
|
|
|
|
print("\n" + "=" * 60)
|
|
|
|
if all_passed:
|
|
print("🎉 TOUS LES TESTS DE FONCTIONNALITÉ RÉELLE PASSENT !")
|
|
print("\n🚀 Le système est validé avec:")
|
|
print(" • Opérations FAISS réelles")
|
|
print(" • Stockage de fichiers réel")
|
|
print(" • Configuration chargée réellement")
|
|
print(" • Permissions vérifiées")
|
|
print(" • Flux d'intégration testé")
|
|
print(f"\n🎯 Prêt pour le lancement:")
|
|
print(f" ./run.sh --server")
|
|
return 0
|
|
else:
|
|
print("⚠️ CERTAINS TESTS DE FONCTIONNALITÉ ÉCHOUENT")
|
|
print("Vérifiez les erreurs détaillées ci-dessus")
|
|
print("\n💡 Conseils de dépannage:")
|
|
print(" • Vérifiez que les dépendances sont installées")
|
|
print(" • Vérifiez les permissions des répertoires")
|
|
print(" • Vérifiez la configuration .env.local")
|
|
return 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |