Esempio n. 1
0
def test_backend_connection_connect_connection_exception(
    mock_os_module, mock_datetime_module, mock_socket_module, mock_subprocess_module
):
    now = datetime.datetime.now()
    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now
    )

    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config,
        [],
        serializer=mock.sentinel.SERIALIZER,
        provide_async_reader=mock_provide_async_reader,
    )
    connection.connect()

    # run state methods during "connected":
    mock_async_reader.queue_.put("This is the JEP service, listening on port 4711.")

    assert TIMEOUT_BACKEND_STARTUP > datetime.timedelta(seconds=0)
    decorate_connection_state_dispatch(connection, 1, mock_datetime_module)

    # fail connection return value:
    mock_socket_module.create_connection = mock.MagicMock(side_effect=NotImplementedError)

    # nothing happens within allowed timeout period:
    connection.run(datetime.timedelta(seconds=2))
    assert connection.state is State.Disconnected

    assert mock_process.kill.call_count == 1
    assert mock_async_reader.join.call_count == 1
    assert not connection._process
    assert not connection._process_output_reader
Esempio n. 2
0
def test_backend_connection_send_message_send_failed():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(return_value=mock.sentinel.SERIALIZED)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock(NotImplementedError)

    connection = BackendConnection(mock.sentinel.FRONTEND, mock.sentinel.SERVICE_CONFIG, [], serializer=mock_serializer)
    connection._socket = mock_socket
    connection.state = State.Connected

    # no message is sent if serialization fails, but no exception surfaces either:
    connection.send_message(mock.sentinel.MESSAGE)
Esempio n. 3
0
def test_backend_connection_send_message_serialization_failed():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(side_effect=NotImplementedError)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock()

    connection = BackendConnection(mock.sentinel.FRONTEND, mock.sentinel.SERVICE_CONFIG, [], serializer=mock_serializer)
    connection._socket = mock_socket
    connection.state = State.Connected

    # no message is sent if serialization fails:
    connection.send_message(mock.sentinel.MESSAGE)
    assert not mock_socket.send.called
Esempio n. 4
0
def test_backend_connection_connect_no_port_announcement(
        mock_os_module, mock_datetime_module, mock_socket_module,
        mock_subprocess_module):
    now = datetime.datetime.now()
    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now)

    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config, [],
        serializer=mock.sentinel.SERIALIZER,
        provide_async_reader=mock_provide_async_reader)
    connection.connect()

    # run state methods during "connected":
    mock_async_reader.queue_.put('Nothing special to say.')
    mock_async_reader.queue_.put('No port announcement whatsoever.')

    assert TIMEOUT_BACKEND_STARTUP > datetime.timedelta(seconds=0)
    decorate_connection_state_dispatch(connection, 1, mock_datetime_module)

    # nothing happens within allowed timeout period:
    connection.run(TIMEOUT_BACKEND_STARTUP)
    assert connection.state is State.Connecting

    # rollback of connection after timeout has expired:
    connection.run(datetime.timedelta(seconds=2))
    assert connection.state is State.Disconnected

    assert mock_process.kill.call_count == 1
    assert mock_async_reader.join.call_count == 1
    assert not connection._process
    assert not connection._process_output_reader
Esempio n. 5
0
def test_backend_connection_send_message_wrong_state():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(return_value=mock.sentinel.SERIALIZED)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock()

    connection = BackendConnection(mock.sentinel.FRONTEND, mock.sentinel.SERVICE_CONFIG, [], serializer=mock_serializer)
    connection._socket = mock_socket

    # no message is sent in any state that is not connected:
    for state in {State.Disconnected, State.Connecting, State.Disconnecting}:
        connection.state = state
        connection.send_message(mock.sentinel.MESSAGE)
        assert not mock_serializer.serialize.called
        assert not mock_socket.send.called
