"""Explicit isolated MariaDB browser lanes; self-check never touches a server.""" import argparse import base64 import datetime import hashlib import json import os from pathlib import Path import re import socket import subprocess import sys import time import uuid ROOT = Path(__file__).resolve().parents[4] OUT = ROOT / '.artifacts/p9-requal-01' UI = ROOT / 'job-tracker-ui' CLIENT = ROOT / '.artifacts/mariadb/runtime/mariadb-12.2.2-winx64/bin/mariadb.exe' CONTAINER = 'jobtracker-it-p9-requal-mariadb-test-1' IMAGE = 'mariadb:12.2.2@sha256:42a27baaba3e8f3f0159d16381d5a7156661aa91dcc65f663cabb6a6f9503c00' CONFIGS = { 'mariadb-browser': ('playwright.mariadb.config.ts', 1), 'mariadb-observations': ('../docs/redesign/phase-9/p9-requal-01/observations/playwright.config.ts', 2), 'performance': ('../docs/redesign/phase-9/p9-requal-01/performance/playwright.config.ts', 1), } def utc(): return datetime.datetime.now(datetime.timezone.utc).isoformat() def scrub(value): if isinstance(value, dict): return {k: '[REDACTED]' if re.search(r'password|connectionstring', k, re.I) else scrub(v) for k, v in value.items()} if isinstance(value, list): return [scrub(v) for v in value] if not isinstance(value, str): return value value = re.sub(r'Server=127\.0\.0\.1;Port=33308;Database=jt_it_[a-f0-9]{32};User ID=root;Password=[^;\r\n]+;SslMode=None;?', '[REDACTED CONNECTION]', value) for secret in ('jt-integration-only', 'E2ePassword123!'): value = value.replace(secret, '[REDACTED]') return re.sub(r'(Password\s*=\s*)[^;\s]+', r'\1[REDACTED]', value, flags=re.I) def write(path, value): path.parent.mkdir(parents=True, exist_ok=True) path.write_text(json.dumps(scrub(value), indent=2) + '\n', encoding='utf-8') def schema_sql(schema, drop=False): if not re.fullmatch(r'jt_it_[a-f0-9]{32}', schema): raise ValueError('Invalid generated schema') return f'DROP DATABASE `{schema}`;' if drop else f'CREATE DATABASE `{schema}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;' def ownership(data): labels = data['Config'].get('Labels', {}) ports = data['NetworkSettings']['Ports'].get('3306/tcp', []) if (data['Name'] != '/' + CONTAINER or not data['State']['Running'] or data['Config']['Image'] != IMAGE or labels.get('com.docker.compose.project') != 'jobtracker-it-p9-requal' or labels.get('com.docker.compose.service') != 'mariadb-test' or ports != [{'HostIp': '127.0.0.1', 'HostPort': '33308'}] or data['HostConfig'].get('Privileged') or data['HostConfig'].get('NetworkMode') == 'host' or any(mount.get('Destination') == '/var/lib/mysql' and mount.get('Type') != 'tmpfs' for mount in data.get('Mounts', [])) or '/var/lib/mysql' not in data['HostConfig'].get('Tmpfs', {})): raise ValueError('Exact task-owned pinned loopback disposable container proof required') return {'name': CONTAINER, 'id': data['Id'], 'imageReference': IMAGE, 'imageId': data['Image'], 'project': labels['com.docker.compose.project'], 'service': 'mariadb-test', 'port': 33308, 'bindHost': '127.0.0.1', 'disposableData': 'tmpfs', 'privileged': False} def cases(report): result = [] def walk(suite): for spec in suite.get('specs', []): for test in spec.get('tests', []): result.append(test) for child in suite.get('suites', []): walk(child) for suite in report.get('suites', []): walk(suite) return result def extract_performance(report, process_code): tests = cases(report) attachments = [a for test in tests for run in test.get('results', []) for a in run.get('attachments', []) if a.get('name') == 'p9-requal-01-mariadb-performance'] if len(attachments) != 1: raise ValueError('Expected exactly one performance evidence attachment') attachment = attachments[0] if attachment.get('body'): evidence = json.loads(base64.b64decode(attachment['body'])) elif attachment.get('path'): path = Path(attachment['path']) if not path.is_absolute(): path = UI / path path = path.resolve() if not path.is_relative_to(OUT.resolve()): raise ValueError('Attachment outside task artifacts') evidence = json.loads(path.read_text(encoding='utf-8')) else: raise ValueError('Performance attachment has no body/path') passed = process_code == 0 and len(tests) == 1 and not report.get('errors') and tests[0].get('status') == 'expected' passed = passed and len(tests[0].get('results', [])) == 1 and tests[0]['results'][0].get('status') == 'passed' passed = passed and evidence.get('phase') == 'complete' and evidence.get('actualDurationMs', 0) >= 900000 return {**evidence, 'status': 'PASS' if passed else 'FAIL', 'processExitCode': process_code, 'attachmentName': 'p9-requal-01-mariadb-performance'} def self_check(): schema = 'jt_it_' + 'a' * 32 assert schema_sql(schema, True) == f'DROP DATABASE `{schema}`;' for bad in ('main', 'jt_it_' + 'a' * 31, schema + ';DROP DATABASE main'): try: schema_sql(bad, True) except ValueError: pass else: raise AssertionError('Invalid schema accepted') fixture = {'Name': '/' + CONTAINER, 'Id': 'test', 'Image': 'sha256:test', 'State': {'Running': True}, 'Config': {'Image': IMAGE, 'Labels': {'com.docker.compose.project': 'jobtracker-it-p9-requal', 'com.docker.compose.service': 'mariadb-test'}}, 'NetworkSettings': {'Ports': {'3306/tcp': [{'HostIp': '127.0.0.1', 'HostPort': '33308'}]}}, 'HostConfig': {'Privileged': False, 'NetworkMode': 'bridge', 'Tmpfs': {'/var/lib/mysql': ''}}, 'Mounts': []} assert ownership(fixture)['port'] == 33308 fixture['HostConfig']['NetworkMode'] = 'host' try: ownership(fixture) except ValueError: pass else: raise AssertionError('Host networking accepted') fixture['HostConfig']['NetworkMode'] = 'bridge' fixture['Config']['Image'] = 'mariadb:latest' try: ownership(fixture) except ValueError: pass else: raise AssertionError('Unpinned image accepted') fixture['Config']['Image'] = IMAGE fixture['NetworkSettings']['Ports']['3306/tcp'][0]['HostIp'] = '0.0.0.0' try: ownership(fixture) except ValueError: pass else: raise AssertionError('Public database binding accepted') evidence = {'phase': 'complete', 'actualDurationMs': 900000} result = {'status': 'passed', 'attachments': [{'name': 'p9-requal-01-mariadb-performance', 'body': base64.b64encode(json.dumps(evidence).encode()).decode()}]} report = {'suites': [{'specs': [{'tests': [{'status': 'expected', 'results': [result]}]}]}]} assert extract_performance(report, 0)['status'] == 'PASS' assert extract_performance(report, 1)['status'] == 'FAIL' assert 'jt-integration-only' not in scrub('Server=127.0.0.1;Port=33308;Database=' + schema + ';User ID=root;Password=jt-integration-only;SslMode=None') print('PASS: schema ownership/drop guards, pinned container/network guards, performance extraction/status and redaction; no services touched') def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('mode', choices=list(CONFIGS) + ['self-check']) args = parser.parse_args() if args.mode == 'self-check': self_check(); return 0 lane = args.mode config, expected = CONFIGS[lane] report_path = OUT / (lane + '.json') exit_path = OUT / (lane + '-exit.json') results_path = OUT / (lane + '-results') if any(path.exists() for path in (report_path, exit_path, results_path)) or (lane == 'performance' and (OUT / 'performance/result.json').exists()): raise ValueError('Existing evidence present; archive it explicitly before a new invocation') OUT.mkdir(parents=True, exist_ok=True) env = {**os.environ, 'MYSQL_PWD': 'jt-integration-only', 'DOTNET_ROOT': 'C:/Users/Connor/.dotnet', 'DOTNET_HOST_PATH': 'C:/Users/Connor/.dotnet/dotnet.exe', 'PLAYWRIGHT_STATIC_EXPORT': 'true', 'PLAYWRIGHT_PREBUILT_EXPORT': 'true', 'PLAYWRIGHT_REUSE_SERVERS': 'false', 'PLAYWRIGHT_JSON_OUTPUT_NAME': str(report_path), 'JOBTRACKER_MARIADB_BROWSER_PORT': '33308', 'JOBTRACKER_MARIADB_CLIENT': str(CLIENT), 'NEXT_PUBLIC_API_BASE_URL': 'http://localhost:5302/api', 'SKIP_MODEL_LOAD': '1', 'AI_SERVICE_SKIP_MODEL_LOAD': '1', 'PYTHONIOENCODING': 'utf-8'} schema = 'jt_it_' + uuid.uuid4().hex created = False process = None record = {'lane': lane, 'startedUtc': utc(), 'generatedSchema': schema, 'commands': [], 'exitCode': 1, 'cleanup': {'attempted': False}} started = time.monotonic() def execute(command, name): nonlocal created completed = subprocess.run(['rtk', 'proxy', *command], cwd=ROOT, env=env, capture_output=True, text=True, encoding='utf-8', errors='replace', timeout=30) # Cleanup ownership must survive a diagnostic write failing after successful CREATE. if name == 'create-schema' and completed.returncode == 0: created = True log = OUT / (lane + '-' + name + '.log') log.write_text(scrub(completed.stdout + completed.stderr), encoding='utf-8') record['commands'].append({'operation': name, 'exitCode': completed.returncode, 'log': str(log.relative_to(ROOT))}) if completed.returncode: raise RuntimeError(name + ' failed; inspect sanitized operation log') return completed.stdout.strip() def sql(query, name): return execute([str(CLIENT), '--host=127.0.0.1', '--port=33308', '--user=root', '--batch', '--raw', '--skip-column-names', '--execute=' + query], name) try: for port in (5302, 3300): for family, address in ((socket.AF_INET, '127.0.0.1'), (socket.AF_INET6, '::1')): with socket.socket(family) as probe: probe.settimeout(0.2) if probe.connect_ex((address, port)) == 0: raise ValueError(f'Port {port} occupied; exclusive lane required') # Inspect only this exact task container; full inspection stays in memory, never a report/log. inspected = subprocess.run(['rtk', 'proxy', 'docker', 'inspect', CONTAINER], capture_output=True, text=True, timeout=20) if inspected.returncode: raise ValueError('Task container inspection unavailable') record['ownership'] = ownership(json.loads(inspected.stdout)[0]) version = sql('SELECT VERSION();', 'version') record['serverVersion'] = version if not re.fullmatch(r'12\.2\.2-MariaDB(?:-[A-Za-z0-9.]+)?', version): raise ValueError('Unexpected actual server version') sql(schema_sql(schema), 'create-schema') env['JOBTRACKER_MARIADB_BROWSER_CONNECTION'] = f'Server=127.0.0.1;Port=33308;Database={schema};User ID=root;Password=jt-integration-only;SslMode=None' command = ['node', 'node_modules/@playwright/test/cli.js', 'test', '--config=' + config, '--retries=0', '--reporter=list,json', '--output=' + str(results_path)] record['command'] = command with (OUT / (lane + '.log')).open('w', encoding='utf-8') as log: process = subprocess.Popen(['rtk', 'proxy', *command], cwd=UI, env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, encoding='utf-8', errors='replace') record['processId'] = process.pid for line in process.stdout: log.write(scrub(line)); log.flush() record['exitCode'] = process.wait() report = json.loads(report_path.read_text(encoding='utf-8')) write(report_path, report) tests = cases(report) record['caseCount'] = len(tests) if len(tests) != expected or any(test.get('status') != 'expected' or len(test.get('results', [])) != 1 or test['results'][0].get('status') != 'passed' for test in tests) or report.get('errors'): record['exitCode'] = record['exitCode'] or 1 if lane == 'performance': write(OUT / 'performance/result.json', extract_performance(report, record['exitCode'])) except Exception as error: record['error'] = scrub(type(error).__name__ + ': ' + str(error)) record['exitCode'] = record['exitCode'] or 1 if lane == 'performance' and not (OUT / 'performance/result.json').exists(): write(OUT / 'performance/result.json', {'status': 'FAIL', 'reason': record['error'], 'processExitCode': record['exitCode']}) finally: # Stop only this invocation's process tree before dropping its schema after an interrupted run. if process is not None and process.poll() is None: stopped = subprocess.run(['rtk', 'proxy', 'taskkill', '/PID', str(process.pid), '/T', '/F'], capture_output=True, text=True, timeout=20) record['processTreeStopExitCode'] = stopped.returncode try: process.wait(timeout=20) except subprocess.TimeoutExpired: created = False record['cleanup']['error'] = 'Owned process tree still running; schema retained for operator cleanup' record['exitCode'] = record['exitCode'] or 1 if created: record['cleanup']['attempted'] = True try: sql(schema_sql(schema, True), 'drop-schema') remaining = sql(f"SELECT COUNT(*) FROM information_schema.SCHEMATA WHERE SCHEMA_NAME='{schema}';", 'verify-drop') if remaining != '0': raise ValueError('Generated schema remains after cleanup') record['cleanup'].update(exitCode=0, schemaAbsent=True) except Exception as error: record['cleanup'].update(exitCode=1, error=scrub(str(error))) record['exitCode'] = record['exitCode'] or 1 record.update(finishedUtc=utc(), durationSeconds=time.monotonic() - started, helperSha256=hashlib.sha256(Path(__file__).read_bytes()).hexdigest()) if lane == 'performance' and (OUT / 'performance/result.json').exists(): result = json.loads((OUT / 'performance/result.json').read_text()) if record['exitCode']: result['status'] = 'FAIL' result['cleanup'] = record['cleanup'] write(OUT / 'performance/result.json', result) write(exit_path, record) print(json.dumps({'lane': lane, 'exitCode': record['exitCode'], 'processRecord': str(exit_path)})) return record['exitCode'] if __name__ == '__main__': try: sys.exit(main()) except ValueError as error: raise SystemExit(scrub(str(error)))