from ops import *
p=read('plan.json');rt=Runtime(load_config(NEW),R)
states=rt.states();result=read('ascent/result.json');assert not result['runtime_error']
rows=p['rows'];active=[r for r in rows if r['original']]
for row in rows:
    q=states[row['stream_id']]
    assert q['state']==('running' if row['original'] else 'stopped')
    if row['original']:
        assert q['child_pid'] and not q['last_error']
        assert not q['metadata_path']['performance']['detail']
    else:
        c=q['last_cleanup'];assert not q['child_pid'] and c['completed'] and c['child_reaped'] and c['writer_released'] and not c['forced']
    s=rt.settings(row['stream_id']);assert s['pose']['enabled'] and s['tracking']['enabled'] and not s['intrusion']['enabled']
    assert s==read('prepared.json')['settings'][row['stream_id']]
before=read('unused-model-before.json');after={n:rt.triton('v2/models/'+n+'/stats') for n in before}
def counts(v):return {(x['name'],x['version']):(x['inference_count'],x['execution_count']) for x in v['model_stats']}
assert all(counts(before[n])==counts(after[n]) for n in before)
code='''import json,glob,os,configparser
out=[]
for p in glob.glob('/tmp/**/medium_*.txt',recursive=True):
 t=open(p).read()
 if 'RFDETRKeypointPreview' not in t:continue
 c=configparser.ConfigParser();c.read(p+'.preprocess')
 assert 'enable_cuda_buffer_sharing: true' in t and c['property']['tensor-data-type']=='7'
 assert c['property']['scaling-buf-pool-size']=='4' and c['property']['tensor-buf-pool-size']=='4'
 out.append(dict(path=p,dtype=7,sharing=True))
print(json.dumps(dict(configs=out,children=[dict(pid=int(x.split('/')[2]),cmd=open(x,'rb').read().decode(errors='replace')) for x in glob.glob('/proc/[0-9]*/cmdline') if b'multiprocessing.spawn' in open(x,'rb').read()])))
'''
render=json.loads(cmd(['docker','exec',rt.container,'python3','-c',code]))
assert len(render['configs'])==16
live_pids={q['child_pid'] for q in states.values() if q.get('child_pid')}
assert len(live_pids)==3
all_sample_pids={v['pid'] for v in read('ascent/window-16.json')['samples'][-1]['channels'].values()}
actual_pids={x['pid'] for x in render['children']}
assert live_pids<=actual_pids and not ((all_sample_pids-live_pids)&actual_pids)
sender=json.loads(cmd(['python3',str(REPO/'tools/rtsp_test.py'),'list']))
def stable_sender(value):
 value=copy.deepcopy(value)
 for x in value:
  for k in ('packets','latestRtpTimestamp','lastPacketAgeSeconds','rtpFrames'):x.get('media',{}).pop(k,None)
  x.get('accessChecks',{}).get('senderLoopback',{}).pop('checkedAt',None)
 return value
assert stable_sender(sender)==stable_sender(p['sender'])
assert json.loads(cmd(['docker','inspect','contextra-redis-1']))[0]['Id']==p['redis_id']
save('readback.json',dict(states=states,model_stats=after,unused_models_unchanged=True,render=render,
    recovered_children=13,active_children=3,sender_preserved=True,redis_preserved=True,quality='user pending'))
print('Readback PASS: three Pose children, thirteen reaped, details Off, preserved Medium/Fire/sender/Redis')
