3e03e1da5fb7fd5a2124865e42fde49e5e6bae0f
[yardstick.git] / yardstick / benchmark / scenarios / availability / serviceha.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 import pkg_resources
10 import logging
11 import time
12 import yaml
13 import yardstick.ssh as ssh
14 from yardstick.benchmark.scenarios import base
15 from yardstick.benchmark.scenarios.availability import monitor
16
17 LOG = logging.getLogger(__name__)
18
19
20 class ServiceHA(base.Scenario):
21     """TODO: docstring of ServiceHA
22     """
23     __scenario_type__ = "ServiceHA"
24
25     HA_CONF = "ha_tools/ha_conf.yaml"
26
27     def __init__(self, scenario_cfg, context_cfg):
28         self.scenario_cfg = scenario_cfg
29         self.context_cfg = context_cfg
30         self.service_name = scenario_cfg["options"]["component"]
31         self.fault_type = scenario_cfg["options"]["fault_type"]
32         self.fault_time = scenario_cfg["options"].get("fault_time", 0)
33         self.fault_cfg = None
34         self.setup_done = False
35         self.need_teardown = False
36
37     def setup(self):
38         '''scenario setup'''
39         self.ha_conf_file = pkg_resources.resource_filename(
40             "yardstick.benchmark.scenarios.availability",
41             ServiceHA.HA_CONF)
42         ha_cfg = []
43         with open(self.ha_conf_file) as stream:
44                 ha_cfg = yaml.load(stream)
45         LOG.debug("ha_cfg content:%s" % ha_cfg)
46
47         # check the ha_conf contains the service defined in test cases yaml
48         service_cfg = ha_cfg.get(self.service_name, None)
49         if not service_cfg:
50             LOG.error(
51                 "The component %s can not be supported!" % self.service_name)
52             return
53
54         for fault in service_cfg:
55             if fault["type"] == self.fault_type:
56                 self.fault_cfg = fault
57                 break
58         if not self.fault_cfg:
59             LOG.error(
60                 "The fualt_type %s can not be supproted!" % self.fault_type)
61             return
62         LOG.debug("the fault_cfg :%s" % self.fault_cfg)
63
64         self.fault_script = pkg_resources.resource_filename(
65             "yardstick.benchmark.scenarios.availability",
66             self.fault_cfg["inject_script"])
67         self.recovery_script = pkg_resources.resource_filename(
68             "yardstick.benchmark.scenarios.availability",
69             self.fault_cfg["recovery_script"])
70         self.check_script = pkg_resources.resource_filename(
71             "yardstick.benchmark.scenarios.availability",
72             self.fault_cfg["check_script"])
73
74         host = self.context_cfg.get("host", None)
75         ip = host.get("ip", None)
76         user = host.get("user", "root")
77         key_filename = host.get("key_filename", "~/.ssh/id_rsa")
78         LOG.info("The host: %s  the service: %s" % (ip, self.service_name))
79         LOG.debug("The params, host:%s  fault_cfg:%s" % (host, self.fault_cfg))
80
81         LOG.debug(
82             "ssh connection ip:%s, user:%s, key_file:%s",
83             ip, user, key_filename)
84         self.connection = ssh.SSH(user, ip, key_filename=key_filename)
85         self.connection.wait(timeout=600)
86         LOG.debug("ssh host success!")
87
88         # check the host envrioment
89         exit_status, stdout, stderr = self.connection.execute(
90             "/bin/sh -s {0}".format(self.service_name),
91             stdin=open(self.check_script, "r"))
92         LOG.info(
93             "the exit_status:%s stdout:%s stderr:%s" %
94             (exit_status, stdout, stderr))
95         if exit_status:
96             raise RuntimeError(stderr)
97
98         if stdout and "running" in stdout:
99             LOG.info("check the envrioment success!")
100         else:
101             LOG.error(
102                 "the host envrioment is error, stdout:%s, stderr:%s" %
103                 (stdout, stderr))
104             return
105
106         self.setup_done = True
107
108     def run(self, result):
109         """execute the benchmark"""
110         if not self.setup_done:
111             LOG.error("The setup not finished!")
112             return
113
114         monitorInstance = monitor.Monitor()
115         monitorInstance.setup(self.fault_cfg)
116         monitorInstance.start()
117         LOG.info("monitor start!")
118
119         LOG.info("Inject fault!")
120         exit_status, stdout, stderr = self.connection.execute(
121             "/bin/sh -s {0}".format(self.service_name),
122             stdin=open(self.fault_script, "r"))
123
124         if exit_status != 0:
125             monitorInstance.stop()
126             raise RuntimeError(stderr)
127
128         self.need_teardown = True
129         time.sleep(self.fault_time)
130
131         monitorInstance.stop()
132         LOG.info("monitor stop!")
133
134         ret = monitorInstance.get_result()
135         LOG.info("The monitor result:%s" % ret)
136         outage_time = ret.get("outage_time")
137         result["outage_time"] = outage_time
138         LOG.info("the result:%s" % result)
139
140         if "sla" in self.scenario_cfg:
141             sla_outage_time = int(self.scenario_cfg["sla"]["outage_time"])
142             assert outage_time <= sla_outage_time, "outage_time %f > sla:outage_time(%f)" % \
143                 (outage_time, sla_outage_time)
144
145         return
146
147     def teardown(self):
148         '''scenario teardown'''
149         LOG.info("recory the everiment!")
150
151         if self.need_teardown:
152             exit_status, stdout, stderr = self.connection.execute(
153                 "/bin/sh -s {0} ".format(self.service_name),
154                 stdin=open(self.recovery_script, "r"))
155
156             if exit_status:
157                 raise RuntimeError(stderr)
158             else:
159                 self.need_teardown = False
160
161 """
162 def _test():
163     '''internal test function'''
164     host = {
165         "ip": "10.20.0.5",
166         "user": "root",
167         "key_filename": "/root/.ssh/id_rsa"
168     }
169     ctx = {"host": host}
170
171     logger = logging.getLogger("yardstick")
172     logger.setLevel(logging.DEBUG)
173
174     options = {
175         "component": "nova-api",
176         "fault_type": "stop-service"
177     }
178     sla = {"outage_time": 5}
179     args = {"options": options, "sla": sla}
180
181     print "create instance"
182     terstInstance = ServiceHA(args, ctx)
183
184     terstInstance.setup()
185     result = {}
186     terstInstance.run(result)
187     print result
188
189     terstInstance.teardown()
190
191 if __name__ == '__main__':
192     _test()
193 """