""" 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'])