90 lines
7.5 KiB
Python
90 lines
7.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Publish failing color evidence without converting diagnosis into acceptance."""
|
|
from datetime import datetime, timezone
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
|
|
ROOT=Path(__file__).resolve().parents[2]
|
|
RESULTS=ROOT/'tests/results/cmyk-lut'
|
|
|
|
|
|
def sha(path):
|
|
with path.open('rb') as stream: return hashlib.file_digest(stream,'sha256').hexdigest()
|
|
|
|
|
|
def main():
|
|
prior=json.loads((RESULTS/'prior-validation-record.json').read_text())
|
|
assert sha(RESULTS/'prior-validation-record.json')=='c80457d32c246e40743f59f5e602ff0f71d59d496b33a72618a97475659c9013'
|
|
for name,digest in prior['evidenceSha256'].items(): assert sha(ROOT/name)==digest,name
|
|
sources={str(p.relative_to(ROOT)):sha(p) for directory in ('src','qml','cmake','resources')
|
|
for p in (ROOT/directory).rglob('*') if p.is_file() and '__pycache__' not in p.parts}
|
|
sources.update({name:sha(ROOT/name) for name in ('CMakeLists.txt','resources.qrc')})
|
|
assert sources==prior['sourceSha256']
|
|
for name,digest in prior['builds']['arch']['binaries'].items(): assert sha(ROOT/'build'/name)==digest
|
|
package=prior['ubuntuPackage']
|
|
assert sha(ROOT/'build-ubuntu-vm/packages'/package['archive'])==package['archiveSha256']
|
|
diagnosis=json.loads((RESULTS/'diagnosis.json').read_text())
|
|
assert diagnosis['diagnosisVerified'] and not diagnosis['renderingAcceptance']
|
|
assert not diagnosis['relativeIntentPreserved'] and diagnosis['toleranceUnchanged']==4
|
|
assert diagnosis['diagnoserSha256']==sha(ROOT/'tests/cmyk_lut/diagnose.py')
|
|
reports={}
|
|
for os_name in ('arch','ubuntu'):
|
|
report=json.loads((RESULTS/os_name/'report.json').read_text())
|
|
assert not report['success'] and report['originalUnchanged'] and report['binariesUnchanged']
|
|
assert len(report['scales'])==3
|
|
for name,digest in report['evidenceSha256'].items(): assert sha(RESULTS/os_name/name)==digest
|
|
assert report['binaries']['docview-pdf-worker']==prior['builds'][os_name]['binaries']['docview-pdf-worker']
|
|
assert report['runnerSha256']==sha(ROOT/'tests/cmyk_lut/run.py')
|
|
entry=next(r for r in diagnosis['results'] if r['os']==os_name)
|
|
assert entry['comparisonReportSha256']==sha(RESULTS/os_name/'report.json')
|
|
assert entry['failedPdfiumAnalyticProbes']==30 and entry['failedPopplerAnalyticProbes']==0
|
|
reports[os_name]=report
|
|
assert sha(ROOT/'build/pdf-worker-evidence')==reports['arch']['binaries']['pdf-worker-evidence']
|
|
assert sha(ROOT/'.deps/pdfium/lib/libpdfium.so')=='08f6ea53a64f6fbb9f5ba8d9c02e0051987c6a9175f3fb5ba25f219174731aaa'
|
|
reproduced=json.loads((RESULTS/'reproduction.json').read_text())
|
|
for name,digest in reproduced['filesByteIdentical'].items():
|
|
assert sha(ROOT/'tests/fixtures/pdf/cmyk-lut'/name)==digest==sha(RESULTS/'reproduction'/name)
|
|
shutdown=json.loads((RESULTS/'shutdown.json').read_text())
|
|
assert shutdown['qemuExitCode']==0 and shutdown['guestPowerDownObserved']
|
|
assert sha(RESULTS/'shutdown-tail.txt')==shutdown['tailSha256']
|
|
gallery=['''<!doctype html><html lang="ja"><meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1"><title>ICC CMYK 描画比較</title>
|
|
<style>body{margin:0;background:#f5f6f8;color:#202734;font:16px/1.7 system-ui,sans-serif}main{max-width:1500px;margin:auto;padding:36px 24px}h1{font-size:28px;line-height:1.4}h2{margin-top:40px}h3{margin:20px 0 8px}.status{background:#fff0ee;border-left:4px solid #bb3b30;padding:16px 20px}a{color:#1459a0}.row{display:grid;grid-template-columns:repeat(3,minmax(260px,1fr));gap:16px;overflow:auto}figure{margin:0;background:white;padding:12px}figcaption{font-weight:600;margin-bottom:8px}img{display:block;width:100%;height:auto}.hint{color:#596476;font-size:14px}</style>
|
|
<main><h1>ICC CMYK の追加描画比較</h1>
|
|
<p class="status"><strong>色の一致は未達です。</strong> Arch・Ubuntu各48点中30点が許容差を超えました。原因の照合は完了していますが、描画の受入や人による承認は完了していません。</p>
|
|
<p>相対的な測色を指定した資料に対して、固定PDFiumは知覚的なICC変換を使用します。上2段の右端の暗色に明瞭な差があります。下段はプロファイルを適用しないDeviceCMYKの対照です。</p>
|
|
<p><a href="README.md">試験条件・原因・未完了事項</a> / <a href="../../fixtures/pdf/cmyk-lut/icc-cmyk-lut.pdf">生成PDF</a> / <a href="diagnosis.json">数値による原因照合</a></p>
|
|
<p class="hint">各画像を開くと元の解像度で確認できます。差分画像は絶対RGB差で、色差の許容性や印刷色を判定する画像ではありません。</p>''']
|
|
for os_name,label in [('arch','Arch Linux'),('ubuntu','Ubuntu 24.04')]:
|
|
gallery.append('<h2>'+label+'</h2>')
|
|
for scale in reports[os_name]['scales']:
|
|
folder=os_name+'/scale-'+str(scale['scale']).replace('.','_')
|
|
gallery.append(f'<h3>{scale["scale"]:g}倍 / {scale["dpi"]:g} dpi</h3><div class="row">')
|
|
for title,name in [('PDFium / 本番隔離ワーカー','pdfium/page-1.png'),('Poppler / 独立した比較','poppler.png'),('絶対RGB差','difference.png')]:
|
|
path=folder+'/'+name
|
|
assert (RESULTS/path).is_file()
|
|
gallery.append(f'<figure><figcaption>{title}</figcaption><a href="{path}"><img src="{path}" alt="{title}の描画比較" loading="lazy"></a></figure>')
|
|
gallery.append('</div>')
|
|
gallery.append('</main></html>')
|
|
(RESULTS/'index.html').write_text('\n'.join(gallery))
|
|
tools=['tests/cmyk_lut/run.py','tests/cmyk_lut/diagnose.py','tests/cmyk_lut/record.py','tests/fixtures/pdf/generate_cmyk_lut.py','tests/render_pdf_worker.cpp']
|
|
new_requirement='Resolve or explicitly review the fixed PDFium ICC rendering-intent discrepancy demonstrated by the CMYK CLUT fixture; runtime detection/notice is not yet implemented'
|
|
record={**prior,'schemaVersion':4,'recordedAtUtc':datetime.now(timezone.utc).isoformat(),
|
|
'scope':'Unchanged validation3 product plus a new, failing CMYK ICC rendering comparison on Arch and Ubuntu. '
|
|
'Prior passing functional/package tests remain scoped to their original runs; color acceptance is not achieved.',
|
|
'goalComplete':False,'colorRenderingFinding':diagnosis,
|
|
'colorRenderingReports':{name:{'path':'tests/results/cmyk-lut/'+name+'/report.json','sha256':sha(RESULTS/name/'report.json')} for name in reports},
|
|
'previousValidation':{'record':'tests/results/cmyk-lut/prior-validation-record.json','sha256':sha(RESULTS/'prior-validation-record.json'),
|
|
'scope':'Validation3 package, all prior test executions and their exact product identities. No product bytes changed in the ICC investigation.'},
|
|
'remainingAcceptance':prior['remainingAcceptance']+[new_requirement],
|
|
'validationToolsSha256':{**prior['validationToolsSha256'],**{name:sha(ROOT/name) for name in tools}},
|
|
'evidenceSha256':{**prior['evidenceSha256'],**{str(p.relative_to(ROOT)):sha(p) for folder in (RESULTS,ROOT/'tests/fixtures/pdf/cmyk-lut')
|
|
for p in sorted(folder.rglob('*')) if p.is_file() and p.suffix!='.pyc' and p!=RESULTS/'record.json'}}}
|
|
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({'colorRenderingAcceptance':False,'failedAnalyticProbes':60,'productUnchanged':True,'goalComplete':False}))
|
|
|
|
|
|
if __name__=='__main__': main()
|