Files
mcm-26-b/tests/test_practice_replay.py
T

48 lines
2.3 KiB
Python

"""Offline verification of captured practice evidence; never contacts simulator."""
import json
import math
from pathlib import Path
import unittest
from mcm26b.geometry import Measurement, solve
ROOT=Path(__file__).resolve().parents[1]
class PracticeReplayTests(unittest.TestCase):
def test_action_log_and_derived_geometry(self):
folder=ROOT/'output/q1/practice'
files=list(folder.glob('*_actions.json'))
self.assertTrue(files, '缺少本次演练采集证据')
for path in files:
events=json.loads(path.read_text(encoding='utf-8'))
pos=(0,0);channel=1;virtual=0
self.assertEqual(events[0]['path'],'/enter')
self.assertEqual(events[-1]['path'],'/exit')
self.assertEqual(events[-1]['response']['exit_reason'],'user_exit')
ids=[]
for event in events:
self.assertIn(event['path'],('/enter','/measure','/exit'))
request,response=event['request'],event['response']
self.assertTrue(response['accepted'])
ids.append(request['request_id'])
if event['path']=='/measure':
new=(request['position']['x'],request['position']['y'])
virtual+=math.dist(pos,new)/5+5+(request['channel']!=channel)
pos,channel=new,request['channel']
self.assertAlmostEqual(virtual,response['virtual_time_s'],places=5)
self.assertEqual(len(ids),len(set(ids)))
observation_path=path.with_name(path.name.replace('_actions','_observations'))
data=json.loads(observation_path.read_text(encoding='utf-8'))
ms=[Measurement(**m) for m in data['measurements']]
recomputed=solve(ms)
self.assertAlmostEqual(recomputed['diameter_m'],data['result']['diameter_m'],places=9)
self.assertEqual(data['source'],'official_practice')
self.assertIsNone(data['ground_truth'])
directions=[e for e in events if e['response'].get('measure_result')=='direction']
self.assertEqual(directions[0]['request']['position'],directions[1]['request']['position'])
self.assertEqual(directions[0]['response']['svd_deg'],directions[1]['response']['svd_deg'])
if __name__=='__main__': unittest.main()