Files
behavior-tree/tools/http_smoke.py
T

49 lines
2.5 KiB
Python
Raw Normal View History

"""Real HTTP -> coordinator -> portable C++ StageRunner -> durable delivery test."""
import http.client
import json
import sys
import tempfile
import threading
import time
from pathlib import Path
ROOT=Path(__file__).resolve().parents[1]
sys.path.insert(0,str(ROOT/'coordinator'))
from robot_bt_coordinator.backends import DemoBackend
from robot_bt_coordinator.http_api import make_server
from robot_bt_coordinator.replay import replay_events
from robot_bt_coordinator.service import Coordinator,demo_site
def main():
with tempfile.TemporaryDirectory() as tmp:
backend=DemoBackend(ROOT/'build/bt_demo',Path(tmp)/'sim')
coordinator=Coordinator(str(Path(tmp)/'tasks.db'),backend,{'robot_01'},demo_site())
server=make_server(coordinator,'127.0.0.1',0,'smoke-local-only')
thread=threading.Thread(target=server.serve_forever,daemon=True);thread.start()
def request(method,path,body=None):
c=http.client.HTTPConnection('127.0.0.1',server.server_port,timeout=5)
c.request(method,path,json.dumps(body) if body is not None else None,{'Authorization':'Bearer smoke-local-only','Content-Type':'application/json'})
r=c.getresponse();data=json.loads(r.read());c.close()
assert r.status<300,(r.status,data)
return data
try:
payload=json.loads((ROOT/'config/demo_request.json').read_text())
start=time.monotonic();receipt=request('POST','/v1/tasks',payload);ack_ms=(time.monotonic()-start)*1000
tid=receipt['task_id']
for _ in range(200):
coordinator.tick();view=request('GET','/v1/tasks/'+tid)
if view['status'] in ('SUCCEEDED','FAILED','INTERVENTION_REQUIRED'):break
time.sleep(.01)
assert view['status']=='SUCCEEDED',view
assert view['completed_quantity']==1,view
duplicate=request('POST','/v1/tasks',payload)
assert duplicate['task_id']==tid and duplicate['deduplicated'] is True
events=request('GET',f'/v1/tasks/{tid}/events?limit=500')['events']
replay=replay_events(events)
assert replay['status']=='SUCCEEDED' and replay['completed_quantity']==1
print(json.dumps({'http_e2e':'passed','task_id':tid,'completed_quantity':1,'deduplicated':True,'offline_replay':'passed','event_count':len(events),'single_receipt_ms':round(ack_ms,2),'robot_motion':'simulated only'},indent=2))
finally:
server.shutdown();server.server_close();thread.join();coordinator.close()
if __name__=='__main__':main()