Delete functest.utils.functest_logger
[functest.git] / functest / opnfv_tests / openstack / vping / vping_ssh.py
1 #!/usr/bin/python
2 #
3 # Copyright (c) 2015 All rights reserved
4 # 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 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 import logging
11 import os
12 import re
13 import sys
14 import time
15
16 import argparse
17 import paramiko
18 from scp import SCPClient
19
20 import functest.utils.openstack_utils as os_utils
21 import vping_base
22 import functest.core.testcase as testcase
23
24
25 class VPingSSH(vping_base.VPingBase):
26
27     def __init__(self, **kwargs):
28         if "case_name" not in kwargs:
29             kwargs["case_name"] = "vping_ssh"
30         super(VPingSSH, self).__init__(**kwargs)
31         self.logger = logging.getLogger(__name__)
32
33     def do_vping(self, vm, test_ip):
34         floatip = self.add_float_ip(vm)
35         if not floatip:
36             return testcase.TestCase.EX_RUN_ERROR
37         ssh = self.establish_ssh(vm, floatip)
38         if not ssh:
39             return testcase.TestCase.EX_RUN_ERROR
40         if not self.transfer_ping_script(ssh, floatip):
41             return testcase.TestCase.EX_RUN_ERROR
42         return self.do_vping_ssh(ssh, test_ip)
43
44     def add_float_ip(self, vm):
45         self.logger.info("Creating floating IP for VM '%s'..." % self.vm2_name)
46         floatip_dic = os_utils.create_floating_ip(self.neutron_client)
47         floatip = floatip_dic['fip_addr']
48
49         if floatip is None:
50             self.logger.error("Cannot create floating IP.")
51             return None
52         self.logger.info("Floating IP created: '%s'" % floatip)
53
54         self.logger.info("Associating floating ip: '%s' to VM '%s' "
55                          % (floatip, self.vm2_name))
56         if not os_utils.add_floating_ip(self.nova_client, vm.id, floatip):
57             self.logger.error("Cannot associate floating IP to VM.")
58             return None
59
60         return floatip
61
62     def establish_ssh(self, vm, floatip):
63         self.logger.info("Trying to establish SSH connection to %s..."
64                          % floatip)
65         ssh = paramiko.SSHClient()
66         ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
67
68         timeout = 50
69         nolease = False
70         got_ip = False
71         discover_count = 0
72         cidr_first_octet = self.private_subnet_cidr.split('.')[0]
73         while timeout > 0:
74             try:
75                 ssh.connect(floatip, username=self.image_username,
76                             password=self.image_password, timeout=2)
77                 self.logger.debug("SSH connection established to %s."
78                                   % floatip)
79                 break
80             except:
81                 self.logger.debug("Waiting for %s..." % floatip)
82                 time.sleep(6)
83                 timeout -= 1
84
85             console_log = vm.get_console_output()
86
87             # print each "Sending discover" captured on the console log
88             if (len(re.findall("Sending discover", console_log)) >
89                     discover_count and not got_ip):
90                 discover_count += 1
91                 self.logger.debug("Console-log '%s': Sending discover..."
92                                   % self.vm2_name)
93
94             # check if eth0 got an ip,the line looks like this:
95             # "inet addr:192.168."....
96             # if the dhcp agent fails to assing ip, this line will not appear
97             if "inet addr:" + cidr_first_octet in console_log and not got_ip:
98                 got_ip = True
99                 self.logger.debug("The instance '%s' succeeded to get the IP "
100                                   "from the dhcp agent." % self.vm2_name)
101
102             # if dhcp not work,it shows "No lease, failing".The test will fail
103             if ("No lease, failing" in console_log and
104                 not nolease and
105                     not got_ip):
106                 nolease = True
107                 self.logger.debug("Console-log '%s': No lease, failing..."
108                                   % self.vm2_name)
109                 self.logger.info("The instance failed to get an IP from DHCP "
110                                  "agent. The test will probably timeout...")
111
112         if timeout == 0:  # 300 sec timeout (5 min)
113             self.logger.error("Cannot establish connection to IP '%s'. "
114                               "Aborting" % floatip)
115             return None
116         return ssh
117
118     def transfer_ping_script(self, ssh, floatip):
119         self.logger.info("Trying to transfer ping.sh to %s..." % floatip)
120         scp = SCPClient(ssh.get_transport())
121         local_path = self.functest_repo + "/" + self.repo
122         ping_script = os.path.join(local_path, "ping.sh")
123         try:
124             scp.put(ping_script, "~/")
125         except:
126             self.logger.error("Cannot SCP the file '%s' to VM '%s'"
127                               % (ping_script, floatip))
128             return False
129
130         cmd = 'chmod 755 ~/ping.sh'
131         (stdin, stdout, stderr) = ssh.exec_command(cmd)
132         for line in stdout.readlines():
133             print line
134
135         return True
136
137     def do_vping_ssh(self, ssh, test_ip):
138         EXIT_CODE = -1
139         self.logger.info("Waiting for ping...")
140
141         sec = 0
142         cmd = '~/ping.sh ' + test_ip
143         flag = False
144
145         while True:
146             time.sleep(1)
147             (stdin, stdout, stderr) = ssh.exec_command(cmd)
148             output = stdout.readlines()
149
150             for line in output:
151                 if "vPing OK" in line:
152                     self.logger.info("vPing detected!")
153                     EXIT_CODE = 0
154                     flag = True
155                     break
156
157                 elif sec == self.ping_timeout:
158                     self.logger.info("Timeout reached.")
159                     flag = True
160                     break
161             if flag:
162                 break
163             self.logger.debug("Pinging %s. Waiting for response..." % test_ip)
164             sec += 1
165         return EXIT_CODE
166
167
168 if __name__ == '__main__':
169     logging.basicConfig()
170     args_parser = argparse.ArgumentParser()
171     args_parser.add_argument("-r", "--report",
172                              help="Create json result file",
173                              action="store_true")
174     args = vars(args_parser.parse_args())
175     sys.exit(vping_base.VPingMain(VPingSSH).main(**args))