53 lines
3.3 KiB
Python
53 lines
3.3 KiB
Python
"""Create an isolated Windows acceptance workspace and launch its identified GUI."""
|
|
from pathlib import Path
|
|
import hashlib
|
|
import json
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
from datetime import datetime, timezone
|
|
|
|
root = Path(__file__).resolve().parent.parent
|
|
trial = root / '.local/native-qa/canvas-20260911'
|
|
mode = sys.argv[1]
|
|
if mode == 'prepare':
|
|
assert not trial.exists(), 'Do not overwrite a native trial'
|
|
trial.mkdir()
|
|
records = []
|
|
for name, rel in {
|
|
'scenario': 'harness/fixtures/scenario-authoring/base',
|
|
'process': 'harness/fixtures/source7-native/base',
|
|
'staged-source': 'harness/fixtures/staged-source-authoring/base',
|
|
}.items():
|
|
original = root / rel
|
|
assert original.is_dir()
|
|
shutil.copytree(original, trial / name)
|
|
for file in sorted(original.rglob('*')):
|
|
if file.is_file():
|
|
path = file.relative_to(original)
|
|
raw = file.read_bytes()
|
|
assert (trial / name / path).read_bytes() == raw
|
|
records.append({'path': f'{name}/{path.as_posix()}', 'source': f'{rel}/{path.as_posix()}', 'bytes': len(raw), 'sha256': hashlib.sha256(raw).hexdigest()})
|
|
for folder in ['profile/Desktop', 'profile/Documents', 'profile/AppData/Local', 'profile/AppData/Roaming', 'temp', 'evidence']:
|
|
(trial / folder).mkdir(parents=True, exist_ok=True)
|
|
(trial / 'preparation.json').write_text(json.dumps({'prepared_utc': datetime.now(timezone.utc).isoformat(), 'files': records}, indent=2) + '\n', encoding='utf-8', newline='\n')
|
|
print(json.dumps({'trial': str(trial), 'byte_identical_fixture_files': len(records)}))
|
|
elif mode == 'launch':
|
|
assert (trial / 'preparation.json').is_file()
|
|
assert not (trial / 'launch.json').exists(), 'Use a new explicit trial for another launch'
|
|
binary = Path(sys.argv[2]).resolve()
|
|
assert binary.is_relative_to(root / '.local/native-qa') and binary.name == 'arcadia-studio.exe'
|
|
assert binary.is_file() and (binary.parent / 'manifest.json').is_file()
|
|
profile = trial / 'profile'
|
|
env = {key: os.environ[key] for key in ['SystemRoot', 'WINDIR', 'SystemDrive', 'ProgramData', 'ALLUSERSPROFILE', 'PUBLIC', 'COMSPEC', 'PATHEXT', 'NUMBER_OF_PROCESSORS', 'PROCESSOR_ARCHITECTURE', 'OS'] if key in os.environ}
|
|
windows = Path(env['SystemRoot'])
|
|
env.update({'PATH': os.pathsep.join(map(str, [binary.parent, windows / 'System32', windows])), 'USERPROFILE': str(profile), 'LOCALAPPDATA': str(profile / 'AppData/Local'), 'APPDATA': str(profile / 'AppData/Roaming'), 'TEMP': str(trial / 'temp'), 'TMP': str(trial / 'temp')})
|
|
with (trial / 'stdout.log').open('wb') as out, (trial / 'stderr.log').open('wb') as err:
|
|
process = subprocess.Popen([str(binary)], cwd=trial, env=env, stdin=subprocess.DEVNULL, stdout=out, stderr=err, creationflags=subprocess.CREATE_NO_WINDOW)
|
|
record = {'started_utc': datetime.now(timezone.utc).isoformat(), 'pid': process.pid, 'binary': str(binary), 'bytes': binary.stat().st_size, 'sha256': hashlib.sha256(binary.read_bytes()).hexdigest(), 'private_profile': str(profile), 'acceptance': 'Launch requested; native behavior not yet verified.'}
|
|
(trial / 'launch.json').write_text(json.dumps(record, indent=2) + '\n', encoding='utf-8', newline='\n')
|
|
print(json.dumps(record))
|
|
else:
|
|
raise SystemExit('Expected prepare or launch')
|