- 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>
99 lines
3.2 KiB
Python
99 lines
3.2 KiB
Python
"""
|
|
Tests unitaires pour FAISSManager avec property-based testing.
|
|
|
|
Property 11: FAISS Index Consistency
|
|
- L'index FAISS doit maintenir la cohérence entre vecteurs et métadonnées
|
|
- Validates: Requirements 4.8, 12.3, 12.6
|
|
"""
|
|
|
|
import pytest
|
|
import numpy as np
|
|
import tempfile
|
|
import shutil
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
|
|
from core.embedding.faiss_manager import FAISSManager
|
|
|
|
|
|
class TestFAISSManager:
|
|
"""Tests pour FAISSManager."""
|
|
|
|
def setup_method(self):
|
|
"""Setup avant chaque test."""
|
|
self.temp_dir = tempfile.mkdtemp()
|
|
self.index_path = Path(self.temp_dir) / "test_index"
|
|
self.manager = FAISSManager(dimensions=512)
|
|
|
|
def teardown_method(self):
|
|
"""Cleanup après chaque test."""
|
|
shutil.rmtree(self.temp_dir, ignore_errors=True)
|
|
|
|
def test_add_single_embedding(self):
|
|
"""Test ajout d'un seul embedding."""
|
|
vector = np.random.randn(512).astype(np.float32)
|
|
vector = vector / np.linalg.norm(vector)
|
|
|
|
metadata = {
|
|
'state_id': 'state_001',
|
|
'timestamp': '2024-11-22T10:00:00'
|
|
}
|
|
|
|
idx = self.manager.add_embedding('emb_001', vector, metadata)
|
|
|
|
assert idx == 0
|
|
assert self.manager.index.ntotal == 1
|
|
|
|
def test_property_index_consistency(self):
|
|
"""Property 11: Cohérence entre index et métadonnées."""
|
|
n_vectors = 20
|
|
|
|
for i in range(n_vectors):
|
|
vector = np.random.randn(512).astype(np.float32)
|
|
vector = vector / np.linalg.norm(vector)
|
|
metadata = {'state_id': f'state_{i:03d}', 'index': i}
|
|
self.manager.add_embedding(f'emb_{i:03d}', vector, metadata)
|
|
|
|
assert self.manager.index.ntotal == n_vectors
|
|
assert len(self.manager.metadata_store) == n_vectors
|
|
|
|
def test_search_similar(self):
|
|
"""Test recherche de similarité."""
|
|
vectors = []
|
|
for i in range(5):
|
|
vector = np.random.randn(512).astype(np.float32)
|
|
vector = vector / np.linalg.norm(vector)
|
|
vectors.append(vector)
|
|
self.manager.add_embedding(f'emb_{i}', vector, {'state_id': f'state_{i}'})
|
|
|
|
query = vectors[0]
|
|
results = self.manager.search_similar(query, k=3)
|
|
|
|
assert len(results) == 3
|
|
assert results[0].similarity > 0.99
|
|
|
|
def test_save_and_load(self):
|
|
"""Test sauvegarde et chargement."""
|
|
n_vectors = 10
|
|
original_vectors = []
|
|
|
|
for i in range(n_vectors):
|
|
vector = np.random.randn(512).astype(np.float32)
|
|
vector = vector / np.linalg.norm(vector)
|
|
original_vectors.append(vector)
|
|
self.manager.add_embedding(f'emb_{i}', vector, {'state_id': f'state_{i}'})
|
|
|
|
index_path = self.index_path / "index.faiss"
|
|
metadata_path = self.index_path / "metadata.pkl"
|
|
self.manager.save(index_path, metadata_path)
|
|
|
|
new_manager = FAISSManager.load(index_path, metadata_path)
|
|
|
|
assert new_manager.index.ntotal == n_vectors
|
|
assert len(new_manager.metadata_store) == n_vectors
|
|
|
|
|
|
if __name__ == '__main__':
|
|
pytest.main([__file__, '-v'])
|