diff options
22 files changed, 274 insertions, 156 deletions
diff --git a/docker/Dockerfile.aarch64.patch b/docker/Dockerfile.aarch64.patch index e8dbea288..720a39970 100644 --- a/docker/Dockerfile.aarch64.patch +++ b/docker/Dockerfile.aarch64.patch @@ -1,24 +1,17 @@ From: Cristina Pauna <cristina.pauna@enea.com> -Date: Thu, 11 Jan 2018 19:06:26 +0200 -Subject: [PATCH] Patch for Yardstick AARCH64 Docker file +Date: Mon, 30 Apr 2018 14:09:00 +0300 +Subject: [PATCH] [PATCH] Patch for Yardstick AARCH64 Docker file Signed-off-by: Cristina Pauna <cristina.pauna@enea.com> Signed-off-by: Alexandru Nemes <alexandru.nemes@enea.com> --- - docker/Dockerfile | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) + docker/Dockerfile | 12 +++++++----- + 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile -index 2ee5b4c..23e5ea5 100644 +index fed9f9bd..9654b5dc 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile -@@ -1,5 +1,5 @@ - ############################################################################## --# Copyright (c) 2015 Ericsson AB and others. -+# Copyright (c) 2017 Enea AB and others. - # - # All rights reserved. This program and the accompanying materials - # are made available under the terms of the Apache License, Version 2.0 @@ -7,9 +7,9 @@ # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## @@ -31,17 +24,18 @@ index 2ee5b4c..23e5ea5 100644 ARG BRANCH=master -@@ -24,7 +24,8 @@ ENV YARDSTICK_REPO_DIR="${REPOS_DIR}/yardstick" \ +@@ -24,7 +24,9 @@ ENV YARDSTICK_REPO_DIR="${REPOS_DIR}/yardstick/" \ RELENG_REPO_DIR="${REPOS_DIR}/releng" \ STORPERF_REPO_DIR="${REPOS_DIR}/storperf" --RUN apt-get update && apt-get install -y git python-setuptools python-pip && apt-get -y autoremove && apt-get clean -+RUN apt-get update && apt-get install -y git python-setuptools python-pip && apt-get -y autoremove && \ +-RUN apt-get update && apt-get install -y git python python-setuptools python-pip && apt-get -y autoremove && apt-get clean ++RUN apt-get update && apt-get install -y git python python-setuptools python-pip && apt-get -y autoremove && \ + apt-get install -y libssl-dev && apt-get -y install libffi-dev && apt-get clean ++ RUN easy_install -U setuptools==30.0.0 - RUN pip install appdirs==1.4.0 pyopenssl==17.5.0 python-openstackclient==3.11.0 python-heatclient==1.11.0 + RUN pip install appdirs==1.4.0 pyopenssl==17.5.0 python-openstackclient==3.11.0 python-heatclient==1.11.0 ansible==2.4.2 -@@ -43,8 +44,8 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf +@@ -45,8 +47,8 @@ RUN echo "daemon off;" >> /etc/nginx/nginx.conf # nginx=5000, rabbitmq=5672 EXPOSE 5000 5672 @@ -50,5 +44,5 @@ index 2ee5b4c..23e5ea5 100644 +ADD http://download.cirros-cloud.net/daily/20161201/cirros-d161201-aarch64-disk.img ${IMAGE_DIR} +ADD http://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-arm64-disk1.img ${IMAGE_DIR} - COPY ./exec_tests.sh /usr/local/bin/ + COPY ./docker/exec_tests.sh /usr/local/bin/ diff --git a/yardstick/benchmark/core/task.py b/yardstick/benchmark/core/task.py index 955b8cae2..697cc007f 100644 --- a/yardstick/benchmark/core/task.py +++ b/yardstick/benchmark/core/task.py @@ -112,9 +112,9 @@ class Task(object): # pragma: no cover continue try: - data = self._run(tasks[i]['scenarios'], - tasks[i]['run_in_parallel'], - output_config) + success, data = self._run(tasks[i]['scenarios'], + tasks[i]['run_in_parallel'], + output_config) except KeyboardInterrupt: raise except Exception: # pylint: disable=broad-except @@ -123,9 +123,15 @@ class Task(object): # pragma: no cover testcases[tasks[i]['case_name']] = {'criteria': 'FAIL', 'tc_data': []} else: - LOG.info('Testcase: "%s" SUCCESS!!!', tasks[i]['case_name']) - testcases[tasks[i]['case_name']] = {'criteria': 'PASS', - 'tc_data': data} + if success: + LOG.info('Testcase: "%s" SUCCESS!!!', tasks[i]['case_name']) + testcases[tasks[i]['case_name']] = {'criteria': 'PASS', + 'tc_data': data} + else: + LOG.error('Testcase: "%s" FAILED!!!', tasks[i]['case_name'], + exc_info=True) + testcases[tasks[i]['case_name']] = {'criteria': 'FAIL', + 'tc_data': data} if args.keep_deploy: # keep deployment, forget about stack @@ -240,6 +246,7 @@ class Task(object): # pragma: no cover background_runners = [] + task_success = True result = [] # Start all background scenarios for scenario in filter(_is_background_scenario, scenarios): @@ -258,8 +265,8 @@ class Task(object): # pragma: no cover for runner in runners: status = runner_join(runner, background_runners, self.outputs, result) if status != 0: - raise RuntimeError( - "{0} runner status {1}".format(runner.__execution_type__, status)) + LOG.error("%s runner status %s", runner.__execution_type__, status) + task_success = False LOG.info("Runner ended") else: # run serially @@ -271,8 +278,8 @@ class Task(object): # pragma: no cover LOG.error('Scenario NO.%s: "%s" ERROR!', scenarios.index(scenario) + 1, scenario.get('type')) - raise RuntimeError( - "{0} runner status {1}".format(runner.__execution_type__, status)) + LOG.error("%s runner status %s", runner.__execution_type__, status) + task_success = False LOG.info("Runner ended") # Abort background runners @@ -289,7 +296,7 @@ class Task(object): # pragma: no cover base_runner.Runner.release(runner) print("Background task ended") - return result + return task_success, result def atexit_handler(self): """handler for process termination""" diff --git a/yardstick/benchmark/scenarios/availability/scenario_general.py b/yardstick/benchmark/scenarios/availability/scenario_general.py index 9ac55471d..1fadd2532 100644 --- a/yardstick/benchmark/scenarios/availability/scenario_general.py +++ b/yardstick/benchmark/scenarios/availability/scenario_general.py @@ -26,7 +26,6 @@ class ScenarioGeneral(base.Scenario): self.scenario_cfg = scenario_cfg self.context_cfg = context_cfg self.intermediate_variables = {} - self.pass_flag = True def setup(self): self.director = Director(self.scenario_cfg, self.context_cfg) @@ -47,7 +46,7 @@ class ScenarioGeneral(base.Scenario): step['actionType'], step['actionKey']) if actionRollbacker: self.director.executionSteps.append(actionRollbacker) - except Exception: + except Exception: # pylint: disable=broad-except LOG.exception("Exception") LOG.debug( "\033[91m exception when running step: %s .... \033[0m", @@ -59,31 +58,16 @@ class ScenarioGeneral(base.Scenario): self.director.stopMonitors() verify_result = self.director.verify() - - self.director.store_result(result) - for k, v in self.director.data.items(): if v == 0: result['sla_pass'] = 0 verify_result = False - self.pass_flag = False - LOG.info( - "\033[92m The service process not found in the host \ -envrioment, the HA test case NOT pass") + LOG.info("\033[92m The service process (%s) not found in the host environment", k) - if verify_result: - result['sla_pass'] = 1 - LOG.info( - "\033[92m Congratulations, " - "the HA test case PASS! \033[0m") - else: - result['sla_pass'] = 0 - self.pass_flag = False - LOG.info( - "\033[91m Aoh, the HA test case FAIL," - "please check the detail debug information! \033[0m") + result['sla_pass'] = 1 if verify_result else 0 + self.director.store_result(result) + + assert verify_result is True, "The HA test case NOT passed" def teardown(self): self.director.knockoff() - - assert self.pass_flag, "The HA test case NOT passed" diff --git a/yardstick/benchmark/scenarios/availability/serviceha.py b/yardstick/benchmark/scenarios/availability/serviceha.py index 6d0d812af..dcd0fe598 100755 --- a/yardstick/benchmark/scenarios/availability/serviceha.py +++ b/yardstick/benchmark/scenarios/availability/serviceha.py @@ -29,7 +29,6 @@ class ServiceHA(base.Scenario): self.context_cfg = context_cfg self.setup_done = False self.data = {} - self.pass_flag = True def setup(self): """scenario setup""" @@ -73,18 +72,12 @@ class ServiceHA(base.Scenario): sla_pass = self.monitorMgr.verify_SLA() for k, v in self.data.items(): if v == 0: - result['sla_pass'] = 0 - self.pass_flag = False - LOG.info("The service process not found in the host envrioment, \ -the HA test case NOT pass") - return + sla_pass = False + LOG.info("The service process (%s) not found in the host envrioment", k) + + result['sla_pass'] = 1 if sla_pass else 0 self.monitorMgr.store_result(result) - if sla_pass: - result['sla_pass'] = 1 - LOG.info("The HA test case PASS the SLA") - else: - result['sla_pass'] = 0 - self.pass_flag = False + assert sla_pass is True, "The HA test case NOT pass the SLA" return @@ -94,8 +87,6 @@ the HA test case NOT pass") for attacker in self.attackers: attacker.recover() - assert self.pass_flag, "The HA test case NOT passed" - def _test(): # pragma: no cover """internal test function""" diff --git a/yardstick/benchmark/scenarios/lib/attach_volume.py b/yardstick/benchmark/scenarios/lib/attach_volume.py index 88124964b..96dd130b1 100644 --- a/yardstick/benchmark/scenarios/lib/attach_volume.py +++ b/yardstick/benchmark/scenarios/lib/attach_volume.py @@ -6,30 +6,31 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## - -from __future__ import print_function -from __future__ import absolute_import - import logging from yardstick.benchmark.scenarios import base -import yardstick.common.openstack_utils as op_utils +from yardstick.common import openstack_utils +from yardstick.common import exceptions LOG = logging.getLogger(__name__) class AttachVolume(base.Scenario): - """Attach a volmeu to an instance""" + """Attach a volume to an instance""" __scenario_type__ = "AttachVolume" def __init__(self, scenario_cfg, context_cfg): self.scenario_cfg = scenario_cfg self.context_cfg = context_cfg - self.options = self.scenario_cfg['options'] + self.options = self.scenario_cfg["options"] - self.server_id = self.options.get("server_id", "TestServer") - self.volume_id = self.options.get("volume_id", None) + self.server_name_or_id = self.options["server_name_or_id"] + self.volume_name_or_id = self.options["volume_name_or_id"] + self.device = self.options.get("device") + self.wait = self.options.get("wait", True) + self.timeout = self.options.get("timeout") + self.shade_client = openstack_utils.get_shade_client() self.setup_done = False @@ -44,10 +45,14 @@ class AttachVolume(base.Scenario): if not self.setup_done: self.setup() - status = op_utils.attach_server_volume(self.server_id, - self.volume_id) + status = openstack_utils.attach_volume_to_server( + self.shade_client, self.server_name_or_id, self.volume_name_or_id, + device=self.device, wait=self.wait, timeout=self.timeout) + + if not status: + result.update({"attach_volume": 0}) + LOG.error("Attach volume to server failed!") + raise exceptions.ScenarioAttachVolumeError - if status: - LOG.info("Attach volume to server successful!") - else: - LOG.info("Attach volume to server failed!") + result.update({"attach_volume": 1}) + LOG.info("Attach volume to server successful!") diff --git a/yardstick/common/exceptions.py b/yardstick/common/exceptions.py index bc16cab8f..13117e02f 100644 --- a/yardstick/common/exceptions.py +++ b/yardstick/common/exceptions.py @@ -148,6 +148,14 @@ class TaskRenderError(YardstickException): message = 'Failed to render template:\n%(input_task)s' +class TimerTimeout(YardstickException): + message = 'Timer timeout expired, %(timeout)s seconds' + + +class WaitTimeout(YardstickException): + message = 'Wait timeout while waiting for condition' + + class ScenarioCreateNetworkError(YardstickException): message = 'Create Neutron Network Scenario failed' @@ -206,3 +214,7 @@ class ScenarioCreateKeypairError(YardstickException): class ScenarioDeleteKeypairError(YardstickException): message = 'Nova Delete Keypair Scenario failed' + + +class ScenarioAttachVolumeError(YardstickException): + message = 'Nova Attach Volume Scenario failed' diff --git a/yardstick/common/openstack_utils.py b/yardstick/common/openstack_utils.py index 0902d29e1..0a3cfb5fc 100644 --- a/yardstick/common/openstack_utils.py +++ b/yardstick/common/openstack_utils.py @@ -264,17 +264,36 @@ def create_instance_and_wait_for_active(shade_client, name, image, "Exception message, '%s'", o_exc.orig_message) -def attach_server_volume(server_id, volume_id, - device=None): # pragma: no cover +def attach_volume_to_server(shade_client, server_name_or_id, volume_name_or_id, + device=None, wait=True, timeout=None): + """Attach a volume to a server. + + This will attach a volume, described by the passed in volume + dict, to the server described by the passed in server dict on the named + device on the server. + + If the volume is already attached to the server, or generally not + available, then an exception is raised. To re-attach to a server, + but under a different device, the user must detach it first. + + :param server_name_or_id:(string) The server name or id to attach to. + :param volume_name_or_id:(string) The volume name or id to attach. + :param device:(string) The device name where the volume will attach. + :param wait:(bool) If true, waits for volume to be attached. + :param timeout: Seconds to wait for volume attachment. None is forever. + + :returns: True if attached successful, False otherwise. + """ try: - get_nova_client().volumes.create_server_volume(server_id, - volume_id, device) - except Exception: # pylint: disable=broad-except - log.exception("Error [attach_server_volume(nova_client, '%s', '%s')]", - server_id, volume_id) - return False - else: + server = shade_client.get_server(name_or_id=server_name_or_id) + volume = shade_client.get_volume(volume_name_or_id) + shade_client.attach_volume( + server, volume, device=device, wait=wait, timeout=timeout) return True + except exc.OpenStackCloudException as o_exc: + log.error("Error [attach_volume_to_server(shade_client)]. " + "Exception message: %s", o_exc.orig_message) + return False def delete_instance(shade_client, name_or_id, wait=False, timeout=180, diff --git a/yardstick/common/utils.py b/yardstick/common/utils.py index 44cc92a7c..108ee17bc 100644 --- a/yardstick/common/utils.py +++ b/yardstick/common/utils.py @@ -23,9 +23,11 @@ import logging import os import random import re +import signal import socket import subprocess import sys +import time import six from flask import jsonify @@ -34,6 +36,8 @@ from oslo_serialization import jsonutils from oslo_utils import encodeutils import yardstick +from yardstick.common import exceptions + logger = logging.getLogger(__name__) logger.setLevel(logging.DEBUG) @@ -405,15 +409,24 @@ class ErrorClass(object): class Timer(object): - def __init__(self): + def __init__(self, timeout=None): super(Timer, self).__init__() self.start = self.delta = None + self._timeout = int(timeout) if timeout else None + + def _timeout_handler(self, *args): + raise exceptions.TimerTimeout(timeout=self._timeout) def __enter__(self): self.start = datetime.datetime.now() + if self._timeout: + signal.signal(signal.SIGALRM, self._timeout_handler) + signal.alarm(self._timeout) return self def __exit__(self, *_): + if self._timeout: + signal.alarm(0) self.delta = datetime.datetime.now() - self.start def __getattr__(self, item): @@ -460,3 +473,22 @@ def open_relative_file(path, task_path): if e.errno == errno.ENOENT: return open(os.path.join(task_path, path)) raise + + +def wait_until_true(predicate, timeout=60, sleep=1, exception=None): + """Wait until callable predicate is evaluated as True + + :param predicate: (func) callable deciding whether waiting should continue + :param timeout: (int) timeout in seconds how long should function wait + :param sleep: (int) polling interval for results in seconds + :param exception: exception instance to raise on timeout. If None is passed + (default) then WaitTimeout exception is raised. + """ + try: + with Timer(timeout=timeout): + while not predicate(): + time.sleep(sleep) + except exceptions.TimerTimeout: + if exception and issubclass(exception, Exception): + raise exception # pylint: disable=raising-bad-type + raise exceptions.WaitTimeout diff --git a/yardstick/tests/unit/benchmark/scenarios/availability/test_scenario_general.py b/yardstick/tests/unit/benchmark/scenarios/availability/test_scenario_general.py index 45840d569..d1172d5a6 100644 --- a/yardstick/tests/unit/benchmark/scenarios/availability/test_scenario_general.py +++ b/yardstick/tests/unit/benchmark/scenarios/availability/test_scenario_general.py @@ -14,7 +14,8 @@ from yardstick.benchmark.scenarios.availability import scenario_general class ScenarioGeneralTestCase(unittest.TestCase): - def setUp(self): + @mock.patch.object(scenario_general, 'Director') + def setUp(self, *args): self.scenario_cfg = { 'type': "general_scenario", 'options': { @@ -36,32 +37,28 @@ class ScenarioGeneralTestCase(unittest.TestCase): } } self.instance = scenario_general.ScenarioGeneral(self.scenario_cfg, None) - - self._mock_director = mock.patch.object(scenario_general, 'Director') - self.mock_director = self._mock_director.start() - self.addCleanup(self._stop_mock) - - def _stop_mock(self): - self._mock_director.stop() + self.instance.setup() + self.instance.director.verify.return_value = True def test_scenario_general_all_successful(self): - self.instance.setup() - self.instance.run({}) + + ret = {} + self.instance.run(ret) self.instance.teardown() + self.assertEqual(ret['sla_pass'], 1) def test_scenario_general_exception(self): - mock_obj = mock.Mock() - mock_obj.createActionPlayer.side_effect = KeyError('Wrong') - self.instance.director = mock_obj + self.instance.director.createActionPlayer.side_effect = KeyError('Wrong') self.instance.director.data = {} - self.instance.run({}) + ret = {} + self.instance.run(ret) self.instance.teardown() + self.assertEqual(ret['sla_pass'], 1) def test_scenario_general_case_fail(self): - mock_obj = mock.Mock() - mock_obj.verify.return_value = False - self.instance.director = mock_obj + self.instance.director.verify.return_value = False self.instance.director.data = {} - self.instance.run({}) - self.instance.pass_flag = True + ret = {} + self.assertRaises(AssertionError, self.instance.run, ret) self.instance.teardown() + self.assertEqual(ret['sla_pass'], 0) diff --git a/yardstick/tests/unit/benchmark/scenarios/availability/test_serviceha.py b/yardstick/tests/unit/benchmark/scenarios/availability/test_serviceha.py index 6bb3ec63b..dd656fbd5 100644 --- a/yardstick/tests/unit/benchmark/scenarios/availability/test_serviceha.py +++ b/yardstick/tests/unit/benchmark/scenarios/availability/test_serviceha.py @@ -60,15 +60,16 @@ class ServicehaTestCase(unittest.TestCase): p.setup() self.assertTrue(p.setup_done) - # def test__serviceha_run_sla_error(self, mock_attacker, mock_monitor): - # p = serviceha.ServiceHA(self.args, self.ctx) + @mock.patch.object(serviceha, 'baseattacker') + @mock.patch.object(serviceha, 'basemonitor') + def test__serviceha_run_sla_error(self, mock_monitor, *args): + p = serviceha.ServiceHA(self.args, self.ctx) - # p.setup() - # self.assertEqual(p.setup_done, True) + p.setup() + self.assertEqual(p.setup_done, True) - # result = {} - # result["outage_time"] = 10 - # mock_monitor.Monitor().get_result.return_value = result + mock_monitor.MonitorMgr().verify_SLA.return_value = False - # ret = {} - # self.assertRaises(AssertionError, p.run, ret) + ret = {} + self.assertRaises(AssertionError, p.run, ret) + self.assertEqual(ret['sla_pass'], 0) diff --git a/yardstick/tests/unit/benchmark/scenarios/lib/test_attach_volume.py b/yardstick/tests/unit/benchmark/scenarios/lib/test_attach_volume.py index 2964ecc14..bb7fa4536 100644 --- a/yardstick/tests/unit/benchmark/scenarios/lib/test_attach_volume.py +++ b/yardstick/tests/unit/benchmark/scenarios/lib/test_attach_volume.py @@ -6,21 +6,51 @@ # which accompanies this distribution, and is available at # http://www.apache.org/licenses/LICENSE-2.0 ############################################################################## +from oslo_utils import uuidutils import unittest import mock -from yardstick.benchmark.scenarios.lib.attach_volume import AttachVolume +from yardstick.common import openstack_utils +from yardstick.common import exceptions +from yardstick.benchmark.scenarios.lib import attach_volume class AttachVolumeTestCase(unittest.TestCase): - @mock.patch('yardstick.common.openstack_utils.attach_server_volume') - def test_attach_volume(self, mock_attach_server_volume): - options = { - 'volume_id': '123-456-000', - 'server_id': '000-123-456' - } - args = {"options": options} - obj = AttachVolume(args, {}) - obj.run({}) - mock_attach_server_volume.assert_called_once() + def setUp(self): + + self._mock_attach_volume_to_server = mock.patch.object( + openstack_utils, 'attach_volume_to_server') + self.mock_attach_volume_to_server = ( + self._mock_attach_volume_to_server.start()) + self._mock_get_shade_client = mock.patch.object( + openstack_utils, 'get_shade_client') + self.mock_get_shade_client = self._mock_get_shade_client.start() + self._mock_log = mock.patch.object(attach_volume, 'LOG') + self.mock_log = self._mock_log.start() + _uuid = uuidutils.generate_uuid() + self.args = {'options': {'server_name_or_id': _uuid, + 'volume_name_or_id': _uuid}} + self.result = {} + self.addCleanup(self._stop_mock) + self.attachvol_obj = attach_volume.AttachVolume(self.args, mock.ANY) + + def _stop_mock(self): + self._mock_attach_volume_to_server.stop() + self._mock_get_shade_client.stop() + self._mock_log.stop() + + def test_run(self): + self.mock_attach_volume_to_server.return_value = True + self.assertIsNone(self.attachvol_obj.run(self.result)) + self.assertEqual({'attach_volume': 1}, self.result) + self.mock_log.info.asset_called_once_with( + 'Attach volume to server successful!') + + def test_run_fail(self): + self.mock_attach_volume_to_server.return_value = False + with self.assertRaises(exceptions.ScenarioAttachVolumeError): + self.attachvol_obj.run(self.result) + self.assertEqual({'attach_volume': 0}, self.result) + self.mock_log.error.assert_called_once_with( + 'Attach volume to server failed!') diff --git a/yardstick/tests/unit/common/test_openstack_utils.py b/yardstick/tests/unit/common/test_openstack_utils.py index 4dc4a7082..3441ad264 100644 --- a/yardstick/tests/unit/common/test_openstack_utils.py +++ b/yardstick/tests/unit/common/test_openstack_utils.py @@ -445,3 +445,25 @@ class DeleteKeypairTestCase(unittest.TestCase): 'key_name') mock_logger.error.assert_called_once() self.assertFalse(output) + + +class AttachVolumeToServerTestCase(unittest.TestCase): + + def test_attach_volume_to_server(self): + self.mock_shade_client = mock.Mock() + self.mock_shade_client.get_server.return_value = {'server_dict'} + self.mock_shade_client.get_volume.return_value = {'volume_dict'} + self.mock_shade_client.attach_volume.return_value = True + output = openstack_utils.attach_volume_to_server( + self.mock_shade_client, 'server_name_or_id', 'volume_name_or_id') + self.assertTrue(output) + + @mock.patch.object(openstack_utils, 'log') + def test_attach_volume_to_server_fail(self, mock_logger): + self.mock_shade_client = mock.Mock() + self.mock_shade_client.attach_volume.side_effect = ( + exc.OpenStackCloudException('error message')) + output = openstack_utils.attach_volume_to_server( + self.mock_shade_client, 'server_name_or_id', 'volume_name_or_id') + mock_logger.error.assert_called_once() + self.assertFalse(output) diff --git a/yardstick/tests/unit/common/test_utils.py b/yardstick/tests/unit/common/test_utils.py index 9540a39e8..666b29b5f 100644 --- a/yardstick/tests/unit/common/test_utils.py +++ b/yardstick/tests/unit/common/test_utils.py @@ -16,13 +16,15 @@ import mock import os import six from six.moves import configparser +import time import unittest import yardstick from yardstick import ssh import yardstick.error -from yardstick.common import utils from yardstick.common import constants +from yardstick.common import utils +from yardstick.common import exceptions class IterSubclassesTestCase(unittest.TestCase): @@ -1158,3 +1160,43 @@ class ReadMeminfoTestCase(unittest.TestCase): output = utils.read_meminfo(ssh_client) mock_get_client.assert_called_once_with('/proc/meminfo', mock.ANY) self.assertEqual(self.MEMINFO_DICT, output) + + +class TimerTestCase(unittest.TestCase): + + def test__getattr(self): + with utils.Timer() as timer: + time.sleep(1) + self.assertEqual(1, round(timer.total_seconds(), 0)) + self.assertEqual(1, timer.delta.seconds) + + def test__enter_with_timeout(self): + with utils.Timer(timeout=10) as timer: + time.sleep(1) + self.assertEqual(1, round(timer.total_seconds(), 0)) + + def test__enter_with_timeout_exception(self): + with self.assertRaises(exceptions.TimerTimeout): + with utils.Timer(timeout=1): + time.sleep(2) + + +class WaitUntilTrueTestCase(unittest.TestCase): + + def test_no_timeout(self): + self.assertIsNone(utils.wait_until_true(lambda: True, + timeout=1, sleep=1)) + + def test_timeout_generic_exception(self): + with self.assertRaises(exceptions.WaitTimeout): + self.assertIsNone(utils.wait_until_true(lambda: False, + timeout=1, sleep=1)) + + def test_timeout_given_exception(self): + class MyTimeoutException(exceptions.YardstickException): + message = 'My timeout exception' + + with self.assertRaises(MyTimeoutException): + self.assertIsNone( + utils.wait_until_true(lambda: False, timeout=1, sleep=1, + exception=MyTimeoutException)) diff --git a/tests/unit/network_services/collector/__init__.py b/yardstick/tests/unit/network_services/__init__.py index e69de29bb..e69de29bb 100644 --- a/tests/unit/network_services/collector/__init__.py +++ b/yardstick/tests/unit/network_services/__init__.py diff --git a/tests/unit/network_services/libs/__init__.py b/yardstick/tests/unit/network_services/collector/__init__.py index e69de29bb..e69de29bb 100644 --- a/tests/unit/network_services/libs/__init__.py +++ b/yardstick/tests/unit/network_services/collector/__init__.py diff --git a/tests/unit/network_services/collector/test_publisher.py b/yardstick/tests/unit/network_services/collector/test_publisher.py index 4a175841d..145441ddd 100644 --- a/tests/unit/network_services/collector/test_publisher.py +++ b/yardstick/tests/unit/network_services/collector/test_publisher.py @@ -13,9 +13,6 @@ # limitations under the License. # -# Unittest for yardstick.network_services.collector.publisher - -from __future__ import absolute_import import unittest from yardstick.network_services.collector import publisher diff --git a/tests/unit/network_services/collector/test_subscriber.py b/yardstick/tests/unit/network_services/collector/test_subscriber.py index d4b4ecf7a..9b9649979 100644 --- a/tests/unit/network_services/collector/test_subscriber.py +++ b/yardstick/tests/unit/network_services/collector/test_subscriber.py @@ -13,9 +13,6 @@ # limitations under the License. # -# Unittest for yardstick.network_services.collector.subscriber - -from __future__ import absolute_import import unittest import mock diff --git a/tests/unit/network_services/libs/ixia_libs/__init__.py b/yardstick/tests/unit/network_services/libs/__init__.py index e69de29bb..e69de29bb 100644 --- a/tests/unit/network_services/libs/ixia_libs/__init__.py +++ b/yardstick/tests/unit/network_services/libs/__init__.py diff --git a/yardstick/tests/unit/network_services/libs/ixia_libs/__init__.py b/yardstick/tests/unit/network_services/libs/ixia_libs/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/yardstick/tests/unit/network_services/libs/ixia_libs/__init__.py diff --git a/tests/unit/network_services/libs/ixia_libs/test_IxNet.py b/yardstick/tests/unit/network_services/libs/ixia_libs/test_IxNet.py index 2a97048aa..fe750e5ba 100644 --- a/tests/unit/network_services/libs/ixia_libs/test_IxNet.py +++ b/yardstick/tests/unit/network_services/libs/ixia_libs/test_IxNet.py @@ -13,9 +13,6 @@ # limitations under the License. # -# Unittest for yardstick.network_services.libs.ixia_libs.IxNet - -from __future__ import absolute_import import unittest import mock @@ -23,10 +20,10 @@ from yardstick.network_services.libs.ixia_libs.IxNet.IxNet import IxNextgen from yardstick.network_services.libs.ixia_libs.IxNet.IxNet import IP_VERSION_4 from yardstick.network_services.libs.ixia_libs.IxNet.IxNet import IP_VERSION_6 - UPLINK = "uplink" DOWNLINK = "downlink" + class TestIxNextgen(unittest.TestCase): def test___init__(self): @@ -40,7 +37,8 @@ class TestIxNextgen(unittest.TestCase): ixnet_gen.get_config = mock.MagicMock() ixnet_gen.get_ixnet = mock.MagicMock() - self.assertRaises(ImportError, ixnet_gen._connect, {"py_lib_path": "/tmp"}) + self.assertRaises(ImportError, ixnet_gen._connect, + {"py_lib_path": "/tmp"}) def test_clear_ixia_config(self): ixnet = mock.MagicMock() @@ -628,11 +626,9 @@ class TestIxNextgen(unittest.TestCase): def test_set_random_ip_multi_attributes_bad_ip_version(self): bad_ip_version = object() ixnet_gen = IxNextgen(mock.Mock()) - mock1 = mock.Mock() - mock2 = mock.Mock() - mock3 = mock.Mock() with self.assertRaises(ValueError): - ixnet_gen.set_random_ip_multi_attributes(mock1, bad_ip_version, mock2, mock3) + ixnet_gen.set_random_ip_multi_attributes( + mock.Mock(), bad_ip_version, mock.Mock(), mock.Mock()) def test_get_config(self): tg_cfg = { diff --git a/tests/unit/network_services/test_utils.py b/yardstick/tests/unit/network_services/test_utils.py index bf98a4474..2b2eb7109 100644 --- a/tests/unit/network_services/test_utils.py +++ b/yardstick/tests/unit/network_services/test_utils.py @@ -13,8 +13,6 @@ # limitations under the License. # -# Unittest for yardstick.network_services.utils - import os import unittest import mock diff --git a/tests/unit/network_services/test_yang_model.py b/yardstick/tests/unit/network_services/test_yang_model.py index 0b29da701..a7eb36b8a 100644 --- a/tests/unit/network_services/test_yang_model.py +++ b/yardstick/tests/unit/network_services/test_yang_model.py @@ -13,14 +13,8 @@ # limitations under the License. # -# Unittest for yardstick.network_services.utils - -from __future__ import absolute_import - -import unittest import mock - -import yaml +import unittest from yardstick.network_services.yang_model import YangModel @@ -95,9 +89,9 @@ class YangModelTestCase(unittest.TestCase): y._get_entries() self.assertEqual(y._rules, '') - @mock.patch('yardstick.network_services.yang_model.yaml_load') @mock.patch('yardstick.network_services.yang_model.open') - def test__read_config(self, mock_open, mock_safe_load): + @mock.patch('yardstick.network_services.yang_model.yaml_load') + def test__read_config(self, mock_safe_load, *args): cfg = "yang.yaml" y = YangModel(cfg) mock_safe_load.return_value = expected = {'key1': 'value1', 'key2': 'value2'} |