#!/usr/bin/env python
# Copyright (c) 2016 - 2017, Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""``test_tool_generate.py``
`ToolGeneral Unittests`
"""
from unittest.mock import Mock, MagicMock
import pytest
import itertools
from testlib import clissh
from testlib import dev_linux_host
from testlib.dev_linux_host import GenericLinuxHost
from testlib.cli_template import CmdStatus
from testlib.custom_exceptions import UICmdException
from testlib.linux import service_lib
from testlib.linux.tool_general import GenericTool, RC_SERVICE_INACTIVE
[docs]class CmdExecSimul(object):
"""Simulate clissh (blackbox).
Specify commands behavior - an (sequence of) input command(s) to output(s)
including side effect(s).
"""
MAKE_ITER_MAP = [
iter,
itertools.cycle
]
def __init__(self, cmd_exec_sim, cycle=False):
super(CmdExecSimul, self).__init__()
self.sim_cmd_iter = None
if cmd_exec_sim:
self.set_simul(cmd_exec_sim, cycle=cycle)
[docs] def set_simul(self, cmd_exec_sim, cycle=False):
make_iterable = self.MAKE_ITER_MAP[cycle]
if isinstance(cmd_exec_sim, list):
pass
else:
cmd_exec_sim = [cmd_exec_sim]
self.sim_cmd_iter = make_iterable(cmd_exec_sim)
[docs] def __call__(self, *args, **kwargs):
"""Any exception raised is considered an expected behavior (side_effect).
The mocked signature: exec_command(command, timeout=None)
"""
if args:
command = args[0]
mock_obj = self._find_match(command)
if not mock_obj:
raise self.InputCommandNoMatch(command)
return mock_obj()
else:
raise self.InputCommandNoMatch(None)
def _find_match(self, command):
sim_cmd = None
try:
sim_cmd = next(self.sim_cmd_iter)
except StopIteration:
assert False
if isinstance(sim_cmd, MagicMock):
mock_obj = sim_cmd
elif isinstance(sim_cmd, dict):
mock_obj = sim_cmd.get(command)
# TODO; implement other match representatinos
if isinstance(mock_obj, Mock):
return mock_obj
if isinstance(mock_obj, dict):
return MagicMock(**mock_obj)
# TODO; implement other mock representatinos
[docs]class FakeSSH(clissh.CLISSH):
login_status = True
def __init__(self, *args, **kwargs):
pass
[docs] def shell_read(self, *args, **kwargs):
pass
[docs] def exec_command(self, *args, **kwargs):
pass
[docs]class MockSSH(FakeSSH):
def __init__(self, *args, **kwargs):
self.exec_command = MagicMock(wraps=self._exec_cmd_wrappee, **kwargs)
_exec_cmd_wrappee = FakeSSH.exec_command
[docs]class SimulatedSSH(MockSSH, CmdExecSimul):
def __init__(self, *args, **kwargs):
MockSSH.__init__(self, *args, **kwargs)
CmdExecSimul.__init__(self, None)
_exec_cmd_wrappee = CmdExecSimul.__call__
[docs]class FakeLinuxHost(GenericLinuxHost):
FAKE_CFG = {
'name': 'FakeHost',
'id': 'FakeID',
'instance_type': 'generic_linux_host',
'ipaddr': 'localhost',
'ssh_user': 'fake_user',
'ssh_pass': 'fake_pass'
}
def __init__(self, config=None, opts=None):
if not config:
config = self.FAKE_CFG
if not opts:
opts = self.FakeOpts()
super(FakeLinuxHost, self).__init__(config, opts)
[docs] class FakeOpts(object):
setup = 'fake.setup.json'
env = 'fake.env.json'
gen_only = False
lhost_ui = 'linux_bash'
@pytest.fixture
[docs]def patch_clissh_sim(monkeypatch):
monkeypatch.setattr(dev_linux_host.clissh, 'CLISSH', SimulatedSSH)
@pytest.fixture
[docs]def lh(request, patch_clissh_sim):
lh = FakeLinuxHost()
request.addfinalizer(lh.destroy)
return lh
SERVICE_NAME = 'generic_tool'
@pytest.fixture
@pytest.fixture
[docs]def systemctl(gen_tool):
service_factory = service_lib.SpecificServiceManager
systemctl = service_factory(SERVICE_NAME, gen_tool.run_command)
return systemctl
@pytest.fixture