077e0e8138b82e7411214ede52fe3706ade0c6fa
[yardstick.git] / yardstick / benchmark / runners / iteration.py
1 ##############################################################################
2 # Copyright (c) 2015 Huawei Technologies Co.,Ltd 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 runs a configurable number of times before it returns
11 '''
12
13 import os
14 import multiprocessing
15 import logging
16 import traceback
17 import time
18
19 from yardstick.benchmark.runners import base
20
21 LOG = logging.getLogger(__name__)
22
23
24 def _worker_process(queue, cls, method_name, scenario_cfg, context_cfg):
25
26     sequence = 1
27
28     runner_cfg = scenario_cfg['runner']
29
30     interval = runner_cfg.get("interval", 1)
31     iterations = runner_cfg.get("iterations", 1)
32     LOG.info("worker START, iterations %d times, class %s", iterations, cls)
33
34     runner_cfg['runner_id'] = os.getpid()
35
36     benchmark = cls(scenario_cfg, context_cfg)
37     benchmark.setup()
38     method = getattr(benchmark, method_name)
39
40     queue.put({'runner_id': runner_cfg['runner_id'],
41                'scenario_cfg': scenario_cfg,
42                'context_cfg': context_cfg})
43
44     sla_action = None
45     if "sla" in scenario_cfg:
46         sla_action = scenario_cfg["sla"].get("action", "assert")
47
48     while True:
49
50         LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
51                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
52
53         data = {}
54         errors = ""
55
56         try:
57             method(data)
58         except AssertionError as assertion:
59             # SLA validation failed in scenario, determine what to do now
60             if sla_action == "assert":
61                 raise
62             elif sla_action == "monitor":
63                 LOG.warning("SLA validation failed: %s" % assertion.args)
64                 errors = assertion.args
65         except Exception as e:
66             errors = traceback.format_exc()
67             LOG.exception(e)
68
69         time.sleep(interval)
70
71         benchmark_output = {
72             'timestamp': time.time(),
73             'sequence': sequence,
74             'data': data,
75             'errors': errors
76         }
77
78         record = {'runner_id': runner_cfg['runner_id'],
79                   'benchmark': benchmark_output}
80
81         queue.put(record)
82
83         LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
84                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
85
86         sequence += 1
87
88         if (errors and sla_action is None) or (sequence > iterations):
89             LOG.info("worker END")
90             break
91
92     benchmark.teardown()
93
94
95 class IterationRunner(base.Runner):
96     '''Run a scenario for a configurable number of times
97
98 If the scenario ends before the time has elapsed, it will be started again.
99
100   Parameters
101     iterations - amount of times the scenario will be run for
102         type:    int
103         unit:    na
104         default: 1
105     interval - time to wait between each scenario invocation
106         type:    int
107         unit:    seconds
108         default: 1 sec
109     '''
110     __execution_type__ = 'Iteration'
111
112     def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
113         self.process = multiprocessing.Process(
114             target=_worker_process,
115             args=(self.result_queue, cls, method, scenario_cfg, context_cfg))
116         self.process.start()