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