def test_message_serializer_deserialize_completion_response(): # TODO should start with a packed message and use msgpack to unpack, for now start with builtin form: unpacked = { '_message': 'CompletionResponse', 'token': 'thetoken', 'start': 11, 'end': 12, 'limitExceeded': True, 'options': [ {'insert': 'insert', 'desc': 'thedescription', 'semantics': 'string', 'extensionId': 'theExtId'}, {'insert': 'insert2', 'desc': 'thedescription2', 'semantics': 'identifier', 'extensionId': 'theExtId2'} ] } packed = umsgpack.packb(unpacked) # and use serializer without unpacker: serializer = MessageSerializer() msg = serializer.deserialize(packed) expected = CompletionResponse(11, 12, True, [CompletionOption('insert', 'thedescription', semantics=SemanticType.string, extensionId='theExtId'), CompletionOption('insert2', 'thedescription2', semantics=SemanticType.identifier, extensionId='theExtId2')], 'thetoken') # avoid implementation of eq in schema classes, so rely on correct serialization for now: assert serializer.serialize(msg) == serializer.serialize(expected)
def test_regression_009_string_argument_without_encoding(): serialized = b'\x83\xa8_message\xabContentSync\xa4file\xd9!D:\\Work\\jep\\test\\my.requestlogger\xa4data\xa40sdf,smndfsdf M s df jhsdkashdk sjhdjhsjdkakdhsj' serializer = MessageSerializer() serializer.enque_data(serialized) message = next(iter(serializer)) assert isinstance(message, ContentSync)
def test_message_serializer_deserialize_chain(): mock_packer = mock.MagicMock() mock_packer.load = mock.MagicMock(return_value=dict(_message=mock.sentinel.MESSAGE_NAME)) buffer = bytes(b'bytes') with mock.patch('jep_py.protocol.Message.class_by_name', lambda name: Shutdown) as mock_class_by_msgname: serializer = MessageSerializer(mock_packer) assert isinstance(serializer.deserialize(buffer), Shutdown) assert mock_packer.load.called
def test_message_serializer_serialize_chain(): mock_packer = mock.MagicMock() mock_packer.dumps = mock.MagicMock(return_value=mock.sentinel.PACKER_RESULT) serializer = MessageSerializer(mock_packer) # make sure packer is called and its result is returned: assert serializer.serialize(Shutdown()) == mock.sentinel.PACKER_RESULT mock_packer.dumps.assert_called_once_with(dict(_message='Shutdown'))
def test_descode_static_syntax_request(): serialized = b'\x82\xa6format\xa8textmate\xa8_message\xb3StaticSyntaxRequest' serializer = MessageSerializer() serializer.enque_data(serialized) message = next(iter(serializer)) assert isinstance(message, StaticSyntaxRequest)
def test_deserialize_problem_update_ruby_backend(): serialized = b'\x82\xacfileProblems\x91\x82\xa4file\xda\x001C:\\Users\\mthiede\\gitrepos\\jep-ruby\\demo\\test.demo\xa8problems\x91\x83\xa7message\xb5unexpected token kEND\xa8severity\xa5error\xa4line\x04\xa8_message\xadProblemUpdate' serializer = MessageSerializer() serializer.enque_data(serialized) message = next(iter(serializer)) assert isinstance(message, ProblemUpdate) assert message.fileProblems[0].problems[0].severity is Severity.error
def __init__(self, frontend, service_config, listeners, *, serializer=None, provide_async_reader=None): self.frontend = frontend self.service_config = service_config self.listeners = listeners self._state = State.Disconnected self._serializer = serializer or MessageSerializer() self._provide_async_reader = provide_async_reader or AsynchronousFileReader self._process = None self._process_output_reader = None self._socket = None self._state_timer_reset = None self._state_handler = { State.Connecting: self._run_connecting, State.Connected: self._run_connected, State.Disconnecting: self._run_disconnecting, State.Disconnected: self._run_disconnected } #: Does the user expect the connection to be reestablished e.g. after the backend died? self._reconnect_expected = False #: Token used for pending request. self._current_request_token = None #: Message received as response to pending request. self._current_request_response = None
def test_propagate_content_sync(): mock_clientsocket = mock.MagicMock() mock_clientsocket.recv = mock.MagicMock(side_effect=[ MessageSerializer().serialize( ContentSync('/path/to/file', 'new content', 17, 21)), BlockingIOError ]) mock_clientsocket.send = mock.MagicMock() mock_listener = mock.MagicMock() backend = Backend([mock_listener]) mock_content_monitor = mock.MagicMock() mock_content_monitor.synchronize = mock.MagicMock( return_value=SynchronizationResult.Updated) backend.connection[mock_clientsocket] = FrontendConnection( backend, mock_clientsocket, content_monitor=mock_content_monitor) backend._receive(mock_clientsocket) # listeners are called: assert mock_listener.on_content_sync.call_count == 1 mock_content_monitor.synchronize.assert_called_once_with( '/path/to/file', 'new content', 17, 21) assert not mock_clientsocket.send.called arg = mock_listener.on_content_sync.call_args[0][0] assert isinstance(arg, ContentSync) assert arg.file == '/path/to/file' assert arg.data == 'new content' assert arg.start == 17 assert arg.end == 21
def test_propagate_content_sync_out_of_sync(): mock_clientsocket = mock.MagicMock() mock_clientsocket.recv = mock.MagicMock(side_effect=[ MessageSerializer().serialize( ContentSync('/path/to/file', 'new content', 17, 21)), BlockingIOError ]) mock_clientsocket.send = mock.MagicMock() mock_listener = mock.MagicMock() backend = Backend([mock_listener]) mock_content_monitor = mock.MagicMock() mock_content_monitor.synchronize = mock.MagicMock( return_value=SynchronizationResult.OutOfSync) backend.connection[mock_clientsocket] = FrontendConnection( backend, mock_clientsocket, content_monitor=mock_content_monitor) backend._receive(mock_clientsocket) # listeners are called: assert mock_listener.on_content_sync.call_count == 1 mock_content_monitor.synchronize.assert_called_once_with( '/path/to/file', 'new content', 17, 21) assert mock_clientsocket.send.call_count == 1 arg = mock_clientsocket.send.call_args[0][0] assert b'OutOfSync' in arg
def test_message_serializer_enqueue_dequeue(): serializer = MessageSerializer() serializer.enque_data(serializer.serialize(CompletionResponse(1, 2, False, (), 'token'))) serializer.enque_data(serializer.serialize(CompletionResponse(3, 4, True, (), 'token2'))) assert serializer.buffer msg1 = serializer.dequeue_message() msg2 = serializer.dequeue_message() msg3 = serializer.dequeue_message() msg4 = serializer.dequeue_message() assert isinstance(msg1, CompletionResponse) assert msg1.token == 'token' assert msg1.start == 1 assert msg1.end == 2 assert not msg1.limitExceeded assert isinstance(msg2, CompletionResponse) assert msg2.token == 'token2' assert msg2.start == 3 assert msg2.end == 4 assert msg2.limitExceeded assert not msg3 assert not msg4
def test_message_serializer_enqueue_dequeue_incomplete(): serializer = MessageSerializer() packed = serializer.serialize(CompletionResponse(1, 2, False)) assert len(packed) > 1 for b in packed: assert not serializer.dequeue_message() serializer.enque_data([b]) assert isinstance(serializer.dequeue_message(), CompletionResponse) assert not serializer.dequeue_message()
def test_message_serializer_message_iterator(): serializer = MessageSerializer() serializer.enque_data(serializer.serialize(CompletionResponse(1, 2, False))) serializer.enque_data(serializer.serialize(CompletionResponse(3, 4, True))) count = 0 for msg in serializer: assert isinstance(msg, CompletionResponse) count += 1 assert count == 2
def __init__(self, service, sock, *, serializer=None, content_monitor=None): # Backend instance that created this connection. self.service = service # Socket used to talk to frontend. self.sock = sock #: Timestamp of last message received from this frontend (initialized due to accept). self.ts_last_data_received = datetime.datetime.now() #: Serializer used to decode data from frontend. self.serializer = serializer or MessageSerializer() #: Content monitor for synchronized file data sent by connected frontend. self.content_monitor = content_monitor or ContentMonitor()
def __init__(self, listeners=None, *, syntax_fileset=None): #: User message listeners. self.listeners = listeners or [] #: Registry of static syntax definitions. self.syntax_fileset = syntax_fileset or SyntaxFileSet() #: Active sockets, [0] is the server socket. self.sockets = [] #: Current state of backend. self.state = State.Stopped #: Timestamp of last alive message. self.ts_alive_sent = None #: Cache for BackendAlive message in serialized form. self.BACKEND_ALIVE_DATA = MessageSerializer().serialize(BackendAlive()) #: Map of socket to frontend descriptor. self.connection = dict()
def test_frontend_timeout(mock_datetime_mod): now = datetime.datetime.now() mock_datetime_mod.datetime.now = mock.MagicMock(side_effect=lambda: now) mock_clientsocket1 = mock.MagicMock() mock_clientsocket2 = mock.MagicMock() backend = Backend() backend.sockets = [ mock.sentinel.SERVER_SOCKET, mock_clientsocket1, mock_clientsocket2 ] backend.connection[mock_clientsocket1] = FrontendConnection( backend, mock_clientsocket1) backend.connection[mock_clientsocket2] = FrontendConnection( backend, mock_clientsocket2) assert TIMEOUT_LAST_MESSAGE > datetime.timedelta(0) # prevent alive message is mixed into communication: backend.ts_alive_sent = now backend._cyclic() assert not mock_clientsocket1.close.called assert not mock_clientsocket2.close.called now += 0.9 * TIMEOUT_LAST_MESSAGE backend.ts_alive_sent = now backend._cyclic() assert not mock_clientsocket1.close.called assert not mock_clientsocket2.close.called # now receive a message from one frontend: mock_clientsocket1.recv = mock.MagicMock(side_effect=[ MessageSerializer().serialize(CompletionRequest('t', 'g', 10)), BlockingIOError ]) backend._receive(mock_clientsocket1) now += 0.2 * TIMEOUT_LAST_MESSAGE backend.ts_alive_sent = now backend._cyclic() assert not mock_clientsocket1.close.called assert mock_clientsocket2.close.called now += TIMEOUT_LAST_MESSAGE backend.ts_alive_sent = now backend._cyclic() assert mock_clientsocket1.close.called
def test_message_context(): mock_clientsocket = mock.MagicMock() mock_clientsocket.recv = mock.MagicMock(side_effect=[ MessageSerializer().serialize(Shutdown()), BlockingIOError ]) mock_listener = mock.MagicMock() backend = Backend([mock_listener]) backend.connection[mock_clientsocket] = FrontendConnection( backend, mock_clientsocket) backend._receive(mock_clientsocket) message_context = mock_listener.on_shutdown.call_args[0][0] assert message_context.service is backend assert message_context.sock is mock_clientsocket message_context.send_message(BackendAlive()) assert mock_clientsocket.send.call_count == 1
def test_receive_shutdown(): mock_clientsocket = mock.MagicMock() mock_clientsocket.recv = mock.MagicMock(side_effect=[ MessageSerializer().serialize(Shutdown()), BlockingIOError ]) mock_listener1 = mock.MagicMock() mock_listener2 = mock.MagicMock() backend = Backend([mock_listener1, mock_listener2]) backend.connection[mock_clientsocket] = FrontendConnection( backend, mock_clientsocket) assert backend.state is not State.ShutdownPending backend._receive(mock_clientsocket) # listeners are called: assert mock_listener1.on_shutdown.call_count == 1 assert mock_listener2.on_shutdown.call_count == 1 # backend reacted to shutdown: assert backend.state is State.ShutdownPending
import socket import time from jep_py.protocol import MessageSerializer from jep_py.schema import Shutdown clientsocket = socket.create_connection(('localhost', 9001)) time.sleep(3) print(clientsocket.recv(10000)) clientsocket.send(MessageSerializer().serialize(Shutdown())) time.sleep(3) clientsocket.shutdown(socket.SHUT_RDWR) clientsocket.close()
def observable_serializer(): """Provides message serializer to test with msgpack installed via observable mocks.""" mock_packer = mock.MagicMock() mock_packer.loads = mock.MagicMock(side_effect=lambda bindata: umsgpack.loads(bindata)) mock_packer.dumps = mock.MagicMock(side_effect=lambda pydict: umsgpack.dumps(pydict)) return MessageSerializer(mock_packer)