Files
archy/tests/regression/radio-abi.py

44 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""Disposable checks against the actual non-test native v6/v7 executable."""
import ctypes
import os
from pathlib import Path
import subprocess
assert os.geteuid()==0 and os.environ.get('ARCHY_RADIO_ABI')=='1'
binary='/opt/radio-native'
libc=ctypes.CDLL(None,use_errno=True)
def drop():
os.setgroups([]); os.setgid(53001); os.setuid(53001)
assert libc.prctl(38,1,0,0,0)==0
cases=[
('c01-managed-v6',(),'required Tor lifecycle FD12 missing'),
('c01-managed-v7',(),'required v7 radio FD14 missing'),
('c01-managed-v7',(14,),'required Tor lifecycle FD12 missing'),
('c01-managed-v7',(12,14),'required network settings FD11 missing'),
('c01-managed-v7',(11,12,14),'required D09 FD10 missing'),
('c01-managed-v5',(),'obsolete protected application ABI'),
]
for role,slots,expected in cases:
for slot in slots:
fd=os.open('/dev/null',os.O_RDONLY)
os.dup2(fd,slot,inheritable=True)
if fd!=slot: os.close(fd)
try:
result=subprocess.run([binary,role],preexec_fn=drop,pass_fds=slots,capture_output=True,timeout=10)
assert result.returncode!=0 and expected in result.stderr.decode(),(role,result.stderr)
finally:
for slot in slots: os.close(slot)
print('PASS',role,expected,flush=True)
result=subprocess.run([binary,'radio-owner-v1'],capture_output=True,timeout=20)
assert result.returncode!=0 and b'runtime.json' in result.stderr,result.stderr
print('PASS embedded fixed radio owner refuses absent external runtime appointment before device access',flush=True)
Path('/run/archipelago-radio').mkdir(mode=0o700)
result=subprocess.run([binary,'radio-retire-v1'],capture_output=True,timeout=20)
assert result.returncode==0,result.stderr
assert not list(Path('/var/lib/archipelago').iterdir())
print('PASS embedded finite retirement entry point; no app/wallet state created',flush=True)