fe53412ca0ac677b86d1a44ea06e39e1b87d24f0
[yardstick.git] / yardstick / benchmark / runners / sequence.py
1 # Copyright 2014: Mirantis Inc.
2 # All Rights Reserved.
3 #
4 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
5 #    not use this file except in compliance with the License. You may obtain
6 #    a copy of the License at
7 #
8 #         http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #    Unless required by applicable law or agreed to in writing, software
11 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 #    License for the specific language governing permissions and limitations
14 #    under the License.
15
16 # yardstick comment: this is a modified copy of
17 # rally/rally/benchmark/runners/constant.py
18
19 '''A runner that every run changes a specified input value to the scenario.
20 The input value in the sequence is specified in a list in the input file.
21 '''
22
23 import os
24 import multiprocessing
25 import logging
26 import traceback
27 import time
28
29 from yardstick.benchmark.runners import base
30
31 LOG = logging.getLogger(__name__)
32
33
34 def _worker_process(queue, cls, method_name, scenario_cfg,
35                     context_cfg, aborted):
36
37     sequence = 1
38
39     runner_cfg = scenario_cfg['runner']
40
41     interval = runner_cfg.get("interval", 1)
42     arg_name = runner_cfg.get('scenario_option_name')
43     sequence_values = runner_cfg.get('sequence')
44
45     if 'options' not in scenario_cfg:
46         scenario_cfg['options'] = {}
47
48     options = scenario_cfg['options']
49
50     runner_cfg['runner_id'] = os.getpid()
51
52     LOG.info("worker START, sequence_values(%s, %s), class %s",
53              arg_name, sequence_values, cls)
54
55     benchmark = cls(scenario_cfg, context_cfg)
56     benchmark.setup()
57     method = getattr(benchmark, method_name)
58
59     queue.put({'runner_id': runner_cfg['runner_id'],
60                'scenario_cfg': scenario_cfg,
61                'context_cfg': context_cfg})
62
63     sla_action = None
64     if "sla" in scenario_cfg:
65         sla_action = scenario_cfg["sla"].get("action", "assert")
66
67     for value in sequence_values:
68         options[arg_name] = value
69
70         LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
71                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
72
73         data = {}
74         errors = ""
75
76         try:
77             method(data)
78         except AssertionError as assertion:
79             # SLA validation failed in scenario, determine what to do now
80             if sla_action == "assert":
81                 raise
82             elif sla_action == "monitor":
83                 LOG.warning("SLA validation failed: %s" % assertion.args)
84                 errors = assertion.args
85         except Exception as e:
86             errors = traceback.format_exc()
87             LOG.exception(e)
88
89         time.sleep(interval)
90
91         benchmark_output = {
92             'timestamp': time.time(),
93             'sequence': sequence,
94             'data': data,
95             'errors': errors
96         }
97
98         record = {'runner_id': runner_cfg['runner_id'],
99                   'benchmark': benchmark_output}
100
101         queue.put(record)
102
103         LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
104                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
105
106         sequence += 1
107
108         if (errors and sla_action is None) or aborted.is_set():
109             break
110
111     benchmark.teardown()
112     LOG.info("worker END")
113
114
115 class SequenceRunner(base.Runner):
116     '''Run a scenario by changing an input value defined in a list
117
118   Parameters
119     interval - time to wait between each scenario invocation
120         type:    int
121         unit:    seconds
122         default: 1 sec
123     scenario_option_name - name of the option that is increased each invocation
124         type:    string
125         unit:    na
126         default: none
127     sequence - list of values which are executed in their respective scenarios
128         type:    [int]
129         unit:    na
130         default: none
131     '''
132
133     __execution_type__ = 'Sequence'
134
135     def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
136         self.process = multiprocessing.Process(
137             target=_worker_process,
138             args=(self.result_queue, cls, method, scenario_cfg,
139                   context_cfg, self.aborted))
140         self.process.start()