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