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

73 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/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']}))