initial commit
This commit is contained in:
@@ -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']}))
|
||||
Reference in New Issue
Block a user