40e0aa708f58514f65e4347469e4b9e744d74620
[yardstick.git] / yardstick / benchmark / runners / duration.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 runs a specific time 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     duration = runner_cfg.get("duration", 60)
32     LOG.info("worker START, duration %d sec, class %s", duration, 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     sla_action = None
41     if "sla" in scenario_cfg:
42         sla_action = scenario_cfg["sla"].get("action", "assert")
43
44     queue.put({'runner_id': runner_cfg['runner_id'],
45                'scenario_cfg': scenario_cfg,
46                'context_cfg': context_cfg})
47
48     start = time.time()
49     while True:
50
51         LOG.debug("runner=%(runner)s seq=%(sequence)s START" %
52                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
53
54         data = {}
55         errors = ""
56
57         try:
58             method(data)
59         except AssertionError as assertion:
60             # SLA validation failed in scenario, determine what to do now
61             if sla_action == "assert":
62                 raise
63             elif sla_action == "monitor":
64                 LOG.warning("SLA validation failed: %s" % assertion.args)
65                 errors = assertion.args
66         except Exception as e:
67             errors = traceback.format_exc()
68             LOG.exception(e)
69
70         time.sleep(interval)
71
72         benchmark_output = {
73             'timestamp': time.time(),
74             'sequence': sequence,
75             'data': data,
76             'errors': errors
77         }
78
79         record = {'runner_id': runner_cfg['runner_id'],
80                   'benchmark': benchmark_output}
81
82         queue.put(record)
83
84         LOG.debug("runner=%(runner)s seq=%(sequence)s END" %
85                   {"runner": runner_cfg["runner_id"], "sequence": sequence})
86
87         sequence += 1
88
89         if (errors and sla_action is None) or (time.time() - start > duration):
90             LOG.info("worker END")
91             break
92
93     benchmark.teardown()
94
95
96 class DurationRunner(base.Runner):
97     '''Run a scenario for a certain amount of time
98
99 If the scenario ends before the time has elapsed, it will be started again.
100
101   Parameters
102     duration - amount of time the scenario will be run for
103         type:    int
104         unit:    seconds
105         default: 1 sec
106     interval - time to wait between each scenario invocation
107         type:    int
108         unit:    seconds
109         default: 1 sec
110     '''
111     __execution_type__ = 'Duration'
112
113     def _run_benchmark(self, cls, method, scenario_cfg, context_cfg):
114         self.process = multiprocessing.Process(
115             target=_worker_process,
116             args=(self.result_queue, cls, method, scenario_cfg, context_cfg))
117         self.process.start()