Files
archy/scripts/tests/test_c01_kiosk_browser.py

66 lines
3.4 KiB
Python

"""Browser branch execution in disposable user/mount/network namespaces.
No host X socket, profile, service bus, device, or application data is exposed.
"""
import json
import os
from pathlib import Path
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[2]
class BrowserTests(unittest.TestCase):
def run_browser(self, missing=None, socket_present=True):
with tempfile.TemporaryDirectory(prefix='c01-kiosk-test-') as directory:
work = Path(directory)
(work / 'chromium').write_text('#!/usr/bin/python3\nimport json,os,sys\nprint(json.dumps({"args":sys.argv[1:],"display":os.environ["DISPLAY"],"home":os.environ["HOME"],"runtime":os.environ["XDG_RUNTIME_DIR"],"uid":os.getuid(),"groups":os.getgroups()}))\n')
(work / 'chromium').chmod(0o755)
(work / 'driver.py').write_text('''import os,socket,subprocess,sys
os.makedirs('/tmp/.X11-unix')
os.makedirs('/var/lib/archipelago/chromium-kiosk')
s=socket.socket(socket.AF_UNIX)
if sys.argv[1]=='yes':s.bind('/tmp/.X11-unix/X0')
os.environ.update(PATH='/test:/usr/bin',KIOSK_WIN_W='1280',KIOSK_WIN_H='720',KIOSK_SCALE='1.50',ENABLE_FEATURES='OverlayScrollbar,VaapiVideoDecodeLinuxGL',ARCHIPELAGO_UID='1000',GPU_FLAGS='--in-process-gpu',EXTRA_DISABLED_FEATURES='',KIOSK_SAFE_AREA_X_PX='32',KIOSK_SAFE_AREA_Y_PX='24')
if sys.argv[2]!='none':os.environ.pop(sys.argv[2])
r=subprocess.run(['/usr/bin/bash','/launcher','--c01-browser'])
sys.exit(r.returncode)
''')
return subprocess.run(['bwrap','--unshare-all','--die-with-parent','--new-session',
'--uid','1000','--gid','1000','--ro-bind','/usr','/usr','--symlink','usr/bin','/bin',
'--symlink','usr/lib','/lib','--symlink','usr/lib64','/lib64',
'--proc','/proc','--dev','/dev','--tmpfs','/tmp','--tmpfs','/var',
'--ro-bind',str(work),'/test','--ro-bind',str(ROOT/'image-recipe/configs/archipelago-kiosk-launcher.sh'),'/launcher',
'/usr/bin/python3','/test/driver.py','yes' if socket_present else 'no',missing or 'none'],
capture_output=True,text=True,timeout=20)
def test_preserves_browser_profile_display_audio_and_cdp_arguments(self):
result = self.run_browser()
self.assertEqual(result.returncode, 0, result.stderr)
data = json.loads(result.stdout)
self.assertEqual(data['uid'], 1000)
self.assertEqual(data['display'], ':0')
self.assertEqual(data['home'], '/home/archipelago')
self.assertEqual(data['runtime'], '/run/user/1000')
for argument in ('--user-data-dir=/var/lib/archipelago/chromium-kiosk',
'--remote-debugging-port=9222','--window-size=1280,720',
'--force-device-scale-factor=1.50','--in-process-gpu',
'--app=http://localhost/kiosk?safe_area_x=32&safe_area_y=24'):
self.assertIn(argument, data['args'])
def test_waits_for_display_without_starting_browser(self):
result = self.run_browser(socket_present=False)
self.assertEqual(result.returncode, 75, result.stderr)
self.assertEqual(result.stdout, '')
def test_missing_display_owner_environment_refuses_browser(self):
result = self.run_browser(missing='KIOSK_SCALE')
self.assertEqual(result.returncode, 75, result.stderr)
self.assertEqual(result.stdout, '')
if __name__ == '__main__':
unittest.main()