initial commit

This commit is contained in:
2026-09-21 13:41:40 +09:00
commit 855c7328df
411 changed files with 85352 additions and 0 deletions
@@ -0,0 +1,72 @@
#!/usr/bin/env python3
"""Record this dedicated guest build without copying VM credentials or user data."""
import argparse
import ctypes
import hashlib
import json
from pathlib import Path
import platform
import re
import subprocess
import xml.etree.ElementTree as ET
def sha(path):
with path.open('rb') as handle:
return hashlib.file_digest(handle, 'sha256').hexdigest()
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--ctest-name', default='ctest-font-final')
parser.add_argument('--output-name', default='build-record.json')
parser.add_argument('--expected-groups', type=int, default=22)
parser.add_argument('--scope-note', default='Full 22-group baseline; later focused results are recorded separately.')
args = parser.parse_args()
if (not re.fullmatch(r'[a-z0-9][a-z0-9-]{0,63}', args.ctest_name)
or not re.fullmatch(r'[a-z0-9][a-z0-9-]{0,63}\.json', args.output_name)
or not 1 <= args.expected_groups <= 100):
parser.error('Use bounded local evidence names and 1–100 expected groups')
home = Path.home()
source, build = home / 'docview-source', home / 'docview-build'
validation = home / 'validation'
output = validation / args.output_name
if output.exists():
raise SystemExit('Keep previous evidence; output already exists')
ctest = validation / args.ctest_name
cases = ET.parse(ctest / 'tests.xml').findall('.//testcase')
if len(cases) != args.expected_groups or any(x.find('failure') is not None or x.find('skipped') is not None for x in cases):
raise SystemExit('Expected all selected CTest groups to pass')
names = ['docview', 'docview-pdf-worker', 'docview-archive-worker', 'test_app',
'test_core', 'test_pdf', 'test_pdf_canvas', 'test_web_qml', 'test_translations']
files = [source / n for n in ('CMakeLists.txt', 'resources.qrc')]
for folder in ('src', 'qml', 'cmake', 'resources', 'tools'):
files += [p for p in (source / folder).rglob('*')
if p.is_file() and not p.is_symlink() and '__pycache__' not in p.parts]
files += [p for p in (source / 'tests').rglob('*')
if p.is_file() and not p.is_symlink() and 'results' not in p.parts
and '__pycache__' not in p.parts and p.suffix in ('.cpp', '.h', '.py', '.qml')]
libc = ctypes.CDLL(None, use_errno=True)
landlock_abi = libc.syscall(444, 0, 0, 1)
record = {
'scope': 'Ubuntu 24.04 dedicated KVM guest; Xvfb/Sway software rendering, no physical GPU or IME acceptance',
'os': platform.freedesktop_os_release(), 'kernel': platform.release(),
'compiler': subprocess.check_output(['c++', '--version'], text=True).splitlines()[0],
'cmake': subprocess.check_output(['cmake', '--version'], text=True).splitlines()[0],
'qt': subprocess.check_output(['/opt/docview-qt/6.11.2/gcc_64/bin/qtpaths', '--query', 'QT_VERSION'], text=True).strip(),
'landlockABI': landlock_abi,
'apparmorRestrictUnprivilegedUserns': Path('/proc/sys/kernel/apparmor_restrict_unprivileged_userns').read_text().strip(),
'qtWebEngineApparmorProfileSha256': sha(Path('/etc/apparmor.d/docview-qtwebengine')),
'binaries': {n: sha(build / n) for n in names},
'installedBinaries': {n: sha(home / 'docview-install/bin' / n) for n in names[:3]},
'sourceSha256': {str(p.relative_to(source)): sha(p) for p in sorted(set(files))},
'ctest': {'directory': args.ctest_name, 'groups': len(cases), 'failures': 0, 'junitSha256': sha(ctest / 'tests.xml'),
'logSha256': sha(ctest / 'LastTest.log')},
'focusedTestScope': args.scope_note,
'pythonProvenanceScope': '30 passed and 5 explicit zstd skips with Python 3.12; Arch Python 3.14 executes all 35 cases.',
'productionBinariesChangedByTestFixes': False,
}
with output.open('x') as handle:
handle.write(json.dumps(record, ensure_ascii=False, indent=2) + '\n')
print(json.dumps({'ctestGroups': len(cases), 'sourceFiles': len(record['sourceSha256']),
'productionBinarySha256': record['binaries']['docview']}))