Files
archy/scripts/tests/runtime_read_fixture.py

98 lines
4.0 KiB
Python

#!/usr/bin/python3
"""Extend the existing disposable USER-service fixture without editing it.
Run only from the isolated Rust fixture driver with private mounts and artifacts.
Uses the real owner/proxy/Podman userns, plus a real manager-only idmapped view.
"""
import os
from pathlib import Path
import subprocess
import runtime_service_fixture as fixture
import c01_views as views
original = fixture.command
tested = False
original_run = subprocess.run
class ReadComplete(Exception):
"""End the targeted extension through the fixture's unconditional cleanup."""
def diagnosed_run(*args, **kwargs):
result = original_run(*args, **kwargs)
argv = args[0] if args else kwargs.get('args', [])
if argv and argv[0] == '/usr/bin/mount' and result.returncode:
print('FIXTURE idmap mount failure:', result.returncode, result.stderr, flush=True)
return result
subprocess.run = diagnosed_run
def read_cases():
root = fixture.DATA / 'filebrowser'
fixture.owned(root)
(root / 'subuid').mkdir(mode=0o700)
os.chown(root / 'subuid', 2000000, 2000000)
(root / 'subuid/secret').write_bytes(b'R' * 32)
(root / 'subuid/secret').chmod(0o600)
os.chown(root / 'subuid/secret', 2000001, 2000001)
(root / 'leaf').write_bytes(b'L' * 32)
(root / 'leaf').chmod(0o600)
os.chown(root / 'leaf', 2000001, 2000001)
fixture.owned(Path('/run/read-manager'), fixture.MANAGER)
Path('/opt/read-proxy-bin').mkdir()
(Path('/opt/read-proxy-bin') / 'podman').symlink_to('/opt/archipelago-runtime-proxy')
source_fd = views.pin_directory(fixture.DATA)
source = views.PinnedSource.capture(source_fd, fixture.DATA)
pid = os.fork()
if pid == 0:
try:
view = views.PrivateMounts()
view.idmapped_directory(source, fixture.DATA, fixture.UID, fixture.MANAGER)
fixture.require(root.stat().st_uid == fixture.MANAGER, 'manager idmap absent')
fixture.drop(fixture.MANAGER)
os.execve('/opt/read-tests', ['/opt/read-tests', 'runtime_read::tests::manager_read_native_fixture',
'--exact', '--ignored', '--nocapture'], {'PATH':'/opt/read-proxy-bin:/usr/bin:/bin',
'HOME':'/run/read-manager', 'ARCHY_TEST_ISOLATED':'1', 'ARCHY_RUNTIME_READ_ROLE':'protected',
'RUST_MIN_STACK':'16777216'})
except BaseException:
import traceback; traceback.print_exc(); os._exit(111)
os.close(source_fd)
_, status = os.waitpid(pid, 0)
fixture.require(os.waitstatus_to_exitcode(status) == 0, 'protected reader fixture failed')
fixture.require(root.stat().st_uid == fixture.UID, 'original root ownership changed')
# Real runtime UID/USER hierarchy, same legacy data root. The command owns
# only fixture files and the freshly built test/helper artifacts.
output = original(['/usr/bin/env', 'ARCHY_TEST_ISOLATED=1', 'ARCHY_RUNTIME_READ_ROLE=legacy',
'RUST_MIN_STACK=16777216', '/opt/read-tests', 'runtime_read::tests::manager_read_native_fixture',
'--exact', '--ignored', '--nocapture'])
fixture.require('test result: ok.' in output, 'legacy reader did not pass')
print(output, flush=True)
print('PASS real idmapped manager FD + original runtime namespace inode match; original UID/subuid data ownership preserved', flush=True)
def command(argv):
global tested
if not tested:
tested = True
read_cases()
raise ReadComplete()
return original(argv)
fixture.command = command
# The outer isolated Rust runner stays in its own leaf. Give this existing
# service fixture a separate empty delegated root before it enables controllers.
driver = fixture.current_group()
fixture.require(driver.name == 'test-driver', 'dedicated isolated runner leaf required')
suite = driver.parent / 'read-service'
suite.mkdir()
(suite / 'cgroup.procs').write_text(str(os.getpid()))
try:
fixture.main()
except ReadComplete:
print('PASS targeted read scope complete; runtime fixture finally retired its owned services', flush=True)
fixture.require(tested, 'reader fixture was never reached')