80 lines
6.5 KiB
Python
80 lines
6.5 KiB
Python
from pathlib import Path
|
|
import datetime, difflib, hashlib, json, os, shutil, subprocess, sys
|
|
|
|
OUT = Path(__file__).resolve().parent
|
|
ROOT = OUT.parent.parent
|
|
PACKAGE = ROOT / '.local/native-865483b/extracted/ArcadiaStudio-0.2.0-preview.lifecycle-childwork.20260911-x86_64-pc-windows-gnullvm'
|
|
SERVER = PACKAGE / 'arcadia-server.exe'
|
|
DLL = PACKAGE / 'libunwind.dll'
|
|
PWSH = Path('C:/Users/User/.cache/codex-runtimes/codex-primary-runtime/dependencies/native/powershell/pwsh.exe')
|
|
LIMITED_PATH = 'C:/Windows/System32;C:/Windows;' + str(PACKAGE)
|
|
def now(): return datetime.datetime.now(datetime.timezone.utc).isoformat()
|
|
def sha(path): return hashlib.sha256(path.read_bytes()).hexdigest().upper()
|
|
def save(name, value): (OUT / name).write_text(json.dumps(value, indent=2), encoding='utf-8')
|
|
def replace_once(source, old, new):
|
|
assert source.count(old) == 1, (old, source.count(old))
|
|
return source.replace(old, new)
|
|
|
|
assert sha(SERVER) == 'ABA87A5FB795DEB995029A737C2EBB9D2B44C8D274EDAA2295363B226D9AF6BE'
|
|
assert sha(DLL) == 'AA282FA47BB2C4E210CEA5E470CDBDCA58568F0BE0BC73E404D86AB9CD95EF6A'
|
|
cwd = OUT / 'unrelated-cwd'
|
|
cwd.mkdir()
|
|
(OUT / 'schema-store').mkdir()
|
|
env = dict(os.environ)
|
|
env['PATH'] = LIMITED_PATH
|
|
env.pop('ARCADIA_SERVER_TOKEN', None)
|
|
env.pop('PYTHONPATH', None)
|
|
env['PYTHONDONTWRITEBYTECODE'] = '1'
|
|
inputs = [SERVER,DLL,ROOT/'harness/fixtures/rest-coverage/run-coverage-probe.ps1',ROOT/'harness/fixtures/rest-coverage/coverage-probe.json',ROOT/'crates/oa-server/tests/semantic_http_contract.py',ROOT/'docs/openapi.json',ROOT/'crates/oa-core/tests/fixtures/v4-reviewed-prose.json']
|
|
before = {str(p):sha(p) for p in inputs}
|
|
save('preflight.json', {'started':now(),'inputs':before,'python':sys.executable,'server_PATH':LIMITED_PATH,'cwd':str(cwd),'removed_env':['ARCADIA_SERVER_TOKEN','PYTHONPATH'],'python_deps_sys_path_only':str(ROOT/'.local/python-deps')})
|
|
|
|
ps_source = (ROOT/'harness/fixtures/rest-coverage/run-coverage-probe.ps1').read_text(encoding='utf-8-sig')
|
|
ps = replace_once(ps_source, "$taskRoot = (Resolve-Path (Join-Path $PSScriptRoot '../../..')).Path", "$taskRoot = $PSScriptRoot")
|
|
ps = replace_once(ps, "$runRoot = Join-Path $taskRoot ('.local/rest-coverage-' + (Get-Date -Format 'yyyyMMdd-HHmmss'))", "$runRoot = Join-Path $taskRoot 'rest'")
|
|
ps = replace_once(ps, ' FilePath = $exe', " WorkingDirectory = Join-Path $PSScriptRoot 'unrelated-cwd'\n FilePath = $exe")
|
|
ps = replace_once(ps, ' $script:probeProcess = Start-Process @startOptions', ''' $script:probeProcess = Start-Process @startOptions
|
|
@{pid=$script:probeProcess.Id;exe=$exe;arguments=$startOptions.ArgumentList;cwd=$startOptions.WorkingDirectory;PATH=$env:PATH;started=(Get-Date -Format o)} | ConvertTo-Json -Depth 10 | Set-Content (Join-Path $runRoot "server-$script:launch.launch.json")''')
|
|
ps = replace_once(ps, ' $script:probeProcess = $null\n}', ''' if ($null -ne $script:probeProcess) { @{pid=$script:probeProcess.Id;has_exited=$script:probeProcess.HasExited;exit_code=$script:probeProcess.ExitCode;stopped=(Get-Date -Format o);method='owned probe Stop-Process after assertions'} | ConvertTo-Json | Set-Content (Join-Path $runRoot "server-$script:launch.stop.json") }
|
|
$script:probeProcess = $null
|
|
}''')
|
|
(OUT/'coverage-probe.ps1').write_text(ps,encoding='utf-8')
|
|
shutil.copyfile(ROOT/'harness/fixtures/rest-coverage/coverage-probe.json',OUT/'coverage-probe.json')
|
|
(OUT/'coverage-adaptation.diff').write_text(''.join(difflib.unified_diff(ps_source.splitlines(True),ps.splitlines(True),fromfile='original',tofile='private')),encoding='utf-8')
|
|
|
|
source = (ROOT/'crates/oa-server/tests/semantic_http_contract.py').read_text(encoding='utf-8')
|
|
code = replace_once(source, 'ROOT = Path(__file__).resolve().parents[3]', f'ROOT = Path({str(ROOT)!r})\nEVIDENCE = Path({str(OUT)!r})\nimport contextlib')
|
|
code = replace_once(code, 'from jsonschema import Draft202012Validator, FormatChecker', f"sys.path.insert(0, {str(ROOT/'.local/python-deps')!r})\nfrom jsonschema import Draft202012Validator, FormatChecker")
|
|
code = replace_once(code, 'with tempfile.TemporaryDirectory(prefix="arcadia-semantic-http-") as directory:', 'with contextlib.nullcontext(str(EVIDENCE / "schema-store")) as directory:')
|
|
code = replace_once(code, ' banner = process.stderr.readline()', ''' (EVIDENCE / 'schema-launch.json').write_text(json.dumps({'pid':process.pid,'args':process.args,'cwd':os.getcwd(),'PATH':env['PATH']},indent=2))
|
|
banner = process.stderr.readline()
|
|
(EVIDENCE / 'schema-server.stderr.log').write_text(banner)
|
|
responses = []''')
|
|
code = replace_once(code, ' data = json.load(response)', ''' raw = response.read()
|
|
data = json.loads(raw)
|
|
responses.append({'method':method,'path':path,'body':body,'status':response.status,'etag':response.headers.get('ETag'),'response':raw.decode()})
|
|
(EVIDENCE / 'schema-http.json').write_text(json.dumps(responses,indent=2))''')
|
|
code = replace_once(code, ' process.wait(timeout=15)', ''' process.wait(timeout=15)
|
|
stdout, stderr = process.communicate(timeout=15)
|
|
(EVIDENCE / 'schema-server.stdout.log').write_text(stdout)
|
|
with (EVIDENCE / 'schema-server.stderr.log').open('a') as log: log.write(stderr)
|
|
(EVIDENCE / 'schema-stop.json').write_text(json.dumps({'pid':process.pid,'exit_code':process.returncode,'has_exited':process.poll() is not None,'method':'owned process terminate in original finally'},indent=2))''')
|
|
(OUT/'semantic-http.py').write_text(code,encoding='utf-8')
|
|
(OUT/'schema-adaptation.diff').write_text(''.join(difflib.unified_diff(source.splitlines(True),code.splitlines(True),fromfile='original',tofile='private')),encoding='utf-8')
|
|
|
|
results=[]
|
|
try:
|
|
for name,cmd in [('rest',[str(PWSH),'-NoProfile','-File',str(OUT/'coverage-probe.ps1'),'-ServerExe',str(SERVER)]),('schema',[sys.executable,str(OUT/'semantic-http.py'),str(SERVER)])]:
|
|
started=now()
|
|
with (OUT/(name+'.stdout.log')).open('wb') as stdout, (OUT/(name+'.stderr.log')).open('wb') as stderr:
|
|
proc=subprocess.Popen(cmd,cwd=cwd,env=env,stdout=stdout,stderr=stderr,creationflags=subprocess.CREATE_NO_WINDOW)
|
|
result={'name':name,'pid':proc.pid,'command':cmd,'started':started,'exit_code':proc.wait(),'finished':now()}
|
|
results.append(result)
|
|
save('runner-status.json',results)
|
|
print(json.dumps(result),flush=True)
|
|
finally:
|
|
after={str(p):sha(p) for p in inputs}
|
|
save('postflight.json',{'finished':now(),'inputs':after,'all_inputs_unchanged':before==after})
|
|
assert before==after
|
|
assert all(r['exit_code']==0 for r in results), results
|