Files
MagnetismHeroes/tools/android/test-voice-payload-negative.py

58 lines
3.1 KiB
Python

"""Actual inspector rejects missing serialized clips and changed PCM in QA-only APK copies."""
import argparse
import hashlib
import json
from pathlib import Path
import subprocess
import sys
import zipfile
parser = argparse.ArgumentParser()
parser.add_argument('--apk', required=True)
parser.add_argument('--project', required=True)
parser.add_argument('--evidence', required=True)
args = parser.parse_args()
apk, evidence = Path(args.apk), Path(args.evidence)
evidence.mkdir(parents=True, exist_ok=True)
inspector = Path(__file__).with_name('inspect-voice-payload.py')
checks = []
for kind in ('positive', 'missing-clips', 'altered-pcm'):
case = evidence / kind
case.mkdir(exist_ok=True)
target = apk if kind == 'positive' else case / 'qa-mutated.apk'
mutation = None
if kind != 'positive':
with zipfile.ZipFile(apk) as source, zipfile.ZipFile(target, 'w') as output:
for entry in source.infolist():
if not entry.filename.startswith('assets/bin/Data/'):
continue
if kind == 'missing-clips' and entry.filename.startswith('assets/bin/Data/sharedassets0.assets'):
continue
data = source.read(entry)
if kind == 'altered-pcm' and entry.filename in ('assets/bin/Data/sharedassets0.resource.split0', 'assets/bin/Data/sharedassets0.resource'):
data = bytearray(data)
offset = 194000 # Inside first known PCM16 AudioClip resource, outside its FSB header.
data[offset] ^= 32
data = bytes(data)
mutation = {'entry': entry.filename, 'offset': offset, 'xor': 32}
output.writestr(entry, data)
if kind == 'altered-pcm' and mutation is None:
raise RuntimeError('Expected actual PCM split resource is absent')
command = [sys.executable, '-I', str(inspector), '--apk', str(target), '--project', args.project, '--evidence', str(case)]
process = subprocess.run(command, capture_output=True, text=True)
(case / 'stdout.log').write_text(process.stdout, encoding='utf-8')
(case / 'stderr.log').write_text(process.stderr, encoding='utf-8')
record = json.loads((case / 'apk-voice-payload.json').read_text(encoding='utf-8'))
expected = kind == 'positive'
passed = process.returncode == (0 if expected else 1) and (record['status'] == 'passed') == expected
if kind == 'missing-clips':
passed = passed and record.get('actualClipCount') == 0
if kind == 'altered-pcm':
passed = passed and any(not check['passed'] for check in record['checks']) and 'PCM mismatch' in record.get('error', '')
checks.append({'case': kind, 'command': command, 'exitCode': process.returncode, 'passed': passed,
'mutation': mutation, 'inspectorRecord': record})
result = {'originalApkSha256': hashlib.sha256(apk.read_bytes()).hexdigest(), 'scope': 'QA synthetic negative copies only; never installed',
'checks': checks, 'passed': all(check['passed'] for check in checks)}
(evidence / 'regression.json').write_text(json.dumps(result, indent=2), encoding='utf-8')
sys.exit(0 if result['passed'] else 1)