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)
    }))
Esempio n. 2
0
    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)
        ]
Esempio n. 6
0
    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))