From bdad6faa1fafe7cd20ea96aa70a52178d62add63 Mon Sep 17 00:00:00 2001 From: Manuel Buil Date: Mon, 27 Aug 2018 18:11:11 +0200 Subject: Decouple tacker from tests Support n-sfc too and abstract a bit the MANO layer so that other MANO components can be inserted into the test Change-Id: I3fb59fbf40b4207bf1721092cd8ff0559e1d9d90 Signed-off-by: Manuel Buil --- sfc/tests/functest/config.yaml | 4 + sfc/tests/functest/run_sfc_tests.py | 8 +- sfc/tests/functest/sfc_chain_deletion.py | 11 +- .../sfc_one_chain_two_service_functions.py | 11 +- sfc/tests/functest/sfc_parent_function.py | 236 ++++++++++++++++----- sfc/tests/functest/sfc_symmetric_chain.py | 61 +----- sfc/tests/functest/sfc_two_chains_SSH_and_HTTP.py | 10 +- 7 files changed, 220 insertions(+), 121 deletions(-) (limited to 'sfc/tests') diff --git a/sfc/tests/functest/config.yaml b/sfc/tests/functest/config.yaml index 0144352e..d595f0cf 100644 --- a/sfc/tests/functest/config.yaml +++ b/sfc/tests/functest/config.yaml @@ -25,6 +25,10 @@ defaults: vnfd-dir: "vnfd-templates" vnfd-default-params-file: "test-vnfd-default-params.yaml" + # mano_component can be [tacker, no-mano]. When no-mano, + # then networking-sfc is used + mano_component: "no-mano" + # [OPTIONAL] Only when deploying VNFs without the default image (vxlan_tool) # vnf_image_name: xxx # vnf_image_format: yyy diff --git a/sfc/tests/functest/run_sfc_tests.py b/sfc/tests/functest/run_sfc_tests.py index 6fe211bf..2f72acb5 100644 --- a/sfc/tests/functest/run_sfc_tests.py +++ b/sfc/tests/functest/run_sfc_tests.py @@ -176,7 +176,9 @@ class SfcFunctest(testcase.TestCase): result = {'status': 'FAILED'} creators = tc_instance.get_creators() if self.cleanup_flag is True: - sfc_cleanup.cleanup(creators, odl_ip=odl_ip, + sfc_cleanup.cleanup(creators, + COMMON_CONFIG.mano_component, + odl_ip=odl_ip, odl_port=odl_port) cleanup_run_flag = True end_time = time.time() @@ -198,7 +200,9 @@ class SfcFunctest(testcase.TestCase): self.details.update({test_name: dic}) if cleanup_run_flag is not True and self.cleanup_flag is True: - sfc_cleanup.cleanup(creators, odl_ip=odl_ip, + sfc_cleanup.cleanup(creators, + COMMON_CONFIG.mano_component, + odl_ip=odl_ip, odl_port=odl_port) self.stop_time = time.time() diff --git a/sfc/tests/functest/sfc_chain_deletion.py b/sfc/tests/functest/sfc_chain_deletion.py index 527dc822..3944cf90 100644 --- a/sfc/tests/functest/sfc_chain_deletion.py +++ b/sfc/tests/functest/sfc_chain_deletion.py @@ -32,11 +32,12 @@ class SfcChainDeletion(sfc_parent_function.SfcCommonTestCase): def run(self): logger.info("The test scenario %s is starting", __name__) - self.create_custom_vnfd(self.testcase_config.test_vnfd_red, - 'test-vnfd1') + self.register_vnf_template(self.testcase_config.test_vnfd_red, + 'test-vnfd1') self.create_vnf(self.vnfs[0], 'test-vnfd1', 'test-vim') - self.create_chain(self.testcase_config) + self.create_vnffg(self.testcase_config.test_vnffgd_red, 'red', + 'red_http', port=80, protocol='tcp', symmetric=False) t1 = threading.Thread(target=odl_utils.wait_for_classification_rules, args=(self.ovs_logger, self.compute_nodes, @@ -63,7 +64,9 @@ class SfcChainDeletion(sfc_parent_function.SfcCommonTestCase): self.remove_vnffg('red_http', 'red') self.check_deletion() - self.create_chain(self.testcase_config) + self.create_vnffg(self.testcase_config.test_vnffgd_red, 'blue', + 'blue_http', port=80, protocol='tcp', + symmetric=False, only_chain=True) t2 = threading.Thread(target=odl_utils.wait_for_classification_rules, args=(self.ovs_logger, self.compute_nodes, diff --git a/sfc/tests/functest/sfc_one_chain_two_service_functions.py b/sfc/tests/functest/sfc_one_chain_two_service_functions.py index 039cf625..38d6176f 100644 --- a/sfc/tests/functest/sfc_one_chain_two_service_functions.py +++ b/sfc/tests/functest/sfc_one_chain_two_service_functions.py @@ -29,16 +29,17 @@ class SfcOneChainTwoServiceTC(sfc_parent_function.SfcCommonTestCase): def run(self): logger.info("The test scenario %s is starting", __name__) - self.create_custom_vnfd(self.testcase_config.test_vnfd_red, - 'test-vnfd1') - self.create_custom_vnfd(self.testcase_config.test_vnfd_blue, - 'test-vnfd2') + + self.register_vnf_template(self.testcase_config.test_vnfd_red, + 'test-vnfd1') + self.register_vnf_template(self.testcase_config.test_vnfd_blue, + 'test-vnfd2') self.create_vnf(self.vnfs[0], 'test-vnfd1', 'test-vim') self.create_vnf(self.vnfs[1], 'test-vnfd2', 'test-vim') self.create_vnffg(self.testcase_config.test_vnffgd_red, 'red', - 'red_http') + 'red_http', port=80, protocol='tcp', symmetric=False) # Start measuring the time it takes to implement the # classification rules t1 = threading.Thread(target=odl_utils.wait_for_classification_rules, diff --git a/sfc/tests/functest/sfc_parent_function.py b/sfc/tests/functest/sfc_parent_function.py index 6af8e8ec..d93b2fbf 100644 --- a/sfc/tests/functest/sfc_parent_function.py +++ b/sfc/tests/functest/sfc_parent_function.py @@ -51,11 +51,15 @@ class SfcCommonTestCase(object): self.vnf_id = None self.client_floating_ip = None self.server_floating_ip = None - self.fips_sfs = None + self.fips_sfs = [] self.neutron_port = None + self.vnf_objects = dict() self.testcase_config = testcase_config self.vnfs = vnfs + # n-sfc variables + self.port_groups = [] + self.prepare_env(testcase_config, supported_installers, vnfs) def prepare_env(self, testcase_config, supported_installers, vnfs): @@ -117,9 +121,10 @@ class SfcCommonTestCase(object): self.controller_clients = test_utils.get_ssh_clients(controller_nodes) self.compute_clients = test_utils.get_ssh_clients(self.compute_nodes) - self.tacker_client = os_sfc_utils.get_tacker_client() - os_sfc_utils.register_vim(self.tacker_client, - vim_file=COMMON_CONFIG.vim_file) + if COMMON_CONFIG.mano_component == 'tacker': + self.tacker_client = os_sfc_utils.get_tacker_client() + os_sfc_utils.register_vim(self.tacker_client, + vim_file=COMMON_CONFIG.vim_file) self.ovs_logger = ovs_log.OVSLogger( os.path.join(COMMON_CONFIG.sfc_test_dir, 'ovs-logs'), @@ -170,13 +175,15 @@ class SfcCommonTestCase(object): openstack_sfc.create_instance(SERVER, COMMON_CONFIG.flavor, self.image_creator, self.network, self.sg, - self.test_topology['server']) + self.test_topology['server'], + [SERVER + '-port']) self.client_instance, self.client_creator = \ openstack_sfc.create_instance(CLIENT, COMMON_CONFIG.flavor, self.image_creator, self.network, self.sg, - self.test_topology['client']) + self.test_topology['client'], + [CLIENT + '-port']) logger.info('This test is run with the topology {0}'.format( self.test_topology['id'])) logger.info('Topology description: {0}'.format( @@ -186,6 +193,20 @@ class SfcCommonTestCase(object): logger.info("Server instance received private ip [{}]".format( self.server_ip)) + def register_vnf_template(self, test_case_name, template_name): + """ Register the template which defines the VNF + + :param test_case_name: the name of the test case + :param template_name: name of the template + """ + + if COMMON_CONFIG.mano_component == 'tacker': + self.create_custom_vnfd(test_case_name, template_name) + + elif COMMON_CONFIG.mano_component == 'no-mano': + # networking-sfc does not have the template concept + pass + def create_custom_vnfd(self, test_case_name, vnfd_name): """Create VNF Descriptor (VNFD) @@ -201,12 +222,14 @@ class SfcCommonTestCase(object): tosca_file=tosca_file, vnfd_name=vnfd_name) - def create_vnf(self, vnf_names, vnfd_name, vim_name): - """Create vnf + def create_vnf(self, vnf_name, vnfd_name=None, vim_name=None, + symmetric=False): + """Create custom vnf - :param vnf_names: names of available vnf(s) + :param vnf_name: name of the vnf :param vnfd_name: name of the vnfd template (tacker) :param vim_name: name of the vim (tacker) + :param symmetric: specifies whether this is part of the symmetric test :return: av zone """ @@ -215,14 +238,35 @@ class SfcCommonTestCase(object): logger.info('Topology description: {0}' .format(self.test_topology['description'])) - os_sfc_utils.create_vnf_in_av_zone( - self.tacker_client, vnf_names, vnfd_name, vim_name, - self.default_param_file, self.test_topology[vnf_names]) - - self.vnf_id = os_sfc_utils.wait_for_vnf(self.tacker_client, - vnf_name=vnf_names) - if self.vnf_id is None: - raise Exception('ERROR while booting vnfs') + if COMMON_CONFIG.mano_component == 'tacker': + os_sfc_utils.create_vnf_in_av_zone( + self.tacker_client, vnf_name, vnfd_name, vim_name, + self.default_param_file, self.test_topology[vnf_name]) + + self.vnf_id = os_sfc_utils.wait_for_vnf(self.tacker_client, + vnf_name=vnf_name) + if self.vnf_id is None: + raise Exception('ERROR while booting vnfs') + + elif COMMON_CONFIG.mano_component == 'no-mano': + av_zone = self.test_topology[vnf_name] + if symmetric: + ports = [vnf_name + '-port1', vnf_name + '-port2'] + else: + ports = [vnf_name + '-port'] + vnf_instance, vnf_creator = \ + openstack_sfc.create_instance(vnf_name, COMMON_CONFIG.flavor, + self.vnf_image_creator, + self.network, + self.sg, + av_zone, + ports) + + if not openstack_sfc.wait_for_vnf(vnf_creator): + raise Exception('ERROR while booting vnf %s' % vnf_name) + + self.creators.append(vnf_creator) + self.vnf_objects[vnf_name] = [vnf_creator, vnf_instance] def assign_floating_ip_client_server(self): """Assign floating IPs on the router about server and the client @@ -238,18 +282,28 @@ class SfcCommonTestCase(object): self.server_floating_ip = openstack_sfc.assign_floating_ip( self.router, self.server_instance, self.server_creator) - def assign_floating_ip_sfs(self, vnf_ip=None): + def assign_floating_ip_sfs(self): """Assign floating IPs to service function - :param vnf_ip: IP of vnf - optional :return: The list fips_sfs consist of the available IPs for service functions """ logger.info("Assigning floating IPs to service functions") - self.fips_sfs = openstack_sfc.assign_floating_ip_vnfs(self.router, - vnf_ip) + if COMMON_CONFIG.mano_component == 'tacker': + vnf_ip = os_sfc_utils.get_vnf_ip(self.tacker_client, + vnf_id=self.vnf_id) + self.fips_sfs = openstack_sfc.assign_floating_ip_vnfs(self.router, + vnf_ip) + elif COMMON_CONFIG.mano_component == 'no-mano': + for vnf in self.vnfs: + # creator object is in [0] and instance in [1] + vnf_instance = self.vnf_objects[vnf][1] + vnf_creator = self.vnf_objects[vnf][0] + sf_floating_ip = openstack_sfc.assign_floating_ip( + self.router, vnf_instance, vnf_creator) + self.fips_sfs.append(sf_floating_ip) def check_floating_ips(self): """Check the responsivness of the floating IPs @@ -338,37 +392,122 @@ class SfcCommonTestCase(object): :param par_vnffgd_name: The vnffgd name of network components :return: Remove the vnffg and vnffgd components """ + if COMMON_CONFIG.mano_component == 'tacker': + os_sfc_utils.delete_vnffg(self.tacker_client, + vnffg_name=par_vnffg_name) - os_sfc_utils.delete_vnffg(self.tacker_client, - vnffg_name=par_vnffg_name) + os_sfc_utils.delete_vnffgd(self.tacker_client, + vnffgd_name=par_vnffgd_name) - os_sfc_utils.delete_vnffgd(self.tacker_client, - vnffgd_name=par_vnffgd_name) + elif COMMON_CONFIG.mano_component == 'no-mano': + # TODO: If we had a testcase where only one chains must be removed + # we would need to add the logic. Now it removes all of them + openstack_sfc.delete_chain() - def create_vnffg(self, testcase_config_name, vnf_name, conn_name): + def create_vnffg(self, testcase_config_name, vnffgd_name, vnffg_name, + port=80, protocol='tcp', symmetric=False, + only_chain=False): """Create the vnffg components following the instructions from relevant templates. :param testcase_config_name: The config input of the test case - :param vnf_name: The name of the vnf - :param conn_name: Protocol type / name of the component + :param vnffgd_name: The name of the vnffgd template + :param vnffg_name: The name for the vnffg :return: Create the vnffg component """ - tosca_file = os.path.join(COMMON_CONFIG.sfc_test_dir, - COMMON_CONFIG.vnffgd_dir, - testcase_config_name) - - os_sfc_utils.create_vnffgd(self.tacker_client, - tosca_file=tosca_file, - vnffgd_name=vnf_name) - - self.neutron_port = openstack_sfc.get_client_port(self.client_instance, - self.client_creator) - os_sfc_utils.create_vnffg_with_param_file(self.tacker_client, vnf_name, - conn_name, - self.default_param_file, - self.neutron_port.id) + logger.info("Creating the vnffg...") + + if COMMON_CONFIG.mano_component == 'tacker': + tosca_file = os.path.join(COMMON_CONFIG.sfc_test_dir, + COMMON_CONFIG.vnffgd_dir, + testcase_config_name) + + os_sfc_utils.create_vnffgd(self.tacker_client, + tosca_file=tosca_file, + vnffgd_name=vnffgd_name) + + self.neutron_port = \ + openstack_sfc.get_instance_port(self.client_instance, + self.client_creator) + + if symmetric: + server_port = openstack_sfc.get_instance_port( + self.server_instance, + self.server_creator) + server_ip_prefix = self.server_ip + '/32' + + os_sfc_utils.create_vnffg_with_param_file( + self.tacker_client, + vnffgd_name, + vnffg_name, + self.default_param_file, + self.neutron_port.id, + server_port=server_port.id, + server_ip=server_ip_prefix) + + else: + os_sfc_utils.create_vnffg_with_param_file( + self.tacker_client, + vnffgd_name, + vnffg_name, + self.default_param_file, + self.neutron_port.id) + + elif COMMON_CONFIG.mano_component == 'no-mano': + if not only_chain: + for vnf in self.vnfs: + # creator object is in [0] and instance in [1] + vnf_instance = self.vnf_objects[vnf][1] + vnf_creator = self.vnf_objects[vnf][0] + if symmetric: + # VNFs have two ports + p1 = vnf_instance.name + '-port1' + neutron_port1 = \ + openstack_sfc.get_instance_port(vnf_instance, + vnf_creator, + port_name=p1) + p2 = vnf_instance.name + '-port2' + neutron_port2 = \ + openstack_sfc.get_instance_port(vnf_instance, + vnf_creator, + port_name=p2) + neutron_ports = [neutron_port1, neutron_port2] + + else: + neutron_port1 = \ + openstack_sfc.get_instance_port(vnf_instance, + vnf_creator) + neutron_ports = [neutron_port1] + + port_group = \ + openstack_sfc.create_port_groups(neutron_ports, + vnf_instance) + + self.port_groups.append(port_group) + self.neutron_port = \ + openstack_sfc.get_instance_port(self.client_instance, + self.client_creator) + + if symmetric: + # We must pass the server_port and server_ip in the symmetric + # case. Otherwise ODL does not work well + server_port = openstack_sfc.get_instance_port( + self.server_instance, + self.server_creator) + server_ip_prefix = self.server_ip + '/32' + openstack_sfc.create_chain(self.port_groups, + self.neutron_port.id, + port, protocol, vnffg_name, + symmetric, + server_port=server_port.id, + server_ip=server_ip_prefix) + + else: + openstack_sfc.create_chain(self.port_groups, + self.neutron_port.id, + port, protocol, vnffg_name, + symmetric) def present_results_http(self): """Check whether the connection between server and client using @@ -438,19 +577,6 @@ class SfcCommonTestCase(object): return results - def create_chain(self, testcase_config): - """Create a connection chain for the test scenario purposes - - :param testcase_config: The config input of the test case - :return: Create the proper chain for the specific test scenario - """ - - self.neutron_port = openstack_sfc.get_client_port(self.client_instance, - self.client_creator) - odl_utils.create_chain(self.tacker_client, self.default_param_file, - self.neutron_port, COMMON_CONFIG, - testcase_config) - def check_deletion(self): """Check that the deletion of the chain has been completed sucessfully. diff --git a/sfc/tests/functest/sfc_symmetric_chain.py b/sfc/tests/functest/sfc_symmetric_chain.py index 1b57a244..4593d8c6 100644 --- a/sfc/tests/functest/sfc_symmetric_chain.py +++ b/sfc/tests/functest/sfc_symmetric_chain.py @@ -8,13 +8,10 @@ # # http://www.apache.org/licenses/LICENSE-2.0 # -import os -import sys import threading import logging import urllib3 -import sfc.lib.openstack_utils as os_sfc_utils import sfc.lib.odl_utils as odl_utils import sfc.lib.config as sfc_config from sfc.tests.functest import sfc_parent_function @@ -24,7 +21,6 @@ logger = logging.getLogger(__name__) COMMON_CONFIG = sfc_config.CommonConfig() CLIENT = "client" SERVER = "server" -openstack_sfc = os_sfc_utils.OpenStackSFC() class SfcSymmetricChain(sfc_parent_function.SfcCommonTestCase): @@ -42,54 +38,21 @@ class SfcSymmetricChain(sfc_parent_function.SfcCommonTestCase): def run(self): logger.info("The test scenario %s is starting", __name__) - self.create_custom_vnfd(self.testcase_config.test_vnfd, 'test-vnfd1') - self.create_vnf(self.vnfs[0], 'test-vnfd1', 'test-vim') - - if self.vnf_id is None: - logger.error('ERROR while booting VNF') - sys.exit(1) - - tosca_file = os.path.join( - COMMON_CONFIG.sfc_test_dir, - COMMON_CONFIG.vnffgd_dir, - self.testcase_config.test_vnffgd) - os_sfc_utils.create_vnffgd( - self.tacker_client, - tosca_file=tosca_file, - vnffgd_name='test-vnffgd') - - client_port = openstack_sfc.get_client_port( - self.client_instance, - self.client_creator) - server_port = openstack_sfc.get_client_port( - self.server_instance, - self.server_creator) - - server_ip_prefix = self.server_ip + '/32' - - default_param_file = os.path.join( - COMMON_CONFIG.sfc_test_dir, - COMMON_CONFIG.vnfd_dir, - COMMON_CONFIG.vnfd_default_params_file) - - os_sfc_utils.create_vnffg_with_param_file( - self.tacker_client, - 'test-vnffgd', - 'test-vnffg', - default_param_file, - client_port.id, - server_port.id, - server_ip_prefix) + + self.register_vnf_template(self.testcase_config.test_vnfd, + 'test-vnfd1') + self.create_vnf(self.vnfs[0], 'test-vnfd1', 'test-vim', symmetric=True) + + self.create_vnffg(self.testcase_config.test_vnffgd, 'red-symmetric', + 'red_http', port=80, protocol='tcp', symmetric=True) + # Start measuring the time it takes to implement the classification # rules t1 = threading.Thread(target=wait_for_classification_rules, args=(self.ovs_logger, self.compute_nodes, - self.server_instance.compute_host, - server_port, + self.odl_ip, self.odl_port, self.client_instance.compute_host, - client_port, self.odl_ip, - self.odl_port,)) - + [self.neutron_port],)) try: t1.start() except Exception as e: @@ -98,9 +61,7 @@ class SfcSymmetricChain(sfc_parent_function.SfcCommonTestCase): logger.info("Assigning floating IPs to instances") self.assign_floating_ip_client_server() - vnf_ip = os_sfc_utils.get_vnf_ip(self.tacker_client, - vnf_id=self.vnf_id) - self.assign_floating_ip_sfs(vnf_ip) + self.assign_floating_ip_sfs() self.check_floating_ips() diff --git a/sfc/tests/functest/sfc_two_chains_SSH_and_HTTP.py b/sfc/tests/functest/sfc_two_chains_SSH_and_HTTP.py index b8fc2826..e30967b9 100644 --- a/sfc/tests/functest/sfc_two_chains_SSH_and_HTTP.py +++ b/sfc/tests/functest/sfc_two_chains_SSH_and_HTTP.py @@ -32,16 +32,16 @@ class SfcTwoChainsSSHandHTTP(sfc_parent_function.SfcCommonTestCase): logger.info("The test scenario %s is starting", __name__) - self.create_custom_vnfd(self.testcase_config.test_vnfd_red, - 'test-vnfd1') - self.create_custom_vnfd(self.testcase_config.test_vnfd_blue, - 'test-vnfd2') + self.register_vnf_template(self.testcase_config.test_vnfd_red, + 'test-vnfd1') + self.register_vnf_template(self.testcase_config.test_vnfd_blue, + 'test-vnfd2') self.create_vnf(self.vnfs[0], 'test-vnfd1', 'test-vim') self.create_vnf(self.vnfs[1], 'test-vnfd2', 'test-vim') self.create_vnffg(self.testcase_config.test_vnffgd_red, 'red', - 'red_http') + 'red_http', port=80, protocol='tcp', symmetric=False) t1 = threading.Thread(target=odl_utils.wait_for_classification_rules, args=(self.ovs_logger, self.compute_nodes, -- cgit 1.2.3-korg