Added smoke test
This commit is contained in:
parent
ce012e253c
commit
fd798c98aa
131
tests/test_bot_join_smoke.py
Normal file
131
tests/test_bot_join_smoke.py
Normal file
@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Smoke test: two browser-like peers join a lobby with a bot and should receive addPeer messages.
|
||||
|
||||
This test is intentionally simple and fast. It connects two websocket clients to the
|
||||
server WebSocket endpoint, sets distinct names, joins the same lobby, and asserts
|
||||
that each client receives at least one `addPeer` message (indicating the server
|
||||
attempted to establish WebRTC peers). The bot runs in a separate container; the
|
||||
test only verifies that the server signaled peers to the connected clients.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import ssl
|
||||
import websockets
|
||||
import httpx
|
||||
|
||||
BASE_WS = os.environ.get("AI_VOICEBOT_WS") or "wss://localhost:8000/ai-voicebot/ws/lobby"
|
||||
|
||||
|
||||
def _ssl_ctx_insecure():
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
return ctx
|
||||
|
||||
|
||||
async def simple_client(name, lobby_id, recv_queue):
|
||||
# Create session via HTTP API in same container (server listens on 8000)
|
||||
async with httpx.AsyncClient(verify=False) as client:
|
||||
resp = await client.get("https://localhost:8000/ai-voicebot/api/session")
|
||||
resp.raise_for_status()
|
||||
session_id = resp.json().get("id")
|
||||
|
||||
# Connect to lobby websocket path for this session
|
||||
ws_uri = f"{BASE_WS}/{lobby_id}/{session_id}"
|
||||
ssl_ctx = _ssl_ctx_insecure()
|
||||
async with websockets.connect(ws_uri, ssl=ssl_ctx) as ws:
|
||||
# set name
|
||||
await ws.send(json.dumps({"type": "set_name", "data": {"name": name}}))
|
||||
# consume update_name
|
||||
try:
|
||||
msg = await asyncio.wait_for(ws.recv(), timeout=2)
|
||||
except Exception:
|
||||
return
|
||||
# set name
|
||||
await ws.send(json.dumps({"type": "set_name", "data": {"name": name}}))
|
||||
# consume update_name
|
||||
try:
|
||||
msg = await asyncio.wait_for(ws.recv(), timeout=2)
|
||||
except Exception:
|
||||
return
|
||||
|
||||
# join lobby
|
||||
await ws.send(json.dumps({"type": "join", "data": {}}))
|
||||
|
||||
# read messages for a short window and forward addPeer events
|
||||
end_at = asyncio.get_event_loop().time() + 4
|
||||
while asyncio.get_event_loop().time() < end_at:
|
||||
try:
|
||||
msg = await asyncio.wait_for(ws.recv(), timeout=1)
|
||||
except asyncio.TimeoutError:
|
||||
continue
|
||||
try:
|
||||
parsed = json.loads(msg)
|
||||
except Exception:
|
||||
continue
|
||||
if parsed.get("type") == "addPeer":
|
||||
await recv_queue.put(parsed)
|
||||
|
||||
|
||||
async def run_test():
|
||||
|
||||
# Create two sessions and a lobby using the API
|
||||
async with httpx.AsyncClient(verify=False) as client:
|
||||
r1 = await client.get("https://localhost:8000/ai-voicebot/api/session")
|
||||
r1.raise_for_status()
|
||||
s1 = r1.json().get("id")
|
||||
|
||||
r2 = await client.get("https://localhost:8000/ai-voicebot/api/session")
|
||||
r2.raise_for_status()
|
||||
s2 = r2.json().get("id")
|
||||
|
||||
# Create lobby using session 1
|
||||
lobby_req = {"type": "lobby_create", "data": {"name": "smoke-lobby", "private": False}}
|
||||
r3 = await client.post(f"https://localhost:8000/ai-voicebot/api/lobby/{s1}", json=lobby_req)
|
||||
r3.raise_for_status()
|
||||
lobby_id = r3.json().get("data", {}).get("id")
|
||||
|
||||
recv_q1 = asyncio.Queue()
|
||||
recv_q2 = asyncio.Queue()
|
||||
|
||||
# start two websocket clients tied to the created sessions
|
||||
client1 = asyncio.create_task(simple_client("smoke-1", lobby_id, recv_q1))
|
||||
await asyncio.sleep(0.2)
|
||||
client2 = asyncio.create_task(simple_client("smoke-2", lobby_id, recv_q2))
|
||||
|
||||
await asyncio.wait_for(asyncio.gather(client1, client2), timeout=20)
|
||||
|
||||
got1 = False
|
||||
got2 = False
|
||||
try:
|
||||
while True:
|
||||
_ = recv_q1.get_nowait()
|
||||
got1 = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
while True:
|
||||
_ = recv_q2.get_nowait()
|
||||
got2 = True
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
print(f"Client1 got addPeer={got1}, Client2 got addPeer={got2}")
|
||||
|
||||
return got1 and got2
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ok = False
|
||||
try:
|
||||
ok = asyncio.run(run_test())
|
||||
except Exception as e:
|
||||
print(f"Test failed: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
sys.exit(0 if ok else 2)
|
Loading…
x
Reference in New Issue
Block a user