Esempio n. 6
0
def test_backend_connection_send_message_ok():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(return_value=mock.sentinel.SERIALIZED)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock()

    connection = BackendConnection(mock.sentinel.FRONTEND, mock.sentinel.SERVICE_CONFIG, [], serializer=mock_serializer)
    connection._socket = mock_socket
    connection.state = State.Connected

    # we have a socket and are connected, so sending the message must go through just fine:
    connection.send_message(mock.sentinel.MESSAGE)

    mock_serializer.serialize.assert_called_once_with(mock.sentinel.MESSAGE)
    mock_socket.send.assert_called_once_with(mock.sentinel.SERIALIZED)
Esempio n. 7
0
def test_backend_connection_connect(mock_os_module, mock_datetime_module,
                                    mock_socket_module,
                                    mock_subprocess_module):
    now = datetime.datetime.now()

    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now)
    # reset to unpatched module:
    mock_os_module.path = path

    mock_listener = mock.MagicMock()
    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config, [mock_listener],
        serializer=mock.sentinel.SERIALIZER,
        provide_async_reader=mock_provide_async_reader)
    connection.connect()

    # process and reader thread were started and state is adapted:
    assert mock_subprocess_module.Popen.call_args[0][0][
        0] == 'folder/somecommand.ext'
    assert mock_subprocess_module.Popen.call_args[1]['cwd'] == path.abspath(
        'somedir')
    assert mock_async_reader.start.call_count == 1
    assert connection.state is State.Connecting
    assert connection._process is mock_process

    # no more actions if called again:
    mock_subprocess_module.Popen.reset_mock()
    mock_provide_async_reader.reset_mock()
    connection.connect()
    assert not mock_subprocess_module.Popen.called
    assert not mock_provide_async_reader.called
    assert connection._process is mock_process

    # run state methods during "connected":
    mock_async_reader.queue_.put('Nothing special to say.')
    mock_async_reader.queue_.put(
        'This is the JEP service, listening on port 4711. Yes really!')

    # single step as allowed duration is less than time spent in call:
    decorate_connection_state_dispatch(connection, 0.6, mock_datetime_module)
    connection.run(datetime.timedelta(seconds=0.5))

    # connection must have been created to port announced before:
    assert mock_socket_module.create_connection.called
    assert mock_socket_module.create_connection.call_args[0][0] == (
        'localhost', 4711)
    assert connection.state is State.Connected

    mock_listener.on_connection_state_changed.assert_has_calls([
        mock.call(State.Disconnected, State.Connecting, connection),
        mock.call(State.Connecting, State.Connected, connection)
    ])
Esempio n. 8
0
def test_backend_connection_connect_connection_exception(
        mock_os_module, mock_datetime_module, mock_socket_module,
        mock_subprocess_module):
    now = datetime.datetime.now()
    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now)

    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config, [],
        serializer=mock.sentinel.SERIALIZER,
        provide_async_reader=mock_provide_async_reader)
    connection.connect()

    # run state methods during "connected":
    mock_async_reader.queue_.put(
        'This is the JEP service, listening on port 4711.')

    assert TIMEOUT_BACKEND_STARTUP > datetime.timedelta(seconds=0)
    decorate_connection_state_dispatch(connection, 1, mock_datetime_module)

    # fail connection return value:
    mock_socket_module.create_connection = mock.MagicMock(
        side_effect=NotImplementedError)

    # nothing happens within allowed timeout period:
    connection.run(datetime.timedelta(seconds=2))
    assert connection.state is State.Disconnected

    assert mock_process.kill.call_count == 1
    assert mock_async_reader.join.call_count == 1
    assert not connection._process
    assert not connection._process_output_reader
Esempio n. 9
0
def prepare_connected_mocks(mock_datetime_module, mock_socket_module, mock_subprocess_module):
    now = datetime.datetime.now()
    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now
    )
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(return_value=mock.sentinel.SERIALIZED_SHUTDOWN)
    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config,
        [],
        serializer=mock_serializer,
        provide_async_reader=mock_provide_async_reader,
    )
    connection.connect()
    mock_async_reader.queue_.put("This is the JEP service, listening on port 4711")
    mock_socket = mock.MagicMock()
    mock_socket_module.create_connection.return_value = mock_socket
    decorate_connection_state_dispatch(connection, 0.5, mock_datetime_module)
    connection.run(datetime.timedelta(seconds=0.4))
    assert connection.state is State.Connected
    return connection, mock_process, mock_serializer, mock_socket
