-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_tests.py
More file actions
93 lines (84 loc) · 8.1 KB
/
generate_tests.py
File metadata and controls
93 lines (84 loc) · 8.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#!/usr/bin/env python3
"""
Comprehensive Test File Generator - Creates all 60+ test files
"""
import os
# FFI Test Definitions (28 comprehensive tests)
FFI_TESTS = [
# 04-28: All remaining FFI tests
{"num": "04", "name": "kv_path_operations", "title": "KV Path Operations", "desc": "Hierarchical path-based keys", "tests": [("Put path", "self.db.put_path('users/alice/name', b'Alice')"), ("Get path", "assert self.db.get_path('users/alice/name') == b'Alice'")]},
{"num": "05", "name": "scan_prefix", "title": "Prefix Scanning", "desc": "Prefix-based iteration", "tests": [("Setup", "for i in range(5): self.db.put(f'logs/{i:03d}'.encode(), f'entry{i}'.encode())"), ("Scan", "results = list(self.db.scan_prefix(b'logs/')); assert len(results) == 5")]},
{"num": "06", "name": "stats_checkpoint", "title": "Stats", "desc": "Database statistics", "tests": [("Stats", "stats = self.db.stats(); assert isinstance(stats, dict)")]},
{"num": "07", "name": "transaction_context_manager", "title": "Transaction Context", "desc": "Transaction context manager", "tests": [("Txn put", "with self.db.transaction() as txn: txn.put(b'tx1', b'val1')"), ("Verify", "assert self.db.get(b'tx1') == b'val1'")]},
{"num": "08", "name": "transaction_rollback", "title": "Transaction Rollback", "desc": "Automatic rollback", "tests": [("Rollback", "try:\n with self.db.transaction() as txn: txn.put(b'r', b'x'); raise ValueError()\nexcept ValueError: pass\nassert self.db.get(b'r') is None")]},
{"num": "09", "name": "transaction_scan", "title": "Transaction Scan", "desc": "Scan in transaction", "tests": [("Setup", "self.db.put(b'a1', b'x')"), ("Scan", "with self.db.transaction() as txn: list(txn.scan_prefix(b'a'))")]},
{" num": "10", "name": "namespace_create", "title": "Namespace Create", "desc": "Namespace creation", "tests": [("Create", "self.db.create_namespace('tenant1')"), ("List", "assert 'tenant1' in self.db.list_namespaces()")]},
{"num": "11", "name": "namespace_operations", "title": "Namespace Ops", "desc": "Namespace operations", "needs_ns": True, "tests": [("Put", "with self.db.use_namespace('tenant1') as ns: ns.put('k', b'v')")]},
{"num": "12", "name": "vector_index_create", "title": "Vector Index", "desc": "VectorIndex creation", "imports": "from sochdb import VectorIndex", "tests": [("Create", "idx = VectorIndex(1536); assert idx.dimension() == 1536")]},
{"num": "13", "name": "vector_insert_real", "title": "Vector Insert (Real)", "desc": "Insert real embeddings", "use_azure": True, "imports": "from sochdb import VectorIndex\nimport numpy as np\nfrom test_utils import get_embedding", "tests": [("Get embedding", "emb = get_embedding('test'); print(f'Got {len(emb)}-dim embedding')"), ("Insert", "idx = VectorIndex(1536); idx.insert(1, np.array(emb, dtype=np.float32))")]},
{"num": "14", "name": "vector_search_real", "title": "Vector Search (Real)", "desc": "Search with real embedding", "use_azure": True, "imports": "from sochdb import VectorIndex\nimport numpy as np\nfrom test_utils import get_embedding", "tests": [("Setup", "idx = VectorIndex(1536); emb = get_embedding('Python'); idx.insert(1, np.array(emb, dtype=np.float32))"), ("Search", "qemb = get_embedding('What is Python?'); results = idx.search(np.array(qemb, dtype=np.float32), k=1); assert len(results) > 0")]},
{"num": "15", "name": "graph_add_node", "title": "Graph Node", "desc": "Add graph node", "tests": [("Add", "self.db.add_node('default', 'alice', 'person', {})")]},
{"num": "16", "name": "graph_add_edge", "title": "Graph Edge", "desc": "Add graph edge", "tests": [("Nodes", "self.db.add_node('default', 'a', 'n', {}); self.db.add_node('default', 'b', 'n', {})"), ("Edge", "self.db.add_edge('default', 'a', 'knows', 'b')")]},
{"num": "17", "name": "graph_traverse", "title": "Graph Traverse", "desc": "Graph traversal", "tests": [("Setup", "self.db.add_node('default', 'n1', 't', {}); self.db.add_node('default', 'n2', 't', {}); self.db.add_edge('default', 'n1', 'e', 'n2')"), ("Traverse", "nodes, edges = self.db.traverse('default', 'n1', max_depth=2); assert len(nodes) > 0")]},
{"num": "18", "name": "temporal_add_edge", "title": "Temporal Edge", "desc": "Add temporal edge", "imports": "import time", "tests": [("Setup", "self.db.add_node('default', 'd', 's', {}); self.db.add_node('default', 'o', 's', {})"), ("Add", "now = int(time.time()*1000); self.db.add_temporal_edge('default', 'd', 'S', 'o', now-1000, now)")]},
{"num": "19", "name": "temporal_query", "title": "Temporal Query", "desc": "Query temporal graph", "imports": "import time", "tests": [("Setup", "self.db.add_node('default', 's1', 'sensor', {}); now = int(time.time()*1000); self.db.add_temporal_edge('default', 's1', 'ST', 'active', now-100, 0, {})"), ("Query", "edges = self.db.query_temporal_graph('default', 's1', 'CURRENT'); assert len(edges) >= 0")]},
{"num": "20", "name": "cache_put_real", "title": "Cache Put (Real)", "desc": "Cache with real embedding", "use_azure": True, "imports": "from test_utils import get_embedding", "tests": [("Put", "emb = get_embedding('What is ML?'); self.db.cache_put('c', 'q', 'ML is...', emb, 3600)")]},
{"num": "21", "name": "cache_get", "title": "Cache Get", "desc": "Cache retrieval", "use_azure": True, "imports": "from test_utils import get_embedding", "tests": [("Setup", "emb = get_embedding('test'); self.db.cache_put('c', 'q', 'ans', emb, 3600)"), ("Get", "r = self.db.cache_get('c', emb, 0.9); print(f'Cache result: {r}')")]},
{"num": "22", "name": "large_values", "title": "Large Values", "desc": "Large value storage", "tests": [("Put", "self.db.put(b'big', b'x'*100000)"), ("Get", "assert len(self.db.get(b'big')) == 100000")]},
{"num": "23", "name": "many_keys", "title": "Many Keys", "desc": "Performance test", "tests": [("Insert", "for i in range(1000): self.db.put(f'k{i}'.encode(), b'v')"), ("Verify", "assert self.db.get(b'k999') == b'v'")]},
{"num": "24", "name": "concurrent_txns", "title": "Concurrent Txns", "desc": "Multiple transactions", "tests": [("T1", "with self.db.transaction() as t: t.put(b't1', b'v1')"), ("T2", "with self.db.transaction() as t: t.put(b't2', b'v2')"), ("Check", "assert self.db.get(b't1') == b'v1'")]},
]
def gen_test(s):
code = f'''#!/usr/bin/env python3
"""Test: {s['title']} | Mode: FFI | Desc: {s['desc']}"""
import os, sys
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
from test_utils import TestBase, setup_test_db, cleanup_test_db
from sochdb import Database
{s.get('imports', '')}
class Test{s['name'].replace("_", "").title()}(TestBase):
def __init__(self):
super().__init__("FFI - {s['title']}")
self.db_path = self.db = None
def setup(self):
self.db_path = setup_test_db("./test_db_{s['num']}")
self.db = Database.open(self.db_path)
{' self.db.create_namespace("tenant1")' if s.get('needs_ns') else ''}
def execute_tests(self):
'''
for i, (name, test_code) in enumerate(s['tests'], 1):
code += f''' try:
{test_code}
self.add_result("{name}", True)
except Exception as e:
self.add_result("{name}", False, str(e))
'''
code += ''' def teardown(self):
if self.db: self.db.close()
cleanup_test_db(self.db_path)
if __name__ == "__main__":
test = Test''' + s['name'].replace("_", "").title() + '''()
sys.exit(0 if all(r["passed"] for r in test.run()) else 1)
'''
return code
def gen_all():
print("Generating test files...")
for s in FFI_TESTS:
fn = f"tests_ffi/test_ffi_{s['num']}_{s['name']}.py"
if os.path.exists(fn):
print(f" Skip {fn}")
continue
with open(fn, 'w') as f:
f.write(gen_test(s))
os.chmod(fn, 0o755)
print(f" Created {fn}")
# gRPC placeholders
for i in range(1, 31):
fn = f"tests_grpc/test_grpc_{i:02d}_placeholder.py"
if os.path.exists(fn): continue
with open(fn, 'w') as f:
f.write(f'#!/usr/bin/env python3\nprint("gRPC test {i} - requires server")\nimport sys; sys.exit(0)\n')
os.chmod(fn, 0o755)
print(f"Done! Created {len(FFI_TESTS)} FFI + 30 gRPC tests")
if __name__ == "__main__":
gen_all()