3 # Copyright (c) 2017 Orange, IXIA 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 """CloudifyImsPerf testcase implementation."""
20 from jinja2 import Environment, FileSystemLoader
21 from snaps.config.flavor import FlavorConfig
22 from snaps.config.image import ImageConfig
23 from snaps.config.network import NetworkConfig, PortConfig, SubnetConfig
24 from snaps.config.router import RouterConfig
25 from snaps.config.security_group import (
26 Direction, Protocol, SecurityGroupConfig, SecurityGroupRuleConfig)
27 from snaps.config.vm_inst import FloatingIpConfig, VmInstanceConfig
28 from snaps.openstack.create_flavor import OpenStackFlavor
29 from snaps.openstack.create_instance import OpenStackVmInstance
30 from snaps.openstack.create_network import OpenStackNetwork
31 from snaps.openstack.create_router import OpenStackRouter
32 from snaps.openstack.create_security_group import OpenStackSecurityGroup
33 from xtesting.energy import energy
35 from functest.opnfv_tests.openstack.snaps import snaps_utils
36 from functest.opnfv_tests.vnf.ims import cloudify_ims
37 from functest.opnfv_tests.vnf.ims.ixia.utils import IxChassisUtils
38 from functest.opnfv_tests.vnf.ims.ixia.utils import IxLoadUtils
39 from functest.opnfv_tests.vnf.ims.ixia.utils import IxRestUtils
40 from functest.utils import config
42 __author__ = "Valentin Boucher <valentin.boucher@orange.com>"
45 class CloudifyImsPerf(cloudify_ims.CloudifyIms):
46 """Clearwater vIMS deployed with Cloudify Orchestrator Case."""
48 __logger = logging.getLogger(__name__)
50 def __init__(self, **kwargs):
51 """Initialize CloudifyIms testcase object."""
52 if "case_name" not in kwargs:
53 kwargs["case_name"] = "cloudify_ims_perf"
54 super(CloudifyImsPerf, self).__init__(**kwargs)
56 # Retrieve the configuration
58 self.config = getattr(
59 config.CONF, 'vnf_{}_config'.format(self.case_name))
61 raise Exception("VNF config file not found")
64 self.created_object = []
66 config_file = os.path.join(self.case_dir, self.config)
67 self.orchestrator = dict(
68 requirements=get_config("orchestrator.requirements", config_file),
70 self.details['orchestrator'] = dict(
71 name=get_config("orchestrator.name", config_file),
72 version=get_config("orchestrator.version", config_file),
76 self.__logger.debug("Orchestrator configuration %s", self.orchestrator)
78 descriptor=get_config("vnf.descriptor", config_file),
79 inputs=get_config("vnf.inputs", config_file),
80 requirements=get_config("vnf.requirements", config_file)
82 self.details['vnf'] = dict(
83 descriptor_version=self.vnf['descriptor']['version'],
84 name=get_config("vnf.name", config_file),
85 version=get_config("vnf.version", config_file),
87 self.__logger.debug("VNF configuration: %s", self.vnf)
90 version=get_config("vnf_test_suite.version", config_file),
91 inputs=get_config("vnf_test_suite.inputs", config_file),
92 requirements=get_config("vnf_test_suite.requirements", config_file)
95 self.details['test_vnf'] = dict(
96 name=get_config("vnf_test_suite.name", config_file),
97 version=get_config("vnf_test_suite.version", config_file),
98 requirements=get_config("vnf_test_suite.requirements", config_file)
100 self.images = get_config("tenant_images", config_file)
101 self.__logger.info("Images needed for vIMS: %s", self.images)
104 """Run IXIA Stress test on clearwater ims instance."""
105 start_time = time.time()
107 cfy_client = self.orchestrator['object']
109 outputs = cfy_client.deployments.outputs.get(
110 self.vnf['descriptor'].get('name'))['outputs']
111 dns_ip = outputs['dns_ip']
112 ellis_ip = outputs['ellis_ip']
114 self.__logger.info("Creating full IXIA network ...")
115 subnet_settings = SubnetConfig(name='ixia_management_subnet',
116 cidr='10.10.10.0/24')
117 network_settings = NetworkConfig(name='ixia_management_network',
118 subnet_settings=[subnet_settings])
119 network_creator = OpenStackNetwork(self.snaps_creds, network_settings)
120 network_creator.create()
121 self.created_object.append(network_creator)
122 ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds)
123 router_creator = OpenStackRouter(
126 name='ixia_management_router',
127 external_gateway=ext_net_name,
128 internal_subnets=[subnet_settings.name]))
129 router_creator.create()
130 self.created_object.append(router_creator)
132 # security group creation
133 self.__logger.info("Creating security groups for IXIA VMs")
136 SecurityGroupRuleConfig(sec_grp_name="ixia_management",
137 direction=Direction.ingress,
138 protocol=Protocol.tcp, port_range_min=1,
139 port_range_max=65535))
141 SecurityGroupRuleConfig(sec_grp_name="ixia_management",
142 direction=Direction.ingress,
143 protocol=Protocol.udp, port_range_min=1,
144 port_range_max=65535))
146 SecurityGroupRuleConfig(sec_grp_name="ixia_management",
147 direction=Direction.ingress,
148 protocol=Protocol.icmp))
150 ixia_managment_sg_settings = SecurityGroupConfig(
151 name="ixia_management", rule_settings=sg_rules)
152 securit_group_creator = OpenStackSecurityGroup(
154 ixia_managment_sg_settings)
156 securit_group_creator.create()
157 self.created_object.append(securit_group_creator)
161 SecurityGroupRuleConfig(sec_grp_name="ixia_ssh_http",
162 direction=Direction.ingress,
163 protocol=Protocol.tcp, port_range_min=1,
164 port_range_max=65535))
166 ixia_ssh_http_sg_settings = SecurityGroupConfig(
167 name="ixia_ssh_http", rule_settings=sg_rules)
168 securit_group_creator = OpenStackSecurityGroup(
170 ixia_ssh_http_sg_settings)
172 securit_group_creator.create()
173 self.created_object.append(securit_group_creator)
175 chassis_flavor_settings = FlavorConfig(
176 name="ixia_vChassis",
180 flavor_creator = OpenStackFlavor(self.snaps_creds,
181 chassis_flavor_settings)
182 flavor_creator.create()
183 self.created_object.append(flavor_creator)
185 card_flavor_settings = FlavorConfig(
190 flavor_creator = OpenStackFlavor(self.snaps_creds,
191 card_flavor_settings)
192 flavor_creator.create()
193 self.created_object.append(flavor_creator)
195 load_flavor_settings = FlavorConfig(
200 flavor_creator = OpenStackFlavor(self.snaps_creds,
201 load_flavor_settings)
202 flavor_creator.create()
203 self.created_object.append(flavor_creator)
205 chassis_image_settings = ImageConfig(
206 name=self.test['requirements']['chassis']['image'],
210 card_image_settings = ImageConfig(
211 name=self.test['requirements']['card']['image'],
215 load_image_settings = ImageConfig(
216 name=self.test['requirements']['load']['image'],
220 chassis_port_settings = PortConfig(
221 name='ixia_chassis_port', network_name=network_settings.name)
223 card1_port1_settings = PortConfig(
224 name='ixia_card1_port1', network_name=network_settings.name)
226 card2_port1_settings = PortConfig(
227 name='ixia_card2_port1', network_name=network_settings.name)
229 card1_port2_settings = PortConfig(
230 name='ixia_card1_port2', network_name="cloudify_ims_network")
232 card2_port2_settings = PortConfig(
233 name='ixia_card2_port2', network_name="cloudify_ims_network")
235 load_port_settings = PortConfig(
236 name='ixia_load_port', network_name=network_settings.name)
238 chassis_settings = VmInstanceConfig(
239 name='ixia_vChassis',
240 flavor=chassis_flavor_settings.name,
241 port_settings=[chassis_port_settings],
242 security_group_names=[ixia_ssh_http_sg_settings.name,
243 ixia_managment_sg_settings.name],
244 floating_ip_settings=[FloatingIpConfig(
245 name='ixia_vChassis_fip',
246 port_name=chassis_port_settings.name,
247 router_name=router_creator.router_settings.name)])
249 vm_creator = OpenStackVmInstance(self.snaps_creds,
251 chassis_image_settings)
253 self.__logger.info("Creating Ixia vChassis VM")
255 fip_chassis = vm_creator.get_floating_ip().ip
256 self.created_object.append(vm_creator)
258 card1_settings = VmInstanceConfig(
260 flavor=card_flavor_settings.name,
261 port_settings=[card1_port1_settings, card1_port2_settings],
262 security_group_names=[ixia_managment_sg_settings.name])
264 vm_creator = OpenStackVmInstance(self.snaps_creds,
268 self.__logger.info("Creating Ixia vCard1 VM")
271 vcard_ips_p2 = list()
272 vcard_ips.append(vm_creator.get_port_ip('ixia_card1_port1'))
273 vcard_ips_p2.append(vm_creator.get_port_ip('ixia_card1_port2'))
274 self.created_object.append(vm_creator)
276 card2_settings = VmInstanceConfig(
278 flavor=card_flavor_settings.name,
279 port_settings=[card2_port1_settings, card2_port2_settings],
280 security_group_names=[ixia_managment_sg_settings.name])
282 vm_creator = OpenStackVmInstance(self.snaps_creds,
286 self.__logger.info("Creating Ixia vCard2 VM")
288 vcard_ips.append(vm_creator.get_port_ip('ixia_card2_port1'))
289 vcard_ips_p2.append(vm_creator.get_port_ip('ixia_card2_port2'))
290 self.created_object.append(vm_creator)
292 load_settings = VmInstanceConfig(
294 flavor=load_flavor_settings.name,
295 port_settings=[load_port_settings],
296 security_group_names=[ixia_ssh_http_sg_settings.name,
297 ixia_managment_sg_settings.name],
298 floating_ip_settings=[FloatingIpConfig(
299 name='ixia_vLoad_fip',
300 port_name=load_port_settings.name,
301 router_name=router_creator.router_settings.name)])
303 vm_creator = OpenStackVmInstance(self.snaps_creds,
307 self.__logger.info("Creating Ixia vLoad VM")
309 fip_load = vm_creator.get_floating_ip().ip
310 self.created_object.append(vm_creator)
312 self.__logger.info("Chassis IP is: %s", fip_chassis)
313 login_url = "https://" + str(fip_chassis) + "/api/v1/auth/session"
314 cards_url = "https://" + str(fip_chassis) + "/api/v2/ixos/cards/"
316 payload = json.dumps({"username": "admin",
318 "rememberMe": "false"})
319 api_key = json.loads((
320 IxChassisUtils.ChassisRestAPI.postWithPayload(
321 login_url, payload)))["apiKey"]
323 self.__logger.info("Adding 2 card back inside the ixia chassis...")
326 payload = {"ipAddress": str(ip)}
327 response = json.loads(IxChassisUtils.ChassisRestAPI.postOperation(
328 cards_url, api_key, payload))
331 IxChassisUtils.ChassisRestAPI.getWithHeaders(
332 response['url'], api_key)['progress']) != 100):
333 self.__logger.debug("Operation did not finish yet. \
334 Waiting for 1 more second..")
337 raise Exception("Adding card take more than 60 seconds")
340 ssh = paramiko.SSHClient()
341 ssh.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
342 ssh.connect(fip_chassis, username="admin", password="admin")
343 cmd = "set license-check disable"
344 run_blocking_ssh_command(ssh, cmd)
345 cmd = "restart-service ixServer"
346 run_blocking_ssh_command(ssh, cmd)
348 self.config_ellis(ellis_ip)
351 resolver = dns.resolver.Resolver()
352 resolver.nameservers = [dns_ip]
353 result = resolver.query("bono.clearwater.local")
360 iplistims += str(rdata.address)
364 kResourcesUrl = 'http://%s:%s/api/v0/resources' % (fip_load, 8080)
366 kRxfPath = r"REG_CALL_OPNFV_v13.rxf"
367 test_filname = self.test['inputs']['test_filname']
368 kGatewaySharedFolder = '/mnt/ixload-share/'
369 kRxfRelativeUploadPath = 'uploads/%s' % os.path.split(kRxfPath)[1]
370 kRxfAbsoluteUploadPath = os.path.join(kGatewaySharedFolder,
371 kRxfRelativeUploadPath)
372 kChassisList = [str(fip_chassis)]
373 dataFileNameList = [test_filname,
374 'Registration_only_LPS.tst',
377 kPortListPerCommunityCommunity = {"VoIP1@VM1": [(1, 1, 1)],
378 "VoIP2@VM2": [(1, 2, 1)]}
380 kStatsToDisplayDict = self.test['inputs']['stats']
381 connection = IxRestUtils.getConnection(fip_load, 8080)
383 self.__logger.info("Creating a new session...")
384 sessionUrl = IxLoadUtils.createSession(connection,
385 self.test['version'])
387 license_server = self.test['inputs']['licenseServer']
388 IxLoadUtils.configureLicenseServer(connection,
392 files_dir = os.path.join(self.case_dir, 'ixia/files')
393 target_file = open(os.path.join(files_dir, test_filname), 'w')
394 j2_env = Environment(loader=FileSystemLoader(files_dir),
396 self.test['inputs'].update(dict(
397 ipchassis=fip_chassis, ipcard1=vcard_ips_p2[0],
398 ipcard2=vcard_ips_p2[1], iplistims=iplistims
402 j2_env.get_template(test_filname + '.template').render(
407 self.__logger.info('Uploading files %s...' % kRxfPath)
408 for dataFile in dataFileNameList:
409 localFilePath = os.path.join(files_dir, dataFile)
410 remoteFilePath = os.path.join(kGatewaySharedFolder,
411 'uploads/%s' % dataFile)
412 IxLoadUtils.uploadFile(connection, kResourcesUrl,
413 localFilePath, remoteFilePath)
414 self.__logger.info('Upload file finished.')
416 self.__logger.info("Loading repository %s..." % kRxfAbsoluteUploadPath)
417 IxLoadUtils.loadRepository(connection, sessionUrl,
418 kRxfAbsoluteUploadPath)
420 self.__logger.info("Clearing chassis list...")
421 IxLoadUtils.clearChassisList(connection, sessionUrl)
423 self.__logger.info("Adding chassis %s..." % (kChassisList))
424 IxLoadUtils.addChassisList(connection, sessionUrl, kChassisList)
426 self.__logger.info("Assigning new ports...")
427 IxLoadUtils.assignPorts(connection, sessionUrl,
428 kPortListPerCommunityCommunity)
430 self.__logger.info("Starting the test...")
431 IxLoadUtils.runTest(connection, sessionUrl)
434 "Polling values for stats %s..." % (kStatsToDisplayDict))
435 result = IxLoadUtils.pollStats(connection, sessionUrl,
437 self.__logger.info("Test finished.")
438 self.__logger.info("Checking test status...")
439 testRunError = IxLoadUtils.getTestRunError(connection, sessionUrl)
441 self.__logger.info(result)
442 duration = time.time() - start_time
443 self.details['test_vnf'].update(status='PASS',
448 "The test exited with following error: %s" % (testRunError))
449 self.details['test_vnf'].update(status='FAIL', duration=duration)
452 self.__logger.info("The test completed successfully.")
453 self.details['test_vnf'].update(status='PASS', duration=duration)
454 self.result += 1/3 * 100
458 """Clean created objects/functions."""
459 super(CloudifyImsPerf, self).clean()
461 @energy.enable_recording
462 def run(self, **kwargs):
463 """Execute CloudifyIms test case."""
464 return super(CloudifyImsPerf, self).run(**kwargs)
467 # ----------------------------------------------------------
471 # -----------------------------------------------------------
472 def get_config(parameter, file_path):
474 Get config parameter.
476 Returns the value of a given parameter in file.yaml
477 parameter must be given in string format with dots
478 Example: general.openstack.image_name
480 with open(file_path) as config_file:
481 file_yaml = yaml.safe_load(config_file)
484 for element in parameter.split("."):
485 value = value.get(element)
487 raise ValueError("The parameter %s is not defined in"
488 " reporting.yaml" % parameter)
492 def run_blocking_ssh_command(ssh, cmd, error_msg="Unable to run this command"):
493 """Command to run ssh command with the exit status."""
494 stdin, stdout, stderr = ssh.exec_command(cmd)
495 if stdout.channel.recv_exit_status() != 0:
496 raise Exception(error_msg)