"""Check that discarding failed capture releases a real server admission slot. Uses a synthetic microphone, the actual HTTP scheduler and a failing fake engine. No real model, physical recording or external caption relay is used. """ import argparse import json from pathlib import Path import sys import tempfile import threading import urllib.error import urllib.request import wave import numpy as np import uvicorn from playwright.sync_api import sync_playwright from browser_support import browser_options, authenticate from service_test_support import require_free_port ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) from server import create_app def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--output', type=Path, required=True) args = parser.parse_args() require_free_port(8791) args.output.parent.mkdir(parents=True, exist_ok=True) with tempfile.NamedTemporaryFile(suffix='.wav', delete=False) as temporary: fixture = Path(temporary.name) with wave.open(str(fixture), 'wb') as audio: audio.setparams((1, 2, 16000, 0, 'NONE', 'not compressed')) tone = .05 * np.sin(2 * np.pi * 220 * np.arange(96000) / 16000) audio.writeframes((tone * 32767).astype(' failed && !processing && !stopping', timeout=30000) row = {'path': path, 'retained_before_discard': page.evaluate( '() => !!pending && buffer.length > 0'), 'browser_errors': errors} report['pages'].append(row) assert row['retained_before_discard'] assert page.locator('#status').inner_text() == 'Stopped ยท pending audio retained' audio = np.full(16000, .02, dtype=' !failed && !pending && !processing && buffer.length === 0') row['sessions_after_discard'] = request('/health')[1]['sessions'] row['other_producer_after_discard'] = request('/transcribe?language=en', audio)[0] assert row['sessions_after_discard'] == 0, 'Discard left the service admission slot occupied' assert row['other_producer_after_discard'] == 200 assert not errors assert not page.locator('#error').inner_text() assert 'pending audio discarded' in page.locator('#status').inner_text() page.screenshot(path=str(args.output.with_name(f'discard-{slug}-cleared.png')), full_page=True) request('/streams/another-producer', method='DELETE') context.close() browser.close() report['passed'] = True except Exception as error: report['error'] = str(error) raise finally: service.should_exit = True thread.join(timeout=10) fixture.unlink(missing_ok=True) args.output.parent.mkdir(parents=True, exist_ok=True) args.output.write_text(json.dumps(report, indent=2) + '\n', encoding='utf-8', newline='\n') print('Discard releases admission capacity on both capture pages') if __name__ == '__main__': main()