Heat context code refactor part 2
[yardstick.git] / yardstick / benchmark / runners / sequence.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 changes a specified input value to the scenario.
11 The input value in the sequence is specified in a list in the input file.
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('scenario_option_name')
33     sequence_values = runner_cfg.get('sequence')
34
35     if 'options' not in scenario_cfg:
36         scenario_cfg['options'] = {}
37
38     options = scenario_cfg['options']
39
40     runner_cfg['runner_id'] = os.getpid()
41
42     LOG.info("worker START, sequence_values(%s, %s), class %s",
43              arg_name, sequence_values, cls)
44
45     benchmark = cls(scenario_cfg, context_cfg)
46     benchmark.setup()
47     method = getattr(benchmark, method_name)
48
49     queue.put({'runner_id': runner_cfg['runner_id'],
50                'scenario_cfg': scenario_cfg,
51                'context_cfg': context_cfg})
52
53     sla_action = None
54     if "sla" in scenario_cfg:
55         sla_action = scenario_cfg["sla"].get("action", "assert")
56
57     for value in sequence_values:
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 SequenceRunner(base.Runner):
106     '''Run a scenario by changing an input value defined in a list
107
108   Parameters
109     interval - time to wait between each scenario invocation
110         type:    int
111         unit:    seconds
112         default: 1 sec
113     scenario_option_name - name of the option that is increased each invocation
114         type:    string
115         unit:    na
116         default: none
117     sequence - list of values which are executed in their respective scenarios
118         type:    [int]
119         unit:    na
120         default: none
121     '''
122
123     __execution_type__ = 'Sequence'
124
125     def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
126         self.process = multiprocessing.Process(
127             target=_worker_process,
128             args=(self.result_queue, cls, method, scenario_cfg, context_cfg))
129         self.process.start()