Esempio n. 10
0
def test_backend_connection_connect(mock_os_module, mock_datetime_module, mock_socket_module, mock_subprocess_module):
    now = datetime.datetime.now()

    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now
    )
    # reset to unpatched module:
    mock_os_module.path = path

    mock_listener = mock.MagicMock()
    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config,
        [mock_listener],
        serializer=mock.sentinel.SERIALIZER,
        provide_async_reader=mock_provide_async_reader,
    )
    connection.connect()

    # process and reader thread were started and state is adapted:
    assert mock_subprocess_module.Popen.call_args[0][0][0] == "folder/somecommand.ext"
    assert mock_subprocess_module.Popen.call_args[1]["cwd"] == path.abspath("somedir")
    assert mock_async_reader.start.call_count == 1
    assert connection.state is State.Connecting
    assert connection._process is mock_process

    # no more actions if called again:
    mock_subprocess_module.Popen.reset_mock()
    mock_provide_async_reader.reset_mock()
    connection.connect()
    assert not mock_subprocess_module.Popen.called
    assert not mock_provide_async_reader.called
    assert connection._process is mock_process

    # run state methods during "connected":
    mock_async_reader.queue_.put("Nothing special to say.")
    mock_async_reader.queue_.put("This is the JEP service, listening on port 4711. Yes really!")

    # single step as allowed duration is less than time spent in call:
    decorate_connection_state_dispatch(connection, 0.6, mock_datetime_module)
    connection.run(datetime.timedelta(seconds=0.5))

    # connection must have been created to port announced before:
    assert mock_socket_module.create_connection.called
    assert mock_socket_module.create_connection.call_args[0][0] == ("localhost", 4711)
    assert connection.state is State.Connected

    mock_listener.on_connection_state_changed.assert_has_calls(
        [
            mock.call(State.Disconnected, State.Connecting, connection),
            mock.call(State.Connecting, State.Connected, connection),
        ]
    )
Esempio n. 11
0
def test_backend_connection_send_message_send_failed():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(
        return_value=mock.sentinel.SERIALIZED)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock(NotImplementedError)

    connection = BackendConnection(mock.sentinel.FRONTEND,
                                   mock.sentinel.SERVICE_CONFIG, [],
                                   serializer=mock_serializer)
    connection._socket = mock_socket
    connection.state = State.Connected

    # no message is sent if serialization fails, but no exception surfaces either:
    connection.send_message(mock.sentinel.MESSAGE)
Esempio n. 12
0
def test_backend_connection_send_message_serialization_failed():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(side_effect=NotImplementedError)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock()

    connection = BackendConnection(mock.sentinel.FRONTEND,
                                   mock.sentinel.SERVICE_CONFIG, [],
                                   serializer=mock_serializer)
    connection._socket = mock_socket
    connection.state = State.Connected

    # no message is sent if serialization fails:
    connection.send_message(mock.sentinel.MESSAGE)
    assert not mock_socket.send.called
Esempio n. 13
0
def test_backend_connection_send_message_wrong_state():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(
        return_value=mock.sentinel.SERIALIZED)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock()

    connection = BackendConnection(mock.sentinel.FRONTEND,
                                   mock.sentinel.SERVICE_CONFIG, [],
                                   serializer=mock_serializer)
    connection._socket = mock_socket

    # no message is sent in any state that is not connected:
    for state in {State.Disconnected, State.Connecting, State.Disconnecting}:
        connection.state = state
        connection.send_message(mock.sentinel.MESSAGE)
        assert not mock_serializer.serialize.called
        assert not mock_socket.send.called
