Merge "unify pod keywork so api can easily used"
[yardstick.git] / yardstick / benchmark / scenarios / availability / monitor / basemonitor.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 from __future__ import absolute_import
10 import pkg_resources
11 import logging
12 import multiprocessing
13 import time
14 import os
15 import yardstick.common.utils as utils
16 import yaml
17
18 LOG = logging.getLogger(__name__)
19
20 monitor_conf_path = pkg_resources.resource_filename(
21     "yardstick.benchmark.scenarios.availability",
22     "monitor_conf.yaml")
23
24
25 class MonitorMgr(object):
26     """docstring for MonitorMgr"""
27
28     def __init__(self, data):
29         self._monitor_list = []
30         self.monitor_mgr_data = data
31
32     def init_monitors(self, monitor_cfgs, context):
33         LOG.debug("monitorMgr config: %s", monitor_cfgs)
34
35         for monitor_cfg in monitor_cfgs:
36             monitor_type = monitor_cfg["monitor_type"]
37             monitor_cls = BaseMonitor.get_monitor_cls(monitor_type)
38
39             monitor_number = monitor_cfg.get("monitor_number", 1)
40             if monitor_number > 1:
41                 monitor_cls = BaseMonitor.get_monitor_cls("multi-monitor")
42
43             monitor_ins = monitor_cls(monitor_cfg, context,
44                                       self.monitor_mgr_data)
45             if "key" in monitor_cfg:
46                 monitor_ins.key = monitor_cfg["key"]
47             self._monitor_list.append(monitor_ins)
48
49     def __getitem__(self, item):
50         for obj in self._monitor_list:
51             if obj.key == item:
52                 return obj
53         raise KeyError("No such monitor instance of key - %s" % item)
54
55     def start_monitors(self):
56         for _monotor_instace in self._monitor_list:
57             _monotor_instace.start_monitor()
58
59     def wait_monitors(self):
60         for monitor in self._monitor_list:
61             monitor.wait_monitor()
62
63     def verify_SLA(self):
64         sla_pass = True
65         for monitor in self._monitor_list:
66             sla_pass = sla_pass & monitor.verify_SLA()
67         return sla_pass
68
69
70 class BaseMonitor(multiprocessing.Process):
71     """docstring for BaseMonitor"""
72     monitor_cfgs = {}
73
74     def __init__(self, config, context, data):
75         if not BaseMonitor.monitor_cfgs:
76             with open(monitor_conf_path) as stream:
77                 BaseMonitor.monitor_cfgs = yaml.load(stream)
78         multiprocessing.Process.__init__(self)
79         self._config = config
80         self._context = context
81         self._queue = multiprocessing.Queue()
82         self._event = multiprocessing.Event()
83         self.monitor_data = data
84         self.setup_done = False
85
86     @staticmethod
87     def get_monitor_cls(monitor_type):
88         """return monitor class of specified type"""
89
90         for monitor in utils.itersubclasses(BaseMonitor):
91             if monitor_type == monitor.__monitor_type__:
92                 return monitor
93         raise RuntimeError("No such monitor_type %s" % monitor_type)
94
95     def get_script_fullpath(self, path):
96         base_path = os.path.dirname(monitor_conf_path)
97         return os.path.join(base_path, path)
98
99     def run(self):
100         LOG.debug("config:%s context:%s", self._config, self._context)
101
102         self.setup()
103         monitor_time = self._config.get("monitor_time", 0)
104
105         total_time = 0
106         outage_time = 0
107         total_count = 0
108         outage_count = 0
109         first_outage = 0
110         last_outage = 0
111
112         begin_time = time.time()
113         while True:
114             total_count = total_count + 1
115
116             one_check_begin_time = time.time()
117             exit_status = self.monitor_func()
118             one_check_end_time = time.time()
119
120             if exit_status is False:
121                 outage_count = outage_count + 1
122
123                 outage_time = outage_time + (
124                     one_check_end_time - one_check_begin_time)
125
126                 if not first_outage:
127                     first_outage = one_check_begin_time
128
129                 last_outage = one_check_end_time
130
131             if self._event.is_set():
132                 LOG.debug("the monitor process stop")
133                 break
134
135             if one_check_end_time - begin_time > monitor_time:
136                 LOG.debug("the monitor max_time finished and exit!")
137                 break
138
139         end_time = time.time()
140         total_time = end_time - begin_time
141
142         self._queue.put({"total_time": total_time,
143                          "outage_time": last_outage - first_outage,
144                          "last_outage": last_outage,
145                          "first_outage": first_outage,
146                          "total_count": total_count,
147                          "outage_count": outage_count})
148
149     def start_monitor(self):
150         self.start()
151
152     def wait_monitor(self):
153         self.join()
154         self._result = self._queue.get()
155         LOG.debug("the monitor result:%s", self._result)
156
157     def setup(self):  # pragma: no cover
158         pass
159
160     def monitor_func(self):  # pragma: no cover
161         pass
162
163     def verify_SLA(self):
164         pass
165
166     def result(self):
167         return self._result