diff options
-rw-r--r-- | yardstick/benchmark/runners/duration.py | 6 | ||||
-rw-r--r-- | yardstick/benchmark/runners/iteration.py | 6 | ||||
-rw-r--r-- | yardstick/benchmark/scenarios/base.py | 30 | ||||
-rw-r--r-- | yardstick/benchmark/scenarios/networking/vnf_generic.py | 9 | ||||
-rw-r--r-- | yardstick/tests/unit/benchmark/scenarios/test_base.py | 30 |
5 files changed, 69 insertions, 12 deletions
diff --git a/yardstick/benchmark/runners/duration.py b/yardstick/benchmark/runners/duration.py index fbf72a74c..60b0348c3 100644 --- a/yardstick/benchmark/runners/duration.py +++ b/yardstick/benchmark/runners/duration.py @@ -66,6 +66,8 @@ def _worker_process(queue, cls, method_name, scenario_cfg, data = {} errors = "" + benchmark.pre_run_wait_time(interval) + try: result = method(data) except AssertionError as assertion: @@ -77,7 +79,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, errors = assertion.args # catch all exceptions because with multiprocessing we can have un-picklable exception # problems https://bugs.python.org/issue9400 - except Exception: + except Exception: # pylint: disable=broad-except errors = traceback.format_exc() LOG.exception("") else: @@ -86,7 +88,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, # if we do timeout we don't care about dropping individual KPIs output_queue.put(result, True, QUEUE_PUT_TIMEOUT) - time.sleep(interval) + benchmark.post_run_wait_time(interval) benchmark_output = { 'timestamp': time.time(), diff --git a/yardstick/benchmark/runners/iteration.py b/yardstick/benchmark/runners/iteration.py index cb0424377..20d6da054 100644 --- a/yardstick/benchmark/runners/iteration.py +++ b/yardstick/benchmark/runners/iteration.py @@ -71,6 +71,8 @@ def _worker_process(queue, cls, method_name, scenario_cfg, data = {} errors = "" + benchmark.pre_run_wait_time(interval) + try: result = method(data) except AssertionError as assertion: @@ -90,7 +92,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, scenario_cfg['options']['rate'] -= delta sequence = 1 continue - except Exception: + except Exception: # pylint: disable=broad-except errors = traceback.format_exc() LOG.exception("") else: @@ -99,7 +101,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, # if we do timeout we don't care about dropping individual KPIs output_queue.put(result, True, QUEUE_PUT_TIMEOUT) - time.sleep(interval) + benchmark.post_run_wait_time(interval) benchmark_output = { 'timestamp': time.time(), diff --git a/yardstick/benchmark/scenarios/base.py b/yardstick/benchmark/scenarios/base.py index 10a728828..58a02805c 100644 --- a/yardstick/benchmark/scenarios/base.py +++ b/yardstick/benchmark/scenarios/base.py @@ -13,9 +13,10 @@ # License for the specific language governing permissions and limitations # under the License. -# yardstick comment: this is a modified copy of -# rally/rally/benchmark/scenarios/base.py +import abc +import time +import six from stevedore import extension import yardstick.common.utils as utils @@ -37,20 +38,29 @@ def _iter_scenario_classes(scenario_type=None): yield scenario +@six.add_metaclass(abc.ABCMeta) class Scenario(object): def setup(self): - """ default impl for scenario setup """ + """Default setup implementation for Scenario classes""" pass + @abc.abstractmethod def run(self, *args): - """ catcher for not implemented run methods in subclasses """ - raise RuntimeError("run method not implemented") + """Entry point for scenario classes, called from runner worker""" def teardown(self): - """ default impl for scenario teardown """ + """Default teardown implementation for Scenario classes""" pass + def pre_run_wait_time(self, time_seconds): + """Time waited before executing the run method""" + pass + + def post_run_wait_time(self, time_seconds): + """Time waited after executing the run method""" + time.sleep(time_seconds) + @staticmethod def get_types(): """return a list of known runner type (class) names""" @@ -88,10 +98,14 @@ class Scenario(object): """ return cls.__doc__.splitlines()[0] if cls.__doc__ else str(None) - def _push_to_outputs(self, keys, values): + @staticmethod + def _push_to_outputs(keys, values): + """Return a dictionary given the keys and the values""" return dict(zip(keys, values)) - def _change_obj_to_dict(self, obj): + @staticmethod + def _change_obj_to_dict(obj): + """Return a dictionary from the __dict__ attribute of an object""" dic = {} for k, v in vars(obj).items(): try: diff --git a/yardstick/benchmark/scenarios/networking/vnf_generic.py b/yardstick/benchmark/scenarios/networking/vnf_generic.py index 0e4785294..be2fa3f3b 100644 --- a/yardstick/benchmark/scenarios/networking/vnf_generic.py +++ b/yardstick/benchmark/scenarios/networking/vnf_generic.py @@ -14,6 +14,7 @@ import copy import logging +import time import ipaddress from itertools import chain @@ -484,3 +485,11 @@ class NetworkServiceTestCase(scenario_base.Scenario): # https://bugs.python.org/issue9400 LOG.exception("") raise RuntimeError("Error in teardown") + + def pre_run_wait_time(self, time_seconds): + """Time waited before executing the run method""" + time.sleep(time_seconds) + + def post_run_wait_time(self, time_seconds): + """Time waited after executing the run method""" + pass diff --git a/yardstick/tests/unit/benchmark/scenarios/test_base.py b/yardstick/tests/unit/benchmark/scenarios/test_base.py index 985338532..284a71cc8 100644 --- a/yardstick/tests/unit/benchmark/scenarios/test_base.py +++ b/yardstick/tests/unit/benchmark/scenarios/test_base.py @@ -13,10 +13,21 @@ # License for the specific language governing permissions and limitations # under the License. +import time + +import mock + from yardstick.benchmark.scenarios import base from yardstick.tests.unit import base as ut_base +class _TestScenario(base.Scenario): + __scenario_type__ = 'Test Scenario' + + def run(self): + pass + + class ScenarioTestCase(ut_base.BaseUnitTestCase): def test_get_scenario_type(self): @@ -85,6 +96,25 @@ class ScenarioTestCase(ut_base.BaseUnitTestCase): self.assertEqual('No such scenario type %s' % wrong_scenario_name, str(exc.exception)) + def test_scenario_abstract_class(self): + # pylint: disable=abstract-class-instantiated + with self.assertRaises(TypeError): + base.Scenario() + + @mock.patch.object(time, 'sleep') + def test_pre_run_wait_time(self, mock_sleep): + """Ensure default behaviour (backwards compatibility): no wait time""" + test_scenario = _TestScenario() + test_scenario.pre_run_wait_time(mock.ANY) + mock_sleep.assert_not_called() + + @mock.patch.object(time, 'sleep') + def test_post_run_wait_time(self, mock_sleep): + """Ensure default behaviour (backwards compatibility): wait time""" + test_scenario = _TestScenario() + test_scenario.post_run_wait_time(100) + mock_sleep.assert_called_once_with(100) + class IterScenarioClassesTestCase(ut_base.BaseUnitTestCase): |