diff options
Diffstat (limited to 'functest/opnfv_tests/openstack/tempest')
5 files changed, 361 insertions, 48 deletions
diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml index 8d7d6eca9..e559f619a 100644 --- a/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml @@ -4,10 +4,9 @@ - os-ovn-nofeature-ha - os-ovn-nofeature-noha tests: - - neutron_tempest_plugin.api.admin.test_agent_management - neutron_tempest_plugin.api.admin.test_dhcp_agent_scheduler + - neutron_tempest_plugin.api.test_trunk.TrunkTestInheritJSONBase.test_add_subport - patrole_tempest_plugin.tests.api.network.test_agents_rbac - patrole_tempest_plugin.tests.api.network.test_networks_rbac.NetworksRbacTest.test_create_network_provider_network_type - patrole_tempest_plugin.tests.api.network.test_networks_rbac.NetworksRbacTest.test_create_network_provider_segmentation_id - - tempest.api.network.admin.test_agent_management - tempest.api.network.admin.test_dhcp_agent_scheduler diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml new file mode 100644 index 000000000..e53b577b2 --- /dev/null +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml @@ -0,0 +1,15 @@ +--- +- + scenarios: + - os-* + tests: + - neutron_tempest_plugin.api.admin.test_floating_ips_admin_actions.FloatingIPAdminTestJSON.test_associate_floating_ip_with_port_from_another_project + - neutron_tempest_plugin.api.admin.test_quotas.QuotasTest.test_detail_quotas + - neutron_tempest_plugin.api.admin.test_quotas.QuotasTest.test_quotas + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_floatingip_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_network_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_port_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_router_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_security_group_rule_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_security_group_when_quotas_is_full + - neutron_tempest_plugin.api.admin.test_quotas_negative.QuotasAdminNegativeTestJSON.test_create_subnet_when_quotas_is_full diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml index ab0bfa98e..758547359 100644 --- a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf.yaml @@ -2,25 +2,93 @@ compute: max_microversion: 2.65 compute-feature-enabled: - shelve: false - vnc_console: false - cold_migration: false - block_migration_for_live_migration: true + attach_encrypted_volume: false + block_migration_for_live_migration: false + block_migrate_cinder_iscsi: false + change_password: false + cold_migration: true + config_drive: true + console_output: true + disk_config: true + enable_instance_password: true + interface_attach: true + live_migration: true + live_migrate_back_and_forth: false + metadata_service: true + pause: true + personality: false + rdp_console: false + rescue: true + resize: true + scheduler_available_filters: "RetryFilter,AvailabilityZoneFilter,\ + ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,\ + ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,SameHostFilter,\ + DifferentHostFilter" + serial_console: false + shelve: true + snapshot: true + spice_console: false + suspend: true + swap_volume: false + vnc_console: true + volume_backed_live_migration: false + volume_multiattach: false identity: + auth_version: v3 user_unique_last_password_count: 2 user_lockout_duration: 10 user_lockout_failure_attempts: 2 identity-feature-enabled: + trust: true api_v2: false api_v2_admin: false security_compliance: true + federation: false + external_idp: false + project_tags: true + application_credentials: true image-feature-enabled: api_v2: true api_v1: false +network-feature-enabled: + port_admin_state_change: true + port_security: true placement: - max_microversion: 1.30 + max_microversion: "1.30" +validation: + image_ssh_user: cirros + ssh_timeout: 196 + ip_version_for_ssh: 4 + run_validation: true volume: max_microversion: 3.55 - storage_protocol: iSCSI + storage_protocol: ceph + manage_volume_ref: source-name,volume-%s + manage_snapshot_ref: source-name,snapshot-%s volume-feature-enabled: + multi_backend: false backup: true + snapshot: true + clone: true + manage_snapshot: true + manage_volume: true + extend_attached_volume: false + consistency_group: false + volume_revert: true +neutron_plugin_options: + agent_availability_zone: nova + available_type_drivers: flat,geneve,vlan,gre,local,vxlan + provider_vlans: foo, +object-storage-feature-enabled: + discoverable_apis: "account_quotas,formpost,bulk_upload,bulk_delete,\ + tempurl,crossdomain,container_quotas,staticweb,account_quotas,slo" + object_versioning: true + discoverability: true +heat_plugin: + skip_functional_test_list: EncryptionVolTypeTest + skip_scenario_test_list: "AodhAlarmTest,SoftwareConfigIntegrationTest,\ + VolumeBackupRestoreIntegrationTest,CfnInitIntegrationTest,\ + LoadBalancerTest" + auth_version: 3 +heat_features_enabled: + multi_cloud: false diff --git a/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml new file mode 100644 index 000000000..37aa2810b --- /dev/null +++ b/functest/opnfv_tests/openstack/tempest/custom_tests/tempest_conf_ovn.yaml @@ -0,0 +1,94 @@ +--- +compute: + max_microversion: 2.65 +compute-feature-enabled: + attach_encrypted_volume: false + block_migration_for_live_migration: false + block_migrate_cinder_iscsi: false + change_password: false + cold_migration: true + config_drive: true + console_output: true + disk_config: true + enable_instance_password: true + interface_attach: true + live_migration: true + live_migrate_back_and_forth: false + metadata_service: true + pause: true + personality: false + rdp_console: false + rescue: true + resize: true + scheduler_available_filters: "RetryFilter,AvailabilityZoneFilter,\ + ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter,\ + ServerGroupAntiAffinityFilter,ServerGroupAffinityFilter,SameHostFilter,\ + DifferentHostFilter" + serial_console: false + shelve: true + snapshot: true + spice_console: false + suspend: true + swap_volume: false + vnc_console: true + volume_backed_live_migration: false + volume_multiattach: false +identity: + auth_version: v3 + user_unique_last_password_count: 2 + user_lockout_duration: 10 + user_lockout_failure_attempts: 2 +identity-feature-enabled: + trust: true + api_v2: false + api_v2_admin: false + security_compliance: true + federation: false + external_idp: false + project_tags: true + application_credentials: true +image-feature-enabled: + api_v2: true + api_v1: false +network-feature-enabled: + port_admin_state_change: true + port_security: true +placement: + max_microversion: "1.30" +validation: + image_ssh_user: cirros + ssh_timeout: 196 + ip_version_for_ssh: 4 + run_validation: true +volume: + max_microversion: 3.55 + storage_protocol: ceph + manage_volume_ref: source-name,volume-%s + manage_snapshot_ref: source-name,snapshot-%s +volume-feature-enabled: + multi_backend: false + backup: true + snapshot: true + clone: true + manage_snapshot: true + manage_volume: true + extend_attached_volume: false + consistency_group: false + volume_revert: true +neutron_plugin_options: + agent_availability_zone: nova + available_type_drivers: flat,geneve,vlan,local + provider_vlans: public, +object-storage-feature-enabled: + discoverable_apis: "account_quotas,formpost,bulk_upload,bulk_delete,\ + tempurl,crossdomain,container_quotas,staticweb,account_quotas,slo" + object_versioning: true + discoverability: true +heat_plugin: + skip_functional_test_list: EncryptionVolTypeTest + skip_scenario_test_list: "AodhAlarmTest,SoftwareConfigIntegrationTest,\ + VolumeBackupRestoreIntegrationTest,CfnInitIntegrationTest,\ + LoadBalancerTest" + auth_version: 3 +heat_features_enabled: + multi_cloud: false diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py index faf2ab5ca..48c673673 100644 --- a/functest/opnfv_tests/openstack/tempest/tempest.py +++ b/functest/opnfv_tests/openstack/tempest/tempest.py @@ -21,6 +21,7 @@ import subprocess import time import pkg_resources +import six from six.moves import configparser from xtesting.core import testcase import yaml @@ -50,6 +51,9 @@ class TempestCommon(singlevm.VmReady2): tempest_blacklist = pkg_resources.resource_filename( 'functest', 'opnfv_tests/openstack/tempest/custom_tests/blacklist.yaml') + tempest_public_blacklist = pkg_resources.resource_filename( + 'functest', + 'opnfv_tests/openstack/tempest/custom_tests/public_blacklist.yaml') def __init__(self, **kwargs): if "case_name" not in kwargs: @@ -95,6 +99,7 @@ class TempestCommon(singlevm.VmReady2): except Exception: # pylint: disable=broad-except pass self.deny_skipping = kwargs.get("deny_skipping", False) + self.tests_count = kwargs.get("tests_count", 0) def check_services(self): """Check the mandatory services.""" @@ -195,9 +200,16 @@ class TempestCommon(singlevm.VmReady2): cmd = ("rally verify list-verifiers | awk '/" + getattr(config.CONF, 'tempest_verifier_name') + "/ {print $2}'") - proc = subprocess.Popen(cmd, shell=True, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT) + if six.PY3: + # pylint: disable=no-member + proc = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL) + else: + with open(os.devnull, 'wb') as devnull: + proc = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, + stderr=devnull) verifier_uuid = proc.stdout.readline().rstrip() return verifier_uuid.decode("utf-8") @@ -266,27 +278,8 @@ class TempestCommon(singlevm.VmReady2): # enable multinode tests rconfig.set('compute', 'min_compute_nodes', compute_cnt) rconfig.set('compute-feature-enabled', 'live_migration', True) - filters = ['RetryFilter', 'AvailabilityZoneFilter', 'ComputeFilter', - 'ComputeCapabilitiesFilter', 'ImagePropertiesFilter', - 'ServerGroupAntiAffinityFilter', - 'ServerGroupAffinityFilter'] - rconfig.set( - 'compute-feature-enabled', 'scheduler_available_filters', - functest_utils.convert_list_to_ini(filters)) if os.environ.get('OS_REGION_NAME'): rconfig.set('identity', 'region', os.environ.get('OS_REGION_NAME')) - if env.get("NEW_USER_ROLE").lower() != "member": - rconfig.set( - 'auth', 'tempest_roles', - functest_utils.convert_list_to_ini([env.get("NEW_USER_ROLE")])) - if not json.loads(env.get("USE_DYNAMIC_CREDENTIALS").lower()): - rconfig.set('auth', 'use_dynamic_credentials', False) - account_file = os.path.join( - getattr(config.CONF, 'dir_functest_data'), 'accounts.yaml') - assert os.path.exists( - account_file), "{} doesn't exist".format(account_file) - rconfig.set('auth', 'test_accounts_file', account_file) - rconfig.set('identity', 'auth_version', 'v3') rconfig.set('identity', 'admin_role', admin_role_name) rconfig.set('identity', 'default_domain_id', domain_id) if not rconfig.has_section('network'): @@ -350,7 +343,7 @@ class TempestCommon(singlevm.VmReady2): LOGGER.info("%s\n%s", cmd, output.decode("utf-8")) os.remove('/etc/tempest.conf') - def apply_tempest_blacklist(self): + def apply_tempest_blacklist(self, black_list): """Exclude blacklisted test cases.""" LOGGER.debug("Applying tempest blacklist...") if os.path.exists(self.raw_list): @@ -363,7 +356,7 @@ class TempestCommon(singlevm.VmReady2): deploy_scenario = env.get('DEPLOY_SCENARIO') if bool(deploy_scenario): # if DEPLOY_SCENARIO is set we read the file - black_list_file = open(self.tempest_blacklist) + black_list_file = open(black_list) black_list_yaml = yaml.safe_load(black_list_file) black_list_file.close() for item in black_list_yaml: @@ -500,14 +493,47 @@ class TempestCommon(singlevm.VmReady2): with open(rally_conf, 'w') as config_file: rconfig.write(config_file) + def update_auth_section(self): + """Update auth section in tempest.conf""" + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section("auth"): + rconfig.add_section("auth") + if env.get("NEW_USER_ROLE").lower() != "member": + tempest_roles = [] + if rconfig.has_option("auth", "tempest_roles"): + tempest_roles = functest_utils.convert_ini_to_list( + rconfig.get("auth", "tempest_roles")) + rconfig.set( + 'auth', 'tempest_roles', + functest_utils.convert_list_to_ini( + [env.get("NEW_USER_ROLE")] + tempest_roles)) + if not json.loads(env.get("USE_DYNAMIC_CREDENTIALS").lower()): + rconfig.set('auth', 'use_dynamic_credentials', False) + account_file = os.path.join( + getattr(config.CONF, 'dir_functest_data'), 'accounts.yaml') + assert os.path.exists( + account_file), "{} doesn't exist".format(account_file) + rconfig.set('auth', 'test_accounts_file', account_file) + if env.get('NO_TENANT_NETWORK').lower() == 'true': + rconfig.set('auth', 'create_isolated_networks', False) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + def update_network_section(self): """Update network section in tempest.conf""" rconfig = configparser.RawConfigParser() rconfig.read(self.conf_file) - if not rconfig.has_section('network'): - rconfig.add_section('network') - rconfig.set('network', 'public_network_id', self.ext_net.id) - rconfig.set('network', 'floating_network_name', self.ext_net.name) + if self.ext_net: + if not rconfig.has_section('network'): + rconfig.add_section('network') + rconfig.set('network', 'public_network_id', self.ext_net.id) + rconfig.set('network', 'floating_network_name', self.ext_net.name) + rconfig.set('network-feature-enabled', 'floating_ips', True) + else: + if not rconfig.has_section('network-feature-enabled'): + rconfig.add_section('network-feature-enabled') + rconfig.set('network-feature-enabled', 'floating_ips', False) with open(self.conf_file, 'w') as config_file: rconfig.write(config_file) @@ -517,7 +543,24 @@ class TempestCommon(singlevm.VmReady2): rconfig.read(self.conf_file) if not rconfig.has_section('compute'): rconfig.add_section('compute') - rconfig.set('compute', 'fixed_network_name', self.network.name) + rconfig.set( + 'compute', 'fixed_network_name', + self.network.name if self.network else env.get("EXTERNAL_NETWORK")) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + + def update_validation_section(self): + """Update validation section in tempest.conf""" + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section('validation'): + rconfig.add_section('validation') + rconfig.set( + 'validation', 'connect_method', + 'floating' if self.ext_net else 'fixed') + rconfig.set( + 'validation', 'network_for_ssh', + self.network.name if self.network else env.get("EXTERNAL_NETWORK")) with open(self.conf_file, 'w') as config_file: rconfig.write(config_file) @@ -567,8 +610,8 @@ class TempestCommon(singlevm.VmReady2): self.deployment_dir = self.get_verifier_deployment_dir( self.verifier_id, self.deployment_id) - compute_cnt = len(self.orig_cloud.list_hypervisors()) - + compute_cnt = self.count_hypervisors() if self.count_hypervisors( + ) <= 10 else 10 self.image_alt = self.publish_image_alt() self.flavor_alt = self.create_flavor_alt() LOGGER.debug("flavor: %s", self.flavor_alt) @@ -585,8 +628,10 @@ class TempestCommon(singlevm.VmReady2): flavor_alt_id=self.flavor_alt.id, admin_role_name=self.role_name, cidr=self.cidr, domain_id=self.project.domain.id) + self.update_auth_section() self.update_network_section() self.update_compute_section() + self.update_validation_section() self.update_scenario_section() self.backup_tempest_config(self.conf_file, self.res_dir) @@ -603,7 +648,10 @@ class TempestCommon(singlevm.VmReady2): shutil.copy("/etc/rally/rally.conf", self.res_dir) self.configure(**kwargs) self.generate_test_list(**kwargs) - self.apply_tempest_blacklist() + self.apply_tempest_blacklist(TempestCommon.tempest_blacklist) + if env.get('PUBLIC_ENDPOINT_ONLY').lower() == 'true': + self.apply_tempest_blacklist( + TempestCommon.tempest_public_blacklist) self.run_verifier_tests(**kwargs) self.parse_verifier_result() rally.RallyBase.verify_report( @@ -637,16 +685,105 @@ class TempestCommon(singlevm.VmReady2): skips = self.details.get("skipped_number", 0) if skips > 0 and self.deny_skipping: return testcase.TestCase.EX_TESTCASE_FAILED + if self.tests_count and ( + self.details.get("tests_number", 0) != self.tests_count): + return testcase.TestCase.EX_TESTCASE_FAILED return super(TempestCommon, self).is_successful() -class TempestScenario(TempestCommon): - """Tempest scenario testcase implementation class.""" +class TempestHorizon(TempestCommon): + """Tempest Horizon testcase implementation class.""" - quota_instances = -1 + def configure(self, **kwargs): + super(TempestHorizon, self).configure(**kwargs) + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section('dashboard'): + rconfig.add_section('dashboard') + rconfig.set('dashboard', 'dashboard_url', env.get('DASHBOARD_URL')) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + self.backup_tempest_config(self.conf_file, self.res_dir) - def run(self, **kwargs): - self.orig_cloud.set_compute_quotas( - self.project.project.name, - instances=self.quota_instances) - return super(TempestScenario, self).run(**kwargs) + +class TempestHeat(TempestCommon): + """Tempest Heat testcase implementation class.""" + + filename_alt = ('/home/opnfv/functest/images/' + 'Fedora-Cloud-Base-30-1.2.x86_64.qcow2') + flavor_alt_ram = 512 + flavor_alt_vcpus = 1 + flavor_alt_disk = 4 + + def __init__(self, **kwargs): + super(TempestHeat, self).__init__(**kwargs) + self.user2 = self.orig_cloud.create_user( + name='{}-user2_{}'.format(self.case_name, self.project.guid), + password=self.project.password, + domain_id=self.project.domain.id) + self.orig_cloud.grant_role( + self.role_name, user=self.user2.id, + project=self.project.project.id, domain=self.project.domain.id) + if not self.orig_cloud.get_role("heat_stack_owner"): + self.role = self.orig_cloud.create_role("heat_stack_owner") + self.orig_cloud.grant_role( + "heat_stack_owner", user=self.user2.id, + project=self.project.project.id, + domain=self.project.domain.id) + + def configure(self, **kwargs): + assert self.user2 + super(TempestHeat, self).configure(**kwargs) + rconfig = configparser.RawConfigParser() + rconfig.read(self.conf_file) + if not rconfig.has_section('heat_plugin'): + rconfig.add_section('heat_plugin') + # It fails if region and domain ids are unset + rconfig.set( + 'heat_plugin', 'region', + os.environ.get('OS_REGION_NAME', 'RegionOne')) + rconfig.set('heat_plugin', 'auth_url', os.environ["OS_AUTH_URL"]) + rconfig.set('heat_plugin', 'project_domain_id', self.project.domain.id) + rconfig.set('heat_plugin', 'user_domain_id', self.project.domain.id) + rconfig.set( + 'heat_plugin', 'project_domain_name', self.project.domain.name) + rconfig.set( + 'heat_plugin', 'user_domain_name', self.project.domain.name) + rconfig.set('heat_plugin', 'username', self.user2.name) + rconfig.set('heat_plugin', 'password', self.project.password) + rconfig.set('heat_plugin', 'project_name', self.project.project.name) + rconfig.set('heat_plugin', 'admin_username', self.project.user.name) + rconfig.set('heat_plugin', 'admin_password', self.project.password) + rconfig.set( + 'heat_plugin', 'admin_project_name', self.project.project.name) + rconfig.set('heat_plugin', 'image_ref', self.image_alt.id) + rconfig.set('heat_plugin', 'instance_type', self.flavor_alt.id) + rconfig.set('heat_plugin', 'minimal_image_ref', self.image.id) + rconfig.set('heat_plugin', 'minimal_instance_type', self.flavor.id) + if self.ext_net: + rconfig.set( + 'heat_plugin', 'floating_network_name', self.ext_net.name) + if self.network: + rconfig.set('heat_plugin', 'fixed_network_name', self.network.name) + rconfig.set('heat_plugin', 'fixed_subnet_name', self.subnet.name) + rconfig.set('heat_plugin', 'network_for_ssh', self.network.name) + else: + LOGGER.warning( + 'No tenant network created. ' + 'Trying EXTERNAL_NETWORK as a fallback') + rconfig.set( + 'heat_plugin', 'fixed_network_name', + env.get("EXTERNAL_NETWORK")) + rconfig.set( + 'heat_plugin', 'network_for_ssh', env.get("EXTERNAL_NETWORK")) + with open(self.conf_file, 'w') as config_file: + rconfig.write(config_file) + self.backup_tempest_config(self.conf_file, self.res_dir) + + def clean(self): + """ + Cleanup all OpenStack objects. Should be called on completion. + """ + super(TempestHeat, self).clean() + if self.user2: + self.orig_cloud.delete_user(self.user2.id) |