Esempio n. 14
0
def test_backend_connection_send_message_ok():
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(
        return_value=mock.sentinel.SERIALIZED)
    mock_socket = mock.MagicMock()
    mock_socket.send = mock.MagicMock()

    connection = BackendConnection(mock.sentinel.FRONTEND,
                                   mock.sentinel.SERVICE_CONFIG, [],
                                   serializer=mock_serializer)
    connection._socket = mock_socket
    connection.state = State.Connected

    # we have a socket and are connected, so sending the message must go through just fine:
    connection.send_message(mock.sentinel.MESSAGE)

    mock_serializer.serialize.assert_called_once_with(mock.sentinel.MESSAGE)
    mock_socket.send.assert_called_once_with(mock.sentinel.SERIALIZED)
Esempio n. 15
0
def test_backend_connection_connect_no_port_announcement(
    mock_os_module, mock_datetime_module, mock_socket_module, mock_subprocess_module
):
    now = datetime.datetime.now()
    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now
    )

    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config,
        [],
        serializer=mock.sentinel.SERIALIZER,
        provide_async_reader=mock_provide_async_reader,
    )
    connection.connect()

    # run state methods during "connected":
    mock_async_reader.queue_.put("Nothing special to say.")
    mock_async_reader.queue_.put("No port announcement whatsoever.")

    assert TIMEOUT_BACKEND_STARTUP > datetime.timedelta(seconds=0)
    decorate_connection_state_dispatch(connection, 1, mock_datetime_module)

    # nothing happens within allowed timeout period:
    connection.run(TIMEOUT_BACKEND_STARTUP)
    assert connection.state is State.Connecting

    # rollback of connection after timeout has expired:
    connection.run(datetime.timedelta(seconds=2))
    assert connection.state is State.Disconnected

    assert mock_process.kill.call_count == 1
    assert mock_async_reader.join.call_count == 1
    assert not connection._process
    assert not connection._process_output_reader
Esempio n. 16
0
def prepare_connected_mocks(mock_datetime_module, mock_socket_module,
                            mock_subprocess_module):
    now = datetime.datetime.now()
    mock_async_reader, mock_process, mock_provide_async_reader, mock_service_config = prepare_connecting_mocks(
        mock_datetime_module, mock_socket_module, mock_subprocess_module, now)
    mock_serializer = mock.MagicMock()
    mock_serializer.serialize = mock.MagicMock(
        return_value=mock.sentinel.SERIALIZED_SHUTDOWN)
    connection = BackendConnection(
        mock.sentinel.FRONTEND,
        mock_service_config, [],
        serializer=mock_serializer,
        provide_async_reader=mock_provide_async_reader)
    connection.connect()
    mock_async_reader.queue_.put(
        'This is the JEP service, listening on port 4711')
    mock_socket = mock.MagicMock()
    mock_socket_module.create_connection.return_value = mock_socket
    decorate_connection_state_dispatch(connection, 0.5, mock_datetime_module)
    connection.run(datetime.timedelta(seconds=0.4))
    assert connection.state is State.Connected
    return connection, mock_process, mock_serializer, mock_socket
Esempio n. 17
0
def test_backend_connection_request_message_no_token_attribute():
    connection = BackendConnection(mock.sentinel.FRONTEND, mock.sentinel.SERVICE_CONFIG, [])
    connection.state = State.Connected
    with pytest.raises(AttributeError):
        connection.request_message(Shutdown(), mock.sentinel.DURATION)
Esempio n. 18
0
def test_backend_connection_request_message_no_token_attribute():
    connection = BackendConnection(mock.sentinel.FRONTEND,
                                   mock.sentinel.SERVICE_CONFIG, [])
    connection.state = State.Connected
    with pytest.raises(AttributeError):
        connection.request_message(Shutdown(), mock.sentinel.DURATION)
Esempio n. 19
0
def test_backend_connection_initial_state():
    connection = BackendConnection(mock.sentinel.FRONTEND,
                                   mock.sentinel.SERVICE_CONFIG,
                                   mock.sentinel.LISTENERS)
    assert connection.state is State.Disconnected