10 KiB
Integration Test: SSE Event Streamer
Summary
Validate the Server-Sent Events (SSE) Event Streamer component that provides real-time updates about image processing status and results to connected clients.
Component Under Test
Component: SSE Event Streamer
Location: gps_denied_14_sse_event_streamer
Dependencies:
- REST API (provides SSE endpoint)
- Result Manager (source of events)
- Flight Manager (flight state changes)
- Factor Graph Optimizer (trajectory updates)
Detailed Description
This test validates that the SSE Event Streamer can:
- Establish SSE connections from clients
- Stream events in real-time as images are processed (AC-8)
- Send immediate results as soon as available (AC-8)
- Send refined results when trajectory is re-optimized (AC-8)
- Maintain multiple concurrent client connections
- Handle client disconnections gracefully
- Implement proper SSE protocol (event format, keep-alive)
- Provide event filtering and subscriptions
- Buffer events for slow clients
Per AC-8: "Results of image processing should appear immediately to user, so that user shouldn't wait for the whole route to complete in order to analyze first results. Also, system could refine existing calculated results and send refined results again to user."
Input Data
Test Case 1: Single Client Connection
- Scenario: Client connects to SSE stream for a flight
- Flight: Test_Flight_001 with 10 images
- Expected: Receive events for each image processed
Test Case 2: Multiple Client Connections
- Scenario: 5 clients connect to same flight stream
- Flight: Test_Flight_002 with 10 images
- Expected: All clients receive all events
Test Case 3: Image Processed Event
- Trigger: Image AD000001.jpg completed by vision pipeline
- Expected Event:
{
"event": "image_processed",
"data": {
"flight_id": "flight_123",
"image_id": "AD000001",
"sequence_number": 1,
"estimated_gps": {"lat": 48.275292, "lon": 37.385220},
"confidence": 0.92,
"processing_time_ms": 450,
"timestamp": "2025-11-24T21:00:00Z"
}
}
Test Case 4: Trajectory Refined Event
- Trigger: Factor graph optimizes and refines past trajectory
- Expected Event:
{
"event": "trajectory_refined",
"data": {
"flight_id": "flight_123",
"refined_images": ["AD000001", "AD000002", "AD000003"],
"refinement_reason": "new_gps_anchor",
"timestamp": "2025-11-24T21:00:05Z"
}
}
Test Case 5: User Fix Applied Event
- Trigger: User submits manual GPS fix for image
- Expected Event:
{
"event": "user_fix_applied",
"data": {
"flight_id": "flight_123",
"image_id": "AD000015",
"fixed_gps": {"lat": 48.268291, "lon": 37.369815},
"affected_images": 5,
"timestamp": "2025-11-24T21:00:10Z"
}
}
Test Case 6: Processing Error Event
- Trigger: Image fails to process
- Expected Event:
{
"event": "processing_error",
"data": {
"flight_id": "flight_123",
"image_id": "AD000999",
"error_type": "tracking_lost",
"error_message": "Insufficient features for matching",
"timestamp": "2025-11-24T21:00:15Z"
}
}
Test Case 7: Flight Status Event
- Trigger: Flight processing completes
- Expected Event:
{
"event": "flight_status",
"data": {
"flight_id": "flight_123",
"status": "completed",
"total_images": 60,
"processed_images": 60,
"success_rate": 0.95,
"mean_error_m": 23.5,
"timestamp": "2025-11-24T21:05:00Z"
}
}
Test Case 8: Keep-Alive Heartbeat
- Scenario: No events for 30 seconds
- Expected: Heartbeat/comment sent every 15 seconds to keep connection alive
Test Case 9: Event Ordering
- Scenario: Process 5 images rapidly
- Expected: Events received in correct sequence order
Test Case 10: Client Reconnection
- Scenario: Client disconnects and reconnects
- Expected: Can resume stream, no missed events (if buffered)
Test Case 11: Slow Client
- Scenario: Client with slow network connection
- Expected: Events buffered, connection maintained or gracefully closed
Test Case 12: Event Filtering
- Scenario: Client subscribes only to "image_processed" events
- Expected: Only receives filtered event types
Expected Output
For each test case, verify:
{
"connection_established": true/false,
"events_received": <integer>,
"events_expected": <integer>,
"event_types": ["image_processed", "trajectory_refined", ...],
"latency_ms": <float>,
"connection_duration_s": <float>,
"disconnection_reason": "string|null"
}
Success Criteria
Test Case 1 (Single Client):
- connection_established = true
- events_received = 10 (one per image)
- Average latency < 500ms from event generation to client receipt
- No disconnections
Test Case 2 (Multiple Clients):
- All 5 clients receive all events
- No event loss
- Similar latency across clients
Test Case 3-7 (Event Types):
- All event types received correctly
- JSON format valid and parseable
- All required fields present
- Timestamps reasonable
Test Case 8 (Keep-Alive):
- Heartbeat sent every ~15 seconds
- Connection does not timeout
- No proxy/intermediary closes connection
Test Case 9 (Ordering):
- Events received in order of sequence_number
- No out-of-order delivery
Test Case 10 (Reconnection):
- Reconnection succeeds
- If Last-Event-ID supported, resumes from last event
- Or starts fresh stream
Test Case 11 (Slow Client):
- Buffer grows but doesn't exceed limit
- If limit exceeded, connection closed gracefully
- No server-side memory leak
Test Case 12 (Filtering):
- Only subscribed event types received
- Other events not sent
- Reduces bandwidth usage
Maximum Expected Time
- Connection establishment: < 100ms
- Event latency (generation to receipt): < 500ms
- Heartbeat interval: 15 seconds
- Total test suite: < 300 seconds (includes processing wait times)
Test Execution Steps
-
Setup Phase: a. Start REST API server with SSE support b. Create test flight with sample images c. Prepare SSE test clients
-
Test Case 1 - Single Client: a. Open SSE connection to GET /flights/{flightId}/stream b. Upload 10 images to flight c. Collect all events d. Verify event count and content e. Close connection
-
Test Case 2 - Multiple Clients: a. Open 5 SSE connections to same flight b. Upload 10 images c. Verify all clients receive all events d. Compare events across clients
-
Test Cases 3-7 - Event Types: a. Trigger each type of event b. Verify correct event emitted c. Validate JSON structure d. Check field values
-
Test Case 8 - Keep-Alive: a. Open connection b. Wait 45 seconds without triggering events c. Verify 2-3 heartbeats received d. Check connection still alive
-
Test Case 9 - Ordering: a. Upload 5 images rapidly (< 1 second apart) b. Collect events c. Verify sequence_number ordering d. Check no events skipped
-
Test Case 10 - Reconnection: a. Open connection, receive some events b. Close connection c. Immediately reconnect d. Check if stream resumes or restarts
-
Test Case 11 - Slow Client: a. Simulate slow client (delay reading events) b. Trigger many events rapidly c. Monitor buffer size d. Verify behavior when buffer full
-
Test Case 12 - Filtering: a. Connect with filter parameter: ?events=image_processed b. Trigger multiple event types c. Verify only subscribed events received
Pass/Fail Criteria
Overall Test Passes If:
- All 12 test cases meet their success criteria
- No event loss in normal conditions
- Latency consistently < 500ms
- Multiple clients supported without degradation
- Protocol correctly implemented
- No memory leaks or resource exhaustion
Test Fails If:
- Events lost or duplicated
- Latency exceeds 1 second regularly
- Connections drop unexpectedly
- Invalid SSE format
- Server crashes under load
- Memory leak detected
Additional Validation
SSE Protocol Compliance:
- Content-Type: text/event-stream
- Cache-Control: no-cache
- Connection: keep-alive
- Event format:
event: name\ndata: json\n\n - Support for
id:field for resumption - Support for
retry:field
Event Schema Validation: Define and validate JSON schemas for each event type:
- image_processed
- trajectory_refined
- user_fix_applied
- processing_error
- flight_status
- failure_detected (when system requests user input per AC-6)
Performance Under Load:
- 100 concurrent clients: all receive events
- 1000 events/second: latency < 1 second
- Long-lived connections: stable over 1 hour
Error Scenarios:
- Client closes connection mid-event: no server error
- Client sends data on read-only SSE connection: rejected
- Invalid flight_id: connection refused with 404
- Server restart: clients reconnect automatically
Browser Compatibility (if web client):
- EventSource API works in Chrome, Firefox, Safari
- Automatic reconnection on network loss
- Error event handling
Buffering Strategy:
- Recent events buffered (last 100?)
- Old events discarded
- Configurable buffer size
- Buffer per-client or shared
Event Priority:
- Critical events (errors, user input needed) sent immediately
- Non-critical events (refinements) can be batched
- Priority queue for event delivery
Integration with AC-8: Verify AC-8 requirement:
- Immediate Results: Events sent as soon as image processed (< 1 second delay)
- Refinement Notification: trajectory_refined events sent when optimization updates past results
- Continuous Streaming: User can see first results before route completes
Measure:
- Time from image processing complete to event sent: < 100ms
- Time from event sent to client received: < 500ms
- Total latency: < 1 second (meets AC-8 "immediately")
Monitoring and Metrics
Track and report:
- Active connections count
- Events sent per second
- Average event latency
- Buffer usage (current/max)
- Reconnection rate
- Client disconnection reasons
- Memory usage per connection
- Network bandwidth per connection
Security Considerations
- Authentication: Verify SSE requires auth token
- Authorization: Clients can only subscribe to their own flights
- Rate limiting: Prevent connection flooding
- Input validation: Validate flight_id in URL
- DoS protection: Limit connections per IP/user