Skip to content

Commit

Permalink
fix: hanging ci and rework mp aux and proxy pytest
Browse files Browse the repository at this point in the history
  • Loading branch information
BKaDamien authored and Pog3k committed Aug 1, 2022
1 parent 21fa403 commit 40de2ad
Show file tree
Hide file tree
Showing 5 changed files with 322 additions and 112 deletions.
3 changes: 1 addition & 2 deletions src/pykiso/interfaces/mp_auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def delete_instance(self) -> bool:
:return: verdict on instance deletion, False if everything was
fine otherwise True(instance was not deleted correctly)
"""
if self.lock.acquire() and self.is_alive:
if self.lock.acquire() and self.is_alive():
# Trigger the internal requests
self.queue_in.put("delete_auxiliary_instance")
# Wait until the request was processed
Expand Down Expand Up @@ -173,7 +173,6 @@ def run(self) -> None:
self.logger.warning(
f"Unknown request '{request}', will not be processed!"
)
self.logger.warning(f"Aux status: {self.__dict__}")

# Step 2: Check if something was received from the aux instance if instance was created
if self.is_instance:
Expand Down
3 changes: 0 additions & 3 deletions src/pykiso/lib/auxiliaries/mp_proxy_auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,6 @@ def _dispatch_command(self, con_use: CChannel, **kwargs: dict):

def _abort_command(self) -> None:
"""Not Used."""
return True

def _receive_message(self, timeout_in_s: float = 0) -> None:
"""When no request are sent this method is called by
Expand Down Expand Up @@ -327,8 +326,6 @@ def run(self) -> None:
self.logger.warning(
f"Unknown request '{request}', will not be processed!"
)
self.logger.warning(f"Aux status: {self.__dict__}")

# Step 2: Send stack command and propagate them to others
# connected auxiliaires and check if something was received
# if instance was created
Expand Down
2 changes: 1 addition & 1 deletion src/pykiso/lib/connectors/cc_socket_can/cc_socket_can.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import platform
import time
from pathlib import Path
from typing import Union, Dict
from typing import Dict, Union

import can
import can.bus
Expand Down
260 changes: 190 additions & 70 deletions tests/test_mp_auxiliary.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,104 +11,224 @@

import pytest

from pykiso.interfaces.mp_auxiliary import MpAuxiliaryInterface
from pykiso.interfaces.mp_auxiliary import (
AuxiliaryCreationError,
MpAuxiliaryInterface,
)


@pytest.fixture
def MpAuxiliaryInterface_constructor(mocker):
class MpAuxinterface(MpAuxiliaryInterface):
def mp_inst(mocker):
class ConcreteMpAux(MpAuxiliaryInterface):
def __init__(self):
super().__init__(name="mp_aux")

_create_auxiliary_instance = mocker.stub(name="_create_auxiliary_instance")
_create_auxiliary_instance.return_value = True
_delete_auxiliary_instance = mocker.stub(name="_delete_auxiliary_instance")
_delete_auxiliary_instance.return_value = True
_run_command = mocker.stub(name="_run_command")
_abort_command = mocker.stub(name="_abort_command")
_abort_command.return_value = "Test"
_receive_message = mocker.stub(name="_receive_message")
_receive_message.return_value = "Test"

return MpAuxinterface()
return ConcreteMpAux()


def test_create_instance(mocker, MpAuxiliaryInterface_constructor):
mock_get = mocker.patch.object(MpAuxiliaryInterface_constructor.queue_out, "get")
mock_get.return_value = True
def test_create_instance(mocker, mp_inst):
mock_put = mocker.patch.object(mp_inst.queue_in, "put")
mock_get = mocker.patch.object(mp_inst.queue_out, "get", return_value=True)

result_create_inst = MpAuxiliaryInterface_constructor.create_instance()
assert result_create_inst is True
assert MpAuxiliaryInterface_constructor.is_instance is True
assert (
MpAuxiliaryInterface_constructor.queue_in.get() == "create_auxiliary_instance"
)
mock_get.assert_called()
state = mp_inst.create_instance()

mock_put.assert_called_with("create_auxiliary_instance")
mock_get.assert_called_once()
assert state is True

def test_delete_instance(mocker, MpAuxiliaryInterface_constructor):
mock_get = mocker.patch.object(MpAuxiliaryInterface_constructor.queue_out, "get")
mock_get.return_value = True

