from unittest.mock import MagicMock, patch import pytest from semantica.graph_store.graph_store import GraphStore @pytest.fixture def mock_neo4j_driver(): """ Creates a mock of of Neo4j Driver Simulates: Driver -> Session -> Transaction -> Result -> Record """ mock_result = MagicMock() fake_props = {"name": "TestNode", "age": 30} def get_item(key): if key == "id": return 12345 if key == "n": return fake_props if key == "count": return 42 return None mock_record = MagicMock() mock_record.__getitem__.side_effect = get_item mock_record.keys.return_value = ["id", "n"] mock_record.values.return_value = [12345, fake_props] # dict conversion - essentially doing it because the db sometimes demands it mock_record.items.return_value = [("id", 12345), ("n", fake_props)] # ~~ Result Methods ~~ mock_result = MagicMock() mock_result.single.return_value = mock_record mock_result.__iter__.side_effect = lambda: iter([mock_record]) # ~~ Session ~~ mock_session = MagicMock() mock_session.run.return_value = mock_result mock_session.__enter__.return_value = mock_session mock_session.__exit__.return_value = None # ~~ Driver ~~ mock_driver = MagicMock() mock_driver.session.return_value = mock_session mock_driver.verify_connectivity.return_value = True return mock_driver @pytest.fixture def graph_store(mock_neo4j_driver): """ Returns a GraphsStore connected to mnock driver. """ # ~~ Patch GraphDatbase ~~ with patch("semantica.graph_store.neo4j_store.GraphDatabase") as mockDB: mockDB.driver.return_value = mock_neo4j_driver store = GraphStore( backend="neo4j", uri="bolt://mock:7687", user="mock", password="mock" ) store.connect() if hasattr(store, "progress_tracker"): store.progress_tracker = MagicMock() return store # ~~ Benchmarks ~~ def test_node_creation_overhead(benchmark, graph_store): """ Benchamrks the full stack overhead for creating a single node. Path: GraphStore -> NodeManager -> Neo4jStore, Driver """ def op(): return graph_store.create_node( labels=["Person"], properties={"name": "Alexander", "age": 17} ) result = benchmark(op) assert result["id"] == 12345 def test_batch_node_creation_overhead(benchmark, graph_store): """ Benchmarks the loop overhead in create_nodes (Batch). Checks if it handles lists efficiently. """ nodes = [{"labels": ["Person"], "properties": {"id": i}} for i in range(50)] def op(): return graph_store.create_nodes(nodes) result = benchmark(op) assert len(result) == 50 def test_query_construction_and_parsing(benchmark, graph_store): """ Benchmarks every execution overhead. Measures how fast `QueryEngine` parses result into a Python dict. """ query = "MATCH ( n:Person) RETURN n LIMIT 1" def op(): return graph_store.execute_query(query) result = benchmark(op) assert result["success"] is True assert len(result["records"]) > 0 def test_analytics_shortest_path_overhead(benchmark, graph_store): """ Benchmarks the wrapper overhead for graph analytics. """ def op(): return graph_store.shortest_path( start_node_id=1, end_node_id=2, rel_type="KNOWS" ) try: benchmark(op) except Exception: # v pass as we are only trying to benchmark the function overhead call mainly pass