59 lines
3.9 KiB
Python
59 lines
3.9 KiB
Python
"""Decode full pristine/saved source bundles with the exact packaged server."""
|
|
from pathlib import Path
|
|
import copy, hashlib, http.client, json, os, socket, subprocess, time
|
|
root=Path(__file__).resolve().parent
|
|
proof=json.loads((root/'extraction-check.json').read_text(encoding='utf-8'))
|
|
bundle=Path(proof['bundle'])
|
|
run=root/'native-model-oracle';run.mkdir(exist_ok=False)
|
|
exe=bundle/'arcadia-server.exe'
|
|
assert hashlib.sha256(exe.read_bytes()).hexdigest()==proof['sha256']['arcadia-server.exe']
|
|
assert hashlib.sha256((bundle/'libunwind.dll').read_bytes()).hexdigest()==proof['sha256']['libunwind.dll']
|
|
env={k:os.environ[k] for k in ['SystemRoot','WINDIR','TEMP','TMP','USERPROFILE','LOCALAPPDATA','APPDATA','COMSPEC','OS','PROCESSOR_ARCHITECTURE'] if k in os.environ}
|
|
env['PATH']=str(Path(os.environ['SystemRoot'])/'System32')+';'+os.environ['SystemRoot']
|
|
with socket.socket() as s:s.bind(('127.0.0.1',0));port=s.getsockname()[1]
|
|
cmd=[str(exe),'--bind',f'127.0.0.1:{port}','--data-dir',str(run/'store')]
|
|
report={'status':'RUNNING','command':cmd,'path':env['PATH'],'server_sha256':proof['sha256']['arcadia-server.exe'],'runtime_sha256':proof['sha256']['libunwind.dll']}
|
|
counter=0
|
|
def request(method,path,body=None):
|
|
global counter
|
|
counter+=1
|
|
raw=b'' if body is None else json.dumps(body,ensure_ascii=False).encode('utf-8')
|
|
(run/f'{counter:02d}.request.json').write_bytes(raw)
|
|
c=http.client.HTTPConnection('127.0.0.1',port,timeout=10)
|
|
c.request(method,path,body=raw or None,headers={'Content-Type':'application/json','Connection':'close'})
|
|
r=c.getresponse();data=r.read();status=r.status
|
|
(run/f'{counter:02d}.response.json').write_bytes(data);c.close()
|
|
assert status in (200,201),(status,data)
|
|
return json.loads(data)
|
|
with (run/'stdout.log').open('xb') as out,(run/'stderr.log').open('xb') as err:
|
|
child=subprocess.Popen(cmd,cwd=run,env=env,stdout=out,stderr=err,creationflags=subprocess.CREATE_NO_WINDOW)
|
|
report['pid']=child.pid
|
|
try:
|
|
for _ in range(100):
|
|
assert child.poll() is None
|
|
try:
|
|
with socket.create_connection(('127.0.0.1',port),timeout=.1):break
|
|
except OSError:time.sleep(.1)
|
|
request('GET','/health/ready')
|
|
models=[]
|
|
source_records=[]
|
|
for folder,entry in [(bundle/'examples/release1','project.arcadia'),(root/'working/collision-a','project.arcadia'),(root/'working/fresh-c','project.arcadia')]:
|
|
files={p.relative_to(folder).as_posix():p.read_bytes().decode('utf-8') for p in folder.rglob('*.arcadia')}
|
|
assert len(files)==30
|
|
source={'entry':entry,'files':files}
|
|
imported=request('POST','/api/v1/projects/import-source-project',source)
|
|
envelope=request('GET','/api/v1/projects/'+imported['resource_id'])
|
|
assert envelope['source_project']==source
|
|
models.append(envelope['model']);source_records.append(imported['resource_id'])
|
|
expected=copy.deepcopy(models[0])
|
|
target='61f7bbfb-74a4-5540-9182-2583dfb27a49'
|
|
assert expected['elements'][target]['name']=='Assess pressure alarm'
|
|
expected['elements'][target]['name']='Assess pressure alarm Package46'
|
|
assert models[1]==models[2]==expected,'Both complete saved Projects must have only declared Activity-name delta'
|
|
report.update({'status':'PASS','resource_ids':source_records,'source_files_each':30,'model_delta':{'id':target,'field':'name','before':'Assess pressure alarm','after':'Assess pressure alarm Package46'},'complete_project_equal_to_declared_delta':True,'source_preserved_exactly':True})
|
|
finally:
|
|
child.terminate();report['server_exit']=child.wait(timeout=15)
|
|
report['shutdown_scope']='Owned TerminateProcess after acknowledged import/read; no graceful shutdown claim.'
|
|
(run/'result.json').write_text(json.dumps(report,indent=2)+'\n',encoding='utf-8')
|
|
print(json.dumps(report,indent=2))
|