import importlib.util, json, re, subprocess, urllib.request
p='/opt/struktur/obsidian-graphiti-reconciler-staging/tests/test_reconciler.py'
s=importlib.util.spec_from_file_location('t',p); m=importlib.util.module_from_spec(s); s.loader.exec_module(m)
fs=[v for k,v in vars(m).items() if k.startswith('test_')]
for f in fs: f()
print('TEST_PASS',len(fs))
print('REPORT_SUM', [x for x in open('/opt/struktur/obsidian-graphiti-reconciler-staging/AA-041.md') if 'Summenprüfung' in x][0].strip())
for u in ['http://127.0.0.1:8644/health']:
r=urllib.request.urlopen(u,timeout=30); print('HEALTH',r.status,len(r.read()))
try:
req=urllib.request.Request('http://127.0.0.1:8644/search',data=json.dumps({'query':'Obsidian'}).encode(),headers={'Content-Type':'application/json'},method='POST')
r=urllib.request.urlopen(req,timeout=60); print('SEARCH',r.status,len(r.read()))
except Exception as e: print('SEARCH_ERROR',type(e).__name__,str(e)[:160])
compose=open('/opt/struktur/graphiti/docker-compose.yml').read(); pw=re.search(r'NEO4J_AUTH: neo4j/(.*)',compose).group(1).strip()
for q in ['MATCH (n) UNWIND labels(n) AS label RETURN label, count(n) AS count ORDER BY label','MATCH ()-[r]->() RETURN count(r)']:
out=subprocess.run(['docker','exec','graphiti-neo4j','cypher-shell','-u','neo4j','-p',pw,'--format','plain',q],capture_output=True,text=True)
print('NEO4J',out.returncode,out.stdout[:2000],out.stderr[:300])