Ruview/archive/v1/scripts/test_websocket_streaming.py
rUv 81cc241b9e
chore(repo): move v1/ → archive/v1/ + add archive/README.md (#430)
The Rust port at v2/ has been the primary codebase since the rename
in #427. The Python implementation at v1/ is no longer the active
target; the only load-bearing path is the deterministic proof bundle
at v1/data/proof/ (per ADR-011 / ADR-028 witness verification).

Move the whole Python tree into archive/v1/ and document the policy
in archive/README.md: no new features, bug fixes only when they affect
a still-load-bearing path (currently just the proof), CI continues to
verify the proof on every push and PR.

Path references updated in 26 files via path-pattern sed (only
matches v1/<known-child> patterns, never bare v1 or API URLs like
/api/v1/). Two double-prefix typos (archive/archive/v1/) caught and
hand-fixed in verify-pipeline.yml and ADR-011.

Validated:
- Python proof verify.py imports cleanly at archive/v1/data/proof/
  (numpy/scipy still required; CI installs requirements-lock.txt
  from archive/v1/ now)
- cargo test --workspace --no-default-features → 1,539 passed,
  0 failed, 8 ignored (unaffected by Python tree relocation)
- ESP32-S3 on COM7 untouched (no firmware paths changed)

After-merge: contributors should re-run any local `python v1/...`
commands as `python archive/v1/...` (CLAUDE.md and CHANGELOG already
updated).
2026-04-25 23:07:52 -04:00

157 lines
No EOL
5.8 KiB
Python
Executable file

#!/usr/bin/env python3
"""
WebSocket Streaming Test Script
Tests real-time pose data streaming via WebSocket
"""
import asyncio
import json
import websockets
from datetime import datetime
async def test_pose_streaming():
"""Test pose data streaming via WebSocket."""
uri = "ws://localhost:8000/api/v1/stream/pose?zone_ids=zone_1,zone_2&min_confidence=0.3&max_fps=10"
print(f"[{datetime.now()}] Connecting to WebSocket...")
try:
async with websockets.connect(uri) as websocket:
print(f"[{datetime.now()}] Connected successfully!")
# Wait for connection confirmation
response = await websocket.recv()
data = json.loads(response)
print(f"[{datetime.now()}] Connection confirmed:")
print(json.dumps(data, indent=2))
# Send a ping message
ping_msg = {"type": "ping"}
await websocket.send(json.dumps(ping_msg))
print(f"[{datetime.now()}] Sent ping message")
# Listen for messages for 10 seconds
print(f"[{datetime.now()}] Listening for pose updates...")
start_time = asyncio.get_event_loop().time()
message_count = 0
while asyncio.get_event_loop().time() - start_time < 10:
try:
# Wait for message with timeout
message = await asyncio.wait_for(websocket.recv(), timeout=1.0)
data = json.loads(message)
message_count += 1
msg_type = data.get("type", "unknown")
if msg_type == "pose_update":
print(f"[{datetime.now()}] Pose update received:")
print(f" - Frame ID: {data.get('frame_id')}")
print(f" - Persons detected: {len(data.get('persons', []))}")
print(f" - Zone summary: {data.get('zone_summary', {})}")
elif msg_type == "pong":
print(f"[{datetime.now()}] Pong received")
else:
print(f"[{datetime.now()}] Message type '{msg_type}' received")
except asyncio.TimeoutError:
# No message received in timeout period
continue
except Exception as e:
print(f"[{datetime.now()}] Error receiving message: {e}")
print(f"\n[{datetime.now()}] Test completed!")
print(f"Total messages received: {message_count}")
# Send disconnect message
disconnect_msg = {"type": "disconnect"}
await websocket.send(json.dumps(disconnect_msg))
except Exception as e:
print(f"[{datetime.now()}] WebSocket error: {e}")
async def test_event_streaming():
"""Test event streaming via WebSocket."""
uri = "ws://localhost:8000/api/v1/stream/events?event_types=motion,presence&zone_ids=zone_1"
print(f"\n[{datetime.now()}] Testing event streaming...")
print(f"[{datetime.now()}] Connecting to WebSocket...")
try:
async with websockets.connect(uri) as websocket:
print(f"[{datetime.now()}] Connected successfully!")
# Wait for connection confirmation
response = await websocket.recv()
data = json.loads(response)
print(f"[{datetime.now()}] Connection confirmed:")
print(json.dumps(data, indent=2))
# Get status
status_msg = {"type": "get_status"}
await websocket.send(json.dumps(status_msg))
print(f"[{datetime.now()}] Requested status")
# Listen for a few messages
for i in range(5):
try:
message = await asyncio.wait_for(websocket.recv(), timeout=2.0)
data = json.loads(message)
print(f"[{datetime.now()}] Event received: {data.get('type')}")
except asyncio.TimeoutError:
print(f"[{datetime.now()}] No event received (timeout)")
except Exception as e:
print(f"[{datetime.now()}] WebSocket error: {e}")
async def test_websocket_errors():
"""Test WebSocket error handling."""
print(f"\n[{datetime.now()}] Testing error handling...")
# Test invalid endpoint
try:
uri = "ws://localhost:8000/api/v1/stream/invalid"
async with websockets.connect(uri) as websocket:
print("Connected to invalid endpoint (unexpected)")
except Exception as e:
print(f"[{datetime.now()}] Expected error for invalid endpoint: {type(e).__name__}")
# Test sending invalid JSON
try:
uri = "ws://localhost:8000/api/v1/stream/pose"
async with websockets.connect(uri) as websocket:
await websocket.send("invalid json {")
response = await websocket.recv()
data = json.loads(response)
if data.get("type") == "error":
print(f"[{datetime.now()}] Received expected error for invalid JSON")
except Exception as e:
print(f"[{datetime.now()}] Error testing invalid JSON: {e}")
async def main():
"""Run all WebSocket tests."""
print("=" * 60)
print("WiFi-DensePose WebSocket Streaming Tests")
print("=" * 60)
# Test pose streaming
await test_pose_streaming()
# Test event streaming
await test_event_streaming()
# Test error handling
await test_websocket_errors()
print("\n" + "=" * 60)
print("All tests completed!")
print("=" * 60)
if __name__ == "__main__":
asyncio.run(main())