from pathlib import Path
from unittest.mock import Mock, patch, MagicMock
import numpy as np
import pytest
from msserviceprofiler.modelevalstate.config.config import CommunicationConfig, get_settings, \
map_param_with_value, default_support_field
from msserviceprofiler.modelevalstate.optimizer.server import Scheduler
from msserviceprofiler.modelevalstate.optimizer.communication import CommunicationForFile, CustomCommand
def test_scheduler_init(tmpdir):
work_path = Path(tmpdir)
res_file = work_path.joinpath("res.txt")
cmd_file = work_path.joinpath("cmd.txt")
communication_config = CommunicationConfig(cmd_file=res_file, res_file=cmd_file)
scheduler = Scheduler(communication_config)
assert scheduler.communication_config == communication_config
assert scheduler.simulator is None
assert isinstance(scheduler.communication, CommunicationForFile)
assert scheduler.communication.res_file == res_file
assert scheduler.communication.cmd_file == cmd_file
assert isinstance(scheduler.cmd, CustomCommand)
def test_backup_path_exists():
scheduler = Scheduler(get_settings().communication)
scheduler.communication = Mock()
params = "/existing/path"
_cmd = scheduler.cmd.start
scheduler.cmd.history = _cmd
with patch("msserviceprofiler.modelevalstate.optimizer.server.Path") as mock_path:
mock_path.return_value.exists.return_value = True
scheduler.backup(params)
scheduler.communication.send_command.assert_called_once_with(f"{scheduler.cmd.history[-1]}:done")
scheduler.communication.clear_res.assert_called_once()
def test_backup_path_not_exists():
scheduler = Scheduler(get_settings().communication)
scheduler.communication = Mock()
params = "/non/existing/path"
_cmd = scheduler.cmd.start
scheduler.cmd.history = _cmd
with patch("msserviceprofiler.modelevalstate.optimizer.server.Path") as mock_path:
mock_path.return_value.exists.return_value = False
mock_path.return_value.mkdir.return_value = None
scheduler.backup(params)
scheduler.communication.send_command.assert_called_once_with(f"{scheduler.cmd.history[-1]}:done")
scheduler.communication.clear_res.assert_called_once()
def test_check_success_no_simulator():
scheduler = Scheduler(get_settings().communication)
scheduler.simulator = None
assert scheduler.check_success() is None
def test_check_success_simulator_succeeds_immediately():
scheduler = Scheduler(get_settings().communication)
scheduler.simulator = Mock()
scheduler.cmd.history = "check success 1111111"
scheduler.simulator.check_success.return_value = True
scheduler.communication = Mock()
scheduler.check_success()
scheduler.communication.send_command.assert_called_once_with("check success 1111111:True")
@patch("time.sleep")
def test_check_success_simulator_succeeds_after_retries(mock_sleep):
scheduler = Scheduler(get_settings().communication)
scheduler.simulator = Mock()
scheduler.cmd.history = "check success 1111111"
scheduler.simulator.check_success.side_effect = [False, False, True]
scheduler.communication = Mock()
scheduler.check_success()
assert scheduler.simulator.check_success.call_count == 3
scheduler.communication.send_command.assert_called_once_with("check success 1111111:True")
mock_sleep.call_count == 2
@patch("time.sleep")
def test_check_success_simulator_always_fails(mock_sleep):
scheduler = Scheduler(get_settings().communication)
scheduler.simulator = Mock()
scheduler.cmd.history = "check success 1111111"
scheduler.simulator.check_success.return_value = False
scheduler.communication = Mock()
scheduler.check_success()
assert scheduler.simulator.check_success.call_count == 10
scheduler.communication.send_command.assert_called_once_with("check success 1111111:False")
mock_sleep.call_count == 10
def test_stop_with_simulator():
scheduler = Scheduler(get_settings().communication)
scheduler.simulator = Mock()
scheduler.communication = Mock()
scheduler.cmd.history = "stop 1111111 params:True"
params = "True"
scheduler.stop(params)
scheduler.simulator.stop.assert_called_once_with(True)
scheduler.communication.send_command.assert_called_once()
scheduler.communication.clear_res.assert_called_once()
def test_stop_without_simulator():
scheduler = Scheduler(get_settings().communication)
scheduler.simulator = None
scheduler.communication = Mock()
scheduler.cmd.history = "stop 1111111 params:True"
params = "True"
scheduler.stop(params)
scheduler.communication.send_command.assert_not_called()
scheduler.communication.clear_res.assert_not_called()
def test_get_cmd_param_empty():
scheduler = Scheduler(get_settings().communication)
scheduler.communication = MagicMock()
scheduler.communication.recv_command.return_value = ""
assert scheduler.get_cmd_param() == (None, None)
def test_get_cmd_param_eof():
scheduler = Scheduler(get_settings().communication)
scheduler.communication = MagicMock()
scheduler.communication.recv_command.return_value = "EOF"
assert scheduler.get_cmd_param() == (None, None)
def test_get_cmd_param_history():
scheduler = Scheduler(get_settings().communication)
scheduler.communication = MagicMock()
scheduler.communication.recv_command.return_value = "cmd1"
scheduler.cmd.history = ["cmd1"]
assert scheduler.get_cmd_param() == (None, None)
def test_get_cmd_param_format_error():
scheduler = Scheduler(get_settings().communication)
scheduler.communication = MagicMock()
scheduler.communication.recv_command.return_value = "cmd1"
assert scheduler.get_cmd_param() == (None, None)
def test_get_cmd_param_success():
scheduler = Scheduler(get_settings().communication)
scheduler.communication = MagicMock()
scheduler.communication.recv_command.return_value = "cmd1 params:123"
assert scheduler.get_cmd_param() == ("cmd1", "123")
class TestSchedulerProcessPoll:
@classmethod
def test_process_poll_with_simulator(cls, scheduler):
scheduler.simulator.process.poll.return_value = True
scheduler.cmd.history = "process_poll 1111111"
scheduler.process_poll()
scheduler.simulator.process.poll.assert_called_once()
scheduler.communication.send_command.assert_called_once_with("process_poll 1111111:True")
scheduler.communication.clear_res.assert_called_once()
@classmethod
def test_process_poll_without_simulator(cls, scheduler):
scheduler.simulator = None
scheduler.cmd.history = "process_poll 1111111"
scheduler.process_poll()
scheduler.communication.send_command.assert_called_once_with("process_poll 1111111:None")
scheduler.communication.clear_res.assert_called_once()
@pytest.fixture
def scheduler(self):
scheduler = Scheduler(get_settings().communication)
scheduler.simulator = MagicMock()
scheduler.communication = MagicMock()
return scheduler
def test_init_cmd_none():
scheduler = Scheduler(get_settings().communication)
scheduler.get_cmd_param = MagicMock(return_value=(None, None))
assert scheduler.init() is False
def test_init_cmd_init():
scheduler = Scheduler(get_settings().communication)
scheduler.get_cmd_param = MagicMock(return_value=("init", None))
scheduler.cmd.history = "init 11111111"
scheduler.communication = MagicMock()
assert scheduler.init() is True
scheduler.communication.send_command.assert_called_once_with("init 11111111:done")
scheduler.communication.clear_res.assert_called_once()
def test_init_cmd_not_init():
scheduler = Scheduler(get_settings().communication)
scheduler.get_cmd_param = MagicMock(return_value=("other_command", None))
assert scheduler.init() is False
def test_run_no_cmd():
scheduler = Scheduler(get_settings().communication)
with patch.object(scheduler, 'get_cmd_param', return_value=(None, None)):
assert scheduler.run() == ''
def test_run_unknown_cmd():
scheduler = Scheduler(get_settings().communication)
with patch.object(scheduler, 'get_cmd_param', return_value=('unknown_cmd', None)):
with patch('msserviceprofiler.modelevalstate.optimizer.server.logger') as mock_logger:
assert scheduler.run() == ''
mock_logger.error.assert_called_once()
def test_run_no_param():
scheduler = Scheduler(get_settings().communication)
scheduler.command = MagicMock(return_value='result')
with patch.object(scheduler, 'get_cmd_param', return_value=('command', None)):
with patch('msserviceprofiler.modelevalstate.optimizer.server.getattr', return_value=scheduler.command):
assert scheduler.run() == 'result'
scheduler.command.assert_called_once()
def test_run_with_param():
scheduler = Scheduler(get_settings().communication)
scheduler.command = MagicMock(return_value='result')
with patch.object(scheduler, 'get_cmd_param', return_value=('command', 'param')):
with patch('msserviceprofiler.modelevalstate.optimizer.server.getattr', return_value=scheduler.command):
assert scheduler.run() == 'result'
scheduler.command.assert_called_once_with('param')