import time
from silk import GraphStore, CompactionPolicy, IntervalPolicy, ThresholdPolicy
ONTOLOGY = {
"node_types": {"entity": {"properties": {}}},
"edge_types": {}
}
def _store():
return GraphStore("test", ONTOLOGY)
def test_threshold_no_compact_below():
store = _store()
store.add_node("n1", "entity", "A")
policy = ThresholdPolicy(max_entries=100)
result = policy.check(store)
assert result is None
assert store.len() > 1
def test_threshold_compacts_above():
store = _store()
for i in range(20):
store.add_node(f"n{i}", "entity", f"Node {i}")
assert store.len() > 20
policy = ThresholdPolicy(max_entries=10)
result = policy.check(store)
assert result is not None assert len(result) == 64 assert store.len() == 1
def test_threshold_preserves_data():
store = _store()
for i in range(15):
store.add_node(f"n{i}", "entity", f"Node {i}")
policy = ThresholdPolicy(max_entries=5)
policy.check(store)
for i in range(15):
assert store.get_node(f"n{i}") is not None
def test_threshold_should_compact():
store = _store()
for i in range(10):
store.add_node(f"n{i}", "entity", f"Node {i}")
policy = ThresholdPolicy(max_entries=100)
assert policy.should_compact(store) is False
policy2 = ThresholdPolicy(max_entries=5)
assert policy2.should_compact(store) is True
def test_interval_first_check_compacts():
store = _store()
store.add_node("n1", "entity", "A")
policy = IntervalPolicy(seconds=0.01)
time.sleep(0.02)
result = policy.check(store)
assert result is not None
assert store.len() == 1
def test_interval_second_check_skips():
store = _store()
store.add_node("n1", "entity", "A")
policy = IntervalPolicy(seconds=10.0) policy.check(store)
store.add_node("n2", "entity", "B")
result = policy.check(store) assert result is None
assert store.len() == 2
def test_interval_compacts_after_wait():
store = _store()
store.add_node("n1", "entity", "A")
policy = IntervalPolicy(seconds=0.01)
policy.check(store)
store.add_node("n2", "entity", "B")
time.sleep(0.02)
result = policy.check(store)
assert result is not None
assert store.len() == 1
def test_custom_policy():
class AlwaysCompact:
def should_compact(self, store):
return True
def check(self, store):
if self.should_compact(store):
return store.compact()
return None
store = _store()
store.add_node("n1", "entity", "A")
policy = AlwaysCompact()
result = policy.check(store)
assert result is not None
assert store.len() == 1
def test_custom_policy_never():
class NeverCompact:
def should_compact(self, store):
return False
def check(self, store):
return None
store = _store()
store.add_node("n1", "entity", "A")
policy = NeverCompact()
result = policy.check(store)
assert result is None
assert store.len() > 1
def test_protocol_check():
class Good:
def should_compact(self, store): return False
def check(self, store): return None
class Bad:
pass
assert isinstance(Good(), CompactionPolicy)
assert not isinstance(Bad(), CompactionPolicy)
def test_builtin_policies_implement_protocol():
assert isinstance(IntervalPolicy(seconds=60), CompactionPolicy)
assert isinstance(ThresholdPolicy(max_entries=100), CompactionPolicy)