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
21 from xtesting.core import testcase
23 from functest.core import singlevm
24 from functest.opnfv_tests.vnf.ims import clearwater
25 from functest.utils import config
26 from functest.utils import env
28 __author__ = "Valentin Boucher <valentin.boucher@kontron.com>"
31 class HeatIms(singlevm.VmReady2):
32 # pylint: disable=too-many-instance-attributes
33 """Clearwater vIMS deployed with Heat Orchestrator Case."""
35 __logger = logging.getLogger(__name__)
37 filename_alt = ('/home/opnfv/functest/images/'
38 'ubuntu-14.04-server-cloudimg-amd64-disk1.img')
44 quota_security_group = 20
45 quota_security_group_rule = 100
48 def __init__(self, **kwargs):
49 """Initialize HeatIms testcase object."""
50 if "case_name" not in kwargs:
51 kwargs["case_name"] = "heat_ims"
52 super(HeatIms, self).__init__(**kwargs)
54 # Retrieve the configuration
56 self.config = getattr(
57 config.CONF, 'vnf_{}_config'.format(self.case_name))
59 raise Exception("VNF config file not found")
61 self.case_dir = pkg_resources.resource_filename(
62 'functest', 'opnfv_tests/vnf/ims')
63 config_file = os.path.join(self.case_dir, self.config)
66 descriptor=get_config("vnf.descriptor", config_file),
67 parameters=get_config("vnf.inputs", config_file)
69 self.details['vnf'] = dict(
70 descriptor_version=self.vnf['descriptor']['version'],
71 name=get_config("vnf.name", config_file),
72 version=get_config("vnf.version", config_file),
74 self.__logger.debug("VNF configuration: %s", self.vnf)
77 self.flavor_alt = None
80 self.clearwater = None
84 # pylint: disable=too-many-locals,too-many-statements
88 network, security group, fip, VM creation
90 self.orig_cloud.set_network_quotas(
91 self.project.project.name,
92 security_group=self.quota_security_group,
93 security_group_rule=self.quota_security_group_rule,
95 if not self.orig_cloud.get_role("heat_stack_owner"):
96 self.role = self.orig_cloud.create_role("heat_stack_owner")
97 self.orig_cloud.grant_role(
98 "heat_stack_owner", user=self.project.user.id,
99 project=self.project.project.id,
100 domain=self.project.domain.id)
101 self.keypair = self.cloud.create_keypair(
102 '{}-kp_{}'.format(self.case_name, self.guid))
103 self.__logger.debug("keypair: %s", self.keypair)
105 if (self.deploy_vnf() and self.test_vnf()):
108 self.result = 1/3 * 100
111 def run(self, **kwargs):
112 """Deploy and test clearwater
114 Here are the main actions:
115 - deploy clearwater stack via heat
116 - test the vnf instance
120 - TestCase.EX_RUN_ERROR on error
122 status = testcase.TestCase.EX_RUN_ERROR
125 self.start_time = time.time()
127 if not self.execute():
129 status = testcase.TestCase.EX_OK
130 except Exception: # pylint: disable=broad-except
131 self.__logger.exception('Cannot run %s', self.case_name)
133 self.stop_time = time.time()
136 def deploy_vnf(self):
137 """Deploy Clearwater IMS."""
138 start_time = time.time()
140 self.image_alt = self.publish_image_alt()
141 self.flavor_alt = self.create_flavor_alt()
142 # KeyPair + Image + Flavor OK
144 descriptor = self.vnf['descriptor']
145 parameters = self.vnf['parameters']
147 parameters['public_mgmt_net_id'] = self.ext_net.id
148 parameters['public_sig_net_id'] = self.ext_net.id
149 parameters['flavor'] = self.flavor_alt.name
150 parameters['image'] = self.image_alt.name
151 parameters['key_name'] = self.keypair.name
152 parameters['external_mgmt_dns_ip'] = env.get('NAMESERVER')
153 parameters['external_sig_dns_ip'] = env.get('NAMESERVER')
155 self.__logger.info("Create Heat Stack")
156 self.stack = self.cloud.create_stack(
157 name=descriptor.get('name'),
158 template_file=descriptor.get('file_name'),
159 wait=True, **parameters)
160 self.__logger.debug("stack: %s", self.stack)
162 servers = self.cloud.list_servers(detailed=True)
163 self.__logger.debug("servers: %s", servers)
164 for server in servers:
165 if not self.check_regex_in_console(
166 server.name, regex='Cloud-init .* finished at ', loop=60):
168 if 'ellis' in server.name:
169 self.__logger.debug("server: %s", server)
170 ellis_ip = server.public_v4
173 self.clearwater = clearwater.ClearwaterTesting(self.case_name,
175 # This call can take time and many retry because Heat is
176 # an infrastructure orchestrator so when Heat say "stack created"
177 # it means that all OpenStack ressources are created but not that
178 # Clearwater are up and ready (Cloud-Init script still running)
179 self.clearwater.availability_check_by_creating_numbers()
181 duration = time.time() - start_time
183 self.details['vnf'].update(status='PASS', duration=duration)
184 self.result += 1/3 * 100
189 """Run test on clearwater ims instance."""
190 start_time = time.time()
192 outputs = self.cloud.get_stack(self.stack.id).outputs
193 self.__logger.debug("stack outputs: %s", outputs)
194 dns_ip = re.findall(r'[0-9]+(?:\.[0-9]+){3}', str(outputs))[0]
199 short_result = self.clearwater.run_clearwater_live_test(
201 public_domain=self.vnf['parameters']["zone"])
202 duration = time.time() - start_time
203 self.__logger.info(short_result)
204 self.details['test_vnf'] = dict(result=short_result,
207 vnf_test_rate = short_result['passed'] / (
208 short_result['total'] - short_result['skipped'])
209 # orchestrator + vnf + test_vnf
210 self.result += vnf_test_rate / 3 * 100
211 except ZeroDivisionError:
212 self.__logger.error("No test has been executed")
213 self.details['test_vnf'].update(status='FAIL')
215 except Exception: # pylint: disable=broad-except
216 self.__logger.exception("Cannot calculate results")
217 self.details['test_vnf'].update(status='FAIL')
219 return True if vnf_test_rate > 0 else False
222 """Clean created objects/functions."""
226 self.cloud.delete_stack(self.stack.id, wait=True)
227 except Exception: # pylint: disable=broad-except
228 self.__logger.exception("Cannot clean stack ressources")
229 super(HeatIms, self).clean()
231 self.orig_cloud.delete_role(self.role.id)
234 # ----------------------------------------------------------
238 # -----------------------------------------------------------
239 def get_config(parameter, file_path):
241 Get config parameter.
243 Returns the value of a given parameter in file.yaml
244 parameter must be given in string format with dots
245 Example: general.openstack.image_name
247 with open(file_path) as config_file:
248 file_yaml = yaml.safe_load(config_file)
251 for element in parameter.split("."):
252 value = value.get(element)
254 raise ValueError("The parameter %s is not defined in"
255 " reporting.yaml" % parameter)