aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docker/Dockerfile5
-rwxr-xr-xfunctest/ci/config_functest.yaml7
-rwxr-xr-xfunctest/ci/testcases.yaml15
-rw-r--r--functest/opnfv_tests/openstack/refstack_client/__init__.py0
-rw-r--r--functest/opnfv_tests/openstack/refstack_client/defcore_201608.txt248
-rwxr-xr-xfunctest/opnfv_tests/openstack/refstack_client/refstack_client.py233
-rw-r--r--functest/opnfv_tests/openstack/tempest/conf_utils.py111
-rw-r--r--functest/opnfv_tests/openstack/tempest/tempest.py63
-rw-r--r--functest/tests/unit/ci/test_tier_builder.py83
-rw-r--r--functest/tests/unit/ci/test_tier_handler.py128
-rw-r--r--functest/tests/unit/opnfv_tests/openstack/refstack_client/__init__.py0
-rw-r--r--functest/tests/unit/opnfv_tests/openstack/refstack_client/test_refstack_client.py104
-rw-r--r--functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py66
-rw-r--r--functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py105
-rw-r--r--functest/tests/unit/utils/test_functest_utils.py12
-rw-r--r--functest/utils/functest_utils.py10
16 files changed, 1048 insertions, 142 deletions
diff --git a/docker/Dockerfile b/docker/Dockerfile
index 9e8d0a217..30c31dad3 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -15,6 +15,7 @@ LABEL version="0.1" description="OPNFV Functest Docker container"
ARG BRANCH=master
ARG RALLY_TAG=0.8.1
ARG TEMPEST_TAG=15.0.0
+ARG REFSTACK_TAG=15.0.0
ARG ODL_TAG=release/beryllium-sr4
ARG OPENSTACK_TAG=stable/mitaka
ARG KINGBIRD_TAG=0.2.2
@@ -97,6 +98,7 @@ RUN git clone --depth 1 -b $OPENSTACK_TAG https://github.com/openstack/networkin
RUN git clone --depth 1 -b $KINGBIRD_TAG https://github.com/openstack/kingbird.git ${REPOS_DIR}/kingbird
RUN git clone --depth 1 -b $RALLY_TAG https://github.com/openstack/rally.git ${REPOS_DIR}/rally
RUN git clone --depth 1 -b $TEMPEST_TAG https://github.com/openstack/tempest.git ${REPOS_DIR}/tempest
+RUN git clone https://github.com/openstack/refstack-client ${REPOS_DIR}/refstack-client
# other repositories
RUN git clone --depth 1 -b $ODL_TAG https://git.opendaylight.org/gerrit/p/integration/test.git ${REPOS_DIR}/odl_test
@@ -143,6 +145,9 @@ RUN cd ${REPOS_DIR}/bgpvpn && pip install -e .
# Kingbird integration
RUN cd ${REPOS_DIR}/kingbird && pip install -e .
+# refstack-client integration
+RUN cd ${REPOS_DIR}/refstack-client && ./setup_env -t ${REFSTACK_TAG}
+
RUN /bin/bash -c ". /etc/profile.d/rvm.sh \
&& cd ${REPOS_VNFS_DIR}/vims-test \
&& rvm autolibs enable"
diff --git a/functest/ci/config_functest.yaml b/functest/ci/config_functest.yaml
index 61a450580..00e44ad59 100755
--- a/functest/ci/config_functest.yaml
+++ b/functest/ci/config_functest.yaml
@@ -39,18 +39,21 @@ general:
ims_data: /home/opnfv/functest/data/ims/
rally_inst: /home/opnfv/.rally
repo_kingbird: /home/opnfv/repos/kingbird
+ refstack_client: /home/opnfv/repos/refstack-client
openstack:
creds: /home/opnfv/functest/conf/openstack.creds
snapshot_file: /home/opnfv/functest/conf/openstack_snapshot.yaml
image_name: Cirros-0.3.5
+ image_name_alt: Cirros-0.3.5-1
image_file_name: cirros-0.3.5-x86_64-disk.img
image_disk_format: qcow2
image_username: cirros
image_password: cubswin:)
flavor_name: opnfv_flavor
+ flavor_name_alt: opnfv_flavor_1
flavor_ram: 512
flavor_disk: 1
flavor_vcpus: 1
@@ -120,6 +123,10 @@ rally:
subnet_cidr: 192.168.140.0/24
router_name: rally-router
+refstack:
+ tempest_conf_path: openstack/refstack_client/tempest.conf
+ defcore_list: openstack/refstack_client/defcore_201608.txt
+
vnf:
aaa:
tenant_name: aaa
diff --git a/functest/ci/testcases.yaml b/functest/ci/testcases.yaml
index 41541223e..bc7ac84ff 100755
--- a/functest/ci/testcases.yaml
+++ b/functest/ci/testcases.yaml
@@ -131,6 +131,21 @@ tiers:
class: 'RallySanity'
-
+ name: refstack_defcore
+ criteria: 'success_rate == 80%'
+ blocking: false
+ clean_flag: false
+ description: >-
+ This test case runs a sub group of tests of the OpenStack
+ Defcore testcases by using refstack client.
+ dependencies:
+ installer: ''
+ scenario: ''
+ run:
+ module: 'functest.opnfv_tests.openstack.refstack_client.refstack_client'
+ class: 'RefstackClient'
+
+ -
name: odl
criteria: 'success_rate == 100%'
blocking: true
diff --git a/functest/opnfv_tests/openstack/refstack_client/__init__.py b/functest/opnfv_tests/openstack/refstack_client/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/opnfv_tests/openstack/refstack_client/__init__.py
diff --git a/functest/opnfv_tests/openstack/refstack_client/defcore_201608.txt b/functest/opnfv_tests/openstack/refstack_client/defcore_201608.txt
new file mode 100644
index 000000000..26eddafcb
--- /dev/null
+++ b/functest/opnfv_tests/openstack/refstack_client/defcore_201608.txt
@@ -0,0 +1,248 @@
+# Set of DefCore tempest test cases not flagged and required. It only contains OpenStack core (no object storage)
+# The approved guidelines (2016.08) are valid for Kilo, Liberty, Mitaka and Newton releases of OpenStack
+# The list can be generated using the Rest API from RefStack project:
+# https://refstack.openstack.org/api/v1/guidelines/2016.08/tests?target=compute&type=required&alias=true&flag=false
+tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_delete_image[id-3731d080-d4c5-4872-b41a-64d0d0021314]
+tempest.api.compute.images.test_images_oneserver.ImagesOneServerTestJSON.test_create_image_specify_multibyte_character_image_name[id-3b7c6fe4-dfe7-477c-9243-b06359db51e6]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b]
+tempest.api.compute.servers.test_create_server.ServersTestJSON.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_host_name_is_same_as_server_name[id-ac1ad47f-984b-4441-9274-c9079b7a0666]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers[id-9a438d88-10c6-4bcd-8b5b-5b6e25e1346f]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_list_servers_with_detail[id-585e934c-448e-43c4-acbf-d06a9b899997]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_created_server_vcpus[id-cbc0f52f-05aa-492b-bdc1-84b575ca294b]
+tempest.api.compute.servers.test_create_server.ServersTestManualDisk.test_verify_server_details[id-5de47127-9977-400a-936f-abcfbec1218f]
+tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_get_instance_action[id-aacc71ca-1d70-4aa5-bbf6-0ff71470e43c]
+tempest.api.compute.servers.test_instance_actions.InstanceActionsTestJSON.test_list_instance_actions[id-77ca5cc5-9990-45e0-ab98-1de8fead201a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_flavor[id-80c574cc-0925-44ba-8602-299028357dd9]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_image[id-b3304c3b-97df-46d2-8cd3-e2b6659724e7]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_name[id-f9eb2b70-735f-416c-b260-9914ac6181e4]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_filter_by_server_status[id-de2612ab-b7dd-4044-b0b1-d2539601911f]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_detailed_limit_results[id-67aec2d0-35fe-4503-9f92-f13272b867ed]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_active_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_flavor[id-573637f5-7325-47bb-9144-3476d0416908]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_image[id-05e8a8e7-9659-459a-989d-92c2f501f4ba]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_limit[id-614cdfc1-d557-4bac-915b-3e67b48eee76]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_name[id-9b067a7b-7fee-4f6a-b29c-be43fe18fc5a]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filter_by_server_status[id-ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e]
+tempest.api.compute.servers.test_list_server_filters.ListServerFiltersTestJSON.test_list_servers_filtered_by_name_wildcard[id-e9f624ee-92af-4562-8bec-437945a18dcb]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_future_date[id-74745ad8-b346-45b5-b9b8-509d7447fc1f]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_changes_since_invalid_date[id-87d12517-e20a-4c9c-97b6-dd1628d6d6c9]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits[id-12c80a9f-2dec-480e-882b-98ba15757659]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_greater_than_actual_count[id-d47c17fb-eebd-4287-8e95-f20a7e627b18]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_negative_value[id-62610dd9-4713-4ee0-8beb-fd2c1aa7f950]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_limits_pass_string[id-679bc053-5e70-4514-9800-3dfab1a380a6]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_flavor[id-5913660b-223b-44d4-a651-a0fbfd44ca75]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_image[id-ff01387d-c7ad-47b4-ae9e-64fa214638fe]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_by_non_existing_server_name[id-e2c77c4a-000a-4af3-a0bd-629a328bde7c]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_detail_server_is_deleted[id-93055106-2d34-46fe-af68-d9ddbf7ee570]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_status_non_existing[id-fcdf192d-0f74-4d89-911f-1ec002b822c4]
+tempest.api.compute.servers.test_list_servers_negative.ListServersNegativeTestJSON.test_list_servers_with_a_deleted_server[id-24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_lock_unlock_server[id-80a8094c-211e-440a-ab88-9e59d556c7ee]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_reboot_server_hard[id-2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_rebuild_server[id-aaa6cdf3-55a7-461a-add9-1c8596b9a07c]
+tempest.api.compute.servers.test_server_actions.ServerActionsTestJSON.test_stop_start_server[id-af8eafd4-38a7-4a4b-bdbc-75145a580560]
+tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_delete_server_metadata_item[id-127642d6-4c7b-4486-b7cd-07265a378658]
+tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_get_server_metadata_item[id-3043c57d-7e0e-49a6-9a96-ad569c265e6a]
+tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_list_server_metadata[id-479da087-92b3-4dcf-aeb3-fd293b2d14ce]
+tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_set_server_metadata[id-211021f6-21de-4657-a68f-908878cfe251]
+tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_set_server_metadata_item[id-58c02d4f-5c67-40be-8744-d3fa5982eb1c]
+tempest.api.compute.servers.test_server_metadata.ServerMetadataTestJSON.test_update_server_metadata[id-344d981e-0c33-4997-8a5d-6c1d803e4134]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_server_with_admin_password[id-b92d5ec7-b1dd-44a2-87e4-45e888c46ef0]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_specify_keypair[id-f9e15296-d7f9-4e62-b53f-a04e89160833]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_create_with_existing_server_name[id-8fea6be7-065e-47cf-89b8-496e6f96c699]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_access_server_address[id-89b90870-bc13-4b73-96af-f9d4f2b70077]
+tempest.api.compute.servers.test_servers.ServersTestJSON.test_update_server_name[id-5e6ccff8-349d-4852-a8b3-055df7988dd2]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_numeric_server_name[id-fd57f159-68d6-4c2a-902b-03070828a87e]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_metadata_exceeds_length_limit[id-7fc74810-0bd2-4cd7-8244-4f33a9db865a]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_server_name_length_exceeds_256[id-c3e0fb12-07fc-4d76-a22e-37409887afe8]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_flavor[id-18f5227f-d155-4429-807c-ccb103887537]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_image[id-fcba1052-0a50-4cf3-b1ac-fae241edf02f]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_create_with_invalid_network_uuid[id-4e72dc2d-44c5-4336-9667-f7972e95c402]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_id_exceeding_length_limit[id-f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_delete_server_pass_negative_id[id-75f79124-277c-45e6-a373-a1d6803f4cc4]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_get_non_existent_server[id-3436b02f-1b1e-4f03-881e-c6a602327439]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_invalid_ip_v6_address[id-5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server[id-d4c023a0-9c55-4747-9dd5-413b820143c7]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_non_existent_server[id-d86141a7-906e-4731-b187-d64a2ea61422]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_rebuild_reboot_deleted_server[id-98fa0458-1485-440f-873b-fe7f0d714930]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_server_name_blank[id-dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_stop_non_existent_server[id-a31460a9-49e1-42aa-82ee-06e0bb7c2d03]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_name_of_non_existent_server[id-aa8eed43-e2cb-4ebf-930b-da14f6a21d81]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_name_length_exceeds_256[id-5c8e244c-dada-4590-9944-749c455b431f]
+tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_update_server_set_empty_name[id-38204696-17c6-44da-9590-40f87fb5a899]
+tempest.api.compute.test_quotas.QuotasTestJSON.test_get_default_quotas[id-9bfecac7-b966-4f47-913f-1a9e2c12134a]
+tempest.api.compute.test_quotas.QuotasTestJSON.test_get_quotas[id-f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107]
+tempest.api.compute.test_versions.TestVersions.test_list_api_versions[id-6c0a0990-43b6-4529-9b61-5fd8daf7c55c]
+tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_attach_detach_volume[id-52e9045a-e90d-4c0d-9087-79d657faffff]
+tempest.api.compute.volumes.test_attach_volume.AttachVolumeTestJSON.test_list_get_volume_attachments[id-7fa563fe-f0f7-43eb-9e22-a1ece036b513]
+tempest.api.identity.v3.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265]
+tempest.api.identity.v3.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd]
+tempest.api.identity.v3.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_media_types[id-657c1970-4722-4189-8831-7325f3bc4265]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_resources[id-b9232f5e-d9e5-4d97-b96c-28d3db4de1bd]
+tempest.api.identity.v3.test_api_discovery.TestApiDiscovery.test_api_version_statuses[id-8879a470-abfb-47bb-bb8d-5a7fd279ad1e]
+tempest.api.identity.v3.test_tokens.TokensV3Test.test_create_token[id-6f8e4436-fc96-4282-8122-e41df57197a9]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_delete_image[id-f848bb94-1c6e-45a4-8726-39e3a5b23535]
+tempest.api.image.v2.test_images.BasicOperationsImagesTest.test_update_image[id-f66891a7-a35c-41a8-b590-a065c2a1caa6]
+tempest.api.image.v2.test_images.ListImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371]
+tempest.api.image.v2.test_images.ListImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684]
+tempest.api.image.v2.test_images.ListImagesTest.test_index_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2]
+tempest.api.image.v2.test_images.ListImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_get_image_schema[id-622b925c-479f-4736-860d-adeaf13bc371]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_get_images_schema[id-25c8d7b2-df21-460f-87ac-93130bcdc684]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_container_format[id-9959ca1d-1aa7-4b7a-a1ea-0fff0499b37e]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_disk_format[id-4a4735a7-f22f-49b6-b0d9-66e1ef7453eb]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_limit[id-e914a891-3cc8-4b40-ad32-e0a39ffbddbb]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_min_max_size[id-4ad8c157-971a-4ba8-aa84-ed61154b1e7f]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_size[id-cf1b9a48-8340-480e-af7b-fe7e17690876]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_status[id-7fc9e369-0f58-4d05-9aa5-0969e2d59d15]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_images_param_visibility[id-7a95bb92-d99e-4b12-9718-7bc6ab73e6d2]
+tempest.api.image.v2.test_images.ListUserImagesTest.test_list_no_params[id-1e341d7a-90a9-494c-b143-2cdf2aeb6aee]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_image_null_id[id-32248db1-ab88-4821-9604-c7c369f1f88c]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_delete_non_existing_image[id-6fe40f1c-57bd-4918-89cc-8500f850f3de]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_delete_deleted_image[id-e57fc127-7ba0-4693-92d7-1d8a05ebcba9]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_image_null_id[id-ef45000d-0a72-4781-866d-4cb7bf2562ad]
+tempest.api.image.v2.test_images_negative.ImagesNegativeTest.test_get_non_existent_image[id-668743d5-08ad-4480-b2b8-15da34f81d9f]
+tempest.api.image.v2.test_images_tags.ImagesTagsTest.test_update_delete_tags_for_image[id-10407036-6059-4f95-a2cd-cbbbee7ed329]
+tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_delete_non_existing_tag[id-39c023a2-325a-433a-9eea-649bf1414b19]
+tempest.api.image.v2.test_images_tags_negative.ImagesTagsNegativeTest.test_update_tags_for_non_existing_image[id-8cd30f82-6f9a-4c6e-8034-c1b51fba43d9]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289]
+tempest.api.network.test_networks.NetworksTest.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3]
+tempest.api.network.test_networks.NetworksTest.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221]
+tempest.api.network.test_networks.NetworksTest.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe]
+tempest.api.network.test_networks.NetworksTest.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43]
+tempest.api.network.test_networks.NetworksTest.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080]
+tempest.api.network.test_networks.NetworksTest.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a]
+tempest.api.network.test_networks.NetworksTest.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412]
+tempest.api.network.test_networks.NetworksTest.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e]
+tempest.api.network.test_networks.NetworksTest.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e]
+tempest.api.network.test_networks.NetworksTest.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc]
+tempest.api.network.test_networks.NetworksTest.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0]
+tempest.api.network.test_networks.NetworksTest.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_all_attributes[id-a4d9ec4c-0306-4111-a75c-db01a709030b]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_allocation_pools[id-bec949c4-3147-4ba6-af5f-cd2306118404]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_dhcp_enabled[id-94ce038d-ff0a-4a4c-a56b-09da3ca0b55d]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw[id-9393b468-186d-496d-aa36-732348cd76e7]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_gw_and_allocation_pools[id-8217a149-0c6c-4cfb-93db-0486f707d13f]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_with_host_routes_and_dns_nameservers[id-d830de0a-be47-468f-8f02-1fd996118289]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_delete_subnet_without_gateway[id-d2d596e2-8e76-47a9-ac51-d4648009f4d3]
+tempest.api.network.test_networks.NetworksTestJSON.test_create_update_delete_network_subnet[id-0e269138-0da6-4efc-a46d-578161e7b221]
+tempest.api.network.test_networks.NetworksTestJSON.test_delete_network_with_subnet[id-f04f61a9-b7f3-4194-90b2-9bcf660d1bfe]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_networks[id-f7ffdeda-e200-4a7a-bcbe-05716e86bf43]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_networks_fields[id-6ae6d24f-9194-4869-9c85-c313cb20e080]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets[id-db68ba48-f4ea-49e9-81d1-e367f6d0b20a]
+tempest.api.network.test_networks.NetworksTestJSON.test_list_subnets_fields[id-842589e3-9663-46b0-85e4-7f01273b0412]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_network[id-2bf13842-c93f-4a69-83ed-717d2ec3b44e]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_network_fields[id-867819bb-c4b6-45f7-acf9-90edcf70aa5e]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet[id-bd635d81-6030-4dd1-b3b9-31ba0cfdf6cc]
+tempest.api.network.test_networks.NetworksTestJSON.test_show_subnet_fields[id-270fff0b-8bfc-411f-a184-1e8fd35286f0]
+tempest.api.network.test_networks.NetworksTestJSON.test_update_subnet_gw_dns_host_routes_dhcp[id-3d3852eb-3009-49ec-97ac-5ce83b73010a]
+tempest.api.network.test_ports.PortsTestJSON.test_create_bulk_port[id-67f1b811-f8db-43e2-86bd-72c074d4a42c]
+tempest.api.network.test_ports.PortsTestJSON.test_create_port_in_allowed_allocation_pools[id-0435f278-40ae-48cb-a404-b8a087bc09b1]
+tempest.api.network.test_ports.PortsTestJSON.test_create_update_delete_port[id-c72c1c0c-2193-4aca-aaa4-b1442640f51c]
+tempest.api.network.test_ports.PortsTestJSON.test_list_ports[id-cf95b358-3e92-4a29-a148-52445e1ac50e]
+tempest.api.network.test_ports.PortsTestJSON.test_list_ports_fields[id-ff7f117f-f034-4e0e-abff-ccef05c454b4]
+tempest.api.network.test_ports.PortsTestJSON.test_show_port[id-c9a685bd-e83f-499c-939f-9f7863ca259f]
+tempest.api.network.test_ports.PortsTestJSON.test_show_port_fields[id-45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd]
+tempest.api.network.test_ports.PortsTestJSON.test_update_port_with_security_group_and_extra_attributes[id-58091b66-4ff4-4cc1-a549-05d60c7acd1a]
+tempest.api.network.test_ports.PortsTestJSON.test_update_port_with_two_security_groups_and_extra_attributes[id-edf6766d-3d40-4621-bc6e-2521a44c257d]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_list_update_show_delete_security_group[id-bfd128e5-3c92-44b6-9d66-7fe29d22c802]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_additional_args[id-87dfbcf9-1849-43ea-b1e4-efa3eeae9f71]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_icmp_type_code[id-c9463db8-b44d-4f52-b6c0-8dbda99f26ce]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_protocol_integer_value[id-0a307599-6655-4220-bebc-fd70c64f2290]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_group_id[id-c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_security_group_rule_with_remote_ip_prefix[id-16459776-5da2-4634-bce4-4b55ee3ec188]
+tempest.api.network.test_security_groups.SecGroupTest.test_create_show_delete_security_group_rule[id-cfb99e0e-7410-4a3d-8a0c-959a63ee77e9]
+tempest.api.network.test_security_groups.SecGroupTest.test_list_security_groups[id-e30abd17-fef9-4739-8617-dc26da88e686]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_additional_default_security_group_fails[id-2323061e-9fbf-4eb0-b547-7e8fafc90849]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_duplicate_security_group_rule_fails[id-8fde898f-ce88-493b-adc9-4e4692879fc5]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_ethertype[id-5666968c-fff3-40d6-9efc-df1c8bd01abb]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_protocol[id-981bdc22-ce48-41ed-900a-73148b583958]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_bad_remote_ip_prefix[id-5f8daf69-3c5f-4aaa-88c9-db1d66f68679]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_invalid_ports[id-0d9c7791-f2ad-4e2f-ac73-abf2373b0d2d]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_remote_groupid[id-4bf786fd-2f02-443c-9716-5b98e159a49a]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_create_security_group_rule_with_non_existent_security_group[id-be308db6-a7cf-4d5c-9baf-71bafd73f35e]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_delete_non_existent_security_group[id-1f1bb89d-5664-4956-9fcd-83ee0fa603df]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group[id-424fd5c3-9ddc-486a-b45f-39bf0c820fc6]
+tempest.api.network.test_security_groups_negative.NegativeSecGroupTest.test_show_non_existent_security_group_rule[id-4c094c09-000b-4e41-8100-9617600c02a6]
+tempest.api.volume.test_availability_zone.AvailabilityZoneV2TestJSON.test_get_availability_zone_list[id-01f1ae88-eba9-4c6b-a011-6f7ace06b725]
+tempest.api.volume.test_extensions.ExtensionsV2TestJSON.test_list_extensions[id-94607eb0-43a5-47ca-82aa-736b41bd2e2c]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_create_get_delete_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_crud_snapshot_metadata[id-a2f20f99-e363-4584-be97-bc33afb1a56c]
+tempest.api.volume.test_snapshot_metadata.SnapshotV2MetadataTestJSON.test_update_snapshot_metadata_item[id-e8ff85c5-8f97-477f-806a-3ac364a949ed]
+tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_create_get_delete_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_crud_volume_metadata[id-6f5b125b-f664-44bf-910f-751591fe5769]
+tempest.api.volume.test_volume_metadata.VolumesV2MetadataTest.test_update_volume_metadata_item[id-862261c5-8df4-475a-8c21-946e50e36a20]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_attach_detach_volume_to_instance[id-fff42874-7db5-4487-a8e1-ddda5fb5288d]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_get_volume_attachment[id-9516a2c8-9135-488c-8dd6-5677a7e5f371]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_reserve_unreserve_volume[id-92c4ef64-51b2-40c0-9f7e-4749fbaaba33]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_bootable[id-63e21b4c-0a0c-41f6-bfc3-7c2816815599]
+tempest.api.volume.test_volumes_actions.VolumesV2ActionsTest.test_volume_readonly_update[id-fff74e1e-5bd3-4b33-9ea9-24c103bc3f59]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete[id-27fb0e9f-fb64-41dd-8bdb-1ffa762f0d51]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_as_clone[id-3f591b4a-7dc6-444c-bd51-77469506b3a1]
+tempest.api.volume.test_volumes_get.VolumesV2GetTest.test_volume_create_get_update_delete_from_image[id-54a01030-c7fc-447c-86ee-c1182beae638]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list[id-0b6ddd39-b948-471f-8038-4787978747c4]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_by_name[id-a28e8da4-0b56-472f-87a8-0f4d3f819c02]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_by_name[id-2de3a6d4-12aa-403b-a8f2-fdeb42a89623]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_param_display_name_and_status[id-777c87c1-2fc4-4883-8b8e-5c0b951d1ec8]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_display_name_and_status[id-856ab8ca-6009-4c37-b691-be1065528ad4]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_detail_param_metadata[id-1ca92d3c-4a8e-4b43-93f5-e4c7fb3b291d]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_details[id-adcbb5a7-5ad8-4b61-bd10-5380e111a877]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_with_param_metadata[id-b5ebea1b-0603-40a0-bb41-15fcd0a53214]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_availability_zone[id-c0cfa863-3020-40d7-b587-e35f597d5d87]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_by_status[id-39654e13-734c-4dab-95ce-7613bf8407ce]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_availability_zone[id-e1b80d13-94f0-4ba2-a40e-386af29f8db1]
+tempest.api.volume.test_volumes_list.VolumesV2ListTestJSON.test_volumes_list_details_by_status[id-2943f712-71ec-482a-bf49-d5ca06216b9f]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_attach_volumes_with_nonexistent_volume_id[id-f5e56b0a-5d02-43c1-a2a7-c9b792c2e3f6]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_invalid_size[id-1ed83a8a-682d-4dfb-a30e-ee63ffd6c049]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_snapshot_id[id-0c36f6ae-4604-4017-b0a9-34fdc63096f9]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_source_volid[id-47c73e08-4be8-45bb-bfdf-0c4e79b88344]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_nonexistent_volume_type[id-10254ed8-3849-454e-862e-3ab8e6aa01d2]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_out_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_negative[id-8b472729-9eba-446e-a83b-916bdb34bef7]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_with_size_zero[id-41331caa-eaf4-4001-869d-bc18c1869360]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_create_volume_without_passing_size[id-9387686f-334f-4d31-a439-33494b9e2683]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_invalid_volume_id[id-1f035827-7c32-4019-9240-b4ec2dbd9dfd]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_delete_volume_without_passing_volume_id[id-441a1550-5d44-4b30-af0f-a6d402f52026]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_detach_volumes_with_invalid_volume_id[id-9f9c24e4-011d-46b5-b992-952140ce237a]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_invalid_volume_id[id-30799cfd-7ee4-446c-b66c-45b383ed211b]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_get_volume_without_passing_volume_id[id-c6c3db06-29ad-4e91-beb0-2ab195fe49e3]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_invalid_status[id-ba94b27b-be3f-496c-a00e-0283b373fa75]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_detail_with_nonexistent_name[id-9ca17820-a0e7-4cbd-a7fa-f4468735e359]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_invalid_status[id-143b279b-7522-466b-81be-34a87d564a7c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_list_volumes_with_nonexistent_name[id-0f4aa809-8c7b-418f-8fb3-84c7a5dfc52f]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_reserve_volume_with_negative_volume_status[id-449c4ed2-ecdd-47bb-98dc-072aeccf158c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_reserve_volume_with_nonexistent_volume_id[id-ac6084c0-0546-45f9-b284-38a367e0e0e2]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_unreserve_volume_with_nonexistent_volume_id[id-eb467654-3dc1-4a72-9b46-47c29d22654c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_empty_volume_id[id-72aeca85-57a5-4c1f-9057-f320f9ea575b]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_invalid_volume_id[id-e66e40d6-65e6-4e75-bdc7-636792fa152d]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_update_volume_with_nonexistent_volume_id[id-0186422c-999a-480e-a026-6a665744c30c]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_delete_nonexistent_volume_id[id-555efa6e-efcd-44ef-8a3b-4a7ca4837a29]
+tempest.api.volume.test_volumes_negative.VolumesV2NegativeTest.test_volume_get_nonexistent_volume_id[id-f131c586-9448-44a4-a8b0-54ca838aa43e]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshot_create_get_list_update_delete[id-2a8abbe4-d871-46db-b049-c41f5af8216e]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots.VolumesV2SnapshotTestJSON.test_volume_from_snapshot[id-677863d1-3142-456d-b6ac-9924f667a7f4]
+tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_details_with_params[id-220a1022-1fcd-4a74-a7bd-6b859156cda2]
+tempest.api.volume.test_volumes_snapshots_list.VolumesV2SnapshotListTestJSON.test_snapshots_list_with_params[id-59f41f43-aebf-48a9-ab5d-d76340fab32b]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_with_nonexistent_volume_id[id-e3e466af-70ab-4f4b-a967-ab04e3532ea7]
+tempest.api.volume.test_volumes_snapshots_negative.VolumesV2SnapshotNegativeTestJSON.test_create_snapshot_without_passing_volume_id[id-bb9da53e-d335-4309-9c15-7e76fd5e4d6d]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_pagination[id-e9138a2c-f67b-4796-8efa-635c196d01de]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_details_with_multiple_params[id-2a7064eb-b9c3-429b-b888-33928fc5edd3]
+tempest.api.volume.v2.test_volumes_list.VolumesV2ListTestJSON.test_volume_list_pagination[id-af55e775-8e4b-4feb-8719-215c43b0238c]
diff --git a/functest/opnfv_tests/openstack/refstack_client/refstack_client.py b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py
new file mode 100755
index 000000000..c9f0f2752
--- /dev/null
+++ b/functest/opnfv_tests/openstack/refstack_client/refstack_client.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python
+
+# matthew.lijun@huawei.com wangwulin@huawei.com
+# 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
+import argparse
+import os
+import re
+import sys
+import subprocess
+import time
+
+from functest.core import testcase_base
+from functest.opnfv_tests.openstack.tempest import conf_utils
+from functest.utils import openstack_utils
+from functest.utils.constants import CONST
+import functest.utils.functest_logger as ft_logger
+import functest.utils.functest_utils as ft_utils
+
+""" logging configuration """
+logger = ft_logger.Logger("refstack_defcore").getLogger()
+
+
+class RefstackClient(testcase_base.TestcaseBase):
+
+ def __init__(self):
+ super(RefstackClient, self).__init__()
+ self.case_name = "refstack_defcore"
+ self.FUNCTEST_TEST = CONST.dir_functest_test
+ self.CONF_PATH = CONST.refstack_tempest_conf_path
+ self.DEFCORE_LIST = CONST.refstack_defcore_list
+ self.confpath = os.path.join(self.FUNCTEST_TEST,
+ self.CONF_PATH)
+ self.defcorelist = os.path.join(self.FUNCTEST_TEST,
+ self.DEFCORE_LIST)
+ self.VERIFIER_ID = conf_utils.get_verifier_id()
+ self.VERIFIER_REPO_DIR = conf_utils.get_verifier_repo_dir(
+ self.VERIFIER_ID)
+ self.DEPLOYMENT_ID = conf_utils.get_verifier_deployment_id()
+ self.DEPLOYMENT_DIR = conf_utils.get_verifier_deployment_dir(
+ self.VERIFIER_ID, self.DEPLOYMENT_ID)
+
+ def source_venv(self):
+
+ cmd = ("cd {0};"
+ ". .venv/bin/activate;"
+ "cd -;".format(CONST.dir_refstack_client))
+ ft_utils.execute_command(cmd)
+
+ def run_defcore(self, conf, testlist):
+ logger.debug("Generating test case list...")
+
+ cmd = ("cd {0};"
+ "./refstack-client test -c {1} -v --test-list {2};"
+ "cd -;".format(CONST.dir_refstack_client,
+ conf,
+ testlist))
+ ft_utils.execute_command(cmd)
+
+ def run_defcore_default(self):
+ logger.debug("Generating test case list...")
+
+ cmd = ("cd {0};"
+ "./refstack-client test -c {1} -v --test-list {2};"
+ "cd -;".format(CONST.dir_refstack_client,
+ self.confpath,
+ self.defcorelist))
+ logger.info("Starting Refstack_defcore test case: '%s'." % cmd)
+
+ header = ("Tempest environment:\n"
+ " Installer: %s\n Scenario: %s\n Node: %s\n Date: %s\n" %
+ (CONST.INSTALLER_TYPE,
+ CONST.DEPLOY_SCENARIO,
+ CONST.NODE_NAME,
+ time.strftime("%a %b %d %H:%M:%S %Z %Y")))
+
+ f_stdout = open(
+ os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+ "refstack.log"), 'w+')
+ f_stderr = open(
+ os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+ "refstack-error.log"), 'w+')
+ f_env = open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+ "environment.log"), 'w+')
+ f_env.write(header)
+
+ p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE,
+ stderr=f_stderr, bufsize=1)
+
+ with p.stdout:
+ for line in iter(p.stdout.readline, b''):
+ if 'Tests' in line:
+ break
+ logger.info(line.replace('\n', ''))
+ f_stdout.write(line)
+ p.wait()
+
+ f_stdout.close()
+ f_stderr.close()
+ f_env.close()
+
+ def parse_refstack_result(self):
+ try:
+ with open(os.path.join(conf_utils.REFSTACK_RESULTS_DIR,
+ "refstack.log"), 'r') as logfile:
+ output = logfile.read()
+
+ for match in re.findall("Ran: (\d+) tests in (\d+\.\d{4}) sec.",
+ output):
+ num_tests = match[0]
+ for match in re.findall("- Passed: (\d+)", output):
+ num_success = match
+ for match in re.findall("- Skipped: (\d+)", output):
+ num_skipped = match
+ for match in re.findall("- Failed: (\d+)", output):
+ num_failures = match
+ success_testcases = ""
+ for match in re.findall(r"\{0\}(.*?)[. ]*ok", output):
+ success_testcases += match + ", "
+ failed_testcases = ""
+ for match in re.findall(r"\{0\}(.*?)[. ]*FAILED", output):
+ failed_testcases += match + ", "
+ skipped_testcases = ""
+ for match in re.findall(r"\{0\}(.*?)[. ]*SKIPPED:", output):
+ skipped_testcases += match + ", "
+
+ num_executed = int(num_tests) - int(num_skipped)
+ success_rate = 100 * int(num_success) / int(num_executed)
+
+ self.details = {"num_tests": int(num_tests),
+ "num_failures": int(num_failures),
+ "success": success_testcases,
+ "failed": failed_testcases,
+ "skipped": skipped_testcases}
+ except Exception:
+ success_rate = 0
+
+ self.criteria = ft_utils.check_success_rate(
+ self.case_name, success_rate)
+ logger.info("Testcase %s success_rate is %s%%, is marked as %s"
+ % (self.case_name, success_rate, self.criteria))
+
+ def defcore_env_prepare(self):
+ try:
+ img_flavor_dict = conf_utils.create_tempest_resources(
+ use_custom_images=True, use_custom_flavors=True)
+ conf_utils.configure_tempest_defcore(
+ self.DEPLOYMENT_DIR, img_flavor_dict)
+ self.source_venv()
+ res = testcase_base.TestcaseBase.EX_OK
+ except KeyError as e:
+ logger.error("defcore prepare env error with: %s", e)
+ res = testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ return res
+
+ def run(self):
+ self.start_time = time.time()
+
+ if not os.path.exists(conf_utils.REFSTACK_RESULTS_DIR):
+ os.makedirs(conf_utils.REFSTACK_RESULTS_DIR)
+
+ try:
+ self.defcore_env_prepare()
+ self.run_defcore_default()
+ self.parse_refstack_result()
+ res = testcase_base.TestcaseBase.EX_OK
+ except Exception as e:
+ logger.error('Error with run: %s', e)
+ res = testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ self.stop_time = time.time()
+ return res
+
+ def main(self, **kwargs):
+ try:
+ tempestconf = kwargs['config']
+ testlist = kwargs['testlist']
+ except KeyError as e:
+ logger.error("Cannot run refstack client. Please check "
+ "%s", e)
+ return self.EX_RUN_ERROR
+ try:
+ openstack_utils.source_credentials(CONST.openstack_creds)
+ self.defcore_env_prepare()
+ self.run_defcore(tempestconf, testlist)
+ res = testcase_base.TestcaseBase.EX_OK
+ except Exception as e:
+ logger.error('Error with run: %s', e)
+ res = testcase_base.TestcaseBase.EX_RUN_ERROR
+
+ return res
+
+
+class RefstackClientParser(testcase_base.TestcaseBase):
+
+ def __init__(self):
+ super(RefstackClientParser, self).__init__()
+ self.FUNCTEST_TEST = CONST.dir_functest_test
+ self.CONF_PATH = CONST.refstack_tempest_conf_path
+ self.DEFCORE_LIST = CONST.refstack_defcore_list
+ self.confpath = os.path.join(self.FUNCTEST_TEST,
+ self.CONF_PATH)
+ self.defcorelist = os.path.join(self.FUNCTEST_TEST,
+ self.DEFCORE_LIST)
+ self.parser = argparse.ArgumentParser()
+ self.parser.add_argument(
+ '-c', '--config',
+ help='the file path of tempest.conf',
+ default=self.confpath)
+ self.parser.add_argument(
+ '-t', '--testlist',
+ help='Specify the file path or URL of a test list text file. '
+ 'This test list will contain specific test cases that '
+ 'should be tested.',
+ default=self.defcorelist)
+
+ def parse_args(self, argv=[]):
+ return vars(self.parser.parse_args(argv))
+
+
+if __name__ == '__main__':
+ refstackclient = RefstackClient()
+ parser = RefstackClientParser()
+ args = parser.parse_args(sys.argv[1:])
+ try:
+ result = refstackclient.main(**args)
+ if result != testcase_base.TestcaseBase.EX_OK:
+ sys.exit(result)
+ except Exception:
+ sys.exit(testcase_base.TestcaseBase.EX_RUN_ERROR)
diff --git a/functest/opnfv_tests/openstack/tempest/conf_utils.py b/functest/opnfv_tests/openstack/tempest/conf_utils.py
index dc08aa25d..a21322d86 100644
--- a/functest/opnfv_tests/openstack/tempest/conf_utils.py
+++ b/functest/opnfv_tests/openstack/tempest/conf_utils.py
@@ -35,6 +35,8 @@ TEMPEST_DEFCORE = os.path.join(REPO_PATH, TEMPEST_TEST_LIST_DIR,
'defcore_req.txt')
TEMPEST_RAW_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_raw_list.txt')
TEMPEST_LIST = os.path.join(TEMPEST_RESULTS_DIR, 'test_list.txt')
+REFSTACK_RESULTS_DIR = os.path.join(CONST.dir_results,
+ 'refstack')
CI_INSTALLER_TYPE = CONST.INSTALLER_TYPE
CI_INSTALLER_IP = CONST.INSTALLER_IP
@@ -43,6 +45,88 @@ CI_INSTALLER_IP = CONST.INSTALLER_IP
logger = ft_logger.Logger("Tempest").getLogger()
+def create_tempest_resources(use_custom_images=False,
+ use_custom_flavors=False):
+ keystone_client = os_utils.get_keystone_client()
+
+ logger.debug("Creating tenant and user for Tempest suite")
+ tenant_id = os_utils.create_tenant(
+ keystone_client,
+ CONST.tempest_identity_tenant_name,
+ CONST.tempest_identity_tenant_description)
+ if not tenant_id:
+ logger.error("Failed to create %s tenant"
+ % CONST.tempest_identity_tenant_name)
+
+ user_id = os_utils.create_user(keystone_client,
+ CONST.tempest_identity_user_name,
+ CONST.tempest_identity_user_password,
+ None, tenant_id)
+ if not user_id:
+ logger.error("Failed to create %s user" %
+ CONST.tempest_identity_user_name)
+
+ logger.debug("Creating private network for Tempest suite")
+ network_dic = os_utils.create_shared_network_full(
+ CONST.tempest_private_net_name,
+ CONST.tempest_private_subnet_name,
+ CONST.tempest_router_name,
+ CONST.tempest_private_subnet_cidr)
+ if network_dic is None:
+ raise Exception('Failed to create private network')
+
+ image_id = ""
+ image_id_alt = ""
+ flavor_id = ""
+ flavor_id_alt = ""
+
+ if CONST.tempest_use_custom_images or use_custom_images:
+ # adding alternative image should be trivial should we need it
+ logger.debug("Creating image for Tempest suite")
+ _, image_id = os_utils.get_or_create_image(
+ CONST.openstack_image_name, GLANCE_IMAGE_PATH,
+ CONST.openstack_image_disk_format)
+ if image_id is None:
+ raise Exception('Failed to create image')
+
+ if use_custom_images:
+ logger.debug("Creating 2nd image for Tempest suite")
+ _, image_id_alt = os_utils.get_or_create_image(
+ CONST.openstack_image_name_alt, GLANCE_IMAGE_PATH,
+ CONST.openstack_image_disk_format)
+ if image_id_alt is None:
+ raise Exception('Failed to create image')
+
+ if CONST.tempest_use_custom_flavors or use_custom_flavors:
+ # adding alternative flavor should be trivial should we need it
+ logger.debug("Creating flavor for Tempest suite")
+ _, flavor_id = os_utils.get_or_create_flavor(
+ CONST.openstack_flavor_name,
+ CONST.openstack_flavor_ram,
+ CONST.openstack_flavor_disk,
+ CONST.openstack_flavor_vcpus)
+ if flavor_id is None:
+ raise Exception('Failed to create flavor')
+
+ if use_custom_flavors:
+ logger.debug("Creating 2nd flavor for tempest_defcore")
+ _, flavor_id_alt = os_utils.get_or_create_flavor(
+ CONST.openstack_flavor_name_alt,
+ CONST.openstack_flavor_ram,
+ CONST.openstack_flavor_disk,
+ CONST.openstack_flavor_vcpus)
+ if flavor_id_alt is None:
+ raise Exception('Failed to create flavor')
+
+ img_flavor_dict = {}
+ img_flavor_dict['image_id'] = image_id
+ img_flavor_dict['image_id_alt'] = image_id_alt
+ img_flavor_dict['flavor_id'] = flavor_id
+ img_flavor_dict['flavor_id_alt'] = flavor_id_alt
+
+ return img_flavor_dict
+
+
def get_verifier_id():
"""
Returns verifer id for current Tempest
@@ -141,6 +225,33 @@ def configure_tempest(deployment_dir, IMAGE_ID=None, FLAVOR_ID=None,
configure_tempest_multisite_params(conf_file)
+def configure_tempest_defcore(deployment_dir, img_flavor_dict):
+ """
+ Add/update needed parameters into tempest.conf file
+ """
+ conf_file = configure_verifier(deployment_dir)
+ configure_tempest_update_params(conf_file,
+ img_flavor_dict.get("image_id"),
+ img_flavor_dict.get("flavor_id"))
+
+ logger.debug("Updating selected tempest.conf parameters for defcore...")
+ config = ConfigParser.RawConfigParser()
+ config.read(conf_file)
+ config.set('compute', 'image_ref', img_flavor_dict.get("image_id"))
+ config.set('compute', 'image_ref_alt',
+ img_flavor_dict['image_id_alt'])
+ config.set('compute', 'flavor_ref', img_flavor_dict.get("flavor_id"))
+ config.set('compute', 'flavor_ref_alt',
+ img_flavor_dict['flavor_id_alt'])
+
+ with open(conf_file, 'wb') as config_file:
+ config.write(config_file)
+
+ confpath = os.path.join(CONST.dir_functest_test,
+ CONST.refstack_tempest_conf_path)
+ shutil.copyfile(conf_file, confpath)
+
+
def configure_tempest_update_params(tempest_conf_file,
IMAGE_ID=None, FLAVOR_ID=None):
"""
diff --git a/functest/opnfv_tests/openstack/tempest/tempest.py b/functest/opnfv_tests/openstack/tempest/tempest.py
index a6ce4ee6c..d3b159264 100644
--- a/functest/opnfv_tests/openstack/tempest/tempest.py
+++ b/functest/opnfv_tests/openstack/tempest/tempest.py
@@ -21,7 +21,6 @@ from functest.opnfv_tests.openstack.tempest import conf_utils
from functest.utils.constants import CONST
import functest.utils.functest_logger as ft_logger
import functest.utils.functest_utils as ft_utils
-import functest.utils.openstack_utils as os_utils
""" logging configuration """
logger = ft_logger.Logger("Tempest").getLogger()
@@ -33,8 +32,6 @@ class TempestCommon(testcase_base.TestcaseBase):
super(TempestCommon, self).__init__()
self.MODE = ""
self.OPTION = ""
- self.FLAVOR_ID = None
- self.IMAGE_ID = None
self.VERIFIER_ID = conf_utils.get_verifier_id()
self.VERIFIER_REPO_DIR = conf_utils.get_verifier_repo_dir(
self.VERIFIER_ID)
@@ -48,55 +45,6 @@ class TempestCommon(testcase_base.TestcaseBase):
with open(filename) as src:
return [line.strip() for line in src.readlines()]
- def create_tempest_resources(self):
- keystone_client = os_utils.get_keystone_client()
-
- logger.debug("Creating tenant and user for Tempest suite")
- tenant_id = os_utils.create_tenant(
- keystone_client,
- CONST.tempest_identity_tenant_name,
- CONST.tempest_identity_tenant_description)
- if not tenant_id:
- logger.error("Failed to create %s tenant"
- % CONST.tempest_identity_tenant_name)
-
- user_id = os_utils.create_user(keystone_client,
- CONST.tempest_identity_user_name,
- CONST.tempest_identity_user_password,
- None, tenant_id)
- if not user_id:
- logger.error("Failed to create %s user" %
- CONST.tempest_identity_user_name)
-
- logger.debug("Creating private network for Tempest suite")
- network_dic = os_utils.create_shared_network_full(
- CONST.tempest_private_net_name,
- CONST.tempest_private_subnet_name,
- CONST.tempest_router_name,
- CONST.tempest_private_subnet_cidr)
- if network_dic is None:
- raise Exception('Failed to create private network')
-
- if CONST.tempest_use_custom_images:
- # adding alternative image should be trivial should we need it
- logger.debug("Creating image for Tempest suite")
- _, self.IMAGE_ID = os_utils.get_or_create_image(
- CONST.openstack_image_name, conf_utils.GLANCE_IMAGE_PATH,
- CONST.openstack_image_disk_format)
- if self.IMAGE_ID is None:
- raise Exception('Failed to create image')
-
- if CONST.tempest_use_custom_flavors:
- # adding alternative flavor should be trivial should we need it
- logger.debug("Creating flavor for Tempest suite")
- _, self.FLAVOR_ID = os_utils.get_or_create_flavor(
- CONST.openstack_flavor_name,
- CONST.openstack_flavor_ram,
- CONST.openstack_flavor_disk,
- CONST.openstack_flavor_vcpus)
- if self.FLAVOR_ID is None:
- raise Exception('Failed to create flavor')
-
def generate_test_list(self, verifier_repo_dir):
logger.debug("Generating test case list...")
if self.MODE == 'defcore':
@@ -265,11 +213,12 @@ class TempestCommon(testcase_base.TestcaseBase):
os.makedirs(conf_utils.TEMPEST_RESULTS_DIR)
try:
- self.create_tempest_resources()
- conf_utils.configure_tempest(self.DEPLOYMENT_DIR,
- self.IMAGE_ID,
- self.FLAVOR_ID,
- self.MODE)
+ image_and_flavor = conf_utils.create_tempest_resources()
+ conf_utils.configure_tempest(
+ self.DEPLOYMENT_DIR,
+ IMAGE_ID=image_and_flavor.get("image_id"),
+ FLAVOR_ID=image_and_flavor.get("flavor_id"),
+ MODE=self.MODE)
self.generate_test_list(self.VERIFIER_REPO_DIR)
self.apply_tempest_blacklist()
self.run_verifier_tests()
diff --git a/functest/tests/unit/ci/test_tier_builder.py b/functest/tests/unit/ci/test_tier_builder.py
new file mode 100644
index 000000000..48c94a57d
--- /dev/null
+++ b/functest/tests/unit/ci/test_tier_builder.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+
+# 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
+
+import logging
+import unittest
+
+import mock
+
+from functest.ci import tier_builder
+
+
+class TierBuilderTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.dependency = {'installer': 'test_installer',
+ 'scenario': 'test_scenario'}
+
+ self.testcase = {'dependencies': self.dependency,
+ 'name': 'test_name',
+ 'criteria': 'test_criteria',
+ 'blocking': 'test_blocking',
+ 'clean_flag': 'test_clean_flag',
+ 'description': 'test_desc'}
+
+ self.dic_tier = {'name': 'test_tier',
+ 'order': 'test_order',
+ 'ci_loop': 'test_ci_loop',
+ 'description': 'test_desc',
+ 'testcases': [self.testcase]}
+
+ self.mock_yaml = mock.Mock()
+ attrs = {'get.return_value': [self.dic_tier]}
+ self.mock_yaml.configure_mock(**attrs)
+
+ with mock.patch('functest.ci.tier_builder.yaml.safe_load',
+ return_value=self.mock_yaml), \
+ mock.patch('__builtin__.open', mock.mock_open()):
+ self.tierbuilder = tier_builder.TierBuilder('test_installer',
+ 'test_scenario',
+ 'testcases_file')
+ self.tier_obj = self.tierbuilder.tier_objects[0]
+
+ def test_get_tiers(self):
+ self.assertEqual(self.tierbuilder.get_tiers(),
+ [self.tier_obj])
+
+ def test_get_tier_names(self):
+ self.assertEqual(self.tierbuilder.get_tier_names(),
+ ['test_tier'])
+
+ def test_get_tier_present_tier(self):
+ self.assertEqual(self.tierbuilder.get_tier('test_tier'),
+ self.tier_obj)
+
+ def test_get_tier_missing_tier(self):
+ self.assertEqual(self.tierbuilder.get_tier('test_tier2'),
+ None)
+
+ def test_get_test_present_test(self):
+ self.assertEqual(self.tierbuilder.get_test('test_name'),
+ self.tier_obj.get_test('test_name'))
+
+ def test_get_test_missing_test(self):
+ self.assertEqual(self.tierbuilder.get_test('test_name2'),
+ None)
+
+ def test_get_tests_present_tier(self):
+ self.assertEqual(self.tierbuilder.get_tests('test_tier'),
+ self.tier_obj.tests_array)
+
+ def test_get_tests_missing_tier(self):
+ self.assertEqual(self.tierbuilder.get_tests('test_tier2'),
+ None)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/ci/test_tier_handler.py b/functest/tests/unit/ci/test_tier_handler.py
new file mode 100644
index 000000000..01d99d7e7
--- /dev/null
+++ b/functest/tests/unit/ci/test_tier_handler.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+
+# 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
+
+import logging
+import unittest
+
+import mock
+
+from functest.ci import tier_handler
+
+
+class TierHandlerTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+
+ def setUp(self):
+ self.test = mock.Mock()
+ attrs = {'get_name.return_value': 'test_name'}
+ self.test.configure_mock(**attrs)
+
+ self.mock_depend = mock.Mock()
+ attrs = {'get_scenario.return_value': 'test_scenario',
+ 'get_installer.return_value': 'test_installer'}
+ self.mock_depend.configure_mock(**attrs)
+
+ self.tier = tier_handler.Tier('test_tier',
+ 'test_order',
+ 'test_ci_loop',
+ description='test_desc')
+ self.testcase = tier_handler.TestCase('test_name',
+ self.mock_depend,
+ 'test_criteria',
+ 'test_blocking',
+ 'test_clean_flag',
+ description='test_desc')
+
+ self.dependency = tier_handler.Dependency('test_installer',
+ 'test_scenario')
+
+ def test_add_test(self):
+ self.tier.add_test(self.test)
+ self.assertEqual(self.tier.tests_array,
+ [self.test])
+
+ def test_get_tests(self):
+ self.tier.tests_array = [self.test]
+ self.assertEqual(self.tier.get_tests(),
+ [self.test])
+
+ def test_get_test_names(self):
+ self.tier.tests_array = [self.test]
+ self.assertEqual(self.tier.get_test_names(),
+ ['test_name'])
+
+ def test_get_test(self):
+ self.tier.tests_array = [self.test]
+ with mock.patch.object(self.tier, 'is_test',
+ return_value=True):
+ self.assertEqual(self.tier.get_test('test_name'),
+ self.test)
+
+ def test_get_test_missing_test(self):
+ self.tier.tests_array = [self.test]
+ with mock.patch.object(self.tier, 'is_test',
+ return_value=False):
+ self.assertEqual(self.tier.get_test('test_name'),
+ None)
+
+ def test_get_name(self):
+ self.assertEqual(self.tier.get_name(),
+ 'test_tier')
+
+ def test_get_order(self):
+ self.assertEqual(self.tier.get_order(),
+ 'test_order')
+
+ def test_get_ci_loop(self):
+ self.assertEqual(self.tier.get_ci_loop(),
+ 'test_ci_loop')
+
+ def test_testcase_is_none_present_item(self):
+ self.assertEqual(tier_handler.TestCase.is_none("item"),
+ False)
+
+ def test_testcase_is_none_missing_item(self):
+ self.assertEqual(tier_handler.TestCase.is_none(None),
+ True)
+
+ def test_testcase_is_compatible(self):
+ self.assertEqual(self.testcase.is_compatible('test_installer',
+ 'test_scenario'),
+ True)
+
+ def test_testcase_is_compatible_missing_installer_scenario(self):
+ self.assertEqual(self.testcase.is_compatible('missing_installer',
+ 'test_scenario'),
+ False)
+ self.assertEqual(self.testcase.is_compatible('test_installer',
+ 'missing_scenario'),
+ False)
+
+ def test_testcase_get_name(self):
+ self.assertEqual(self.tier.get_name(),
+ 'test_tier')
+
+ def test_testcase_get_criteria(self):
+ self.assertEqual(self.tier.get_order(),
+ 'test_order')
+
+ def test_testcase_is_blocking(self):
+ self.assertEqual(self.tier.get_ci_loop(),
+ 'test_ci_loop')
+
+ def test_dependency_get_installer(self):
+ self.assertEqual(self.dependency.get_installer(),
+ 'test_installer')
+
+ def test_dependency_get_scenario(self):
+ self.assertEqual(self.dependency.get_scenario(),
+ 'test_scenario')
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/opnfv_tests/openstack/refstack_client/__init__.py b/functest/tests/unit/opnfv_tests/openstack/refstack_client/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/functest/tests/unit/opnfv_tests/openstack/refstack_client/__init__.py
diff --git a/functest/tests/unit/opnfv_tests/openstack/refstack_client/test_refstack_client.py b/functest/tests/unit/opnfv_tests/openstack/refstack_client/test_refstack_client.py
new file mode 100644
index 000000000..4e83f6bf3
--- /dev/null
+++ b/functest/tests/unit/opnfv_tests/openstack/refstack_client/test_refstack_client.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+
+# 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
+
+import logging
+import mock
+import os
+import unittest
+
+from functest.core import testcase_base
+from functest.opnfv_tests.openstack.refstack_client import refstack_client
+from functest.utils.constants import CONST
+
+
+class OSRefstackClientTesting(unittest.TestCase):
+
+ logging.disable(logging.CRITICAL)
+ _config = \
+ os.path.join(CONST.dir_functest_test, CONST.refstack_tempest_conf_path)
+ _testlist = \
+ os.path.join(CONST.dir_functest_test, CONST.refstack_defcore_list)
+
+ def setUp(self):
+ self.defaultargs = {'config': self._config,
+ 'testlist': self._testlist}
+ self.refstackclient = refstack_client.RefstackClient()
+
+ def test_source_venv(self):
+ CONST.dir_refstack_client = 'test_repo_dir'
+ with mock.patch('functest.opnfv_tests.openstack.refstack_client.'
+ 'refstack_client.ft_utils.execute_command') as m:
+ cmd = ("cd {0};"
+ ". .venv/bin/activate;"
+ "cd -;".format(CONST.dir_refstack_client))
+ self.refstackclient.source_venv()
+ m.assert_any_call(cmd)
+
+ def test_run_defcore(self):
+ config = 'tempest.conf'
+ testlist = 'testlist'
+ with mock.patch('functest.opnfv_tests.openstack.refstack_client.'
+ 'refstack_client.ft_utils.execute_command') as m:
+ cmd = ("cd {0};"
+ "./refstack-client test -c {1} -v --test-list {2};"
+ "cd -;".format(CONST.dir_refstack_client,
+ config,
+ testlist))
+ self.refstackclient.run_defcore(config, testlist)
+ m.assert_any_call(cmd)
+
+ def _get_main_kwargs(self, key=None):
+ kwargs = {'config': self._config,
+ 'testlist': self._testlist}
+ if key:
+ del kwargs[key]
+ return kwargs
+
+ def _test_main(self, status, *args):
+ kwargs = self._get_main_kwargs()
+ self.assertEqual(self.refstackclient.main(**kwargs), status)
+ if len(args) > 0:
+ args[0].assert_called_once_with(
+ refstack_client.RefstackClient.result_dir)
+ if len(args) > 1:
+ args
+
+ def _test_main_missing_keyword(self, key):
+ kwargs = self._get_main_kwargs(key)
+ self.assertEqual(self.refstackclient.main(**kwargs),
+ testcase_base.TestcaseBase.EX_RUN_ERROR)
+
+ def test_main_missing_conf(self):
+ self._test_main_missing_keyword('config')
+
+ def test_main_missing_testlist(self):
+ self._test_main_missing_keyword('testlist')
+
+ def _test_argparser(self, arg, value):
+ self.defaultargs[arg] = value
+ parser = refstack_client.RefstackClientParser()
+ self.assertEqual(parser.parse_args(["--{}={}".format(arg, value)]),
+ self.defaultargs)
+
+ def test_argparser_conf(self):
+ self._test_argparser('config', self._config)
+
+ def test_argparser_testlist(self):
+ self._test_argparser('testlist', self._testlist)
+
+ def test_argparser_multiple_args(self):
+ self.defaultargs['config'] = self._config
+ self.defaultargs['testlist'] = self._testlist
+ parser = refstack_client.RefstackClientParser()
+ self.assertEqual(parser.parse_args(
+ ["--config={}".format(self._config),
+ "--testlist={}".format(self._testlist)
+ ]), self.defaultargs)
+
+
+if __name__ == "__main__":
+ unittest.main(verbosity=2)
diff --git a/functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py b/functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py
index 6121f4ebb..caf21925a 100644
--- a/functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py
+++ b/functest/tests/unit/opnfv_tests/openstack/tempest/test_conf_utils.py
@@ -18,6 +18,72 @@ class OSTempestConfUtilsTesting(unittest.TestCase):
logging.disable(logging.CRITICAL)
+ def test_create_tempest_resources_missing_network_dic(self):
+ with mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.get_keystone_client',
+ return_value=mock.Mock()), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_tenant',
+ return_value='test_tenant_id'), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_user',
+ return_value='test_user_id'), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_shared_network_full',
+ return_value=None), \
+ self.assertRaises(Exception) as context:
+ conf_utils.create_tempest_resources()
+ msg = 'Failed to create private network'
+ self.assertTrue(msg in context)
+
+ def test_create_tempest_resources_missing_image(self):
+ CONST.tempest_use_custom_images = 'test_image'
+ with mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.get_keystone_client',
+ return_value=mock.Mock()), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_tenant',
+ return_value='test_tenant_id'), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_user',
+ return_value='test_user_id'), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_shared_network_full',
+ return_value=mock.Mock()), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.get_or_create_image',
+ return_value=(mock.Mock(), None)), \
+ self.assertRaises(Exception) as context:
+ conf_utils.create_tempest_resources()
+ msg = 'Failed to create image'
+ self.assertTrue(msg in context)
+
+ def test_create_tempest_resources_missing_flavor(self):
+ CONST.tempest_use_custom_images = 'test_image'
+ CONST.tempest_use_custom_flavors = 'test_flavour'
+ with mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.get_keystone_client',
+ return_value=mock.Mock()), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_tenant',
+ return_value='test_tenant_id'), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_user',
+ return_value='test_user_id'), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.create_shared_network_full',
+ return_value=mock.Mock()), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.get_or_create_image',
+ return_value=(mock.Mock(), 'image_id')), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.conf_utils.'
+ 'os_utils.get_or_create_flavor',
+ return_value=(mock.Mock(), None)), \
+ self.assertRaises(Exception) as context:
+ conf_utils.create_tempest_resources()
+ msg = 'Failed to create flavor'
+ self.assertTrue(msg in context)
+
def test_get_verifier_id_missing_verifier(self):
CONST.tempest_deployment_name = 'test_deploy_name'
with mock.patch('functest.opnfv_tests.openstack.tempest.'
diff --git a/functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py b/functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py
index 8ae7b4db3..856cd1434 100644
--- a/functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py
+++ b/functest/tests/unit/opnfv_tests/openstack/tempest/test_tempest.py
@@ -13,7 +13,6 @@ import mock
from functest.core import testcase_base
from functest.opnfv_tests.openstack.tempest import tempest
from functest.opnfv_tests.openstack.tempest import conf_utils
-from functest.utils.constants import CONST
class OSTempestTesting(unittest.TestCase):
@@ -35,72 +34,6 @@ class OSTempestTesting(unittest.TestCase):
return_value='test_verifier_deploy_dir'):
self.tempestcommon = tempest.TempestCommon()
- def test_create_tempest_resources_missing_network_dic(self):
- with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.get_keystone_client',
- return_value=mock.Mock()), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_tenant',
- return_value='test_tenant_id'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_user',
- return_value='test_user_id'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_shared_network_full',
- return_value=None), \
- self.assertRaises(Exception) as context:
- self.tempestcommon.create_tempest_resources()
- msg = 'Failed to create private network'
- self.assertTrue(msg in context)
-
- def test_create_tempest_resources_missing_image(self):
- CONST.tempest_use_custom_images = 'test_image'
- with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.get_keystone_client',
- return_value=mock.Mock()), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_tenant',
- return_value='test_tenant_id'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_user',
- return_value='test_user_id'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_shared_network_full',
- return_value=mock.Mock()), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.get_or_create_image',
- return_value=(mock.Mock(), None)), \
- self.assertRaises(Exception) as context:
- self.tempestcommon.create_tempest_resources()
- msg = 'Failed to create image'
- self.assertTrue(msg in context)
-
- def test_create_tempest_resources_missing_flavor(self):
- CONST.tempest_use_custom_images = 'test_image'
- CONST.tempest_use_custom_flavors = 'test_flavour'
- with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.get_keystone_client',
- return_value=mock.Mock()), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_tenant',
- return_value='test_tenant_id'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_user',
- return_value='test_user_id'), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.create_shared_network_full',
- return_value=mock.Mock()), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.get_or_create_image',
- return_value=(mock.Mock(), 'image_id')), \
- mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
- 'os_utils.get_or_create_flavor',
- return_value=(mock.Mock(), None)), \
- self.assertRaises(Exception) as context:
- self.tempestcommon.create_tempest_resources()
- msg = 'Failed to create flavor'
- self.assertTrue(msg in context)
-
@mock.patch('functest.opnfv_tests.openstack.tempest.tempest.logger.debug')
def test_generate_test_list_defcore_mode(self, mock_logger_debug):
self.tempestcommon.MODE = 'defcore'
@@ -191,8 +124,9 @@ class OSTempestTesting(unittest.TestCase):
'os.path.exists', return_value=False), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'os.makedirs') as mock_os_makedirs, \
- mock.patch.object(self.tempestcommon, 'create_tempest_resources',
- return_value=ret):
+ mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
+ 'conf_utils.create_tempest_resources',
+ return_value="image_and_flavor"):
self.assertEqual(self.tempestcommon.run(),
ret)
self.assertTrue(mock_os_makedirs.called)
@@ -204,9 +138,9 @@ class OSTempestTesting(unittest.TestCase):
'os.path.exists', return_value=False), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'os.makedirs') as mock_os_makedirs, \
- mock.patch.object(self.tempestcommon,
- 'create_tempest_resources',
- return_value=ret_ok), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
+ 'conf_utils.create_tempest_resources',
+ return_value=ret_ok), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'conf_utils.configure_tempest',
return_value=ret):
@@ -221,8 +155,9 @@ class OSTempestTesting(unittest.TestCase):
'os.path.exists', return_value=False), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'os.makedirs') as mock_os_makedirs, \
- mock.patch.object(self.tempestcommon, 'create_tempest_resources',
- return_value=ret_ok), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
+ 'conf_utils.create_tempest_resources',
+ return_value=ret_ok), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'conf_utils.configure_tempest',
return_value=ret_ok), \
@@ -239,8 +174,9 @@ class OSTempestTesting(unittest.TestCase):
'os.path.exists', return_value=False), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'os.makedirs') as mock_os_makedirs, \
- mock.patch.object(self.tempestcommon, 'create_tempest_resources',
- return_value=ret_ok), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
+ 'conf_utils.create_tempest_resources',
+ return_value=ret_ok), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'conf_utils.configure_tempest',
return_value=ret_ok), \
@@ -252,15 +188,16 @@ class OSTempestTesting(unittest.TestCase):
ret)
self.assertTrue(mock_os_makedirs.called)
- def test_run_missing_default_criteria_pass(self):
+ def test_run_missing_parse_verifier_result(self):
+ ret = testcase_base.TestcaseBase.EX_RUN_ERROR
ret_ok = testcase_base.TestcaseBase.EX_OK
- self.tempestcommon.criteria = "PASS"
with mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'os.path.exists', return_value=False), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'os.makedirs') as mock_os_makedirs, \
- mock.patch.object(self.tempestcommon, 'create_tempest_resources',
- return_value=ret_ok), \
+ mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
+ 'conf_utils.create_tempest_resources',
+ return_value=ret_ok), \
mock.patch('functest.opnfv_tests.openstack.tempest.tempest.'
'conf_utils.configure_tempest',
return_value=ret_ok), \
@@ -268,10 +205,12 @@ class OSTempestTesting(unittest.TestCase):
return_value=ret_ok), \
mock.patch.object(self.tempestcommon, 'apply_tempest_blacklist',
return_value=ret_ok), \
- mock.patch.object(self.tempestcommon, 'run_verifier_tests'), \
- mock.patch.object(self.tempestcommon, 'parse_verifier_result'):
+ mock.patch.object(self.tempestcommon, 'run_verifier_tests',
+ return_value=ret_ok), \
+ mock.patch.object(self.tempestcommon, 'parse_verifier_result',
+ return_value=ret):
self.assertEqual(self.tempestcommon.run(),
- ret_ok)
+ ret)
self.assertTrue(mock_os_makedirs.called)
diff --git a/functest/tests/unit/utils/test_functest_utils.py b/functest/tests/unit/utils/test_functest_utils.py
index bb8360119..8bfdb5e49 100644
--- a/functest/tests/unit/utils/test_functest_utils.py
+++ b/functest/tests/unit/utils/test_functest_utils.py
@@ -56,6 +56,7 @@ class FunctestUtilsTesting(unittest.TestCase):
self.testcase_dict = {'name': 'testname', 'criteria': self.criteria}
self.parameter = 'general.openstack.image_name'
self.config_yaml = 'test_config_yaml-'
+ self.db_url_env = 'http://foo/testdb'
self.file_yaml = {'general': {'openstack': {'image_name':
'test_image_name'}}}
@@ -196,8 +197,17 @@ class FunctestUtilsTesting(unittest.TestCase):
self.assertEqual(functest_utils.get_build_tag(),
self.build_tag)
+ def test_get_db_url_env_var(self):
+ with mock.patch.dict(os.environ,
+ {'TEST_DB_URL': self.db_url_env,
+ 'CONFIG_FUNCTEST_YAML':
+ "./functest/ci/config_functest.yaml"},
+ clear=True):
+ self.assertEqual(functest_utils.get_db_url(),
+ self.db_url_env)
+
@mock.patch('functest.utils.functest_utils.get_functest_config')
- def test_get_db_url(self, mock_get_functest_config):
+ def test_get_db_url_default(self, mock_get_functest_config):
mock_get_functest_config.return_value = self.db_url
self.assertEqual(functest_utils.get_db_url(), self.db_url)
mock_get_functest_config.assert_called_once_with('results.test_db_url')
diff --git a/functest/utils/functest_utils.py b/functest/utils/functest_utils.py
index dbed811a7..e5e755d7f 100644
--- a/functest/utils/functest_utils.py
+++ b/functest/utils/functest_utils.py
@@ -151,7 +151,15 @@ def get_db_url():
"""
Returns DB URL
"""
- return get_functest_config('results.test_db_url')
+ # TODO use CONST mechanism
+ try:
+ # if TEST_DB_URL declared in env variable, use it!
+ db_url = os.environ['TEST_DB_URL']
+ except KeyError:
+ logger.info("DB URL not declared as env variable,"
+ "use local configuration")
+ db_url = get_functest_config('results.test_db_url')
+ return db_url
def logger_test_results(project, case_name, status, details):