refactor failure inject
[doctor.git] / tests / main.py
1 ##############################################################################
2 # Copyright (c) 2017 ZTE Corporation 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 os
10 from os.path import isfile, join
11 import random
12 import sys
13 import time
14
15 from alarm import Alarm
16 from common.constants import Host
17 import config
18 from consumer import get_consumer
19 from identity_auth import get_identity_auth
20 from identity_auth import get_session
21 from image import Image
22 from instance import Instance
23 from inspector import get_inspector
24 from installer import get_installer
25 import logger as doctor_log
26 from network import Network
27 from monitor import get_monitor
28 from os_clients import nova_client
29 from scenario.common import calculate_notification_time
30 from scenario.network_failure import NetworkFault
31 from user import User
32
33
34 LOG = doctor_log.Logger('doctor').getLogger()
35
36
37 class DoctorTest(object):
38
39     def __init__(self, conf):
40         self.conf = conf
41         self.image = Image(self.conf, LOG)
42         self.user = User(self.conf, LOG)
43         self.network = Network(self.conf, LOG)
44         self.instance = Instance(self.conf, LOG)
45         self.alarm = Alarm(self.conf, LOG)
46         self.installer = get_installer(self.conf, LOG)
47         self.inspector = get_inspector(self.conf, LOG)
48         self.monitor = get_monitor(self.conf,
49                                    self.inspector.get_inspector_url(),
50                                    LOG)
51         self.consumer = get_consumer(self.conf, LOG)
52         self.fault = NetworkFault(self.conf, self.installer, LOG)
53         auth = get_identity_auth(project=self.conf.doctor_project)
54         self.nova = nova_client(self.conf.nova_version,
55                                 get_session(auth=auth))
56         self.down_host = None
57
58     def setup(self):
59         # prepare the cloud env
60         self.installer.setup()
61
62         # preparing VM image...
63         self.image.create()
64
65         # creating test user...
66         self.user.create()
67         self.user.update_quota()
68
69         # creating VM...
70         self.network.create()
71         self.instance.create()
72         self.instance.wait_for_vm_launch()
73
74         # creating alarm...
75         self.alarm.create()
76
77         # starting doctor sample components...
78         self.inspector.start()
79
80         self.down_host = self.get_host_info_for_random_vm()
81         self.monitor.start(self.down_host)
82
83         self.consumer.start()
84
85     def run(self):
86         """run doctor test"""
87         try:
88             LOG.info('doctor test starting.......')
89
90             # prepare test env
91             self.setup()
92
93             # wait for aodh alarms are updated in caches for event evaluator,
94             # sleep time should be larger than event_alarm_cache_ttl(default 60)
95             time.sleep(60)
96
97             # injecting host failure...
98             # NOTE (umar) add INTERFACE_NAME logic to host injection
99
100             self.fault.start(self.down_host)
101             time.sleep(10)
102
103             # verify the test results
104             # NOTE (umar) copy remote monitor.log file when monitor=collectd
105             self.check_host_status(self.down_host.name, 'down')
106
107             notification_time = calculate_notification_time()
108             if notification_time < 1 and notification_time > 0:
109                 LOG.info('doctor test successfully, notification_time=%s' % notification_time)
110             else:
111                 LOG.error('doctor test failed, notification_time=%s' % notification_time)
112                 sys.exit(1)
113         except Exception as e:
114             LOG.error('doctor test failed, Exception=%s' % e)
115             sys.exit(1)
116         finally:
117             self.cleanup()
118
119     def get_host_info_for_random_vm(self):
120         num = random.randint(0, self.conf.instance_count - 1)
121         vm_name = "%s%d" % (self.conf.instance_basename, num)
122
123         servers = \
124             {getattr(server, 'name'): server
125              for server in self.nova.servers.list()}
126         server = servers.get(vm_name)
127         if not server:
128             raise \
129                 Exception('Can not find instance: vm_name(%s)' % vm_name)
130         host_name = server.__dict__.get('OS-EXT-SRV-ATTR:hypervisor_hostname')
131         host_ip = self.installer.get_host_ip_from_hostname(host_name)
132
133         LOG.info('Get host info(name:%s, ip:%s) which vm(%s) launched at'
134                  % (host_name, host_ip, vm_name))
135         return Host(host_name, host_ip)
136
137     def check_host_status(self, hostname, state):
138         service = self.nova.services.list(host=hostname, binary='nova-compute')
139         host_state = service[0].__dict__.get('state')
140         assert host_state == state
141
142     def unset_forced_down_hosts(self):
143         if self.down_host:
144             self.nova.services.force_down(self.down_host.name, 'nova-compute', False)
145             time.sleep(2)
146             self.check_host_status(self.down_host.name, 'up')
147
148     def cleanup(self):
149         self.unset_forced_down_hosts()
150         self.inspector.stop()
151         self.monitor.stop()
152         self.consumer.stop()
153         self.installer.cleanup()
154         self.alarm.delete()
155         self.instance.delete()
156         self.network.delete()
157         self.image.delete()
158         self.fault.cleanup()
159         self.user.delete()
160
161
162 def main():
163     """doctor main"""
164     doctor_root_dir = os.path.dirname(sys.path[0])
165     config_file_dir = '{0}/{1}'.format(doctor_root_dir, 'etc/')
166     config_files = [join(config_file_dir, f) for f in os.listdir(config_file_dir)
167                     if isfile(join(config_file_dir, f))]
168
169     conf = config.prepare_conf(args=sys.argv[1:],
170                                config_files=config_files)
171
172     doctor = DoctorTest(conf)
173     doctor.run()
174
175
176 if __name__ == '__main__':
177     sys.exit(main())