""" Tests for Memory System Exceptions. """ from uuid import uuid4 import pytest from app.services.memory.exceptions import ( CheckpointError, EmbeddingError, MemoryCapacityError, MemoryConflictError, MemoryConsolidationError, MemoryError, MemoryExpiredError, MemoryNotFoundError, MemoryRetrievalError, MemoryScopeError, MemorySerializationError, MemoryStorageError, ) class TestMemoryError: """Tests for base MemoryError class.""" def test_basic_error(self) -> None: """Test creating a basic memory error.""" error = MemoryError("Something went wrong") assert str(error) == "Something went wrong" assert error.message == "Something went wrong" assert error.memory_type is None assert error.scope_type is None assert error.scope_id is None assert error.details == {} def test_error_with_context(self) -> None: """Test creating an error with context.""" error = MemoryError( "Operation failed", memory_type="episodic", scope_type="project", scope_id="proj-123", details={"operation": "search"}, ) assert error.memory_type == "episodic" assert error.scope_type == "project" assert error.scope_id == "proj-123" assert error.details == {"operation": "search"} def test_error_inheritance(self) -> None: """Test that MemoryError inherits from Exception.""" error = MemoryError("test") assert isinstance(error, Exception) class TestMemoryNotFoundError: """Tests for MemoryNotFoundError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryNotFoundError() assert error.message == "Memory not found" def test_with_memory_id(self) -> None: """Test error with memory ID.""" memory_id = uuid4() error = MemoryNotFoundError( f"Memory {memory_id} not found", memory_id=memory_id, ) assert error.memory_id == memory_id def test_with_key(self) -> None: """Test error with key.""" error = MemoryNotFoundError( "Key not found", key="my_key", ) assert error.key == "my_key" class TestMemoryCapacityError: """Tests for MemoryCapacityError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryCapacityError() assert error.message == "Memory capacity exceeded" def test_with_sizes(self) -> None: """Test error with size information.""" error = MemoryCapacityError( "Working memory full", current_size=1048576, max_size=1000000, item_count=500, ) assert error.current_size == 1048576 assert error.max_size == 1000000 assert error.item_count == 500 class TestMemoryExpiredError: """Tests for MemoryExpiredError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryExpiredError() assert error.message == "Memory has expired" def test_with_expiry_info(self) -> None: """Test error with expiry information.""" error = MemoryExpiredError( "Key expired", key="session_data", expired_at="2025-01-05T00:00:00Z", ) assert error.key == "session_data" assert error.expired_at == "2025-01-05T00:00:00Z" class TestMemoryStorageError: """Tests for MemoryStorageError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryStorageError() assert error.message == "Memory storage operation failed" def test_with_operation_info(self) -> None: """Test error with operation information.""" error = MemoryStorageError( "Redis write failed", operation="set", backend="redis", ) assert error.operation == "set" assert error.backend == "redis" class TestMemorySerializationError: """Tests for MemorySerializationError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemorySerializationError() assert error.message == "Memory serialization failed" def test_with_content_type(self) -> None: """Test error with content type.""" error = MemorySerializationError( "Cannot serialize function", content_type="function", ) assert error.content_type == "function" class TestMemoryScopeError: """Tests for MemoryScopeError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryScopeError() assert error.message == "Memory scope error" def test_with_scope_info(self) -> None: """Test error with scope information.""" error = MemoryScopeError( "Scope access denied", requested_scope="global", allowed_scopes=["project", "session"], ) assert error.requested_scope == "global" assert error.allowed_scopes == ["project", "session"] class TestMemoryConsolidationError: """Tests for MemoryConsolidationError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryConsolidationError() assert error.message == "Memory consolidation failed" def test_with_consolidation_info(self) -> None: """Test error with consolidation information.""" error = MemoryConsolidationError( "Transfer failed", source_type="working", target_type="episodic", items_processed=50, ) assert error.source_type == "working" assert error.target_type == "episodic" assert error.items_processed == 50 class TestMemoryRetrievalError: """Tests for MemoryRetrievalError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryRetrievalError() assert error.message == "Memory retrieval failed" def test_with_query_info(self) -> None: """Test error with query information.""" error = MemoryRetrievalError( "Search timeout", query="complex search query", retrieval_type="semantic", ) assert error.query == "complex search query" assert error.retrieval_type == "semantic" class TestEmbeddingError: """Tests for EmbeddingError class.""" def test_default_message(self) -> None: """Test default error message.""" error = EmbeddingError() assert error.message == "Embedding generation failed" def test_with_embedding_info(self) -> None: """Test error with embedding information.""" error = EmbeddingError( "Content too long", content_length=100000, model="text-embedding-3-small", ) assert error.content_length == 100000 assert error.model == "text-embedding-3-small" class TestCheckpointError: """Tests for CheckpointError class.""" def test_default_message(self) -> None: """Test default error message.""" error = CheckpointError() assert error.message == "Checkpoint operation failed" def test_with_checkpoint_info(self) -> None: """Test error with checkpoint information.""" error = CheckpointError( "Restore failed", checkpoint_id="chk-123", operation="restore", ) assert error.checkpoint_id == "chk-123" assert error.operation == "restore" class TestMemoryConflictError: """Tests for MemoryConflictError class.""" def test_default_message(self) -> None: """Test default error message.""" error = MemoryConflictError() assert error.message == "Memory conflict detected" def test_with_conflict_info(self) -> None: """Test error with conflict information.""" id1 = uuid4() id2 = uuid4() error = MemoryConflictError( "Contradictory facts detected", conflicting_ids=[id1, id2], conflict_type="semantic", ) assert len(error.conflicting_ids) == 2 assert error.conflict_type == "semantic" class TestExceptionHierarchy: """Tests for exception inheritance hierarchy.""" def test_all_exceptions_inherit_from_memory_error(self) -> None: """Test that all exceptions inherit from MemoryError.""" exceptions = [ MemoryNotFoundError(), MemoryCapacityError(), MemoryExpiredError(), MemoryStorageError(), MemorySerializationError(), MemoryScopeError(), MemoryConsolidationError(), MemoryRetrievalError(), EmbeddingError(), CheckpointError(), MemoryConflictError(), ] for exc in exceptions: assert isinstance(exc, MemoryError) assert isinstance(exc, Exception) def test_can_catch_base_error(self) -> None: """Test that catching MemoryError catches all subclasses.""" exceptions = [ MemoryNotFoundError("not found"), MemoryCapacityError("capacity"), MemoryStorageError("storage"), ] for exc in exceptions: with pytest.raises(MemoryError): raise exc