#!/usr/bin/env python3 """Run the isolated candidate's upstream tests and both ICC regression corpora.""" import argparse import hashlib import json import os from pathlib import Path import subprocess import sys import time ROOT = Path(__file__).resolve().parents[2] def sha(path): with path.open('rb') as stream: return hashlib.file_digest(stream, 'sha256').hexdigest() def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--output', type=Path, required=True) parser.add_argument('--build-dir', type=Path, default=ROOT / 'build') parser.add_argument('--source', type=Path, default=ROOT / 'build-pdfium-intent/source') parser.add_argument('--variant', choices=('baseline', 'patched'), default='patched') args = parser.parse_args() output = args.output.resolve() output.mkdir(parents=True, exist_ok=False) source = args.source.resolve() binaries = source / 'out' / args.variant library = binaries / 'libpdfium.so' environment = os.environ.copy() assert not environment.get('LD_PRELOAD') and not environment.get('LD_AUDIT') environment['LD_LIBRARY_PATH'] = str(binaries) + ( ':' + environment['LD_LIBRARY_PATH'] if environment.get('LD_LIBRARY_PATH') else '') environment['LOCPATH'] = str(ROOT / 'build-pdfium-intent/locales') inputs = [library, binaries / 'pdfium_unittests', binaries / 'pdfium_embeddertests', args.build_dir / 'pdf-worker-evidence', args.build_dir / 'docview-pdf-worker', ROOT / '.deps/pdfium/lib/libpdfium.so'] identities = {str(path.resolve()): sha(path) for path in inputs} report = {'schemaVersion': 1, 'variant': args.variant, 'success': False, 'runnerSha256': sha(Path(__file__)), 'inputs': identities, 'commands': [], 'productionDependencyReplaced': False, 'scope': 'Isolated Linux source-build candidate. No Windows, Ubuntu, calibrated display, human golden, or release acceptance claimed.'} def run(label, command, cwd=ROOT): start = time.monotonic() log = output / (label + '.log') with log.open('w') as stream: result = subprocess.run(command, cwd=cwd, env=environment, stdout=stream, stderr=subprocess.STDOUT, timeout=600) report['commands'].append({'name': label, 'command': command, 'exitCode': result.returncode, 'seconds': time.monotonic() - start, 'logSha256': sha(log)}) return result.returncode try: loader = subprocess.run(['ldd', str(args.build_dir.resolve() / 'docview-pdf-worker')], env=environment, capture_output=True, text=True, check=True) assert str(library) in loader.stdout (output / 'worker-ldd.txt').write_text(loader.stdout) upstream = [] for target in ('pdfium_unittests', 'pdfium_embeddertests'): result = output / (target + '.json') status = run(target, [str(binaries / target), '--gtest_output=json:' + str(result)], source) data = json.loads(result.read_text()) if result.exists() else {} upstream.append({'target': target, 'exitCode': status, **{key: data.get(key) for key in ('tests', 'failures', 'disabled', 'errors', 'time')}}) report['upstreamTests'] = upstream run('cmyk', [sys.executable, str(ROOT / 'tests/cmyk_lut/run.py'), '--build-dir', str(args.build_dir.resolve()), '--output', str(output / 'cmyk')]) run('intents', [sys.executable, str(ROOT / 'tests/cmyk_lut/intents.py'), '--build-dir', str(args.build_dir.resolve()), '--pdfium-library', str(library), '--scales', '.5', '1', '4', '--output', str(output / 'intents')]) cmyk = json.loads((output / 'cmyk/report.json').read_text()) intents = json.loads((output / 'intents/report.json').read_text()) report['cmykSuccess'] = cmyk['success'] report['intentPdfiumSuccess'] = intents.get('pdfiumSuccess', False) report['intentPopplerSuccess'] = intents.get('popplerSuccess', False) report['intentRenderingAcceptance'] = intents['renderingAcceptance'] report['upstreamTestsPass'] = all(row['exitCode'] == 0 and row['failures'] == 0 and row['errors'] == 0 for row in upstream) report['allBinaryInputsUnchanged'] = all(sha(Path(path)) == digest for path, digest in identities.items()) report['candidatePdfiumProbesPass'] = cmyk['success'] and report['intentPdfiumSuccess'] report['success'] = (report['upstreamTestsPass'] and report['candidatePdfiumProbesPass'] and report['intentRenderingAcceptance'] and report['allBinaryInputsUnchanged']) finally: report['evidenceSha256'] = {str(path.relative_to(output)): sha(path) for path in sorted(output.rglob('*')) if path.is_file()} (output / 'report.json').write_text(json.dumps(report, indent=2) + '\n') print(json.dumps({key: report.get(key) for key in ('success', 'upstreamTestsPass', 'candidatePdfiumProbesPass', 'intentPopplerSuccess', 'allBinaryInputsUnchanged')})) if not report['success']: raise SystemExit('Validation not fully accepted; see separate candidate and comparison results.') if __name__ == '__main__': main()