3b0a1a9e128aa1751c3822b6826cdff152a896b0
[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:
66             self.logger.error("vm1: IP addr missing")
67             return testcase.TestCase.EX_TESTCASE_FAILED
68
69         self.logger.info("Waiting for ping...")
70         exit_code = testcase.TestCase.EX_TESTCASE_FAILED
71         sec = 0
72         tries = 0
73
74         while True:
75             time.sleep(1)
76             p_console = self.cloud.get_server_console(self.vm2.id)
77             self.logger.debug("console: \n%s", p_console)
78             if "vPing OK" in p_console:
79                 self.logger.info("vPing detected!")
80                 exit_code = testcase.TestCase.EX_OK
81                 break
82             elif "failed to read iid from metadata" in p_console or tries > 5:
83                 self.logger.info("Failed to read iid from metadata")
84                 break
85             elif sec == getattr(config.CONF, 'vping_ping_timeout'):
86                 self.logger.info("Timeout reached.")
87                 break
88             elif sec % 10 == 0:
89                 if "request failed" in p_console:
90                     self.logger.debug(
91                         "It seems userdata is not supported in nova boot. " +
92                         "Waiting a bit...")
93                     tries += 1
94                 else:
95                     self.logger.debug(
96                         "Pinging %s. Waiting for response...",
97                         self.vm1.private_v4)
98             sec += 1
99
100         return exit_code
101
102     def _get_userdata(self):
103         """
104         Returns the post VM creation script to be added into the VM's userdata
105         :param test_ip: the IP value to substitute into the script
106         :return: the bash script contents
107         """
108         if self.vm1.private_v4:
109             return ("#!/bin/sh\n\n"
110                     "while true; do\n"
111                     " ping -c 1 %s 2>&1 >/dev/null\n"
112                     " RES=$?\n"
113                     " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
114                     "  echo 'vPing OK'\n"
115                     "  break\n"
116                     " else\n"
117                     "  echo 'vPing KO'\n"
118                     " fi\n"
119                     " sleep 1\n"
120                     "done\n" % str(self.vm1.private_v4))
121         return None
122
123     def clean(self):
124         assert self.cloud
125         self.cloud.delete_server(
126             self.vm1, wait=True,
127             timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
128         self.cloud.delete_server(
129             self.vm2, wait=True,
130             timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
131         super(VPingUserdata, self).clean()