diff options
Diffstat (limited to 'yardstick')
7 files changed, 150 insertions, 23 deletions
diff --git a/yardstick/benchmark/runners/sequence.py b/yardstick/benchmark/runners/sequence.py index 0148a45b2..58ffddd22 100644 --- a/yardstick/benchmark/runners/sequence.py +++ b/yardstick/benchmark/runners/sequence.py @@ -38,8 +38,6 @@ LOG = logging.getLogger(__name__) def _worker_process(queue, cls, method_name, scenario_cfg, context_cfg, aborted, output_queue): - sequence = 1 - runner_cfg = scenario_cfg['runner'] interval = runner_cfg.get("interval", 1) @@ -56,6 +54,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, LOG.info("worker START, sequence_values(%s, %s), class %s", arg_name, sequence_values, cls) + scenario_output = base.ScenarioOutput(queue, sequence=1, errors="") benchmark = cls(scenario_cfg, context_cfg) benchmark.setup() method = getattr(benchmark, method_name) @@ -68,22 +67,23 @@ def _worker_process(queue, cls, method_name, scenario_cfg, options[arg_name] = value LOG.debug("runner=%(runner)s seq=%(sequence)s START", - {"runner": runner_cfg["runner_id"], "sequence": sequence}) + {"runner": runner_cfg["runner_id"], + "sequence": scenario_output.sequence}) - data = {} - errors = "" + scenario_output.clear() + scenario_output.errors = "" try: - result = method(data) + result = method(scenario_output) except y_exc.SLAValidationError as error: # SLA validation failed in scenario, determine what to do now if sla_action == "assert": raise elif sla_action == "monitor": LOG.warning("SLA validation failed: %s", error.args) - errors = error.args + scenario_output.errors = error.args except Exception as e: # pylint: disable=broad-except - errors = traceback.format_exc() + scenario_output.errors = traceback.format_exc() LOG.exception(e) else: if result: @@ -91,21 +91,16 @@ def _worker_process(queue, cls, method_name, scenario_cfg, time.sleep(interval) - benchmark_output = { - 'timestamp': time.time(), - 'sequence': sequence, - 'data': data, - 'errors': errors - } - - queue.put(benchmark_output) + if scenario_output: + scenario_output.push() LOG.debug("runner=%(runner)s seq=%(sequence)s END", - {"runner": runner_cfg["runner_id"], "sequence": sequence}) + {"runner": runner_cfg["runner_id"], + "sequence": scenario_output.sequence}) - sequence += 1 + scenario_output.sequence += 1 - if (errors and sla_action is None) or aborted.is_set(): + if (scenario_output.errors and sla_action is None) or aborted.is_set(): break try: diff --git a/yardstick/ssh.py b/yardstick/ssh.py index 2ebf40e98..438e8158b 100644 --- a/yardstick/ssh.py +++ b/yardstick/ssh.py @@ -448,6 +448,86 @@ class SSH(object): with client.open_sftp() as sftp: sftp.getfo(remotepath, file_obj) + def interactive_terminal_open(self, time_out=45): + """Open interactive terminal on a SSH channel. + + :param time_out: Timeout in seconds. + :returns: SSH channel with opened terminal. + + .. warning:: Interruptingcow is used here, and it uses + signal(SIGALRM) to let the operating system interrupt program + execution. This has the following limitations: Python signal + handlers only apply to the main thread, so you cannot use this + from other threads. You must not use this in a program that + uses SIGALRM itself (this includes certain profilers) + """ + chan = self._get_client().get_transport().open_session() + chan.get_pty() + chan.invoke_shell() + chan.settimeout(int(time_out)) + chan.set_combine_stderr(True) + + buf = '' + while not buf.endswith((":~# ", ":~$ ", "~]$ ", "~]# ")): + try: + chunk = chan.recv(10 * 1024 * 1024) + if not chunk: + break + buf += chunk + if chan.exit_status_ready(): + self.log.error('Channel exit status ready') + break + except socket.timeout: + raise exceptions.SSHTimeout(error_msg='Socket timeout: %s' % buf) + return chan + + def interactive_terminal_exec_command(self, chan, cmd, prompt): + """Execute command on interactive terminal. + + interactive_terminal_open() method has to be called first! + + :param chan: SSH channel with opened terminal. + :param cmd: Command to be executed. + :param prompt: Command prompt, sequence of characters used to + indicate readiness to accept commands. + :returns: Command output. + + .. warning:: Interruptingcow is used here, and it uses + signal(SIGALRM) to let the operating system interrupt program + execution. This has the following limitations: Python signal + handlers only apply to the main thread, so you cannot use this + from other threads. You must not use this in a program that + uses SIGALRM itself (this includes certain profilers) + """ + chan.sendall('{c}\n'.format(c=cmd)) + buf = '' + while not buf.endswith(prompt): + try: + chunk = chan.recv(10 * 1024 * 1024) + if not chunk: + break + buf += chunk + if chan.exit_status_ready(): + self.log.error('Channel exit status ready') + break + except socket.timeout: + message = ("Socket timeout during execution of command: " + "%(cmd)s\nBuffer content:\n%(buf)s" % {"cmd": cmd, + "buf": buf}) + raise exceptions.SSHTimeout(error_msg=message) + tmp = buf.replace(cmd.replace('\n', ''), '') + for item in prompt: + tmp.replace(item, '') + return tmp + + @staticmethod + def interactive_terminal_close(chan): + """Close interactive terminal SSH channel. + + :param: chan: SSH channel to be closed. + """ + chan.close() + class AutoConnectSSH(SSH): diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_prox_irq.py b/yardstick/tests/unit/network_services/traffic_profile/test_prox_irq.py index 59f37befa..1a9947984 100644 --- a/yardstick/tests/unit/network_services/traffic_profile/test_prox_irq.py +++ b/yardstick/tests/unit/network_services/traffic_profile/test_prox_irq.py @@ -11,6 +11,7 @@ # 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. +import time import unittest import mock @@ -28,7 +29,8 @@ class TestProxIrqProfile(unittest.TestCase): def _stop_mocks(self): self._mock_log_info.stop() - def test_execute_1(self): + @mock.patch.object(time, 'sleep') + def test_execute_1(self, *args): tp_config = { 'traffic_profile': { }, diff --git a/yardstick/tests/unit/network_services/traffic_profile/test_prox_profile.py b/yardstick/tests/unit/network_services/traffic_profile/test_prox_profile.py index 11bee03a4..2660d4134 100644 --- a/yardstick/tests/unit/network_services/traffic_profile/test_prox_profile.py +++ b/yardstick/tests/unit/network_services/traffic_profile/test_prox_profile.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # +import time import unittest import mock @@ -78,7 +79,8 @@ class TestProxProfile(unittest.TestCase): profile.init(queue) self.assertIs(profile.queue, queue) - def test_execute_traffic(self): + @mock.patch.object(time, 'sleep') + def test_execute_traffic(self, *args): packet_sizes = [ 10, 100, diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py index 9a30fb9e9..742dbfe24 100644 --- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_prox_helpers.py @@ -2400,6 +2400,7 @@ class TestProxProfileHelper(unittest.TestCase): with helper.traffic_context(64, 1): pass + @mock.patch.object(time, 'sleep') def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 @@ -2549,6 +2550,7 @@ class TestProxBngProfileHelper(unittest.TestCase): self.assertEqual(helper.arp_task_cores, expected_arp_task) self.assertEqual(helper._cores_tuple, expected_combined) + @mock.patch.object(time, 'sleep') def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 @@ -2675,6 +2677,7 @@ class TestProxVpeProfileHelper(unittest.TestCase): self.assertEqual(helper.inet_ports, expected_inet) self.assertEqual(helper._ports_tuple, expected_combined) + @mock.patch.object(time, 'sleep') def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 @@ -2792,6 +2795,7 @@ class TestProxlwAFTRProfileHelper(unittest.TestCase): self.assertEqual(helper.inet_ports, expected_inet) self.assertEqual(helper._ports_tuple, expected_combined) + @mock.patch.object(time, 'sleep') def test_run_test(self, *args): resource_helper = mock.MagicMock() resource_helper.step_delta = 0.4 diff --git a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py index a9fa5f3c1..7ef94c3d8 100644 --- a/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py +++ b/yardstick/tests/unit/network_services/vnf_generic/vnf/test_tg_rfc2544_trex.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2017 Intel Corporation +# Copyright (c) 2016-2018 Intel Corporation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,6 +11,7 @@ # 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. +import time import mock import unittest @@ -24,7 +25,8 @@ from yardstick.network_services.vnf_generic.vnf import tg_rfc2544_trex class TestTrexRfcResouceHelper(unittest.TestCase): - def test__run_traffic_once(self): + @mock.patch.object(time, 'sleep') + def test__run_traffic_once(self, *args): mock_setup_helper = mock.Mock() mock_traffic_profile = mock.Mock() mock_traffic_profile.config.duration = 3 diff --git a/yardstick/tests/unit/test_ssh.py b/yardstick/tests/unit/test_ssh.py index 71929f1a2..374fb6644 100644 --- a/yardstick/tests/unit/test_ssh.py +++ b/yardstick/tests/unit/test_ssh.py @@ -286,6 +286,48 @@ class SSHTestCase(unittest.TestCase): mock_paramiko_exec_command.assert_called_once_with('cmd', get_pty=True) + @mock.patch("yardstick.ssh.paramiko") + def test_interactive_terminal_open(self, mock_paramiko): + fake_client = mock.Mock() + fake_session = mock.Mock() + fake_session.recv.return_value = ":~# " + fake_transport = mock.Mock() + fake_transport.open_session.return_value = fake_session + fake_client.get_transport.return_value = fake_transport + mock_paramiko.SSHClient.return_value = fake_client + + test_ssh = ssh.SSH("admin", "example.net", pkey="key") + result = test_ssh.interactive_terminal_open() + self.assertEqual(fake_session, result) + + @mock.patch("yardstick.ssh.paramiko") + def test_interactive_terminal_exec_command(self, mock_paramiko): + fake_client = mock.Mock() + fake_session = mock.Mock() + fake_session.recv.return_value = "stdout fake data" + fake_transport = mock.Mock() + fake_transport.open_session.return_value = fake_session + fake_client.get_transport.return_value = fake_transport + mock_paramiko.SSHClient.return_value = fake_client + + test_ssh = ssh.SSH("admin", "example.net", pkey="key") + with mock.patch.object(fake_session, "sendall") \ + as mock_paramiko_send_command: + result = test_ssh.interactive_terminal_exec_command(fake_session, + 'cmd', "vat# ") + self.assertEqual("stdout fake data", result) + mock_paramiko_send_command.assert_called_once_with('cmd\n') + + @mock.patch("yardstick.ssh.paramiko") + def test_interactive_terminal_close(self, _): + fake_session = mock.Mock() + paramiko_sshclient = self.test_client._get_client() + paramiko_sshclient.get_transport.open_session.return_value = fake_session + with mock.patch.object(fake_session, "close") \ + as mock_paramiko_terminal_close: + self.test_client.interactive_terminal_close(fake_session) + mock_paramiko_terminal_close.assert_called_once_with() + class SSHRunTestCase(unittest.TestCase): """Test SSH.run method in different aspects. |