"""Verify a deployed server with two isolated clients: python smoke_commands.py --url wss://host/ws.""" import argparse import json import ssl import time import certifi from websockets.sync.client import connect def verify_commands(url): options = {'ssl': ssl.create_default_context(cafile=certifi.where())} if url.startswith('wss:') else {} def send(ws, **message): ws.send(json.dumps(message)) def receive(ws, kind): deadline = time.monotonic() + 8 while True: message = json.loads(ws.recv(timeout=max(.01, deadline - time.monotonic()))) if message['type'] in ('error', 'reaction_error'): raise RuntimeError(message.get('message')) if message['type'] == kind: return message with connect(url, **options) as host, connect(url, **options) as guest: file_info = {'name': 'command-smoke-test.mkv', 'size': 1234, 'duration': 60} send(host, type='create_room', username='CommandSmokeHost', fileInfo=file_info) code = receive(host, 'room_created')['code'] send(guest, type='join_room', username='CommandSmokeGuest', code=code) receive(guest, 'room_file_check') send(guest, type='confirm_join', fileInfo=file_info) receive(guest, 'room_joined') receive(host, 'user_joined') send(host, type='ready_check', action='begin') check = receive(host, 'ready_check') assert check['active'] and receive(guest, 'ready_check')['id'] == check['id'] for ws in (host, guest): send(ws, type='ready_check', action='vote', id=check['id'], ready=True) for peer in (host, guest): receive(peer, 'ready_check') send(host, type='ready_check', action='start', id=check['id']) for peer in (host, guest): assert receive(peer, 'sync')['action'] == 'play' assert not receive(peer, 'ready_check')['active'] print('PASS /ready: shared panel state, votes, synchronized start', flush=True) for i, kind in enumerate(('ko', 'bell', 'tap', 'robbery')): if i: time.sleep(3.2) send(host, type='reaction', kind=kind) for peer in (host, guest): assert receive(peer, 'reaction')['kind'] == kind assert receive(peer, 'chat')['message'] == '🥊 /' + kind print(f'PASS /{kind}: delivered to both clients', flush=True) poll = receive(host, 'fight_poll') assert receive(guest, 'fight_poll')['id'] == poll['id'] send(guest, type='fight_poll_vote', id=poll['id'], choice='yes') for peer in (host, guest): assert receive(peer, 'fight_poll')['votes']['CommandSmokeGuest'] == 'yes' send(host, type='request_state') assert receive(host, 'state')['state']['playing'] print('PASS /robbery vote and uninterrupted playback', flush=True) if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--url', required=True) verify_commands(parser.parse_args().url)