To avoid breaking tests when monitor is set
[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,
26                     context_cfg, aborted):
27
28     sequence = 1
29
30     runner_cfg = scenario_cfg['runner']
31
32     interval = runner_cfg.get("interval", 1)
33     arg_name = runner_cfg.get('scenario_option_name')
34     sequence_values = runner_cfg.get('sequence')
35
36     if 'options' not in scenario_cfg:
37         scenario_cfg['options'] = {}
38
39     options = scenario_cfg['options']
40
41     runner_cfg['runner_id'] = os.getpid()
42
43     LOG.info("worker START, sequence_values(%s, %s), class %s",
44              arg_name, sequence_values, cls)
45
46     benchmark = cls(scenario_cfg, context_cfg)
47     benchmark.setup()
48     method = getattr(benchmark, method_name)
49
50     queue.put({'runner_id': runner_cfg['runner_id'],
51                'scenario_cfg': scenario_cfg,
52                'context_cfg': context_cfg})
53
54     sla_action = None
55     if "sla" in scenario_cfg:
56         sla_action = scenario_cfg["sla"].get("action", "assert")
57
58     for value in sequence_values:
59         options[arg_name] = value
60
61         LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
62                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
63
64         data = {}
65         errors = ""
66
67         try:
68             method(data)
69         except AssertionError as assertion:
70             # SLA validation failed in scenario, determine what to do now
71             if sla_action == "assert":
72                 raise
73             elif sla_action == "monitor":
74                 LOG.warning("SLA validation failed: %s" % assertion.args)
75                 errors = assertion.args
76         except Exception as e:
77             errors = traceback.format_exc()
78             LOG.exception(e)
79
80         time.sleep(interval)
81
82         benchmark_output = {
83             'timestamp': time.time(),
84             'sequence': sequence,
85             'data': data,
86             'errors': errors
87         }
88
89         record = {'runner_id': runner_cfg['runner_id'],
90                   'benchmark': benchmark_output}
91
92         queue.put(record)
93
94         LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
95                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
96
97         sequence += 1
98
99         if (errors and sla_action is None) or aborted.is_set():
100             break
101
102     benchmark.teardown()
103     LOG.info("worker END")
104
105
106 class SequenceRunner(base.Runner):
107     '''Run a scenario by changing an input value defined in a list
108
109   Parameters
110     interval - time to wait between each scenario invocation
111         type:    int
112         unit:    seconds
113         default: 1 sec
114     scenario_option_name - name of the option that is increased each invocation
115         type:    string
116         unit:    na
117         default: none
118     sequence - list of values which are executed in their respective scenarios
119         type:    [int]
120         unit:    na
121         default: none
122     '''
123
124     __execution_type__ = 'Sequence'
125
126     def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
127         self.process = multiprocessing.Process(
128             target=_worker_process,
129             args=(self.result_queue, cls, method, scenario_cfg,
130                   context_cfg, self.aborted))
131         self.process.start()