111 lines
7.0 KiB
Python
111 lines
7.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Add isolated-candidate evidence while preserving production failure history."""
|
|
from datetime import datetime, timezone
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import xml.etree.ElementTree as ET
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
RESULTS = ROOT / 'tests/results/pdfium-intent-build'
|
|
|
|
|
|
def sha(path):
|
|
with path.open('rb') as stream:
|
|
return hashlib.file_digest(stream, 'sha256').hexdigest()
|
|
|
|
|
|
def read(relative):
|
|
return json.loads((RESULTS / relative).read_text())
|
|
|
|
|
|
def main():
|
|
previous = RESULTS / 'prior-validation-record.json'
|
|
assert sha(previous) == 'e171862993beb61a9786ffee1f6a4a869ba30e3c3bd03223918a20d8e41f297b'
|
|
prior = json.loads(previous.read_text())
|
|
for name, digest in prior['evidenceSha256'].items():
|
|
assert sha(ROOT / name) == digest, name
|
|
for name, digest in prior['sourceSha256'].items():
|
|
assert sha(ROOT / name) == digest, name
|
|
for name, digest in prior['validationToolsSha256'].items():
|
|
assert sha(ROOT / name) == digest, name
|
|
for name, digest in prior['builds']['arch']['binaries'].items():
|
|
assert sha(ROOT / 'build' / name) == digest, name
|
|
package = prior['ubuntuPackage']
|
|
assert sha(ROOT / 'build-ubuntu-vm/packages' / package['archive']) == package['archiveSha256']
|
|
assert sha(ROOT / '.deps/pdfium/lib/libpdfium.so') == '08f6ea53a64f6fbb9f5ba8d9c02e0051987c6a9175f3fb5ba25f219174731aaa'
|
|
candidate = read('candidate-final/report.json')
|
|
assert candidate['upstreamTestsPass'] and candidate['candidatePdfiumProbesPass']
|
|
assert candidate['allBinaryInputsUnchanged'] and not candidate['productionDependencyReplaced']
|
|
assert not candidate['success'] and not candidate['intentPopplerSuccess']
|
|
assert [(r['tests'], r['failures']) for r in candidate['upstreamTests']] == [(1104, 0), (872, 0)]
|
|
for name, digest in candidate['evidenceSha256'].items():
|
|
assert sha(RESULTS / 'candidate-final' / name) == digest, name
|
|
for name, digest in candidate['inputs'].items():
|
|
assert sha(Path(name)) == digest, name
|
|
intents = read('candidate-final/intents/report.json')
|
|
probes = [p for scale in intents['scales'] for p in scale['probes']]
|
|
assert len(probes) == 600 and all(p['matches']['pdfium'] for p in probes)
|
|
comparison_failures = [p for p in probes if not p['matches']['poppler']]
|
|
assert len(comparison_failures) == 18
|
|
assert {p['case'] for p in comparison_failures} == {'shading-pattern-RI-override'}
|
|
baseline = read('intents-baseline/report.json')
|
|
assert sum(not p['matches']['pdfium'] for s in baseline['scales'] for p in s['probes']) == 150
|
|
ctest = read('docview-ctest/report.json')
|
|
assert ctest['exitCode'] == 0 and ctest['libraryUnchanged']
|
|
assert ctest['librarySha256'] == intents['pdfiumLibrary']['sha256']
|
|
suite = ET.parse(RESULTS / 'docview-ctest/tests.xml').getroot()
|
|
assert suite.tag == 'testsuite' and suite.attrib['tests'] == '22' and suite.attrib['failures'] == '0'
|
|
patch = read('candidate-patch.json')
|
|
assert patch['success'] and patch['appliesWithoutFuzz'] and patch['appliedSourcesByteIdentical']
|
|
assert sha(ROOT / patch['patch']) == patch['patchSha256']
|
|
assert sha(ROOT / patch['patchSnapshot']) == patch['patchSha256']
|
|
for row in patch['files']:
|
|
assert sha(ROOT / 'build-pdfium-intent/source' / row['path']) == row['afterSha256']
|
|
reproduced = read('fixture-reproduction.json')
|
|
assert reproduced['success'] and len(reproduced['filesByteIdentical']) == 4
|
|
for name, digest in reproduced['filesByteIdentical'].items():
|
|
assert sha(RESULTS / 'reproduced-fixture' / name) == digest
|
|
assert sha(ROOT / 'tests/fixtures/pdf/rendering-intents' / name) == digest
|
|
tools = ['tests/cmyk_lut/' + name + '.py' for name in
|
|
('prepare_pdfium_source', 'fetch_pdfium_build_tools', 'prepare_pdfium_tools',
|
|
'export_pdfium_patch', 'validate_pdfium_candidate', 'record_candidate', 'intents')]
|
|
tools.append('tests/fixtures/pdf/generate_rendering_intents.py')
|
|
candidate_summary = {
|
|
'productionDependencyReplaced': False, 'candidatePdfiumProbesPass': True,
|
|
'humanRenderingAcceptance': False, 'crossRendererComparisonAccepted': False,
|
|
'sourceRevision': patch['baseRevision'], 'patch': patch['patch'],
|
|
'patchSha256': patch['patchSha256'], 'changedCoreFiles': len(patch['files']),
|
|
'patchSnapshot': patch['patchSnapshot'],
|
|
'library': intents['pdfiumLibrary']['path'], 'librarySha256': intents['pdfiumLibrary']['sha256'],
|
|
'upstreamTests': candidate['upstreamTests'], 'docviewCtestGroups': 22,
|
|
'cmykAnalyticProbesPassed': 48, 'intentProbesPassed': 600,
|
|
'popplerFailedProbes': 18, 'popplerFailureCase': 'shading-pattern-RI-override',
|
|
'report': 'tests/results/pdfium-intent-build/candidate-final/report.json',
|
|
'reportSha256': sha(RESULTS / 'candidate-final/report.json'),
|
|
'scope': 'Arch isolated candidate with existing application/worker binaries; no adoption into the Ubuntu package, Windows execution, calibrated-output or human golden acceptance.'}
|
|
evidence = {str(path.relative_to(ROOT)): sha(path)
|
|
for folder in (RESULTS, ROOT / 'tests/fixtures/pdf/rendering-intents')
|
|
for path in sorted(folder.rglob('*')) if path.is_file()
|
|
and '__pycache__' not in path.parts and path != RESULTS / 'record.json'}
|
|
record = {**prior, 'schemaVersion': 5, 'recordedAtUtc': datetime.now(timezone.utc).isoformat(),
|
|
'scope': 'Unchanged validation3 product plus an isolated source-built PDFium rendering-intent candidate. Candidate numeric/upstream/application tests pass; comparator differences and final adoption/acceptance remain.',
|
|
'goalComplete': False, 'pdfiumRenderingIntentCandidate': candidate_summary,
|
|
'previousValidation': {'record': str(previous.relative_to(ROOT)), 'sha256': sha(previous),
|
|
'scope': 'Unchanged product and original failing ICC evidence; retained without rewriting its verdict.'},
|
|
'sourceSha256': {**prior['sourceSha256'], patch['patch']: patch['patchSha256']},
|
|
'validationToolsSha256': {**prior['validationToolsSha256'], **{name: sha(ROOT / name) for name in tools}},
|
|
'evidenceSha256': {**prior['evidenceSha256'], **evidence},
|
|
'remainingAcceptance': [*prior['remainingAcceptance'],
|
|
'Review and adopt the source-built rendering-intent patch; validate Ubuntu packaging and remaining rendering boundaries (including dedicated soft-mask/tiling probes). Independent Poppler shading-pattern intent differences remain recorded.']}
|
|
encoded = json.dumps(record, ensure_ascii=False, indent=2) + '\n'
|
|
(RESULTS / 'record.json').write_text(encoded)
|
|
(ROOT / 'docs/validation-record.json').write_text(encoded)
|
|
print(json.dumps({'goalComplete': False, 'candidateProbesPassed': 648,
|
|
'upstreamTestsPassed': 1976, 'docviewGroupsPassed': 22,
|
|
'evidenceFiles': len(record['evidenceSha256'])}))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|