1 ##############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
10 '''A runner that every run arithmetically steps specified input value(s) to
11 the scenario. This just means step value(s) is added to the previous value(s).
12 It is possible to combine several named input values and run with those either
13 as nested for loops or combine each i:th index of each "input value list"
14 until the end of the shortest list is reached (optimally all lists should be
15 defined with the same number of values when using such iter_type).
19 import multiprocessing
25 from yardstick.benchmark.runners import base
27 LOG = logging.getLogger(__name__)
30 def _worker_process(queue, cls, method_name, scenario_cfg,
31 context_cfg, aborted):
35 runner_cfg = scenario_cfg['runner']
37 interval = runner_cfg.get("interval", 1)
38 if 'options' in scenario_cfg:
39 options = scenario_cfg['options']
40 else: # options must be instatiated if not present in yaml
42 scenario_cfg['options'] = options
44 runner_cfg['runner_id'] = os.getpid()
46 LOG.info("worker START, class %s", cls)
48 benchmark = cls(scenario_cfg, context_cfg)
50 method = getattr(benchmark, method_name)
52 queue.put({'runner_id': runner_cfg['runner_id'],
53 'scenario_cfg': scenario_cfg,
54 'context_cfg': context_cfg})
57 if "sla" in scenario_cfg:
58 sla_action = scenario_cfg["sla"].get("action", "assert")
60 # To both be able to include the stop value and handle backwards stepping
61 margin = lambda start, stop: -1 if start > stop else 1
64 [xrange(d['start'], d['stop'] + margin(d['start'], d['stop']),
65 d['step']) for d in runner_cfg['iterators']]
66 param_names = [d['name'] for d in runner_cfg['iterators']]
68 iter_type = runner_cfg.get("iter_type", "nested_for_loops")
70 if iter_type == 'nested_for_loops':
71 # Create a complete combination set of all parameter lists
72 loop_iter = itertools.product(*param_iters)
73 elif iter_type == 'tuple_loops':
74 # Combine each i;th index of respective parameter list
75 loop_iter = itertools.izip(*param_iters)
77 LOG.warning("iter_type unrecognized: %s", iter_type)
80 # Populate options and run the requested method for each value combination
81 for comb_values in loop_iter:
86 LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
87 {"runner": runner_cfg["runner_id"], "sequence": sequence})
89 for i, value in enumerate(comb_values):
90 options[param_names[i]] = value
97 except AssertionError as assertion:
98 # SLA validation failed in scenario, determine what to do now
99 if sla_action == "assert":
101 elif sla_action == "monitor":
102 LOG.warning("SLA validation failed: %s" % assertion.args)
103 errors = assertion.args
104 except Exception as e:
105 errors = traceback.format_exc()
111 'timestamp': time.time(),
112 'sequence': sequence,
117 record = {'runner_id': runner_cfg['runner_id'],
118 'benchmark': benchmark_output}
122 LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
123 {"runner": runner_cfg["runner_id"], "sequence": sequence})
127 if (errors and sla_action is None):
131 LOG.info("worker END")
134 class ArithmeticRunner(base.Runner):
135 '''Run a scenario arithmetically stepping input value(s)
138 interval - time to wait between each scenario invocation
142 iter_type: - Iteration type of input parameter(s): nested_for_loops
146 default: nested_for_loops
148 name - name of scenario option that will be increased for each invocation
152 start - value to use in first invocation of scenario
156 stop - value indicating end of invocation. Can be set to same
157 value as start for one single value.
161 step - value added to start value in next invocation of scenario.
162 Must not be set to zero. Can be set negative if start > stop
167 name - and so on......
170 __execution_type__ = 'Arithmetic'
172 def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
173 self.process = multiprocessing.Process(
174 target=_worker_process,
175 args=(self.result_queue, cls, method, scenario_cfg,
176 context_cfg, self.aborted))