def make_message(channel, data): return SSEEvent('123', 'message', None, json.dumps({ 'id':'ZlalwoKlXW:0:0', 'timestamp':1591996755043, 'encoding':'json', 'channel': channel, 'data': json.dumps(data) }))
def test_sse_client_disconnects(self): """Test correct initialization. Client ends the connection.""" server = SSEMockServer() server.start() events = [] def callback(event): """Callback.""" events.append(event) client = SSEClient(callback) def runner(): """SSE client runner thread.""" assert client.start('http://127.0.0.1:' + str(server.port())) client_task = threading.Thread(target=runner) client_task.setDaemon(True) client_task.setName('client') client_task.start() with pytest.raises(RuntimeError): client_task.start() server.publish({'id': '1'}) server.publish({'id': '2', 'event': 'message', 'data': 'abc'}) server.publish({'id': '3', 'event': 'message', 'data': 'def'}) server.publish({'id': '4', 'event': 'message', 'data': 'ghi'}) time.sleep(1) client.shutdown() time.sleep(1) assert events == [ SSEEvent('1', None, None, None), SSEEvent('2', 'message', None, 'abc'), SSEEvent('3', 'message', None, 'def'), SSEEvent('4', 'message', None, 'ghi') ] assert client._conn is None server.publish(server.GRACEFUL_REQUEST_END) server.stop()
def test_segment_change(self, mocker): """Test update-type messages are properly forwarded to the processor.""" sse_event = SSEEvent('1', EventType.MESSAGE, '', '{}') update_message = SegmentChangeUpdate('chan', 123, 456, 'some_segment') parse_event_mock = mocker.Mock(spec=parse_incoming_event) parse_event_mock.return_value = update_message mocker.patch('splitio.push.manager.parse_incoming_event', new=parse_event_mock) processor_mock = mocker.Mock(spec=MessageProcessor) mocker.patch('splitio.push.manager.MessageProcessor', new=processor_mock) manager = PushManager(mocker.Mock(), mocker.Mock(), mocker.Mock()) manager._event_handler(sse_event) assert parse_event_mock.mock_calls == [mocker.call(sse_event)] assert processor_mock.mock_calls == [ mocker.call(Any()), mocker.call().handle(update_message) ]
def test_occupancy_message(self, mocker): """Test control mesage is forwarded to status tracker.""" sse_event = SSEEvent('1', EventType.MESSAGE, '', '{}') occupancy_message = OccupancyMessage( '[?occupancy=metrics.publishers]control_pri', 123, 2) parse_event_mock = mocker.Mock(spec=parse_incoming_event) parse_event_mock.return_value = occupancy_message mocker.patch('splitio.push.manager.parse_incoming_event', new=parse_event_mock) status_tracker_mock = mocker.Mock(spec=PushStatusTracker) mocker.patch('splitio.push.manager.PushStatusTracker', new=status_tracker_mock) manager = PushManager(mocker.Mock(), mocker.Mock(), mocker.Mock()) manager._event_handler(sse_event) assert parse_event_mock.mock_calls == [mocker.call(sse_event)] assert status_tracker_mock.mock_calls == [ mocker.call(), mocker.call().handle_occupancy(occupancy_message) ]
def test_control_message(self, mocker): """Test control mesage is forwarded to status tracker.""" sse_event = SSEEvent('1', EventType.MESSAGE, '', '{}') control_message = ControlMessage('chan', 123, ControlType.STREAMING_ENABLED) parse_event_mock = mocker.Mock(spec=parse_incoming_event) parse_event_mock.return_value = control_message mocker.patch('splitio.push.manager.parse_incoming_event', new=parse_event_mock) status_tracker_mock = mocker.Mock(spec=PushStatusTracker) mocker.patch('splitio.push.manager.PushStatusTracker', new=status_tracker_mock) manager = PushManager(mocker.Mock(), mocker.Mock(), mocker.Mock()) manager._event_handler(sse_event) assert parse_event_mock.mock_calls == [mocker.call(sse_event)] assert status_tracker_mock.mock_calls == [ mocker.call(), mocker.call().handle_control_message(control_message) ]
def test_split_sse_success(self): """Test correct initialization. Client ends the connection.""" events = [] def handler(event): """Handler.""" events.append(event) status = { 'on_connect': False, 'on_disconnect': False, } def on_connect(): """On connect handler.""" status['on_connect'] = True def on_disconnect(): """On disconnect handler.""" status['on_disconnect'] = True request_queue = Queue() server = SSEMockServer(request_queue) server.start() client = SplitSSEClient(handler, SdkMetadata('1.0', 'some', '1.2.3.4'), on_connect, on_disconnect, 'abcd', base_url='http://localhost:' + str(server.port())) token = Token( True, 'some', { 'chan1': ['subscribe'], 'chan2': ['subscribe', 'channel-metadata:publishers'] }, 1, 2) server.publish({'id': '1'}) # send a non-error event early to unblock start assert client.start(token) with pytest.raises(Exception): client.start(token) server.publish({ 'id': '1', 'data': 'a', 'retry': '1', 'event': 'message' }) server.publish({ 'id': '2', 'data': 'a', 'retry': '1', 'event': 'message' }) time.sleep(1) client.stop(True) request = request_queue.get(1) assert request.path == '/event-stream?v=1.1&accessToken=some&channels=chan1,[?occupancy=metrics.publishers]chan2' assert request.headers['accept'] == 'text/event-stream' assert request.headers['SplitSDKVersion'] == '1.0' assert request.headers['SplitSDKMachineIP'] == '1.2.3.4' assert request.headers['SplitSDKMachineName'] == 'some' assert request.headers['SplitSDKClientKey'] == 'abcd' assert events == [ SSEEvent('1', 'message', '1', 'a'), SSEEvent('2', 'message', '1', 'a') ] server.publish(SSEMockServer.VIOLENT_REQUEST_END) server.stop() assert status['on_connect'] assert status['on_disconnect']
def make_error(payload): return SSEEvent('123', 'error', None, json.dumps(payload))