af2303479b8cfe672ad80ed67e2c1298e1d8f135
[yardstick.git] / yardstick / benchmark / runners / arithmetic.py
1 ##############################################################################
2 # Copyright (c) 2015 Ericsson AB and others.
3 #
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 ##############################################################################
9
10 '''A runner that every run arithmetically steps a specified input value to
11 the scenario. This just means a step value is added to the previous value.
12 '''
13
14 import os
15 import multiprocessing
16 import logging
17 import traceback
18 import time
19
20 from yardstick.benchmark.runners import base
21
22 LOG = logging.getLogger(__name__)
23
24
25 def _worker_process(queue, cls, method_name, scenario_cfg, context_cfg):
26
27     sequence = 1
28
29     runner_cfg = scenario_cfg['runner']
30
31     interval = runner_cfg.get("interval", 1)
32     arg_name = runner_cfg.get('name')
33     stop = runner_cfg.get('stop')
34     step = runner_cfg.get('step')
35     options = scenario_cfg['options']
36     start = options.get(arg_name, 0)
37
38     runner_cfg['runner_id'] = os.getpid()
39
40     LOG.info("worker START, step(%s, %d, %d, %d), class %s",
41              arg_name, start, stop, step, cls)
42
43     benchmark = cls(scenario_cfg, context_cfg)
44     benchmark.setup()
45     method = getattr(benchmark, method_name)
46
47     queue.put({'runner_id': runner_cfg['runner_id'],
48                'scenario_cfg': scenario_cfg,
49                'context_cfg': context_cfg})
50
51     sla_action = None
52     if "sla" in scenario_cfg:
53         sla_action = scenario_cfg["sla"].get("action", "assert")
54     margin = 1 if step > 0 else -1
55
56     for value in range(start, stop+margin, step):
57
58         options[arg_name] = value
59
60         LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
61                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
62
63         data = {}
64         errors = ""
65
66         try:
67             method(data)
68         except AssertionError as assertion:
69             # SLA validation failed in scenario, determine what to do now
70             if sla_action == "assert":
71                 raise
72             elif sla_action == "monitor":
73                 LOG.warning("SLA validation failed: %s" % assertion.args)
74                 errors = assertion.args
75         except Exception as e:
76             errors = traceback.format_exc()
77             LOG.exception(e)
78
79         time.sleep(interval)
80
81         benchmark_output = {
82             'timestamp': time.time(),
83             'sequence': sequence,
84             'data': data,
85             'errors': errors
86         }
87
88         record = {'runner_id': runner_cfg['runner_id'],
89                   'benchmark': benchmark_output}
90
91         queue.put(record)
92
93         LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
94                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
95
96         sequence += 1
97
98         if errors:
99             break
100
101     benchmark.teardown()
102     LOG.info("worker END")
103
104
105 class ArithmeticRunner(base.Runner):
106     '''Run a scenario arithmetically stepping an input value
107
108   Parameters
109     interval - time to wait between each scenario invocation
110         type:    int
111         unit:    seconds
112         default: 1 sec
113     name - name of scenario option that will be increased for each invocation
114         type:    string
115         unit:    na
116         default: none
117     start - value to use in first invocation of scenario
118         type:    int
119         unit:    na
120         default: none
121     step - value added to start value in next invocation of scenario
122         type:    int
123         unit:    na
124         default: none
125     stop - value indicating end of invocation
126         type:    int
127         unit:    na
128         default: none
129     '''
130
131     __execution_type__ = 'Arithmetic'
132
133     def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
134         self.process = multiprocessing.Process(
135             target=_worker_process,
136             args=(self.result_queue, cls, method, scenario_cfg, context_cfg))
137         self.process.start()