X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=yardstick%2Fbenchmark%2Frunners%2Farithmetic.py;h=6aaaed888930d6f10008eb732635a21cb73e4854;hb=0b340735f2a37b9a05d3d86f79aa706b3e43bb5d;hp=b1446e01c687aaa51f7105910d46adb16bab470d;hpb=0c98e8f83d3548f4f2dc91cfc6e743833fb635c9;p=yardstick.git diff --git a/yardstick/benchmark/runners/arithmetic.py b/yardstick/benchmark/runners/arithmetic.py index b1446e01c..6aaaed888 100755 --- a/yardstick/benchmark/runners/arithmetic.py +++ b/yardstick/benchmark/runners/arithmetic.py @@ -1,26 +1,40 @@ -############################################################################## -# Copyright (c) 2015 Ericsson AB and others. +# Copyright 2014: Mirantis Inc. +# All Rights Reserved. # -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## +# 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. -'''A runner that every run arithmetically steps specified input value(s) to +# yardstick comment: this is a modified copy of +# rally/rally/benchmark/runners/constant.py + +"""A runner that every run arithmetically steps specified input value(s) to the scenario. This just means step value(s) is added to the previous value(s). It is possible to combine several named input values and run with those either as nested for loops or combine each i:th index of each "input value list" until the end of the shortest list is reached (optimally all lists should be defined with the same number of values when using such iter_type). -''' +""" -import os -import multiprocessing +from __future__ import absolute_import + +import itertools import logging -import traceback +import multiprocessing +import os import time -import itertools +import traceback + +import six +from six.moves import range from yardstick.benchmark.runners import base @@ -28,7 +42,7 @@ LOG = logging.getLogger(__name__) def _worker_process(queue, cls, method_name, scenario_cfg, - context_cfg, aborted): + context_cfg, aborted, output_queue): sequence = 1 @@ -49,20 +63,17 @@ def _worker_process(queue, cls, method_name, scenario_cfg, benchmark.setup() method = getattr(benchmark, method_name) - queue.put({'runner_id': runner_cfg['runner_id'], - 'scenario_cfg': scenario_cfg, - 'context_cfg': context_cfg}) - sla_action = None if "sla" in scenario_cfg: sla_action = scenario_cfg["sla"].get("action", "assert") # To both be able to include the stop value and handle backwards stepping - margin = lambda start, stop: -1 if start > stop else 1 + def margin(start, stop): + return -1 if start > stop else 1 param_iters = \ - [xrange(d['start'], d['stop'] + margin(d['start'], d['stop']), - d['step']) for d in runner_cfg['iterators']] + [range(d['start'], d['stop'] + margin(d['start'], d['stop']), + d['step']) for d in runner_cfg['iterators']] param_names = [d['name'] for d in runner_cfg['iterators']] iter_type = runner_cfg.get("iter_type", "nested_for_loops") @@ -72,10 +83,10 @@ def _worker_process(queue, cls, method_name, scenario_cfg, loop_iter = itertools.product(*param_iters) elif iter_type == 'tuple_loops': # Combine each i;th index of respective parameter list - loop_iter = itertools.izip(*param_iters) + loop_iter = six.moves.zip(*param_iters) else: LOG.warning("iter_type unrecognized: %s", iter_type) - raise + raise TypeError("iter_type unrecognized: %s", iter_type) # Populate options and run the requested method for each value combination for comb_values in loop_iter: @@ -83,7 +94,7 @@ def _worker_process(queue, cls, method_name, scenario_cfg, if aborted.is_set(): break - LOG.debug("runner=%(runner)s seq=%(sequence)s START" % + LOG.debug("runner=%(runner)s seq=%(sequence)s START", {"runner": runner_cfg["runner_id"], "sequence": sequence}) for i, value in enumerate(comb_values): @@ -93,17 +104,20 @@ def _worker_process(queue, cls, method_name, scenario_cfg, errors = "" try: - method(data) + result = method(data) except AssertionError as assertion: # 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" % assertion.args) + LOG.warning("SLA validation failed: %s", assertion.args) errors = assertion.args except Exception as e: errors = traceback.format_exc() LOG.exception(e) + else: + if result: + output_queue.put(result) time.sleep(interval) @@ -114,25 +128,32 @@ def _worker_process(queue, cls, method_name, scenario_cfg, 'errors': errors } - record = {'runner_id': runner_cfg['runner_id'], - 'benchmark': benchmark_output} - - queue.put(record) + queue.put(benchmark_output) - LOG.debug("runner=%(runner)s seq=%(sequence)s END" % + LOG.debug("runner=%(runner)s seq=%(sequence)s END", {"runner": runner_cfg["runner_id"], "sequence": sequence}) sequence += 1 - if errors: + if errors and sla_action is None: break - benchmark.teardown() + try: + benchmark.teardown() + except Exception: + # catch any exception in teardown and convert to simple exception + # never pass exceptions back to multiprocessing, because some exceptions can + # be unpicklable + # https://bugs.python.org/issue9400 + LOG.exception("") + raise SystemExit(1) LOG.info("worker END") + LOG.debug("queue.qsize() = %s", queue.qsize()) + LOG.debug("output_queue.qsize() = %s", output_queue.qsize()) class ArithmeticRunner(base.Runner): - '''Run a scenario arithmetically stepping input value(s) + """Run a scenario arithmetically stepping input value(s) Parameters interval - time to wait between each scenario invocation @@ -165,13 +186,15 @@ class ArithmeticRunner(base.Runner): default: none - name - and so on...... - ''' + """ __execution_type__ = 'Arithmetic' def _run_benchmark(self, cls, method, scenario_cfg, context_cfg): + name = "{}-{}-{}".format(self.__execution_type__, scenario_cfg.get("type"), os.getpid()) self.process = multiprocessing.Process( + name=name, target=_worker_process, args=(self.result_queue, cls, method, scenario_cfg, - context_cfg, self.aborted)) + context_cfg, self.aborted, self.output_queue)) self.process.start()