Files
docview/tests/cmyk_lut/record.py
T
2026-09-21 13:41:40 +09:00

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()