9010895cb7ea860f3c1c9ef735fde587284da6b7
[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
50             result = self._do_vping()
51             self.stop_time = time.time()
52             if result != testcase.TestCase.EX_OK:
53                 return testcase.TestCase.EX_RUN_ERROR
54             self.result = 100
55             return testcase.TestCase.EX_OK
56         except Exception:  # pylint: disable=broad-except
57             self.logger.exception('Unexpected error running vping_userdata')
58             return testcase.TestCase.EX_RUN_ERROR
59
60     def _do_vping(self):
61         """
62         Override from super
63         """
64         if not (self.vm1.private_v4 or self.vm1.addresses[
65                 self.network.name][0].addr):
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             if "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             if sec == getattr(config.CONF, 'vping_ping_timeout'):
86                 self.logger.info("Timeout reached.")
87                 break
88             if 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 or self.vm1.addresses[
98                             self.network.name][0].addr)
99             sec += 1
100
101         return exit_code
102
103     def _get_userdata(self):
104         """
105         Returns the post VM creation script to be added into the VM's userdata
106         :param test_ip: the IP value to substitute into the script
107         :return: the bash script contents
108         """
109         if self.vm1.private_v4 or self.vm1.addresses[
110                 self.network.name][0].addr:
111             return ("#!/bin/sh\n\n"
112                     "while true; do\n"
113                     " ping -c 1 %s 2>&1 >/dev/null\n"
114                     " RES=$?\n"
115                     " if [ \"Z$RES\" = \"Z0\" ] ; then\n"
116                     "  echo 'vPing OK'\n"
117                     "  break\n"
118                     " else\n"
119                     "  echo 'vPing KO'\n"
120                     " fi\n"
121                     " sleep 1\n"
122                     "done\n" % str(
123                         self.vm1.private_v4 or self.vm1.addresses[
124                             self.network.name][0].addr))
125         return None
126
127     def clean(self):
128         assert self.cloud
129         if self.vm1:
130             self.cloud.delete_server(
131                 self.vm1, wait=True,
132                 timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
133         if self.vm2:
134             self.cloud.delete_server(
135                 self.vm2, wait=True,
136                 timeout=getattr(config.CONF, 'vping_vm_delete_timeout'))
137         super(VPingUserdata, self).clean()