mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-08-30 04:40:16 +00:00
138 lines
3.6 KiB
Python
138 lines
3.6 KiB
Python
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
|