Skip to main content
Glama

Adaptive Graph of Thoughts MCP Server

test_health.pyβ€’42.8 kB
""" Health endpoint unit tests using pytest and FastAPI TestClient. This test suite provides comprehensive coverage for the /health endpoint, testing various scenarios including successful connections, different types of database failures, edge cases, and HTTP method validation. Testing Framework: pytest with FastAPI TestClient Mocking: Built-in monkeypatch fixture for dependency injection """ import json import os import sys import types from unittest.mock import Mock, patch import pytest from fastapi.testclient import TestClient stub_config = types.ModuleType("adaptive_graph_of_thoughts.config") stub_config.Settings = object stub_config.runtime_settings = types.SimpleNamespace( neo4j=types.SimpleNamespace( uri="bolt://localhost", user="neo4j", password="test", database="neo4j" ), app=types.SimpleNamespace( log_level="INFO", name="testapp", version="0.1", cors_allowed_origins_str="*", auth_token=None, ), asr_got={}, ) stub_config.settings = stub_config.runtime_settings stub_config.env_settings = types.SimpleNamespace( llm_provider="openai", openai_api_key="test", anthropic_api_key=None, ) stub_config.RuntimeSettings = object stub_config.LegacyConfig = object stub_config.Config = object stub_config.ExaSearchConfig = object stub_config.GoogleScholarConfig = object stub_config.PubMedConfig = object sys.modules.setdefault("adaptive_graph_of_thoughts.config", stub_config) sys.modules.setdefault("src.adaptive_graph_of_thoughts.config", stub_config) AUTH = ("user", "pass") os.environ.setdefault("BASIC_AUTH_USER", AUTH[0]) os.environ.setdefault("BASIC_AUTH_PASS", AUTH[1]) from adaptive_graph_of_thoughts.app_setup import create_app def test_health_ok(monkeypatch): app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert resp.json()["neo4j"] == "up" def test_health_down(monkeypatch): app = create_app() client = TestClient(app) class BadDriver: def session(self, **_kw): raise Exception("fail") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: BadDriver()) headers = {"Authorization": "Basic dGVzdDp0ZXN0"} monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: BadDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_response_structure(monkeypatch): """Test that health response has correct JSON structure.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert "neo4j" in resp.json() assert "status" in resp.json() assert isinstance(resp.json(), dict) assert resp.headers["content-type"] == "application/json" def test_health_connection_timeout(monkeypatch): """Test health check when Neo4j connection times out.""" app = create_app() client = TestClient(app) class TimeoutDriver: def session(self, **_kw): raise TimeoutError("Connection timeout") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: TimeoutDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" assert resp.json()["status"] == "unhealthy" def test_health_connection_refused(monkeypatch): """Test health check when Neo4j connection is refused.""" app = create_app() client = TestClient(app) class RefusedDriver: def session(self, **_kw): raise ConnectionRefusedError("Connection refused") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: RefusedDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_authentication_error(monkeypatch): """Test health check when Neo4j authentication fails.""" app = create_app() client = TestClient(app) class MockAuthError(Exception): pass class AuthErrorDriver: def session(self, **_kw): raise MockAuthError("Invalid credentials") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: AuthErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_session_context_manager_exit_error(monkeypatch): """Test health check when session context manager fails on exit.""" app = create_app() client = TestClient(app) class BadExitDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): raise Exception("Exit error") def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: BadExitDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_query_execution_error(monkeypatch): """Test health check when Neo4j query execution fails.""" app = create_app() client = TestClient(app) class QueryErrorDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): raise Exception("Query execution failed") return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: QueryErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_driver_creation_failure(monkeypatch): """Test health check when Neo4j driver creation fails.""" app = create_app() client = TestClient(app) def failing_driver(*_a, **_k): raise Exception("Driver creation failed") monkeypatch.setattr("neo4j.GraphDatabase.driver", failing_driver) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" @pytest.mark.parametrize("method", ["POST", "PUT", "DELETE", "PATCH"]) def test_health_endpoint_http_methods(monkeypatch, method): """Test that health endpoint only accepts GET requests.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) response = getattr(client, method.lower())("/health") assert response.status_code == 405 # Method Not Allowed def test_health_endpoint_with_query_parameters(monkeypatch): """Test health endpoint behavior with query parameters.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) resp = client.get("/health?test=param&debug=true", auth=AUTH) assert resp.status_code == 200 assert resp.json()["neo4j"] == "up" def test_health_endpoint_with_headers(monkeypatch): """Test health endpoint with custom headers.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) headers = {"User-Agent": "test-client", "Accept": "application/json"} resp = client.get("/health", auth=AUTH, headers=headers) assert resp.status_code == 200 assert resp.json()["neo4j"] == "up" def test_health_multiple_consecutive_calls(monkeypatch): """Test multiple consecutive health check calls to ensure consistency.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) for _ in range(5): resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert resp.json()["neo4j"] == "up" assert resp.json()["status"] == "ok" def test_health_driver_close_error(monkeypatch): """Test health check when driver close() method fails.""" app = create_app() client = TestClient(app) class BadCloseDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): raise Exception("Close failed") monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: BadCloseDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert resp.json()["neo4j"] == "up" def test_health_json_serialization(monkeypatch): """Test health check response JSON serialization.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) resp = client.get("/health", auth=AUTH) json_data = resp.json() assert json.dumps(json_data) is not None assert json.loads(json.dumps(json_data)) == json_data def test_health_response_content_type(monkeypatch): """Test that health endpoint returns correct content type.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) resp = client.get("/health", auth=AUTH) assert "application/json" in resp.headers.get("content-type", "") assert resp.json() is not None def test_health_service_unavailable_error(monkeypatch): """Test health check when Neo4j service is unavailable.""" app = create_app() client = TestClient(app) class ServiceUnavailableDriver: def session(self, **_kw): class MockServiceUnavailableError(Exception): pass raise MockServiceUnavailableError("Service unavailable") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: ServiceUnavailableDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" assert resp.json()["status"] == "unhealthy" def test_health_driver_timeout(monkeypatch): """Test health check when driver() call itself times out.""" app = create_app() client = TestClient(app) class TimeoutDriver: def __init__(self, *a, **k): raise TimeoutError("Timeout creating driver") monkeypatch.setattr("neo4j.GraphDatabase.driver", TimeoutDriver) headers = {"Authorization": "Basic dGVzdDp0ZXN0"} resp = client.get("/health", auth=AUTH, headers=headers) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_concurrent_requests(monkeypatch): """Test health endpoint with concurrent requests to ensure thread safety.""" import threading import time app = create_app() client = TestClient(app) results = [] class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): time.sleep(0.01) # Small delay to test concurrency pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) def make_request(): resp = client.get("/health", auth=AUTH) results.append((resp.status_code, resp.json())) threads = [] for _ in range(10): thread = threading.Thread(target=make_request) threads.append(thread) thread.start() for thread in threads: thread.join() assert len(results) == 10 for status_code, json_data in results: assert status_code == 200 assert json_data["neo4j"] == "up" assert json_data["status"] == "ok" def test_health_session_creation_with_different_kwargs(monkeypatch): """Test health check with different session creation parameters.""" app = create_app() client = TestClient(app) session_kwargs_captured = [] class KwargsCapturingDriver: def session(self, **kwargs): session_kwargs_captured.append(kwargs) class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: KwargsCapturingDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert len(session_kwargs_captured) >= 1 def test_health_memory_error_during_session(monkeypatch): """Test health check when memory error occurs during session creation.""" app = create_app() client = TestClient(app) class MemoryErrorDriver: def session(self, **_kw): raise MemoryError("Out of memory") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: MemoryErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" assert resp.json()["status"] == "unhealthy" def test_health_keyboard_interrupt_during_query(monkeypatch): """Test health check when KeyboardInterrupt occurs during query execution.""" app = create_app() client = TestClient(app) class InterruptDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): raise KeyboardInterrupt("User interrupted") return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: InterruptDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_system_exit_during_connection(monkeypatch): """Test health check when SystemExit is raised during connection.""" app = create_app() client = TestClient(app) class SystemExitDriver: def session(self, **_kw): raise SystemExit("System exit") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: SystemExitDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_unicode_error_in_response(monkeypatch): """Test health check when unicode encoding issues occur.""" app = create_app() client = TestClient(app) class UnicodeErrorDriver: def session(self, **_kw): raise UnicodeDecodeError("utf-8", b"", 0, 1, "invalid unicode") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: UnicodeErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_recursive_exception_handling(monkeypatch): """Test health check with nested exceptions.""" app = create_app() client = TestClient(app) class NestedExceptionDriver: def session(self, **_kw): try: raise ValueError("Original error") except ValueError as e: raise RuntimeError("Wrapped error") from e def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: NestedExceptionDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_session_enter_failure(monkeypatch): """Test health check when session __enter__ method fails.""" app = create_app() client = TestClient(app) class BadEnterDriver: def session(self, **_kw): class S: def __enter__(self): raise Exception("Enter failed") def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: BadEnterDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_response_headers_comprehensive(monkeypatch): """Test comprehensive response headers validation.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert "content-length" in resp.headers assert int(resp.headers["content-length"]) > 0 assert "application/json" in resp.headers.get("content-type", "") def test_health_large_error_message_handling(monkeypatch): """Test health check with very large error messages.""" app = create_app() client = TestClient(app) large_error_message = "A" * 10000 # 10KB error message class LargeErrorDriver: def session(self, **_kw): raise Exception(large_error_message) def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: LargeErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" assert len(resp.content) < 50000 # Ensure response isn't too large def test_health_null_byte_in_error(monkeypatch): """Test health check with null bytes in error messages.""" app = create_app() client = TestClient(app) class NullByteErrorDriver: def session(self, **_kw): raise Exception("Error with null byte: \x00") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: NullByteErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_empty_string_error(monkeypatch): """Test health check with empty string error message.""" app = create_app() client = TestClient(app) class EmptyErrorDriver: def session(self, **_kw): raise Exception("") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: EmptyErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_none_error_message(monkeypatch): """Test health check with None as error message.""" app = create_app() client = TestClient(app) class NoneErrorDriver: def session(self, **_kw): raise Exception(None) def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: NoneErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_response_timing_consistency(monkeypatch): """Test that health check response times are consistent.""" import time app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): time.sleep(0.01) # Consistent delay pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) response_times = [] for _ in range(5): start_time = time.time() resp = client.get("/health", auth=AUTH) end_time = time.time() response_times.append(end_time - start_time) assert resp.status_code == 200 # Check response times are relatively consistent (within reasonable bounds) avg_time = sum(response_times) / len(response_times) for response_time in response_times: assert abs(response_time - avg_time) < 1.0 # Within 1 second variance def test_health_special_characters_in_query(monkeypatch): """Test health check behavior when query contains special characters.""" app = create_app() client = TestClient(app) query_captured = [] class QueryCapturingDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, query): query_captured.append(query) pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: QueryCapturingDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert len(query_captured) == 1 # Verify the query is safe and doesn't contain injection attempts assert isinstance(query_captured[0], str) def test_health_driver_version_compatibility(monkeypatch): """Test health check with different driver version scenarios.""" app = create_app() client = TestClient(app) class VersionCompatDriver: def __init__(self, *args, **kwargs): # Simulate driver initialization with version checks pass def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", VersionCompatDriver) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 assert resp.json()["neo4j"] == "up" def test_health_database_transaction_error(monkeypatch): """Test health check when database transaction fails.""" app = create_app() client = TestClient(app) class TransactionErrorDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): # Simulate transaction-specific error class MockTransactionError(Exception): pass raise MockTransactionError("Transaction failed") return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: TransactionErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_permission_denied_error(monkeypatch): """Test health check when permission is denied.""" app = create_app() client = TestClient(app) class PermissionDeniedDriver: def session(self, **_kw): raise PermissionError("Permission denied") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: PermissionDeniedDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_resource_exhaustion(monkeypatch): """Test health check under resource exhaustion conditions.""" app = create_app() client = TestClient(app) class ResourceExhaustionDriver: def session(self, **_kw): raise OSError("Resource temporarily unavailable") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: ResourceExhaustionDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_json_response_structure_deep_validation(monkeypatch): """Test deep validation of JSON response structure and data types.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 json_data = resp.json() # Deep structure validation assert isinstance(json_data, dict) assert "neo4j" in json_data assert "status" in json_data assert isinstance(json_data["neo4j"], str) assert isinstance(json_data["status"], str) assert json_data["neo4j"] in ["up", "down"] assert json_data["status"] in ["ok", "unhealthy"] # Ensure no unexpected keys expected_keys = {"neo4j", "status"} actual_keys = set(json_data.keys()) assert actual_keys.issubset(expected_keys) or len(actual_keys) >= len(expected_keys) @pytest.mark.parametrize("auth_header", [ "Bearer invalid-token", "Basic invalid-base64", "Digest username=test", "Custom auth-value", "", None ]) def test_health_various_auth_headers(monkeypatch, auth_header): """Test health endpoint with various authentication header formats.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) headers = {} if auth_header is not None: headers["Authorization"] = auth_header resp = client.get("/health", auth=AUTH, headers=headers) assert resp.status_code == 200 assert resp.json()["neo4j"] == "up" def test_health_endpoint_path_variations(monkeypatch): """Test health endpoint with various path variations.""" app = create_app() client = TestClient(app) class GoodDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: GoodDriver()) # Test exact path resp = client.get("/health", auth=AUTH) assert resp.status_code == 200 # Test with trailing slash (should depend on FastAPI configuration) try: resp = client.get("/health/") # If it doesn't redirect or error, check the response if resp.status_code not in [404, 307, 308]: assert resp.status_code in [200, 301, 302] except Exception: # Some configurations might not allow trailing slash pass def test_health_error_logging_verification(monkeypatch): """Test that health check errors are properly logged (if logging is configured).""" app = create_app() client = TestClient(app) class LoggingErrorDriver: def session(self, **_kw): raise Exception("Logged error for testing") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: LoggingErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" # Note: Actual log verification would require log capture setup def test_health_graceful_degradation(monkeypatch): """Test health endpoint graceful degradation under various failure modes.""" app = create_app() client = TestClient(app) class GracefulDegradationDriver: def __init__(self, *args, **kwargs): # Simulate partial initialization success pass def session(self, **_kw): # Session creation succeeds but query fails class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): raise Exception("Query failed but connection exists") return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", GracefulDegradationDriver) resp = client.get("/health", auth=AUTH) # Even with query failure, response should be properly structured assert resp.status_code == 500 assert "neo4j" in resp.json() assert "status" in resp.json() assert resp.json()["neo4j"] == "down" assert resp.json()["status"] == "unhealthy" def test_health_stress_test_rapid_requests(monkeypatch): """Stress test health endpoint with rapid consecutive requests.""" app = create_app() client = TestClient(app) class StressTestDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: StressTestDriver()) # Make 50 rapid requests success_count = 0 for _ in range(50): resp = client.get("/health", auth=AUTH) if resp.status_code == 200: success_count += 1 # At least 90% should succeed assert success_count >= 45 def test_health_with_extremely_long_uri(monkeypatch): """Test health check with extremely long database URI (edge case).""" app = create_app() client = TestClient(app) class LongUriDriver: def __init__(self, uri, *args, **kwargs): # Simulate handling of very long URI if len(uri) > 1000: raise ValueError("URI too long") def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass # Mock runtime_settings to have a very long URI with patch("adaptive_graph_of_thoughts.app_setup.runtime_settings") as mock_settings: mock_settings.neo4j.uri = "bolt://" + "a" * 2000 + ".example.com:7687" mock_settings.neo4j.user = "neo4j" mock_settings.neo4j.password = "password" mock_settings.neo4j.database = "neo4j" monkeypatch.setattr("neo4j.GraphDatabase.driver", LongUriDriver) resp = client.get("/health", auth=AUTH) # Should handle the error gracefully assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_with_malformed_json_response_handling(monkeypatch): """Test health endpoint's ability to always return valid JSON.""" app = create_app() client = TestClient(app) class MalformedDriver: def session(self, **_kw): # Create an object that might cause JSON serialization issues class UnserializableObject: def __str__(self): return "unserializable" raise Exception(UnserializableObject()) def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: MalformedDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 # Should still return valid JSON despite the unserializable exception json_data = resp.json() assert isinstance(json_data, dict) assert "neo4j" in json_data assert json_data["neo4j"] == "down" def test_health_connection_pool_exhaustion(monkeypatch): """Test health check when connection pool is exhausted.""" app = create_app() client = TestClient(app) class PoolExhaustedDriver: def session(self, **_kw): raise Exception("Connection pool exhausted") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: PoolExhaustedDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_ssl_certificate_error(monkeypatch): """Test health check when SSL certificate verification fails.""" app = create_app() client = TestClient(app) import ssl class SSLErrorDriver: def session(self, **_kw): raise ssl.SSLCertVerificationError("Certificate verification failed") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: SSLErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_dns_resolution_failure(monkeypatch): """Test health check when DNS resolution fails.""" app = create_app() client = TestClient(app) import socket class DNSErrorDriver: def session(self, **_kw): raise socket.gaierror("Name resolution failed") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: DNSErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" def test_health_driver_session_context_cleanup_verification(monkeypatch): """Test that session context is properly cleaned up even on errors.""" app = create_app() client = TestClient(app) enter_called = [] exit_called = [] class ContextTrackingDriver: def session(self, **_kw): class S: def __enter__(self): enter_called.append(True) return self def __exit__(self, exc_type, exc, tb): exit_called.append(True) pass def run(self, _q): raise Exception("Query failed") return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: ContextTrackingDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert len(enter_called) == 1 assert len(exit_called) == 1 # Ensure __exit__ was called despite error def test_health_response_immutability(monkeypatch): """Test that health response structure is consistent and immutable.""" app = create_app() client = TestClient(app) class ConsistentDriver: def session(self, **_kw): class S: def __enter__(self): return self def __exit__(self, exc_type, exc, tb): pass def run(self, _q): pass return S() def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: ConsistentDriver()) # Make multiple requests and ensure response structure is identical responses = [] for _ in range(3): resp = client.get("/health", auth=AUTH) responses.append(resp.json()) # All responses should have the same structure for response in responses: assert response == responses[0] assert set(response.keys()) == {"neo4j", "status"} @pytest.mark.parametrize("exception_type", [ BrokenPipeError, ConnectionAbortedError, ConnectionResetError, OSError, IOError ]) def test_health_network_level_exceptions(monkeypatch, exception_type): """Test health check with various network-level exceptions.""" app = create_app() client = TestClient(app) class NetworkErrorDriver: def session(self, **_kw): raise exception_type("Network error") def close(self): pass monkeypatch.setattr("neo4j.GraphDatabase.driver", lambda *_a, **_k: NetworkErrorDriver()) resp = client.get("/health", auth=AUTH) assert resp.status_code == 500 assert resp.json()["neo4j"] == "down" assert resp.json()["status"] == "unhealthy"

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SaptaDey/Adaptive-Graph-of-Thoughts-MCP-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server