Add fallback mechanism if vlan
[functest.git] / functest / opnfv_tests / openstack / vping / vping_userdata.py
1 #!/usr/bin/env 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 """vping_userdata testcase."""
11
12 import logging
13 import time
14
15 from xtesting.core import testcase
16
17 from functest.core import singlevm
18 from functest.utils import config
19
20
21 class VPingUserdata(singlevm.VmReady2):
22     """
23     Class to execute the vPing test using userdata and the VM's console
24     """
25
26     def __init__(self, **kwargs):
27         if "case_name" not in kwargs:
28             kwargs["case_name"] = "vping_userdata"
29         super(VPingUserdata, self).__init__(**kwargs)
30         self.logger = logging.getLogger(__name__)
31         self.vm1 = None
32         self.vm2 = None
33
34     def run(self, **kwargs):
35         """
36         Sets up the OpenStack VM instance objects then executes the ping and
37         validates.
38         :return: the exit code from the super.execute() method
39         """
40         try:
41             assert self.cloud
42             assert super(VPingUserdata, self).run(
43                 **kwargs) == testcase.TestCase.EX_OK
44             self.result = 0
45             self.vm1 = self.boot_vm()
46             self.vm2 = self.boot_vm(
47                 '{}-vm2_{}'.format(self.case_name, self.guid),
48                 userdata=self._get_userdata())
49             self.vm2 = self.cloud.wait_for_server(self.vm2, auto_ip=False)
50
51             result = self._do_vping()
52             self.stop_time = time.time()
53             if result != testcase.TestCase.EX_OK:
54                 return testcase.TestCase.EX_RUN_ERROR
55             self.result = 100
56             return testcase.TestCase.EX_OK
57         except Exception:  # pylint: disable=broad-except
58             self.logger.exception('Unexpected error running vping_userdata')
59             return testcase.TestCase.EX_RUN_ERROR
60
61     def _do_vping(self):
62         """
63         Override from super
64         """
65         if not (self.vm1.private_v4 or self.vm1.addresses[
66                 self.network.name][0].addr):
67             self.logger.error("vm1: IP addr missing")
68             return testcase.TestCase.EX_TESTCASE_FAILED
69
70         self.logger.info("Waiting for ping...")
71         exit_code = testcase.TestCase.EX_TESTCASE_FAILED
72         sec = 0
73         tries = 0
74
75         while True:
76             time.sleep(1)
77             p_console = self.cloud.get_server_console(self.vm2.id)
78             self.logger.debug("console: \n%s", p_console)
79             if "vPing OK" in p_console:
80                 self.logger.info("vPing detected!")
81                 exit_code = testcase.TestCase.EX_OK
82                 break
83             elif "failed to read iid from metadata" in p_console or tries > 5:
84                 self.logger.info("Failed to read iid from metadata")
85                 break
86             elif sec == getattr(config.CONF, 'vping_ping_timeout'):
87                 self.logger.info("Timeout reached.")
88                 break
89             elif sec % 10 == 0:
90                 if "request failed" in p_console:
91                     self.logger.debug(
92                         "It seems userdata is not supported in nova boot. " +
93                         "Waiting a bit...")
94                     tries += 1
95                 else:
96                     self.logger.debug(
97                         "Pinging %s. Waiting for response...",
98                         self.vm1.private_v4 or self.vm1.addresses[
99                             self.network.name][0].addr)
100             sec += 1
101
102         return exit_code
103
104     def _get_userdata(self):
105         """
106         Returns the post VM creation script to be added into the VM's userdata
107         :param test_ip: the IP value to substitute into the script
108         :return: the bash script contents
109         """
110         if self.vm1.private_v4 or self.vm1.addresses[
111                 self.network.name][0].addr:
112             return ("#!/bin/sh\n\n"
113                     "while true; do\n"
114                     " ping -c 1 %s 2>&1 >/dev/null\n"
115                     " RES=$?\n"
116                     " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
117                     "  echo 'vPing OK'\n"
118                     "  break\n"
119                     " else\n"
120                     "  echo 'vPing KO'\n"
121                     " fi\n"
122                     " sleep 1\n"
123                     "done\n" % str(
124                         self.vm1.private_v4 or self.vm1.addresses[
125                             self.network.name][0].addr))
126         return None
127
128     def clean(self):
129         assert self.cloud
130         if self.vm1:
131             self.cloud.delete_server(
132                 self.vm1, wait=True,
133                 timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
134         if self.vm2:
135             self.cloud.delete_server(
136                 self.vm2, wait=True,
137                 timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
138         super(VPingUserdata, self).clean()