Files
rougeGame/Tools/Unreal/VerifyPerformanceAcceptance.py

55 lines
4.2 KiB
Python

"""Verify evidence emitted by the real packaged process; never generate screenshots."""
import argparse
import json
import math
import struct
from pathlib import Path
def verify(folder):
launch=json.loads((folder/'launch.json').read_text(encoding='utf-8-sig'))
checks=[]
def check(name,value):checks.append({'name':name,'passed':bool(value)})
def load(name):return json.loads((folder/(name+'.json')).read_text(encoding='utf-8'))
images=[]
for p in sorted(folder.glob('*.png')):
data=p.read_bytes()
if not data.startswith(b'\x89PNG\r\n\x1a\n'):raise ValueError('Not a PNG: '+str(p))
w,h=struct.unpack('>II',data[16:24]);images.append({'file':p.name,'width':w,'height':h,'environment':launch['environment']})
expected=tuple(map(int,launch['requestedResolution'].split('x')))
required={'Full':11,'UI':4,'Restart':3}[launch['suite']]
check('Actual native screenshots captured',len(images)==required)
check('PNG dimensions match requested resolution',bool(images) and all((i['width'],i['height'])==expected for i in images))
records=[load(Path(i['file']).stem) for i in images]
check('Exactly one overlay after each map transition',bool(records) and all(r['overlayInstances']==1 for r in records))
check('Progress save version remains V1',all(r['saveVersion']==1 for r in records))
check('Measured frame timing and reciprocal FPS agree',all(r['metrics']['fps']>0 and abs(r['metrics']['fps']*r['metrics']['frameMs']-1000)<.001 for r in records))
check('Actual CPU and GPU readings are available on this DX12 device',all(all(math.isfinite(r['metrics'][k]) and r['metrics'][k]>0 for k in ('gameMs','renderMs','gpuMs')) for r in records))
if launch['suite']=='Full':
initial=load('home-default-zh')
check('Fresh preferences default to enabled top-right Chinese',initial['enabled'] and initial['corner']==0 and not initial['english'])
check('Settings toggle disables the overlay',not load('disabled-zh')['enabled'])
check('All four corners selected through settings actions',{load(n)['corner'] for n in ('home-default-zh','top-left-en','bottom-right-en','bottom-left-en')}=={0,1,2,3})
check('Language switches while overlay is visible',load('top-left-en')['enabled'] and load('top-left-en')['english'])
start,end=load('pause-begin'),load('pause-updating')
check('Sampling continues during real world pause',start['worldPaused'] and end['worldPaused'] and end['metrics']['revision']>start['metrics']['revision'])
check('Training and home transitions exercised','TrainingRange' in load('training-shoulder')['map'] and 'TrainingRange' in load('training-cockpit')['map'] and 'Hangar' in load('after-travel')['map'])
elif launch['suite']=='Restart':
saved=load('restart-disabled');enabled=load('restart-enabled')
check('Disabled and bottom-left settings persist across process restart',not saved['enabled'] and saved['corner']==3 and saved['english'])
check('Overlay and default corner can be restored',enabled['enabled'] and enabled['corner']==0 and not enabled['english'])
compare=load('native-comparison');native=compare['nativeStatUnitRaw'];raw=compare['raw']
check('Native stat unit collected actual timings',all(native[k]>0 for k in ('frameMs','gameMs','renderMs','gpuMs')))
check('Raw thread and GPU samples agree with native readouts within frame jitter',all(abs(raw[k]-native[k])<=max(3,.5*native[k]) for k in ('gameMs','renderMs','gpuMs')))
else:
check('Both languages and settings page captured',load('settings-en')['english'] and not load('settings-zh')['english'])
result={'passed':all(c['passed'] for c in checks),'checks':checks,'screenshots':images}
(folder/'verification.json').write_text(json.dumps(result,ensure_ascii=False,indent=2)+'\n',encoding='utf-8')
print(json.dumps({'folder':str(folder),'passed':result['passed'],'checks':len(checks),'failed':[c['name'] for c in checks if not c['passed']]},ensure_ascii=False))
return result['passed']
if __name__=='__main__':
parser=argparse.ArgumentParser();parser.add_argument('folder',type=Path)
raise SystemExit(0 if verify(parser.parse_args().folder.resolve()) else 1)