"""Run the complete Chrome suite and preserve its own descendant sandbox evidence.""" from datetime import datetime, timezone import json import os from pathlib import Path import shlex import subprocess import sys import time ROOT = Path(__file__).resolve().parents[4] EVIDENCE = Path(__file__).resolve().parent def now(): return datetime.now(timezone.utc).isoformat() def descendants(runner_pid): processes = {} for directory in Path('/proc').iterdir(): if not directory.name.isdigit(): continue try: stat = (directory / 'stat').read_text().rsplit(')', 1)[1].split() arguments = (directory / 'cmdline').read_bytes().decode(errors='replace').rstrip('\0').split('\0') status = (directory / 'status').read_text().splitlines() processes[int(directory.name)] = {'pid': int(directory.name), 'ppid': int(stat[1]), 'arguments': arguments, 'commandLine': shlex.join(arguments), 'sandboxStatus': [line for line in status if line.startswith(('NoNewPrivs:', 'Seccomp:', 'Seccomp_filters:', 'NSpid:'))]} except (OSError, ValueError): continue family = {runner_pid} while True: children = {pid for pid, record in processes.items() if record['ppid'] in family} if children <= family: break family |= children return [record for pid, record in processes.items() if pid in family and record['arguments'] and record['arguments'][0].startswith('/opt/google/chrome/') and 'crashpad' not in record['arguments'][0]] env = os.environ.copy() env.pop('PLAYWRIGHT_NO_SANDBOX', None) env['CHROME_PATH'] = '/usr/bin/google-chrome' env['PLAYWRIGHT_JSON_OUTPUT_FILE'] = str(EVIDENCE / 'browser-results.json') command = ['npx', 'playwright', 'test', '--reporter=line,json', '--output', str(EVIDENCE / 'browser-final')] started = now() observed = {} with (EVIDENCE / '06-browser.log').open('x') as log: log.write('$ ' + shlex.join(command) + '\nStarted UTC: ' + started + '\nCHROME_PATH=/usr/bin/google-chrome; PLAYWRIGHT_NO_SANDBOX unset; chromiumSandbox=true\n') log.flush() process = subprocess.Popen(command, cwd=ROOT, env=env, stdout=log, stderr=subprocess.STDOUT) while process.poll() is None: for record in descendants(process.pid): observed[record['pid']] = record time.sleep(2) log.write('\nExit code: ' + str(process.returncode) + '\nFinished UTC: ' + now() + '\n') assert observed, 'No suite Chrome processes observed' assert all('--no-sandbox' not in row['arguments'] for row in observed.values()) report = {'startedAtUtc': started, 'completedAtUtc': now(), 'runnerPid': process.pid, 'command': command, 'chrome': subprocess.check_output(['/usr/bin/google-chrome', '--version'], text=True).strip(), 'method': 'Actual Chrome descendants of this suite runner; Playwright chromiumSandbox=true and opt-out unset.', 'noSandboxFlagPresent': False, 'exitCode': process.returncode, 'processes': list(observed.values())} with (EVIDENCE / 'chrome-sandbox.json').open('x') as out: out.write(json.dumps(report, indent=2) + '\n') print(json.dumps({'exitCode': process.returncode, 'observedChromeProcesses': len(observed), 'noSandboxFlagPresent': False})) print('\n'.join((EVIDENCE / '06-browser.log').read_text().splitlines()[-16:])) sys.exit(process.returncode)