3 # Copyright (c) 2018 Kontron, Orange and others.
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
10 """HeatIms testcase implementation."""
12 from __future__ import division
22 from xtesting.core import testcase
24 from functest.core import singlevm
25 from functest.opnfv_tests.vnf.ims import clearwater
26 from functest.utils import config
27 from functest.utils import env
28 from functest.utils import functest_utils
30 __author__ = "Valentin Boucher <valentin.boucher@kontron.com>"
33 class HeatIms(singlevm.VmReady2):
34 # pylint: disable=too-many-instance-attributes
35 """Clearwater vIMS deployed with Heat Orchestrator Case."""
37 __logger = logging.getLogger(__name__)
39 filename = ('/home/opnfv/functest/images/'
40 'ubuntu-14.04-server-cloudimg-amd64-disk1.img')
46 quota_security_group = 20
47 quota_security_group_rule = 100
51 'private_mgmt_net_cidr': '192.168.100.0/24',
52 'private_mgmt_net_gateway': '192.168.100.254',
53 'private_mgmt_net_pool_start': '192.168.100.1',
54 'private_mgmt_net_pool_end': '192.168.100.253'}
56 def __init__(self, **kwargs):
57 """Initialize HeatIms testcase object."""
58 if "case_name" not in kwargs:
59 kwargs["case_name"] = "heat_ims"
60 super(HeatIms, self).__init__(**kwargs)
62 # Retrieve the configuration
64 self.config = getattr(
65 config.CONF, 'vnf_{}_config'.format(self.case_name))
67 raise Exception("VNF config file not found")
69 self.case_dir = pkg_resources.resource_filename(
70 'functest', 'opnfv_tests/vnf/ims')
71 config_file = os.path.join(self.case_dir, self.config)
74 descriptor=functest_utils.get_parameter_from_yaml(
75 "vnf.descriptor", config_file),
76 parameters=functest_utils.get_parameter_from_yaml(
77 "vnf.inputs", config_file)
79 self.details['vnf'] = dict(
80 descriptor_version=self.vnf['descriptor']['version'],
81 name=functest_utils.get_parameter_from_yaml(
82 "vnf.name", config_file),
83 version=functest_utils.get_parameter_from_yaml(
84 "vnf.version", config_file),
86 self.__logger.debug("VNF configuration: %s", self.vnf)
89 self.clearwater = None
91 (_, self.key_filename) = tempfile.mkstemp()
93 def create_network_resources(self):
97 # pylint: disable=too-many-locals,too-many-statements
101 network, security group, fip, VM creation
103 self.orig_cloud.set_network_quotas(
104 self.project.project.name,
105 security_group=self.quota_security_group,
106 security_group_rule=self.quota_security_group_rule,
107 port=self.quota_port)
108 if not self.orig_cloud.get_role("heat_stack_owner"):
109 self.role = self.orig_cloud.create_role("heat_stack_owner")
110 self.orig_cloud.grant_role(
111 "heat_stack_owner", user=self.project.user.id,
112 project=self.project.project.id,
113 domain=self.project.domain.id)
114 self.keypair = self.cloud.create_keypair(
115 '{}-kp_{}'.format(self.case_name, self.guid))
116 self.__logger.info("keypair:\n%s", self.keypair.private_key)
117 with open(self.key_filename, 'w') as private_key_file:
118 private_key_file.write(self.keypair.private_key)
120 if self.deploy_vnf() and self.test_vnf():
123 self.result = 1/3 * 100
126 def run(self, **kwargs):
127 """Deploy and test clearwater
129 Here are the main actions:
130 - deploy clearwater stack via heat
131 - test the vnf instance
135 - TestCase.EX_RUN_ERROR on error
137 status = testcase.TestCase.EX_RUN_ERROR
140 assert super(HeatIms, self).run(
141 **kwargs) == testcase.TestCase.EX_OK
143 if not self.execute():
145 status = testcase.TestCase.EX_OK
146 except Exception: # pylint: disable=broad-except
147 self.__logger.exception('Cannot run %s', self.case_name)
149 self.stop_time = time.time()
152 def _monit(self, username="ubuntu", timeout=60):
153 servers = self.cloud.list_servers(detailed=True)
154 self.__logger.debug("servers: %s", servers)
155 for server in servers:
156 if 'ns' in server.name:
158 self.__logger.info("server:\n%s", server.name)
159 ssh = paramiko.SSHClient()
160 ssh.set_missing_host_key_policy(paramiko.client.AutoAddPolicy())
162 server.public_v4, username=username,
163 key_filename=self.key_filename, timeout=timeout)
164 (_, stdout, _) = ssh.exec_command('sudo monit summary')
165 self.__logger.info("output:\n%s", stdout.read())
168 def deploy_vnf(self):
169 """Deploy Clearwater IMS."""
170 start_time = time.time()
171 descriptor = self.vnf['descriptor']
172 parameters = self.vnf['parameters']
174 parameters['public_mgmt_net_id'] = self.ext_net.id
175 parameters['flavor'] = self.flavor.name
176 parameters['image'] = self.image.name
177 parameters['key_name'] = self.keypair.name
178 parameters['external_mgmt_dns_ip'] = env.get('NAMESERVER')
179 parameters.update(self.parameters)
181 self.__logger.info("Create Heat Stack")
182 self.stack = self.cloud.create_stack(
183 name=descriptor.get('name'),
184 template_file=descriptor.get('file_name'),
185 wait=True, **parameters)
186 self.__logger.debug("stack: %s", self.stack)
190 servers = self.cloud.list_servers(detailed=True)
191 self.__logger.debug("servers: %s", servers)
192 for server in servers:
193 if not self.check_regex_in_console(
194 server.name, regex='Cloud-init .* finished at ', loop=1):
196 if 'ellis' in server.name:
197 self.__logger.debug("ellis: %s", server)
198 ellis_ip = server.public_v4
199 elif 'bono' in server.name:
200 self.__logger.debug("bono: %s", server)
201 bono_ip = server.public_v4
205 self.clearwater = clearwater.ClearwaterTesting(
206 self.case_name, bono_ip, ellis_ip)
207 # This call can take time and many retry because Heat is
208 # an infrastructure orchestrator so when Heat say "stack created"
209 # it means that all OpenStack ressources are created but not that
210 # Clearwater are up and ready (Cloud-Init script still running)
211 self.clearwater.availability_check()
213 duration = time.time() - start_time
215 self.details['vnf'].update(status='PASS', duration=duration)
216 self.result += 1/3 * 100
221 """Run test on clearwater ims instance."""
222 start_time = time.time()
223 outputs = self.cloud.get_stack(self.stack.id).outputs
224 self.__logger.debug("stack outputs: %s", outputs)
225 dns_ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', str(outputs))[0]
228 short_result, vnf_test_rate = self.clearwater.run_clearwater_live_test(
229 public_domain=self.vnf['parameters']["zone"])
230 duration = time.time() - start_time
231 self.__logger.info(short_result)
232 self.details['test_vnf'] = dict(result=short_result, duration=duration)
233 self.result += vnf_test_rate / 3 * 100
234 if vnf_test_rate == 0:
235 self.details['test_vnf'].update(status='FAIL')
237 return bool(vnf_test_rate > 0)
240 """Clean created objects/functions."""
244 self.cloud.delete_stack(self.stack.id, wait=True)
246 # shade raises TypeError exceptions when checking stack status
248 except Exception: # pylint: disable=broad-except
249 self.__logger.exception("Cannot clean stack ressources")
250 super(HeatIms, self).clean()
252 self.orig_cloud.delete_role(self.role.id)