Files
MagnetismHeroes/.dryforge/002/execution-support/audit-final-product.py
T
2026-10-10 01:27:54 +09:00

59 lines
3.2 KiB
Python

import hashlib
import json
import subprocess
import xml.etree.ElementTree as ET
from pathlib import Path
root = Path('C:/git/MagnetismHeroes')
proof = root / 'artifacts/verification/VisualUpgrade/FinalProduct'
final = root / 'artifacts/verification/Final'
def read(path):
return json.loads(path.read_text(encoding='utf-8-sig'))
def sha(path):
return hashlib.sha256(path.read_bytes()).hexdigest().upper()
completion = read(proof / 'completion.json')
source = '3346eb559bdfba24332feb4d9be4b7104520233e'
assert completion['status'] == 'passed' and completion['sourceCommit'] == source
assert len(completion['phases']) == 4 and completion['productHashesUnchanged']
for phase in completion['phases']:
assert phase['exitCode'] == 0 and phase['status'] == 'passed'
assert phase['sourceCommit'] == source and phase['sourceDirty'] is False and phase['sourceDirtyEnd'] is False
raw = read(Path(phase['evidence']))
assert raw['status'] == 'passed' and raw['exitCode'] == 0 and raw['sourceCommit'].strip() == source
counts = {}
for mode, count in [('editmode', 103), ('playmode', 53)]:
cases = ET.parse(final / (mode + '.xml')).findall('.//test-case')
assert len(cases) == count and all(case.get('result') == 'Passed' for case in cases)
counts[mode] = count
apk_hash = sha(root / 'artifacts/android/Final/MagnetismHeroes.apk')
assert sha(root / 'artifacts/android/MagnetismHeroes.apk') == apk_hash
for path, count in [
('android-final-evidence.json', 226),
('Fresh30/android-final-progression-evidence.json', 151),
('FinalBoundary/android-final-boundary-evidence.json', 37),
('RapidBoundary/android-final-rapid-evidence.json', 39),
('ContentBoundary/android-content-evidence.json', 69),
]:
data = read(final / path)
assert data['status'] == 'passed' and data['sourceCommit'].strip() == source
assert data['apkSha256'].upper() == apk_hash and data['sourceDirty'] is False
assert len(data['checks']) == count and all(check['passed'] for check in data['checks'])
counts[path] = count
before = read(proof / 'product-before.json')
after = read(proof / 'product-after.json')
assert before == after and len(before) == 732
assert all(sha(root / path) == digest.upper() for path, digest in before.items())
assert subprocess.check_output(['git', 'status', '--porcelain'], cwd=root).strip() == b''
assert subprocess.check_output(['git', 'rev-parse', 'dev'], cwd=root).decode().strip() == '58410281e015c6600dc543c4e093fd95c036288c'
for failure in completion.get('failedAttempts', []):
assert failure['exitCode'] == 1 and failure['status'] == 'failed'
archived = read(Path(failure['evidence']))
assert archived['exitCode'] == 1 and archived['status'] == 'failed'
assert Path(failure['outerLog']).is_file()
report = {'status': 'PASS', 'testedProductSourceCommit': source,
'currentHead': subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=root).decode().strip(),
'counts': counts, 'apkSha256': apk_hash, 'productFileHashesUnchanged': len(before),
'failedAttemptsPreserved': len(completion.get('failedAttempts', [])), 'protectedDevUnchanged': True}
(proof / 'root-final-product-audit.json').write_text(json.dumps(report, indent=2) + '\n', encoding='utf-8')
print(json.dumps(report))