result_create_inst = MpAuxiliaryInterface_constructor.delete_instance()
assert result_create_inst is True
assert MpAuxiliaryInterface_constructor.is_instance is True
assert (
MpAuxiliaryInterface_constructor.queue_in.get() == "delete_auxiliary_instance"
)
mock_get.assert_called()
def test_create_instance_error(mocker, mp_inst):
mock_put = mocker.patch.object(mp_inst.queue_in, "put")
mock_get = mocker.patch.object(mp_inst.queue_out, "get", return_value=False)

with pytest.raises(AuxiliaryCreationError):
mp_inst.create_instance()

def test_initialize_logger(mocker, MpAuxiliaryInterface_constructor):
assert MpAuxiliaryInterface_constructor.logger is None
MpAuxiliaryInterface_constructor.initialize_loggers()
assert isinstance(MpAuxiliaryInterface_constructor.logger, logging.Logger)
assert MpAuxiliaryInterface_constructor.logger.level == logging.DEBUG

def test_delete_instance(mocker, mp_inst):
mock_alive = mocker.patch.object(mp_inst, "is_alive", return_value=True)
mock_put = mocker.patch.object(mp_inst.queue_in, "put")
mock_get = mocker.patch.object(mp_inst.queue_out, "get", return_value=True)

@pytest.mark.parametrize(
"is_instance, request_value",
[
(False, "create_auxiliary_instance"),
(True, "delete_auxiliary_instance"),
(True, ("command", "test", "test2")),
(True, "abort"),
(True, "Test"),
],
)
def test_run(
mocker,
MpAuxiliaryInterface_constructor,
is_instance,
request_value,
caplog,
):
spy_logger = mocker.patch.object(
MpAuxiliaryInterface_constructor, "initialize_loggers"
state = mp_inst.delete_instance()

mock_put.assert_called_with("delete_auxiliary_instance")
mock_get.assert_called_once()
mock_alive.assert_called_once()
assert mp_inst.is_instance is True
assert state is True


def test_delete_instance_fail(mocker, mp_inst):
mock_alive = mocker.patch.object(mp_inst, "is_alive", return_value=True)
mock_put = mocker.patch.object(mp_inst.queue_in, "put")
mock_get = mocker.patch.object(mp_inst.queue_out, "get", return_value=False)

state = mp_inst.delete_instance()

mock_put.assert_called_with("delete_auxiliary_instance")
mock_get.assert_called_once()
mock_alive.assert_called_once()
assert mp_inst.is_instance is False
assert state is False


def test_delete_instance_not_alive(mocker, mp_inst):
mock_put = mocker.patch.object(mp_inst.queue_in, "put")
mock_get = mocker.patch.object(mp_inst.queue_out, "get")

state = mp_inst.delete_instance()

mock_put.assert_not_called()
mock_get.assert_not_called()
assert mp_inst.is_instance is False
assert state is None


def test_initialize_loggers(mp_inst):
mp_inst.initialize_loggers()

assert isinstance(mp_inst.logger, logging.Logger)
assert mp_inst.logger.level == logging.DEBUG


def test_run_create_auxiliary_instance_command(mocker, mp_inst):
mock_logger = mocker.patch.object(mp_inst, "initialize_loggers")
mock_empty = mocker.patch.object(mp_inst.queue_in, "empty", return_value=False)
mock_wait = mocker.patch.object(
mp_inst.queue_in, "get_nowait", return_value="create_auxiliary_instance"
)
mock_create = mocker.patch.object(
mp_inst, "_create_auxiliary_instance", return_value=True
)
mock_put = mocker.patch.object(mp_inst.queue_out, "put", side_effect=ValueError)

with pytest.raises(ValueError):
mp_inst.run()
mock_logger.assert_called_once()
mock_create.assert_called_once()
mock_wait.assert_called_once()
mock_put.assert_called_with(True)


def test_run_delete_auxiliary_instance_command(mocker, mp_inst):
mp_inst.is_instance = True
mock_logger = mocker.patch.object(mp_inst, "initialize_loggers")
mock_empty = mocker.patch.object(mp_inst.queue_in, "empty", return_value=False)
mock_wait = mocker.patch.object(
mp_inst.queue_in, "get_nowait", return_value="delete_auxiliary_instance"
)
mock_delete = mocker.patch.object(
mp_inst, "_delete_auxiliary_instance", return_value=True
)
mock_put = mocker.patch.object(mp_inst.queue_out, "put", side_effect=ValueError)

with pytest.raises(ValueError):
mp_inst.run()
mock_logger.assert_called_once()
mock_delete.assert_called_once()
mock_wait.assert_called_once()
mock_put.assert_called_with(True)


def test_run_abort_command(mocker, mp_inst):
mp_inst.is_instance = True
mock_logger = mocker.patch.object(mp_inst, "initialize_loggers")
mock_empty = mocker.patch.object(mp_inst.queue_in, "empty", return_value=False)
mock_wait = mocker.patch.object(
mp_inst.queue_in, "get_nowait", return_value="abort"
)
mock_event_is_set = mocker.patch(
"multiprocessing.synchronize.Event.is_set", side_effect=[False, True]
mock_abort = mocker.patch.object(mp_inst, "_abort_command", return_value=True)
mock_put = mocker.patch.object(mp_inst.queue_out, "put", side_effect=ValueError)

with pytest.raises(ValueError):
mp_inst.run()
mock_logger.assert_called_once()
mock_abort.assert_called_once()
mock_wait.assert_called_once()
mock_put.assert_called_with(True)


def test_run_command(mocker, mp_inst):
mp_inst.is_instance = True
mock_logger = mocker.patch.object(mp_inst, "initialize_loggers")
mock_empty = mocker.patch.object(mp_inst.queue_in, "empty", return_value=False)
mock_wait = mocker.patch.object(
mp_inst.queue_in, "get_nowait", return_value=("command", "supr_command", 1)
)
mock_queue_empty = mocker.patch.object(
MpAuxiliaryInterface_constructor.queue_in, "empty"
mock_cmd = mocker.patch.object(mp_inst, "_run_command", return_value=True)
mock_put = mocker.patch.object(mp_inst.queue_out, "put", side_effect=ValueError)

with pytest.raises(ValueError):
mp_inst.run()
mock_logger.assert_called_once()
mock_cmd.assert_called_with("supr_command", 1)
mock_wait.assert_called_once()
mock_put.assert_called_with(True)


def test_run_unknown_command(mocker, mp_inst):
mp_inst.is_instance = True
mp_inst.initialize_loggers()
mock_empty = mocker.patch.object(mp_inst.queue_in, "empty", return_value=False)
mock_wait = mocker.patch.object(
mp_inst.queue_in, "get_nowait", return_value=("fake_coammnd", "supr_command", 1)
)
mock_queue_empty.return_value = False
mock_queue_get_no_wait = mocker.patch.object(
MpAuxiliaryInterface_constructor.queue_in, "get_nowait"
mock_warning = mocker.patch.object(
mp_inst.logger, "warning", side_effect=ValueError
)

MpAuxiliaryInterface_constructor.logger = logging.getLogger("__name__")
with pytest.raises(ValueError):
mp_inst.run()
mock_warning.assert_called_once()
mock_wait.assert_called_once()


def test_run_receive_message(mocker, mp_inst):
mp_inst.is_instance = True
mock_recv = mocker.patch.object(mp_inst, "_receive_message", return_value=True)
mock_put = mocker.patch.object(mp_inst.queue_out, "put", side_effect=ValueError)

with pytest.raises(ValueError):
mp_inst.run()

mock_recv.assert_called_with(timeout_in_s=0)
mock_put.assert_called_with(True)


def test_run_free_cpu_usage(mocker, mp_inst):
mock_sleep = mocker.patch("time.sleep", side_effect=ValueError)

with pytest.raises(ValueError):
mp_inst.run()
mock_sleep.assert_called_with(0.050)


def test_run_stop_command_running_instance(mocker, mp_inst):
mp_inst.is_instance = True
mock_set = mocker.patch.object(mp_inst.stop_event, "is_set", return_value=True)
mock_delete = mocker.patch.object(
mp_inst, "_delete_auxiliary_instance", return_value=True
)

mp_inst.run()

mock_delete.assert_called_once()
mock_set.assert_called_once()

mock_queue_get_no_wait.return_value = request_value
MpAuxiliaryInterface_constructor.is_instance = is_instance

with caplog.at_level(logging.INFO):
MpAuxiliaryInterface_constructor.run()
spy_logger.assert_called()
def test_run_stop_command_not_running_instance(mocker, mp_inst):
mp_inst.is_instance = False
mock_set = mocker.patch.object(mp_inst.stop_event, "is_set", return_value=True)
mock_delete = mocker.patch.object(mp_inst, "_delete_auxiliary_instance")

assert mock_event_is_set.call_count == 2
mock_queue_empty.assert_called()
mp_inst.run()

if request_value == "Test":
assert "Unknown request 'Test', will not be processed!" in caplog.text
assert f"Aux status: {MpAuxiliaryInterface_constructor.__dict__}" in caplog.text
mock_delete.assert_not_called()
mock_set.assert_called_once()
Loading

0 comments on commit 40de2ad

Please sign in to comment.