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