aboutsummaryrefslogtreecommitdiffstats
path: root/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.py
diff options
context:
space:
mode:
authorboucherv <valentin.boucher@orange.com>2017-08-23 16:23:34 +0200
committerCédric Ollivier <cedric.ollivier@orange.com>2017-09-14 23:04:29 +0200
commit2f9219dfa44982779990e13c177a703f2239b488 (patch)
treebf79f37e735410ee8ed607f48d916a5ff164cb75 /functest/opnfv_tests/vnf/ims/cloudify_ims_perf.py
parent7a759b0b687d66af60dc03955e33ea0f125193a4 (diff)
New testcase creation named "cloudify_ims_perf"
* IMS deployment with "cloudify_ims" testcase * IXIA infrastructure creation with SNAPS * Module configuration with REST API * Configure and run the perf tests with REST API Change-Id: I3dfddda87f9e9f4f03df375f6a032ded26a627b3 Signed-off-by: boucherv <valentin.boucher@orange.com> Co-Authored-By: Arturo Sordo Miralles <asordo@ixiacom.com>
Diffstat (limited to 'functest/opnfv_tests/vnf/ims/cloudify_ims_perf.py')
-rw-r--r--functest/opnfv_tests/vnf/ims/cloudify_ims_perf.py509
1 files changed, 509 insertions, 0 deletions
diff --git a/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.py b/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.py
new file mode 100644
index 000000000..90068525a
--- /dev/null
+++ b/functest/opnfv_tests/vnf/ims/cloudify_ims_perf.py
@@ -0,0 +1,509 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 Orange, IXIA and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+
+"""CloudifyImsPerf testcase implementation."""
+
+import logging
+import os
+import time
+
+import json
+import yaml
+import paramiko
+import dns.resolver
+from jinja2 import Environment, FileSystemLoader
+
+
+from functest.energy import energy
+from functest.opnfv_tests.openstack.snaps import snaps_utils
+import functest.opnfv_tests.vnf.ims.cloudify_ims as cloudify_ims
+from functest.utils.constants import CONST
+
+from snaps.openstack.create_network import (NetworkSettings, SubnetSettings,
+ OpenStackNetwork, PortSettings)
+from snaps.openstack.create_security_group import (SecurityGroupSettings,
+ SecurityGroupRuleSettings,
+ Direction, Protocol,
+ OpenStackSecurityGroup)
+from snaps.openstack.create_router import RouterSettings, OpenStackRouter
+from snaps.openstack.create_instance import (VmInstanceSettings,
+ FloatingIpSettings,
+ OpenStackVmInstance)
+from snaps.openstack.create_flavor import FlavorSettings, OpenStackFlavor
+from snaps.openstack.create_image import ImageSettings
+
+from ixia.utils.IxChassisUtils import ChassisRestAPI
+import ixia.utils.IxLoadUtils as IxLoadUtils
+import ixia.utils.IxRestUtils as IxRestUtils
+
+__author__ = "Valentin Boucher <valentin.boucher@orange.com>"
+
+
+class CloudifyImsPerf(cloudify_ims.CloudifyIms):
+ """Clearwater vIMS deployed with Cloudify Orchestrator Case."""
+
+ __logger = logging.getLogger(__name__)
+
+ def __init__(self, **kwargs):
+ """Initialize CloudifyIms testcase object."""
+ if "case_name" not in kwargs:
+ kwargs["case_name"] = "cloudify_ims_perf"
+ super(CloudifyImsPerf, self).__init__(**kwargs)
+
+ # Retrieve the configuration
+ try:
+ self.config = CONST.__getattribute__(
+ 'vnf_{}_config'.format(self.case_name))
+ except Exception:
+ raise Exception("VNF config file not found")
+
+ self.snaps_creds = ''
+ self.created_object = []
+
+ config_file = os.path.join(self.case_dir, self.config)
+ self.orchestrator = dict(
+ requirements=get_config("orchestrator.requirements", config_file),
+ )
+ self.details['orchestrator'] = dict(
+ name=get_config("orchestrator.name", config_file),
+ version=get_config("orchestrator.version", config_file),
+ status='ERROR',
+ result=''
+ )
+ self.__logger.debug("Orchestrator configuration %s", self.orchestrator)
+ self.vnf = dict(
+ descriptor=get_config("vnf.descriptor", config_file),
+ inputs=get_config("vnf.inputs", config_file),
+ requirements=get_config("vnf.requirements", config_file)
+ )
+ self.details['vnf'] = dict(
+ descriptor_version=self.vnf['descriptor']['version'],
+ name=get_config("vnf.name", config_file),
+ version=get_config("vnf.version", config_file),
+ )
+ self.__logger.debug("VNF configuration: %s", self.vnf)
+
+ self.test = dict(
+ version=get_config("vnf_test_suite.version", config_file),
+ inputs=get_config("vnf_test_suite.inputs", config_file),
+ requirements=get_config("vnf_test_suite.requirements", config_file)
+ )
+
+ self.details['test_vnf'] = dict(
+ name=get_config("vnf_test_suite.name", config_file),
+ version=get_config("vnf_test_suite.version", config_file),
+ requirements=get_config("vnf_test_suite.requirements", config_file)
+ )
+ self.images = get_config("tenant_images", config_file)
+ self.__logger.info("Images needed for vIMS: %s", self.images)
+
+ def test_vnf(self):
+ """Run IXIA Stress test on clearwater ims instance."""
+ start_time = time.time()
+
+ cfy_client = self.orchestrator['object']
+
+ outputs = cfy_client.deployments.outputs.get(
+ self.vnf['descriptor'].get('name'))['outputs']
+ dns_ip = outputs['dns_ip']
+ ellis_ip = outputs['ellis_ip']
+
+ self.__logger.info("Creating full IXIA network ...")
+ subnet_settings = SubnetSettings(name='ixia_management_subnet',
+ cidr='10.10.10.0/24')
+ network_settings = NetworkSettings(name='ixia_management_network',
+ subnet_settings=[subnet_settings])
+ network_creator = OpenStackNetwork(self.snaps_creds, network_settings)
+ network_creator.create()
+ self.created_object.append(network_creator)
+ ext_net_name = snaps_utils.get_ext_net_name(self.snaps_creds)
+ router_creator = OpenStackRouter(
+ self.snaps_creds,
+ RouterSettings(
+ name='ixia_management_router',
+ external_gateway=ext_net_name,
+ internal_subnets=[subnet_settings.name]))
+ router_creator.create()
+ self.created_object.append(router_creator)
+
+ # security group creation
+ self.__logger.info("Creating security groups for IXIA VMs")
+ sg_rules = list()
+ sg_rules.append(
+ SecurityGroupRuleSettings(sec_grp_name="ixia_management",
+ direction=Direction.ingress,
+ protocol=Protocol.tcp, port_range_min=1,
+ port_range_max=65535))
+ sg_rules.append(
+ SecurityGroupRuleSettings(sec_grp_name="ixia_management",
+ direction=Direction.ingress,
+ protocol=Protocol.udp, port_range_min=1,
+ port_range_max=65535))
+ sg_rules.append(
+ SecurityGroupRuleSettings(sec_grp_name="ixia_management",
+ direction=Direction.ingress,
+ protocol=Protocol.icmp))
+
+ ixia_managment_sg_settings = SecurityGroupSettings(
+ name="ixia_management",
+ rule_settings=sg_rules)
+ securit_group_creator = OpenStackSecurityGroup(
+ self.snaps_creds,
+ ixia_managment_sg_settings)
+
+ securit_group_creator.create()
+ self.created_object.append(securit_group_creator)
+
+ sg_rules = list()
+ sg_rules.append(
+ SecurityGroupRuleSettings(sec_grp_name="ixia_ssh_http",
+ direction=Direction.ingress,
+ protocol=Protocol.tcp, port_range_min=1,
+ port_range_max=65535))
+
+ ixia_ssh_http_sg_settings = SecurityGroupSettings(
+ name="ixia_ssh_http",
+ rule_settings=sg_rules)
+ securit_group_creator = OpenStackSecurityGroup(
+ self.snaps_creds,
+ ixia_ssh_http_sg_settings)
+
+ securit_group_creator.create()
+ self.created_object.append(securit_group_creator)
+
+ chassis_flavor_settings = FlavorSettings(
+ name="ixia_vChassis",
+ ram=4096,
+ disk=40,
+ vcpus=2)
+ flavor_creator = OpenStackFlavor(self.snaps_creds,
+ chassis_flavor_settings)
+ flavor_creator.create()
+ self.created_object.append(flavor_creator)
+
+ card_flavor_settings = FlavorSettings(
+ name="ixia_vCard",
+ ram=4096,
+ disk=4,
+ vcpus=2)
+ flavor_creator = OpenStackFlavor(self.snaps_creds,
+ card_flavor_settings)
+ flavor_creator.create()
+ self.created_object.append(flavor_creator)
+
+ load_flavor_settings = FlavorSettings(
+ name="ixia_vLoad",
+ ram=8192,
+ disk=100,
+ vcpus=4)
+ flavor_creator = OpenStackFlavor(self.snaps_creds,
+ load_flavor_settings)
+ flavor_creator.create()
+ self.created_object.append(flavor_creator)
+
+ chassis_image_settings = ImageSettings(
+ name=self.test['requirements']['chassis']['image'],
+ image_user='admin',
+ exists=True)
+
+ card_image_settings = ImageSettings(
+ name=self.test['requirements']['card']['image'],
+ image_user='admin',
+ exists=True)
+
+ load_image_settings = ImageSettings(
+ name=self.test['requirements']['load']['image'],
+ image_user='admin',
+ exists=True)
+
+ chassis_port_settings = PortSettings(
+ name='ixia_chassis_port',
+ network_name=network_settings.name)
+
+ card1_port1_settings = PortSettings(
+ name='ixia_card1_port1',
+ network_name=network_settings.name)
+
+ card2_port1_settings = PortSettings(
+ name='ixia_card2_port1',
+ network_name=network_settings.name)
+
+ card1_port2_settings = PortSettings(
+ name='ixia_card1_port2',
+ network_name="cloudify_ims_network")
+
+ card2_port2_settings = PortSettings(
+ name='ixia_card2_port2',
+ network_name="cloudify_ims_network")
+
+ load_port_settings = PortSettings(
+ name='ixia_load_port',
+ network_name=network_settings.name)
+
+ chassis_settings = VmInstanceSettings(
+ name='ixia_vChassis',
+ flavor=chassis_flavor_settings.name,
+ port_settings=[chassis_port_settings],
+ security_group_names=[ixia_ssh_http_sg_settings.name,
+ ixia_managment_sg_settings.name],
+ floating_ip_settings=[FloatingIpSettings(
+ name='ixia_vChassis_fip',
+ port_name=chassis_port_settings.name,
+ router_name=router_creator.router_settings.name)])
+
+ vm_creator = OpenStackVmInstance(self.snaps_creds,
+ chassis_settings,
+ chassis_image_settings)
+
+ self.__logger.info("Creating Ixia vChassis VM")
+ vm_creator.create()
+ fip_chassis = vm_creator.get_floating_ip().ip
+ self.created_object.append(vm_creator)
+
+ card1_settings = VmInstanceSettings(
+ name='ixia_vCard1',
+ flavor=card_flavor_settings.name,
+ port_settings=[card1_port1_settings, card1_port2_settings],
+ security_group_names=[ixia_managment_sg_settings.name])
+
+ vm_creator = OpenStackVmInstance(self.snaps_creds,
+ card1_settings,
+ card_image_settings)
+
+ self.__logger.info("Creating Ixia vCard1 VM")
+ vm_creator.create()
+ vcard_ips = list()
+ vcard_ips_p2 = list()
+ vcard_ips.append(vm_creator.get_port_ip('ixia_card1_port1'))
+ vcard_ips_p2.append(vm_creator.get_port_ip('ixia_card1_port2'))
+ self.created_object.append(vm_creator)
+
+ card2_settings = VmInstanceSettings(
+ name='ixia_vCard2',
+ flavor=card_flavor_settings.name,
+ port_settings=[card2_port1_settings, card2_port2_settings],
+ security_group_names=[ixia_managment_sg_settings.name])
+
+ vm_creator = OpenStackVmInstance(self.snaps_creds,
+ card2_settings,
+ card_image_settings)
+
+ self.__logger.info("Creating Ixia vCard2 VM")
+ vm_creator.create()
+ vcard_ips.append(vm_creator.get_port_ip('ixia_card2_port1'))
+ vcard_ips_p2.append(vm_creator.get_port_ip('ixia_card2_port2'))
+ self.created_object.append(vm_creator)
+
+ load_settings = VmInstanceSettings(
+ name='ixia_vLoad',
+ flavor=load_flavor_settings.name,
+ port_settings=[load_port_settings],
+ security_group_names=[ixia_ssh_http_sg_settings.name,
+ ixia_managment_sg_settings.name],
+ floating_ip_settings=[FloatingIpSettings(
+ name='ixia_vLoad_fip',
+ port_name=load_port_settings.name,
+ router_name=router_creator.router_settings.name)])
+
+ vm_creator = OpenStackVmInstance(self.snaps_creds,
+ load_settings,
+ load_image_settings)
+
+ self.__logger.info("Creating Ixia vLoad VM")
+ vm_creator.create()
+ fip_load = vm_creator.get_floating_ip().ip
+ self.created_object.append(vm_creator)
+
+ self.__logger.info("Chassis IP is: %s", fip_chassis)
+ login_url = "https://" + str(fip_chassis) + "/api/v1/auth/session"
+ cards_url = "https://" + str(fip_chassis) + "/api/v2/ixos/cards/"
+
+ payload = json.dumps({"username": "admin",
+ "password": "admin",
+ "rememberMe": "false"})
+ api_key = json.loads((
+ ChassisRestAPI.postWithPayload(login_url, payload)))["apiKey"]
+
+ self.__logger.info("Adding 2 card back inside the ixia chassis...")
+
+ for ip in vcard_ips:
+ payload = {"ipAddress": str(ip)}
+ response = json.loads(ChassisRestAPI.postOperation(cards_url,
+ api_key,
+ payload))
+ count = 0
+ while (int(
+ ChassisRestAPI.getWithHeaders(response['url'],
+ api_key)['progress']) != 100):
+ self.__logger.debug("Operation did not finish yet. \
+ Waiting for 1 more second..")
+ time.sleep(1)
+ if count > 60:
+ raise Exception("Adding card take more than 60 seconds")
+ count += 1
+
+ ssh = paramiko.SSHClient()
+ ssh.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
+ ssh.connect(fip_chassis, username="admin", password="admin")
+ cmd = "set license-check disable"
+ run_blocking_ssh_command(ssh, cmd)
+ cmd = "restart-service ixServer"
+ run_blocking_ssh_command(ssh, cmd)
+
+ self.config_ellis(ellis_ip)
+
+ # Get IPs of P-CSCF
+ resolver = dns.resolver.Resolver()
+ resolver.nameservers = [dns_ip]
+ result = resolver.query("bono.clearwater.local")
+
+ iplistims = ''
+ i = 0
+ for rdata in result:
+ i = i + 1
+ print rdata.address
+ iplistims += str(rdata.address)
+ if i != len(result):
+ iplistims += ';'
+
+ kResourcesUrl = 'http://%s:%s/api/v0/resources' % (fip_load, 8080)
+
+ kRxfPath = r"REG_CALL_OPNFV_v13.rxf"
+ test_filname = self.test['inputs']['test_filname']
+ kGatewaySharedFolder = '/mnt/ixload-share/'
+ kRxfRelativeUploadPath = 'uploads/%s' % os.path.split(kRxfPath)[1]
+ kRxfAbsoluteUploadPath = os.path.join(kGatewaySharedFolder,
+ kRxfRelativeUploadPath)
+ kChassisList = [str(fip_chassis)]
+ dataFileNameList = [test_filname,
+ 'Registration_only_LPS.tst',
+ 'SIPCall.tst']
+
+ kPortListPerCommunityCommunity = {"VoIP1@VM1": [(1, 1, 1)],
+ "VoIP2@VM2": [(1, 2, 1)]}
+
+ kStatsToDisplayDict = self.test['inputs']['stats']
+ connection = IxRestUtils.getConnection(fip_load, 8080)
+
+ self.__logger.info("Creating a new session...")
+ sessionUrl = IxLoadUtils.createSession(connection,
+ self.test['version'])
+
+ license_server = self.test['inputs']['licenseServer']
+ IxLoadUtils.configureLicenseServer(connection,
+ sessionUrl,
+ license_server)
+
+ files_dir = os.path.join(self.case_dir, 'ixia/files')
+ target_file = open(os.path.join(files_dir, test_filname), 'w')
+ j2_env = Environment(loader=FileSystemLoader(files_dir),
+ trim_blocks=True)
+ self.test['inputs'].update(dict(
+ ipchassis=fip_chassis,
+ ipcard1=vcard_ips_p2[0],
+ ipcard2=vcard_ips_p2[1],
+ iplistims=iplistims
+ ))
+
+ target_file.write(
+ j2_env.get_template(test_filname + '.template').render(
+ self.test['inputs']
+ ))
+ target_file.close()
+
+ self.__logger.info('Uploading files %s...' % kRxfPath)
+ for dataFile in dataFileNameList:
+ localFilePath = os.path.join(files_dir, dataFile)
+ remoteFilePath = os.path.join(kGatewaySharedFolder,
+ 'uploads/%s' % dataFile)
+ IxLoadUtils.uploadFile(connection, kResourcesUrl,
+ localFilePath, remoteFilePath)
+ self.__logger.info('Upload file finished.')
+
+ self.__logger.info("Loading repository %s..." % kRxfAbsoluteUploadPath)
+ IxLoadUtils.loadRepository(connection, sessionUrl,
+ kRxfAbsoluteUploadPath)
+
+ self.__logger.info("Clearing chassis list...")
+ IxLoadUtils.clearChassisList(connection, sessionUrl)
+
+ self.__logger.info("Adding chassis %s..." % (kChassisList))
+ IxLoadUtils.addChassisList(connection, sessionUrl, kChassisList)
+
+ self.__logger.info("Assigning new ports...")
+ IxLoadUtils.assignPorts(connection, sessionUrl,
+ kPortListPerCommunityCommunity)
+
+ self.__logger.info("Starting the test...")
+ IxLoadUtils.runTest(connection, sessionUrl)
+
+ self.__logger.info("Polling values for stats %s..." % (
+ kStatsToDisplayDict))
+ result = IxLoadUtils.pollStats(connection, sessionUrl,
+ kStatsToDisplayDict)
+ self.__logger.info("Test finished.")
+ self.__logger.info("Checking test status...")
+ testRunError = IxLoadUtils.getTestRunError(connection, sessionUrl)
+
+ self.__logger.info(result)
+ duration = time.time() - start_time
+ self.details['test_vnf'].update(status='PASS',
+ result=result,
+ duration=duration)
+ if testRunError:
+ self.__logger.info("The test exited with following error: %s" % (
+ testRunError))
+ self.details['test_vnf'].update(status='FAIL', duration=duration)
+ return False
+ else:
+ self.__logger.info("The test completed successfully.")
+ self.details['test_vnf'].update(status='PASS', duration=duration)
+ self.result += 1/3 * 100
+ return True
+
+ def clean(self):
+ """Clean created objects/functions."""
+ super(CloudifyImsPerf, self).clean()
+
+ @energy.enable_recording
+ def run(self, **kwargs):
+ """Execute CloudifyIms test case."""
+ return super(CloudifyImsPerf, self).run(**kwargs)
+
+
+# ----------------------------------------------------------
+#
+# YAML UTILS
+#
+# -----------------------------------------------------------
+def get_config(parameter, file_path):
+ """
+ Get config parameter.
+
+ Returns the value of a given parameter in file.yaml
+ parameter must be given in string format with dots
+ Example: general.openstack.image_name
+ """
+ with open(file_path) as config_file:
+ file_yaml = yaml.safe_load(config_file)
+ config_file.close()
+ value = file_yaml
+ for element in parameter.split("."):
+ value = value.get(element)
+ if value is None:
+ raise ValueError("The parameter %s is not defined in"
+ " reporting.yaml" % parameter)
+ return value
+
+
+def run_blocking_ssh_command(ssh, cmd, error_msg="Unable to run this command"):
+ """Command to run ssh command with the exit status."""
+ stdin, stdout, stderr = ssh.exec_command(cmd)
+ if stdout.channel.recv_exit_status() != 0:
+ raise Exception(error_msg)