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
23 from functest.energy import energy
24 from functest.opnfv_tests.openstack.snaps import snaps_utils
25 import functest.opnfv_tests.vnf.ims.cloudify_ims as cloudify_ims
26 from functest.utils.constants import CONST
28 from snaps.config.flavor import FlavorConfig
29 from snaps.config.image import ImageConfig
30 from snaps.config.network import NetworkConfig, PortConfig, SubnetConfig
31 from snaps.config.router import RouterConfig
32 from snaps.config.security_group import (
33 Direction, Protocol, SecurityGroupConfig, SecurityGroupRuleConfig)
34 from snaps.config.vm_inst import FloatingIpConfig, VmInstanceConfig
36 from snaps.openstack.create_flavor import OpenStackFlavor
37 from snaps.openstack.create_instance import OpenStackVmInstance
38 from snaps.openstack.create_network import OpenStackNetwork
39 from snaps.openstack.create_router import OpenStackRouter
40 from snaps.openstack.create_security_group import OpenStackSecurityGroup
42 from ixia.utils.IxChassisUtils import ChassisRestAPI
43 import ixia.utils.IxLoadUtils as IxLoadUtils
44 import ixia.utils.IxRestUtils as IxRestUtils
46 __author__ = "Valentin Boucher <valentin.boucher@orange.com>"
49 class CloudifyImsPerf(cloudify_ims.CloudifyIms):
50 """Clearwater vIMS deployed with Cloudify Orchestrator Case."""
52 __logger = logging.getLogger(__name__)
54 def __init__(self, **kwargs):
55 """Initialize CloudifyIms testcase object."""
56 if "case_name" not in kwargs:
57 kwargs["case_name"] = "cloudify_ims_perf"
58 super(CloudifyImsPerf, self).__init__(**kwargs)
60 # Retrieve the configuration
62 self.config = CONST.__getattribute__(
63 'vnf_{}_config'.format(self.case_name))
65 raise Exception("VNF config file not found")
68 self.created_object = []
70 config_file = os.path.join(self.case_dir, self.config)
71 self.orchestrator = dict(
72 requirements=get_config("orchestrator.requirements", config_file),
74 self.details['orchestrator'] = dict(
75 name=get_config("orchestrator.name", config_file),
76 version=get_config("orchestrator.version", config_file),
80 self.__logger.debug("Orchestrator configuration %s", self.orchestrator)
82 descriptor=get_config("vnf.descriptor", config_file),
83 inputs=get_config("vnf.inputs", config_file),
84 requirements=get_config("vnf.requirements", config_file)
86 self.details['vnf'] = dict(
87 descriptor_version=self.vnf['descriptor']['version'],
88 name=get_config("vnf.name", config_file),
89 version=get_config("vnf.version", config_file),
91 self.__logger.debug("VNF configuration: %s", self.vnf)
94 version=get_config("vnf_test_suite.version", config_file),
95 inputs=get_config("vnf_test_suite.inputs", config_file),
96 requirements=get_config("vnf_test_suite.requirements", config_file)
99 self.details['test_vnf'] = dict(
100 name=get_config("vnf_test_suite.name", config_file),
101 version=get_config("vnf_test_suite.version", config_file),
102 requirements=get_config("vnf_test_suite.requirements", config_file)
104 self.images = get_config("tenant_images", config_file)
105 self.__logger.info("Images needed for vIMS: %s", self.images)
108 """Run IXIA Stress test on clearwater ims instance."""
109 start_time = time.time()
111 cfy_client = self.orchestrator['object']
113 outputs = cfy_client.deployments.outputs.get(
114 self.vnf['descriptor'].get('name'))['outputs']
115 dns_ip = outputs['dns_ip']
116 ellis_ip = outputs['ellis_ip']
118 self.__logger.info("Creating full IXIA network ...")
119 subnet_settings = SubnetConfig(name='ixia_management_subnet',
120 cidr='10.10.10.0/24')
121 network_settings = NetworkConfig(name='ixia_management_network',
122 subnet_settings=[subnet_settings])
123 network_creator = OpenStackNetwork(self.snaps_creds, network_settings)
124 network_creator.create()
125 self.created_object.append(network_creator)
126 ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds)
127 router_creator = OpenStackRouter(
130 name='ixia_management_router',
131 external_gateway=ext_net_name,
132 internal_subnets=[subnet_settings.name]))
133 router_creator.create()
134 self.created_object.append(router_creator)
136 # security group creation
137 self.__logger.info("Creating security groups for IXIA VMs")
140 SecurityGroupRuleConfig(sec_grp_name="ixia_management",
141 direction=Direction.ingress,
142 protocol=Protocol.tcp, port_range_min=1,
143 port_range_max=65535))
145 SecurityGroupRuleConfig(sec_grp_name="ixia_management",
146 direction=Direction.ingress,
147 protocol=Protocol.udp, port_range_min=1,
148 port_range_max=65535))
150 SecurityGroupRuleConfig(sec_grp_name="ixia_management",
151 direction=Direction.ingress,
152 protocol=Protocol.icmp))
154 ixia_managment_sg_settings = SecurityGroupConfig(
155 name="ixia_management",
156 rule_settings=sg_rules)
157 securit_group_creator = OpenStackSecurityGroup(
159 ixia_managment_sg_settings)
161 securit_group_creator.create()
162 self.created_object.append(securit_group_creator)
166 SecurityGroupRuleConfig(sec_grp_name="ixia_ssh_http",
167 direction=Direction.ingress,
168 protocol=Protocol.tcp, port_range_min=1,
169 port_range_max=65535))
171 ixia_ssh_http_sg_settings = SecurityGroupConfig(
172 name="ixia_ssh_http",
173 rule_settings=sg_rules)
174 securit_group_creator = OpenStackSecurityGroup(
176 ixia_ssh_http_sg_settings)
178 securit_group_creator.create()
179 self.created_object.append(securit_group_creator)
181 chassis_flavor_settings = FlavorConfig(
182 name="ixia_vChassis",
186 flavor_creator = OpenStackFlavor(self.snaps_creds,
187 chassis_flavor_settings)
188 flavor_creator.create()
189 self.created_object.append(flavor_creator)
191 card_flavor_settings = FlavorConfig(
196 flavor_creator = OpenStackFlavor(self.snaps_creds,
197 card_flavor_settings)
198 flavor_creator.create()
199 self.created_object.append(flavor_creator)
201 load_flavor_settings = FlavorConfig(
206 flavor_creator = OpenStackFlavor(self.snaps_creds,
207 load_flavor_settings)
208 flavor_creator.create()
209 self.created_object.append(flavor_creator)
211 chassis_image_settings = ImageConfig(
212 name=self.test['requirements']['chassis']['image'],
216 card_image_settings = ImageConfig(
217 name=self.test['requirements']['card']['image'],
221 load_image_settings = ImageConfig(
222 name=self.test['requirements']['load']['image'],
226 chassis_port_settings = PortConfig(
227 name='ixia_chassis_port',
228 network_name=network_settings.name)
230 card1_port1_settings = PortConfig(
231 name='ixia_card1_port1',
232 network_name=network_settings.name)
234 card2_port1_settings = PortConfig(
235 name='ixia_card2_port1',
236 network_name=network_settings.name)
238 card1_port2_settings = PortConfig(
239 name='ixia_card1_port2',
240 network_name="cloudify_ims_network")
242 card2_port2_settings = PortConfig(
243 name='ixia_card2_port2',
244 network_name="cloudify_ims_network")
246 load_port_settings = PortConfig(
247 name='ixia_load_port',
248 network_name=network_settings.name)
250 chassis_settings = VmInstanceConfig(
251 name='ixia_vChassis',
252 flavor=chassis_flavor_settings.name,
253 port_settings=[chassis_port_settings],
254 security_group_names=[ixia_ssh_http_sg_settings.name,
255 ixia_managment_sg_settings.name],
256 floating_ip_settings=[FloatingIpConfig(
257 name='ixia_vChassis_fip',
258 port_name=chassis_port_settings.name,
259 router_name=router_creator.router_settings.name)])
261 vm_creator = OpenStackVmInstance(self.snaps_creds,
263 chassis_image_settings)
265 self.__logger.info("Creating Ixia vChassis VM")
267 fip_chassis = vm_creator.get_floating_ip().ip
268 self.created_object.append(vm_creator)
270 card1_settings = VmInstanceConfig(
272 flavor=card_flavor_settings.name,
273 port_settings=[card1_port1_settings, card1_port2_settings],
274 security_group_names=[ixia_managment_sg_settings.name])
276 vm_creator = OpenStackVmInstance(self.snaps_creds,
280 self.__logger.info("Creating Ixia vCard1 VM")
283 vcard_ips_p2 = list()
284 vcard_ips.append(vm_creator.get_port_ip('ixia_card1_port1'))
285 vcard_ips_p2.append(vm_creator.get_port_ip('ixia_card1_port2'))
286 self.created_object.append(vm_creator)
288 card2_settings = VmInstanceConfig(
290 flavor=card_flavor_settings.name,
291 port_settings=[card2_port1_settings, card2_port2_settings],
292 security_group_names=[ixia_managment_sg_settings.name])
294 vm_creator = OpenStackVmInstance(self.snaps_creds,
298 self.__logger.info("Creating Ixia vCard2 VM")
300 vcard_ips.append(vm_creator.get_port_ip('ixia_card2_port1'))
301 vcard_ips_p2.append(vm_creator.get_port_ip('ixia_card2_port2'))
302 self.created_object.append(vm_creator)
304 load_settings = VmInstanceConfig(
306 flavor=load_flavor_settings.name,
307 port_settings=[load_port_settings],
308 security_group_names=[ixia_ssh_http_sg_settings.name,
309 ixia_managment_sg_settings.name],
310 floating_ip_settings=[FloatingIpConfig(
311 name='ixia_vLoad_fip',
312 port_name=load_port_settings.name,
313 router_name=router_creator.router_settings.name)])
315 vm_creator = OpenStackVmInstance(self.snaps_creds,
319 self.__logger.info("Creating Ixia vLoad VM")
321 fip_load = vm_creator.get_floating_ip().ip
322 self.created_object.append(vm_creator)
324 self.__logger.info("Chassis IP is: %s", fip_chassis)
325 login_url = "https://" + str(fip_chassis) + "/api/v1/auth/session"
326 cards_url = "https://" + str(fip_chassis) + "/api/v2/ixos/cards/"
328 payload = json.dumps({"username": "admin",
330 "rememberMe": "false"})
331 api_key = json.loads((
332 ChassisRestAPI.postWithPayload(login_url, payload)))["apiKey"]
334 self.__logger.info("Adding 2 card back inside the ixia chassis...")
337 payload = {"ipAddress": str(ip)}
338 response = json.loads(ChassisRestAPI.postOperation(cards_url,
343 ChassisRestAPI.getWithHeaders(response['url'],
344 api_key)['progress']) != 100):
345 self.__logger.debug("Operation did not finish yet. \
346 Waiting for 1 more second..")
349 raise Exception("Adding card take more than 60 seconds")
352 ssh = paramiko.SSHClient()
353 ssh.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
354 ssh.connect(fip_chassis, username="admin", password="admin")
355 cmd = "set license-check disable"
356 run_blocking_ssh_command(ssh, cmd)
357 cmd = "restart-service ixServer"
358 run_blocking_ssh_command(ssh, cmd)
360 self.config_ellis(ellis_ip)
363 resolver = dns.resolver.Resolver()
364 resolver.nameservers = [dns_ip]
365 result = resolver.query("bono.clearwater.local")
372 iplistims += str(rdata.address)
376 kResourcesUrl = 'http://%s:%s/api/v0/resources' % (fip_load, 8080)
378 kRxfPath = r"REG_CALL_OPNFV_v13.rxf"
379 test_filname = self.test['inputs']['test_filname']
380 kGatewaySharedFolder = '/mnt/ixload-share/'
381 kRxfRelativeUploadPath = 'uploads/%s' % os.path.split(kRxfPath)[1]
382 kRxfAbsoluteUploadPath = os.path.join(kGatewaySharedFolder,
383 kRxfRelativeUploadPath)
384 kChassisList = [str(fip_chassis)]
385 dataFileNameList = [test_filname,
386 'Registration_only_LPS.tst',
389 kPortListPerCommunityCommunity = {"VoIP1@VM1": [(1, 1, 1)],
390 "VoIP2@VM2": [(1, 2, 1)]}
392 kStatsToDisplayDict = self.test['inputs']['stats']
393 connection = IxRestUtils.getConnection(fip_load, 8080)
395 self.__logger.info("Creating a new session...")
396 sessionUrl = IxLoadUtils.createSession(connection,
397 self.test['version'])
399 license_server = self.test['inputs']['licenseServer']
400 IxLoadUtils.configureLicenseServer(connection,
404 files_dir = os.path.join(self.case_dir, 'ixia/files')
405 target_file = open(os.path.join(files_dir, test_filname), 'w')
406 j2_env = Environment(loader=FileSystemLoader(files_dir),
408 self.test['inputs'].update(dict(
409 ipchassis=fip_chassis,
410 ipcard1=vcard_ips_p2[0],
411 ipcard2=vcard_ips_p2[1],
416 j2_env.get_template(test_filname + '.template').render(
421 self.__logger.info('Uploading files %s...' % kRxfPath)
422 for dataFile in dataFileNameList:
423 localFilePath = os.path.join(files_dir, dataFile)
424 remoteFilePath = os.path.join(kGatewaySharedFolder,
425 'uploads/%s' % dataFile)
426 IxLoadUtils.uploadFile(connection, kResourcesUrl,
427 localFilePath, remoteFilePath)
428 self.__logger.info('Upload file finished.')
430 self.__logger.info("Loading repository %s..." % kRxfAbsoluteUploadPath)
431 IxLoadUtils.loadRepository(connection, sessionUrl,
432 kRxfAbsoluteUploadPath)
434 self.__logger.info("Clearing chassis list...")
435 IxLoadUtils.clearChassisList(connection, sessionUrl)
437 self.__logger.info("Adding chassis %s..." % (kChassisList))
438 IxLoadUtils.addChassisList(connection, sessionUrl, kChassisList)
440 self.__logger.info("Assigning new ports...")
441 IxLoadUtils.assignPorts(connection, sessionUrl,
442 kPortListPerCommunityCommunity)
444 self.__logger.info("Starting the test...")
445 IxLoadUtils.runTest(connection, sessionUrl)
447 self.__logger.info("Polling values for stats %s..." % (
448 kStatsToDisplayDict))
449 result = IxLoadUtils.pollStats(connection, sessionUrl,
451 self.__logger.info("Test finished.")
452 self.__logger.info("Checking test status...")
453 testRunError = IxLoadUtils.getTestRunError(connection, sessionUrl)
455 self.__logger.info(result)
456 duration = time.time() - start_time
457 self.details['test_vnf'].update(status='PASS',
461 self.__logger.info("The test exited with following error: %s" % (
463 self.details['test_vnf'].update(status='FAIL', duration=duration)
466 self.__logger.info("The test completed successfully.")
467 self.details['test_vnf'].update(status='PASS', duration=duration)
468 self.result += 1/3 * 100
472 """Clean created objects/functions."""
473 super(CloudifyImsPerf, self).clean()
475 @energy.enable_recording
476 def run(self, **kwargs):
477 """Execute CloudifyIms test case."""
478 return super(CloudifyImsPerf, self).run(**kwargs)
481 # ----------------------------------------------------------
485 # -----------------------------------------------------------
486 def get_config(parameter, file_path):
488 Get config parameter.
490 Returns the value of a given parameter in file.yaml
491 parameter must be given in string format with dots
492 Example: general.openstack.image_name
494 with open(file_path) as config_file:
495 file_yaml = yaml.safe_load(config_file)
498 for element in parameter.split("."):
499 value = value.get(element)
501 raise ValueError("The parameter %s is not defined in"
502 " reporting.yaml" % parameter)
506 def run_blocking_ssh_command(ssh, cmd, error_msg="Unable to run this command"):
507 """Command to run ssh command with the exit status."""
508 stdin, stdout, stderr = ssh.exec_command(cmd)
509 if stdout.channel.recv_exit_status() != 0:
510 raise Exception(error_msg)