diff options
-rw-r--r-- | HACKING.rst | 2 | ||||
-rw-r--r-- | README.rst | 4 | ||||
-rw-r--r-- | REVIEWING.rst | 2 | ||||
-rw-r--r-- | doc/source/conf.py | 3 | ||||
-rw-r--r-- | doc/source/microversion_testing.rst | 24 | ||||
-rw-r--r-- | doc/source/test_removal.rst | 2 | ||||
-rw-r--r-- | releasenotes/notes/10/10.0-supported-openstack-releases-b88db468695348f6.yaml (renamed from releasenotes/notes/10.0-supported-openstack-releases-b88db468695348f6.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/10/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml (renamed from releasenotes/notes/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml) | 2 | ||||
-rw-r--r-- | releasenotes/notes/10/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml (renamed from releasenotes/notes/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/11/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml (renamed from releasenotes/notes/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/11/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml (renamed from releasenotes/notes/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/11/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml (renamed from releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.0.0-supported-openstack-releases-f10aac381d933dd1.yaml (renamed from releasenotes/notes/12.0.0-supported-openstack-releases-f10aac381d933dd1.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml (renamed from releasenotes/notes/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml (renamed from releasenotes/notes/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml (renamed from releasenotes/notes/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml (renamed from releasenotes/notes/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml (renamed from releasenotes/notes/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-bug-1486834-7ebca15836ae27a9.yaml (renamed from releasenotes/notes/12.1.0-bug-1486834-7ebca15836ae27a9.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml (renamed from releasenotes/notes/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml (renamed from releasenotes/notes/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-new-test-utils-module-adf34468c4d52719.yaml (renamed from releasenotes/notes/12.1.0-new-test-utils-module-adf34468c4d52719.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml (renamed from releasenotes/notes/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml (renamed from releasenotes/notes/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml (renamed from releasenotes/notes/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-remove-trove-tests-666522e9113549f9.yaml (renamed from releasenotes/notes/12.1.0-remove-trove-tests-666522e9113549f9.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-routers-client-as-library-25a363379da351f6.yaml (renamed from releasenotes/notes/12.1.0-routers-client-as-library-25a363379da351f6.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml (renamed from releasenotes/notes/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml (renamed from releasenotes/notes/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml (renamed from releasenotes/notes/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml (renamed from releasenotes/notes/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-clients_module-16f3025f515bf9ec.yaml (renamed from releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml (renamed from releasenotes/notes/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml (renamed from releasenotes/notes/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml (renamed from releasenotes/notes/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-service_client_config-8a1d7b4de769c633.yaml (renamed from releasenotes/notes/12.2.0-service_client_config-8a1d7b4de769c633.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml (renamed from releasenotes/notes/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/13/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml (renamed from releasenotes/notes/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/13/13.0.0-add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml (renamed from releasenotes/notes/13.0.0-add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/13/13.0.0-deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml (renamed from releasenotes/notes/13.0.0-deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/13/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml (renamed from releasenotes/notes/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/13/13.0.0-start-of-newton-support-3ebb274f300f28eb.yaml (renamed from releasenotes/notes/13.0.0-start-of-newton-support-3ebb274f300f28eb.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/13/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml (renamed from releasenotes/notes/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/13/13.0.0-volume-clients-as-library-660811011be29d1a.yaml (renamed from releasenotes/notes/13.0.0-volume-clients-as-library-660811011be29d1a.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-add-cred-provider-abstract-class-to-lib-70ff513221f8a871.yaml (renamed from releasenotes/notes/14.0.0-add-cred-provider-abstract-class-to-lib-70ff513221f8a871.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-add-cred_client-to-tempest.lib-4d4af33f969c576f.yaml (renamed from releasenotes/notes/14.0.0-add-cred_client-to-tempest.lib-4d4af33f969c576f.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-add-error-code-translation-to-versions-clients-acbc78292e24b014.yaml (renamed from releasenotes/notes/14.0.0-add-error-code-translation-to-versions-clients-acbc78292e24b014.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml (renamed from releasenotes/notes/14.0.0-add-image-clients-af94564fb34ddca6.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-add-role-assignments-client-as-a-library-d34b4fdf376984ad.yaml (renamed from releasenotes/notes/14.0.0-add-role-assignments-client-as-a-library-d34b4fdf376984ad.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-add-service-provider-client-cbba77d424a30dd3.yaml (renamed from releasenotes/notes/14.0.0-add-service-provider-client-cbba77d424a30dd3.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-add-ssh-port-parameter-to-client-6d16c374ac4456c1.yaml (renamed from releasenotes/notes/14.0.0-add-ssh-port-parameter-to-client-6d16c374ac4456c1.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-deprecate-nova-api-extensions-df16b02485dae203.yaml (renamed from releasenotes/notes/14.0.0-deprecate-nova-api-extensions-df16b02485dae203.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-move-cinder-v3-to-lib-service-be3ba0c20753b594.yaml (renamed from releasenotes/notes/14.0.0-move-cinder-v3-to-lib-service-be3ba0c20753b594.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-new-volume-limit-client-517c17d9090f4df4.yaml (renamed from releasenotes/notes/14.0.0-new-volume-limit-client-517c17d9090f4df4.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-remo-stress-tests-81052b211ad95d2e.yaml (renamed from releasenotes/notes/14.0.0-remo-stress-tests-81052b211ad95d2e.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-remove-baremetal-tests-65186d9e15d5b8fb.yaml (renamed from releasenotes/notes/14.0.0-remove-baremetal-tests-65186d9e15d5b8fb.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-remove-bootable-option-024f8944c056a3e0.yaml (renamed from releasenotes/notes/14.0.0-remove-bootable-option-024f8944c056a3e0.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-remove-negative-test-generator-1653f4c0f86ccf75.yaml (renamed from releasenotes/notes/14.0.0-remove-negative-test-generator-1653f4c0f86ccf75.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-remove-sahara-tests-1532c47c7df80e3a.yaml (renamed from releasenotes/notes/14.0.0-remove-sahara-tests-1532c47c7df80e3a.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/14/14.0.0-volume-clients-as-library-309030c7a16e62ab.yaml (renamed from releasenotes/notes/14.0.0-volume-clients-as-library-309030c7a16e62ab.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-add-identity-v3-clients-as-a-library-d34b4fdf376984ad.yaml (renamed from releasenotes/notes/15.0.0-add-identity-v3-clients-as-a-library-d34b4fdf376984ad.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml (renamed from releasenotes/notes/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml (renamed from releasenotes/notes/15.0.0-add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml (renamed from releasenotes/notes/15.0.0-add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml (renamed from releasenotes/notes/15.0.0-deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-deprecate-identity-feature-enabled.reseller-84800a8232fe217f.yaml (renamed from releasenotes/notes/15.0.0-deprecate-identity-feature-enabled.reseller-84800a8232fe217f.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-deprecate-volume_feature_enabled.volume_services-dbe024ea067d5ab2.yaml (renamed from releasenotes/notes/15.0.0-deprecate-volume_feature_enabled.volume_services-dbe024ea067d5ab2.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-jsonschema-validator-2377ba131e12d3c7.yaml (renamed from releasenotes/notes/15.0.0-jsonschema-validator-2377ba131e12d3c7.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml (renamed from releasenotes/notes/15.0.0-remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml (renamed from releasenotes/notes/15.0.0-remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml (renamed from releasenotes/notes/15.0.0-remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/15/15.0.0-remove-deprecated-network-config-options-f9ce276231578fe6.yaml (renamed from releasenotes/notes/15.0.0-remove-deprecated-network-config-options-f9ce276231578fe6.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml (renamed from releasenotes/notes/16.0.0-add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-additional-methods-to-roles-client-library-178d4a6000dec72d.yaml (renamed from releasenotes/notes/16.0.0-add-additional-methods-to-roles-client-library-178d4a6000dec72d.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-cascade-parameter-to-volumes-client-ff4f7f12795003a4.yaml (renamed from releasenotes/notes/16.0.0-add-cascade-parameter-to-volumes-client-ff4f7f12795003a4.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-compute-server-evaculate-client-as-a-library-ed76baf25f02c3ca.yaml (renamed from releasenotes/notes/16.0.0-add-compute-server-evaculate-client-as-a-library-ed76baf25f02c3ca.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-content-type-without-spaces-b2c9b91b257814f3.yaml (renamed from releasenotes/notes/16.0.0-add-content-type-without-spaces-b2c9b91b257814f3.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-list-auth-project-client-5905076d914a3943.yaml (renamed from releasenotes/notes/16.0.0-add-list-auth-project-client-5905076d914a3943.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-list-glance-api-versions-ec5fc8081fc8a0ae.yaml (renamed from releasenotes/notes/16.0.0-add-list-glance-api-versions-ec5fc8081fc8a0ae.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-list-security-groups-by-servers-to-servers-client-library-088df48f6d81f4be.yaml (renamed from releasenotes/notes/16.0.0-add-list-security-groups-by-servers-to-servers-client-library-088df48f6d81f4be.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-list-version-to-identity-client-944cb7396088a575.yaml (renamed from releasenotes/notes/16.0.0-add-list-version-to-identity-client-944cb7396088a575.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml (renamed from releasenotes/notes/16.0.0-add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-quota-sets-detail-kwarg-74b72183295b3ce7.yaml (renamed from releasenotes/notes/16.0.0-add-quota-sets-detail-kwarg-74b72183295b3ce7.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-tempest-lib-remote-client-adbeb3f42a36910b.yaml (renamed from releasenotes/notes/16.0.0-add-tempest-lib-remote-client-adbeb3f42a36910b.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-tempest-run-combine-option-e94c1049ba8985d5.yaml (renamed from releasenotes/notes/16.0.0-add-tempest-run-combine-option-e94c1049ba8985d5.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-update-encryption-type-to-encryption-types-client-f3093532a0bcf9a1.yaml (renamed from releasenotes/notes/16.0.0-add-update-encryption-type-to-encryption-types-client-f3093532a0bcf9a1.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml (renamed from releasenotes/notes/16.0.0-add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-create-server-tags-client-8c0042a77e859af6.yaml (renamed from releasenotes/notes/16.0.0-create-server-tags-client-8c0042a77e859af6.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-deprecate-deactivate_image-config-7a282c471937bbcb.yaml (renamed from releasenotes/notes/16.0.0-deprecate-deactivate_image-config-7a282c471937bbcb.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-deprecate-dvr_extra_resources-config-8c319d6dab7f7e5c.yaml (renamed from releasenotes/notes/16.0.0-deprecate-dvr_extra_resources-config-8c319d6dab7f7e5c.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-deprecate-glance-api-version-config-options-8370b63aea8e14cf.yaml (renamed from releasenotes/notes/16.0.0-deprecate-glance-api-version-config-options-8370b63aea8e14cf.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-deprecate-resources-prefix-option-ad490c0a30a0266b.yaml (renamed from releasenotes/notes/16.0.0-deprecate-resources-prefix-option-ad490c0a30a0266b.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-deprecate-skip_unless_attr-decorator-450a1ed727494724.yaml (renamed from releasenotes/notes/16.0.0-deprecate-skip_unless_attr-decorator-450a1ed727494724.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-deprecate-skip_unless_config-decorator-64c32d588043ab12.yaml (renamed from releasenotes/notes/16.0.0-deprecate-skip_unless_config-decorator-64c32d588043ab12.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml (renamed from releasenotes/notes/16.0.0-deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-dreprecate_client_parameters-cb8d069e62957f7e.yaml (renamed from releasenotes/notes/16.0.0-dreprecate_client_parameters-cb8d069e62957f7e.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-fix-volume-v2-service-clients-bugfix-1667354-73d2c3c8fedc08bf.yaml (renamed from releasenotes/notes/16.0.0-fix-volume-v2-service-clients-bugfix-1667354-73d2c3c8fedc08bf.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-mitaka-eol-88ff8355fff81b55.yaml (renamed from releasenotes/notes/16.0.0-mitaka-eol-88ff8355fff81b55.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-call_until_true-of-test-de9c13bc8f969921.yaml (renamed from releasenotes/notes/16.0.0-remove-call_until_true-of-test-de9c13bc8f969921.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-cinder-v1-api-tests-71e266b8d55d475f.yaml (renamed from releasenotes/notes/16.0.0-remove-cinder-v1-api-tests-71e266b8d55d475f.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-deprecated-allow_port_security_disabled-option-d0ffaeb2e7817707.yaml (renamed from releasenotes/notes/16.0.0-remove-deprecated-allow_port_security_disabled-option-d0ffaeb2e7817707.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-deprecated-compute-validation-config-options-part-2-5cd17b6e0e6cb8a3.yaml (renamed from releasenotes/notes/16.0.0-remove-deprecated-compute-validation-config-options-part-2-5cd17b6e0e6cb8a3.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-deprecated-dvr_extra_resources-option-e8c441c38eab7ddd.yaml (renamed from releasenotes/notes/16.0.0-remove-deprecated-dvr_extra_resources-option-e8c441c38eab7ddd.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-deprecated-identity-reseller-option-4411c7e3951f1094.yaml (renamed from releasenotes/notes/16.0.0-remove-deprecated-identity-reseller-option-4411c7e3951f1094.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-sahara-service-available-44a642aa9c634ab4.yaml (renamed from releasenotes/notes/16.0.0-remove-sahara-service-available-44a642aa9c634ab4.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-remove-volume_feature_enabled.volume_services-c6aa142cc1021297.yaml (renamed from releasenotes/notes/16.0.0-remove-volume_feature_enabled.volume_services-c6aa142cc1021297.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-use-keystone-v3-api-935860d30ddbb8e9.yaml (renamed from releasenotes/notes/16.0.0-use-keystone-v3-api-935860d30ddbb8e9.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/16/16.0.0-volume-transfers-client-e5ed3f5464c0cdc0.yaml (renamed from releasenotes/notes/16.0.0-volume-transfers-client-e5ed3f5464c0cdc0.yaml) | 0 | ||||
-rw-r--r-- | releasenotes/notes/add-params-to-v2-list-backups-api-c088d2b4bfe90247.yaml | 6 | ||||
-rw-r--r-- | releasenotes/notes/extra-compute-services-tests-92b6c0618972e02f.yaml | 6 | ||||
-rw-r--r-- | releasenotes/notes/identity_client-635275d43abbb807.yaml | 5 | ||||
-rw-r--r-- | releasenotes/notes/intermediate-pike-release-2ce492432ff8f012.yaml | 4 | ||||
-rw-r--r-- | releasenotes/notes/tempest-identity-catalog-client-f5c8589a9d7c1eb5.yaml | 5 | ||||
-rw-r--r-- | releasenotes/source/index.rst | 1 | ||||
-rw-r--r-- | releasenotes/source/v16.1.0.rst | 6 | ||||
-rw-r--r-- | requirements.txt | 2 | ||||
-rw-r--r-- | setup.cfg | 2 | ||||
-rw-r--r-- | tempest/api/compute/admin/test_live_migration.py | 49 | ||||
-rw-r--r-- | tempest/api/compute/admin/test_live_migration_negative.py (renamed from tempest/api/compute/admin/test_live_block_migration_negative.py) | 18 | ||||
-rw-r--r-- | tempest/api/compute/admin/test_servers_negative.py | 1 | ||||
-rw-r--r-- | tempest/api/compute/base.py | 18 | ||||
-rw-r--r-- | tempest/api/compute/servers/test_create_server.py | 105 | ||||
-rw-r--r-- | tempest/api/compute/servers/test_create_server_multi_nic.py | 120 | ||||
-rw-r--r-- | tempest/api/identity/admin/v3/test_endpoint_groups.py | 10 | ||||
-rw-r--r-- | tempest/api/identity/admin/v3/test_tokens.py | 3 | ||||
-rw-r--r-- | tempest/api/identity/base.py | 1 | ||||
-rwxr-xr-x | tempest/api/identity/v3/test_catalog.py | 41 | ||||
-rw-r--r-- | tempest/api/network/admin/test_routers.py | 7 | ||||
-rw-r--r-- | tempest/api/volume/admin/test_volume_quotas.py | 2 | ||||
-rw-r--r-- | tempest/api/volume/admin/test_volume_type_access.py | 2 | ||||
-rw-r--r-- | tempest/api/volume/test_volumes_clone.py | 24 | ||||
-rw-r--r-- | tempest/clients.py | 114 | ||||
-rwxr-xr-x | tempest/cmd/account_generator.py | 12 | ||||
-rw-r--r-- | tempest/cmd/cleanup_service.py | 4 | ||||
-rw-r--r-- | tempest/cmd/verify_tempest_config.py | 2 | ||||
-rw-r--r-- | tempest/common/credentials_factory.py | 103 | ||||
-rw-r--r-- | tempest/common/dynamic_creds.py | 66 | ||||
-rw-r--r-- | tempest/common/preprov_creds.py | 13 | ||||
-rw-r--r-- | tempest/lib/api_schema/response/compute/v2_1/servers.py | 9 | ||||
-rw-r--r-- | tempest/lib/api_schema/response/compute/v2_1/services.py | 22 | ||||
-rw-r--r-- | tempest/lib/api_schema/response/compute/v2_11/__init__.py | 0 | ||||
-rw-r--r-- | tempest/lib/api_schema/response/compute/v2_11/services.py | 46 | ||||
-rw-r--r-- | tempest/lib/common/cred_provider.py | 8 | ||||
-rw-r--r-- | tempest/lib/services/compute/services_client.py | 37 | ||||
-rw-r--r-- | tempest/lib/services/identity/v3/__init__.py | 17 | ||||
-rw-r--r-- | tempest/lib/services/identity/v3/catalog_client.py | 30 | ||||
-rw-r--r-- | tempest/lib/services/identity/v3/endpoint_groups_client.py | 156 | ||||
-rw-r--r-- | tempest/lib/services/identity/v3/identity_client.py | 7 | ||||
-rw-r--r-- | tempest/lib/services/volume/v2/backups_client.py | 13 | ||||
-rw-r--r-- | tempest/scenario/manager.py | 19 | ||||
-rw-r--r-- | tempest/scenario/test_stamp_pattern.py | 18 | ||||
-rw-r--r-- | tempest/scenario/test_volume_boot_pattern.py | 24 | ||||
-rw-r--r-- | tempest/scenario/test_volume_migrate_attached.py | 1 | ||||
-rw-r--r-- | tempest/services/object_storage/bulk_middleware_client.py | 6 | ||||
-rw-r--r-- | tempest/test.py | 7 | ||||
-rw-r--r-- | tempest/tests/cmd/test_account_generator.py | 16 | ||||
-rw-r--r-- | tempest/tests/common/test_dynamic_creds.py | 6 | ||||
-rw-r--r-- | tempest/tests/common/test_preprov_creds.py | 5 | ||||
-rw-r--r-- | tempest/tests/lib/services/compute/test_services_client.py | 56 | ||||
-rw-r--r-- | tempest/tests/lib/services/identity/v3/test_catalog_client.py | 86 | ||||
-rw-r--r-- | tempest/tests/lib/services/identity/v3/test_endpoint_groups_client.py | 324 | ||||
-rw-r--r-- | tempest/tests/lib/services/identity/v3/test_identity_client.py | 8 | ||||
-rw-r--r-- | tempest/tests/lib/services/identity/v3/test_oauth_token_client.py | 6 | ||||
-rw-r--r-- | tempest/tests/lib/services/volume/v2/test_backups_client.py | 117 | ||||
-rw-r--r-- | tempest/tests/lib/services/volume/v2/test_snapshot_manage_client.py | 83 | ||||
-rw-r--r-- | tempest/tests/lib/services/volume/v2/test_transfers_client.py | 123 | ||||
-rw-r--r-- | tempest/tests/lib/services/volume/v2/test_volume_manage_client.py | 111 | ||||
-rw-r--r-- | tools/tempest-plugin-sanity.sh | 122 | ||||
-rw-r--r-- | tox.ini | 8 |
169 files changed, 1655 insertions, 627 deletions
diff --git a/HACKING.rst b/HACKING.rst index 999f92e6a..e5f45ac1b 100644 --- a/HACKING.rst +++ b/HACKING.rst @@ -2,7 +2,7 @@ Tempest Coding Guide ==================== - Step 1: Read the OpenStack Style Commandments - http://docs.openstack.org/developer/hacking/ + https://docs.openstack.org/hacking/latest/ - Step 2: Read on Tempest Specific Commandments diff --git a/README.rst b/README.rst index 1bc213b66..2e13fec5a 100644 --- a/README.rst +++ b/README.rst @@ -11,7 +11,7 @@ Tempest - The OpenStack Integration Test Suite ============================================== The documentation for Tempest is officially hosted at: -http://docs.openstack.org/developer/tempest/ +https://docs.openstack.org/tempest/latest/ This is a set of integration tests to be run against a live OpenStack cluster. Tempest has batteries of tests for OpenStack API validation, @@ -117,7 +117,7 @@ as it is simpler, and quicker to work with. will run the same set of tests as the default gate jobs. .. _testr: https://testrepository.readthedocs.org/en/latest/MANUAL.html -.. _ostestr: http://docs.openstack.org/developer/os-testr/ +.. _ostestr: https://docs.openstack.org/os-testr/latest/ Library ------- diff --git a/REVIEWING.rst b/REVIEWING.rst index 9ad9ea0cd..7d28320b4 100644 --- a/REVIEWING.rst +++ b/REVIEWING.rst @@ -111,7 +111,7 @@ deprecation), CLI additions or deprecations, major feature additions, and anything backwards incompatible or would require a user to take note or do something extra. -.. _reno: http://docs.openstack.org/developer/reno/ +.. _reno: https://docs.openstack.org/reno/latest/ Deprecated Code --------------- diff --git a/doc/source/conf.py b/doc/source/conf.py index 23f732e17..201d3877b 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -36,7 +36,8 @@ def build_plugin_registry(app): subprocess.call(['tools/generate-tempest-plugins-list.sh'], cwd=root_dir) def setup(app): - app.connect('builder-inited', build_plugin_registry) + if os.getenv('GENERATE_TEMPEST_PLUGIN_LIST', 'true').lower() == 'true': + app.connect('builder-inited', build_plugin_registry) diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst index d6d90ba47..60f4f365a 100644 --- a/doc/source/microversion_testing.rst +++ b/doc/source/microversion_testing.rst @@ -111,7 +111,7 @@ For Details, see: `API Microversion testing Framework`_ This document explains how to implement Microversion tests using those interfaces. -.. _API Microversion testing Framework: http://docs.openstack.org/developer/tempest/library/api_microversion_testing.html +.. _API Microversion testing Framework: https://docs.openstack.org/tempest/latest/library/api_microversion_testing.html Step1: Add skip logic based on configured Microversion range @@ -296,46 +296,46 @@ Microversion tests implemented in Tempest * `2.1`_ - .. _2.1: http://docs.openstack.org/developer/nova/api_microversion_history.html#id1 + .. _2.1: https://docs.openstack.org/nova/latest/api_microversion_history.html#id1 * `2.2`_ - .. _2.2: http://docs.openstack.org/developer/nova/api_microversion_history.html#id2 + .. _2.2: http://docs.openstack.org/nova/latest/api_microversion_history.html#id2 * `2.10`_ - .. _2.10: http://docs.openstack.org/developer/nova/api_microversion_history.html#id9 + .. _2.10: http://docs.openstack.org/nova/latest/api_microversion_history.html#id9 * `2.20`_ - .. _2.20: http://docs.openstack.org/developer/nova/api_microversion_history.html#id18 + .. _2.20: http://docs.openstack.org/nova/latest/api_microversion_history.html#id18 * `2.25`_ - .. _2.25: http://docs.openstack.org/developer/nova/api_microversion_history.html#maximum-in-mitaka + .. _2.25: http://docs.openstack.org/nova/latest/api_microversion_history.html#maximum-in-mitaka * `2.32`_ - .. _2.32: http://docs.openstack.org/developer/nova/api_microversion_history.html#id29 + .. _2.32: http://docs.openstack.org/nova/latest/api_microversion_history.html#id29 * `2.37`_ - .. _2.37: http://docs.openstack.org/developer/nova/api_microversion_history.html#id34 + .. _2.37: http://docs.openstack.org/nova/latest/api_microversion_history.html#id34 * `2.42`_ - .. _2.42: http://docs.openstack.org/developer/nova/api_microversion_history.html#maximum-in-ocata + .. _2.42: http://docs.openstack.org/nova/latest/api_microversion_history.html#maximum-in-ocata * `2.47`_ - .. _2.47: http://docs.openstack.org/developer/nova/api_microversion_history.html#id42 + .. _2.47: http://docs.openstack.org/nova/latest/api_microversion_history.html#id42 * `2.48`_ - .. _2.48: http://docs.openstack.org/developer/nova/api_microversion_history.html#id43 + .. _2.48: http://docs.openstack.org/nova/latest/api_microversion_history.html#id43 * Volume * `3.3`_ - .. _3.3: https://docs.openstack.org/developer/cinder/devref/api_microversion_history.html#id4 + .. _3.3: https://docs.openstack.org/cinder/latest/devref/api_microversion_history.html#id4 diff --git a/doc/source/test_removal.rst b/doc/source/test_removal.rst index d06e4ba41..07c3046b0 100644 --- a/doc/source/test_removal.rst +++ b/doc/source/test_removal.rst @@ -171,7 +171,7 @@ removed assuming there is equivalent testing elsewhere. Preferably using the `tempest plugin mechanism`_ to maintain continuity after migrating the tests out of tempest. -.. _tempest plugin mechanism: http://docs.openstack.org/developer/tempest/plugin.html +.. _tempest plugin mechanism: https://docs.openstack.org/tempest/latest/plugin.html API Compatibility """"""""""""""""" diff --git a/releasenotes/notes/10.0-supported-openstack-releases-b88db468695348f6.yaml b/releasenotes/notes/10/10.0-supported-openstack-releases-b88db468695348f6.yaml index 217c2f6b6..217c2f6b6 100644 --- a/releasenotes/notes/10.0-supported-openstack-releases-b88db468695348f6.yaml +++ b/releasenotes/notes/10/10.0-supported-openstack-releases-b88db468695348f6.yaml diff --git a/releasenotes/notes/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml b/releasenotes/notes/10/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml index 0ed313012..c1edd6316 100644 --- a/releasenotes/notes/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml +++ b/releasenotes/notes/10/10.0.0-Tempest-library-interface-0eb680b810139a50.yaml @@ -5,7 +5,7 @@ prelude: | it lives directly in the tempest project. For more information refer to the `library docs`_. - .. _library docs: http://docs.openstack.org/developer/tempest/library.html#library + .. _library docs: https://docs.openstack.org/tempest/latest/library.html#current-library-apis features: - Tempest library interface diff --git a/releasenotes/notes/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml b/releasenotes/notes/10/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml index 0bc9af58a..0bc9af58a 100644 --- a/releasenotes/notes/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml +++ b/releasenotes/notes/10/10.0.0-start-using-reno-ed9518126fd0e1a3.yaml diff --git a/releasenotes/notes/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml b/releasenotes/notes/11/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml index e98671a52..e98671a52 100644 --- a/releasenotes/notes/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml +++ b/releasenotes/notes/11/11.0.0-api-microversion-testing-support-2ceddd2255670932.yaml diff --git a/releasenotes/notes/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml b/releasenotes/notes/11/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml index de1b35ee1..de1b35ee1 100644 --- a/releasenotes/notes/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml +++ b/releasenotes/notes/11/11.0.0-compute-microversion-support-e0b23f960f894b9b.yaml diff --git a/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml b/releasenotes/notes/11/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml index 09ff15d14..09ff15d14 100644 --- a/releasenotes/notes/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml +++ b/releasenotes/notes/11/11.0.0-supported-openstack-releases-1e5d7295d939d439.yaml diff --git a/releasenotes/notes/12.0.0-supported-openstack-releases-f10aac381d933dd1.yaml b/releasenotes/notes/12/12.0.0-supported-openstack-releases-f10aac381d933dd1.yaml index 9baf0352a..9baf0352a 100644 --- a/releasenotes/notes/12.0.0-supported-openstack-releases-f10aac381d933dd1.yaml +++ b/releasenotes/notes/12/12.0.0-supported-openstack-releases-f10aac381d933dd1.yaml diff --git a/releasenotes/notes/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml b/releasenotes/notes/12/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml index 07e3151ff..07e3151ff 100644 --- a/releasenotes/notes/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml +++ b/releasenotes/notes/12/12.1.0-add-network-versions-client-d90e8334e1443f5c.yaml diff --git a/releasenotes/notes/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml b/releasenotes/notes/12/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml index 297279f99..297279f99 100644 --- a/releasenotes/notes/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml +++ b/releasenotes/notes/12/12.1.0-add-scope-to-auth-b5a82493ea89f41e.yaml diff --git a/releasenotes/notes/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml b/releasenotes/notes/12/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml index 429bf52a5..429bf52a5 100644 --- a/releasenotes/notes/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml +++ b/releasenotes/notes/12/12.1.0-add-tempest-run-3d0aaf69c2ca4115.yaml diff --git a/releasenotes/notes/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml b/releasenotes/notes/12/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml index 9a1cef6e1..9a1cef6e1 100644 --- a/releasenotes/notes/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml +++ b/releasenotes/notes/12/12.1.0-add-tempest-workspaces-228a2ba4690b5589.yaml diff --git a/releasenotes/notes/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml b/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml index 092014e61..092014e61 100644 --- a/releasenotes/notes/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml +++ b/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml diff --git a/releasenotes/notes/12.1.0-bug-1486834-7ebca15836ae27a9.yaml b/releasenotes/notes/12/12.1.0-bug-1486834-7ebca15836ae27a9.yaml index b2190f368..b2190f368 100644 --- a/releasenotes/notes/12.1.0-bug-1486834-7ebca15836ae27a9.yaml +++ b/releasenotes/notes/12/12.1.0-bug-1486834-7ebca15836ae27a9.yaml diff --git a/releasenotes/notes/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml b/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml index f9173a007..f9173a007 100644 --- a/releasenotes/notes/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml +++ b/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml diff --git a/releasenotes/notes/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml b/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml index 1fa4dddc1..1fa4dddc1 100644 --- a/releasenotes/notes/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml +++ b/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml diff --git a/releasenotes/notes/12.1.0-new-test-utils-module-adf34468c4d52719.yaml b/releasenotes/notes/12/12.1.0-new-test-utils-module-adf34468c4d52719.yaml index 55df2b386..55df2b386 100644 --- a/releasenotes/notes/12.1.0-new-test-utils-module-adf34468c4d52719.yaml +++ b/releasenotes/notes/12/12.1.0-new-test-utils-module-adf34468c4d52719.yaml diff --git a/releasenotes/notes/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml b/releasenotes/notes/12/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml index 4ee883f60..4ee883f60 100644 --- a/releasenotes/notes/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml +++ b/releasenotes/notes/12/12.1.0-remove-input-scenarios-functionality-01308e6d4307f580.yaml diff --git a/releasenotes/notes/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml b/releasenotes/notes/12/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml index 294f6d9a5..294f6d9a5 100644 --- a/releasenotes/notes/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml +++ b/releasenotes/notes/12/12.1.0-remove-integrated-horizon-bb57551c1e5f5be3.yaml diff --git a/releasenotes/notes/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml b/releasenotes/notes/12/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml index 89b3f4133..89b3f4133 100644 --- a/releasenotes/notes/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml +++ b/releasenotes/notes/12/12.1.0-remove-legacy-credential-providers-3d653ac3ba1ada2b.yaml diff --git a/releasenotes/notes/12.1.0-remove-trove-tests-666522e9113549f9.yaml b/releasenotes/notes/12/12.1.0-remove-trove-tests-666522e9113549f9.yaml index 7a1fc367f..7a1fc367f 100644 --- a/releasenotes/notes/12.1.0-remove-trove-tests-666522e9113549f9.yaml +++ b/releasenotes/notes/12/12.1.0-remove-trove-tests-666522e9113549f9.yaml diff --git a/releasenotes/notes/12.1.0-routers-client-as-library-25a363379da351f6.yaml b/releasenotes/notes/12/12.1.0-routers-client-as-library-25a363379da351f6.yaml index 35cf2c487..35cf2c487 100644 --- a/releasenotes/notes/12.1.0-routers-client-as-library-25a363379da351f6.yaml +++ b/releasenotes/notes/12/12.1.0-routers-client-as-library-25a363379da351f6.yaml diff --git a/releasenotes/notes/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml b/releasenotes/notes/12/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml index eb45523fe..eb45523fe 100644 --- a/releasenotes/notes/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml +++ b/releasenotes/notes/12/12.1.0-support-chunked-encoding-d71f53225f68edf3.yaml diff --git a/releasenotes/notes/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml b/releasenotes/notes/12/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml index eeda92169..eeda92169 100644 --- a/releasenotes/notes/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml +++ b/releasenotes/notes/12/12.1.0-tempest-init-global-config-dir-location-changes-12260255871d3a2b.yaml diff --git a/releasenotes/notes/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml b/releasenotes/notes/12/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml index a360f8ed5..a360f8ed5 100644 --- a/releasenotes/notes/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml +++ b/releasenotes/notes/12/12.2.0-add-httptimeout-in-restclient-ax78061900e3f3d7.yaml diff --git a/releasenotes/notes/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml b/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml index 3ec8b5678..3ec8b5678 100644 --- a/releasenotes/notes/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml +++ b/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml diff --git a/releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml b/releasenotes/notes/12/12.2.0-clients_module-16f3025f515bf9ec.yaml index d07448aa9..d07448aa9 100644 --- a/releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml +++ b/releasenotes/notes/12/12.2.0-clients_module-16f3025f515bf9ec.yaml diff --git a/releasenotes/notes/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml b/releasenotes/notes/12/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml index cfe97c5de..cfe97c5de 100644 --- a/releasenotes/notes/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml +++ b/releasenotes/notes/12/12.2.0-nova_cert_default-90eb7c1e3cde624a.yaml diff --git a/releasenotes/notes/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml b/releasenotes/notes/12/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml index 64f729ac2..64f729ac2 100644 --- a/releasenotes/notes/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml +++ b/releasenotes/notes/12/12.2.0-plugin-service-client-registration-00b19a2dd4935ba0.yaml diff --git a/releasenotes/notes/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml b/releasenotes/notes/12/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml index 8e893b8dc..8e893b8dc 100644 --- a/releasenotes/notes/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml +++ b/releasenotes/notes/12/12.2.0-remove-javelin-276f62d04f7e4a1d.yaml diff --git a/releasenotes/notes/12.2.0-service_client_config-8a1d7b4de769c633.yaml b/releasenotes/notes/12/12.2.0-service_client_config-8a1d7b4de769c633.yaml index 3e43f9a88..3e43f9a88 100644 --- a/releasenotes/notes/12.2.0-service_client_config-8a1d7b4de769c633.yaml +++ b/releasenotes/notes/12/12.2.0-service_client_config-8a1d7b4de769c633.yaml diff --git a/releasenotes/notes/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml b/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml index cf504ad08..cf504ad08 100644 --- a/releasenotes/notes/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml +++ b/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml diff --git a/releasenotes/notes/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml b/releasenotes/notes/13/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml index 9e828f69b..9e828f69b 100644 --- a/releasenotes/notes/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml +++ b/releasenotes/notes/13/13.0.0-add-new-identity-clients-as-library-5f7ndha733nwdsn9.yaml diff --git a/releasenotes/notes/13.0.0-add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml b/releasenotes/notes/13/13.0.0-add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml index 9cfce0df0..9cfce0df0 100644 --- a/releasenotes/notes/13.0.0-add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml +++ b/releasenotes/notes/13/13.0.0-add-volume-clients-as-a-library-d05b6bc35e66c6ef.yaml diff --git a/releasenotes/notes/13.0.0-deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml b/releasenotes/notes/13/13.0.0-deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml index 0884cfa91..0884cfa91 100644 --- a/releasenotes/notes/13.0.0-deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml +++ b/releasenotes/notes/13/13.0.0-deprecate-get_ipv6_addr_by_EUI64-4673f07677289cf6.yaml diff --git a/releasenotes/notes/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml b/releasenotes/notes/13/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml index 52c04afc1..52c04afc1 100644 --- a/releasenotes/notes/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml +++ b/releasenotes/notes/13/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml diff --git a/releasenotes/notes/13.0.0-start-of-newton-support-3ebb274f300f28eb.yaml b/releasenotes/notes/13/13.0.0-start-of-newton-support-3ebb274f300f28eb.yaml index b9b6fb581..b9b6fb581 100644 --- a/releasenotes/notes/13.0.0-start-of-newton-support-3ebb274f300f28eb.yaml +++ b/releasenotes/notes/13/13.0.0-start-of-newton-support-3ebb274f300f28eb.yaml diff --git a/releasenotes/notes/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml b/releasenotes/notes/13/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml index 813e47f8a..813e47f8a 100644 --- a/releasenotes/notes/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml +++ b/releasenotes/notes/13/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml diff --git a/releasenotes/notes/13.0.0-volume-clients-as-library-660811011be29d1a.yaml b/releasenotes/notes/13/13.0.0-volume-clients-as-library-660811011be29d1a.yaml index 9e9eff66d..9e9eff66d 100644 --- a/releasenotes/notes/13.0.0-volume-clients-as-library-660811011be29d1a.yaml +++ b/releasenotes/notes/13/13.0.0-volume-clients-as-library-660811011be29d1a.yaml diff --git a/releasenotes/notes/14.0.0-add-cred-provider-abstract-class-to-lib-70ff513221f8a871.yaml b/releasenotes/notes/14/14.0.0-add-cred-provider-abstract-class-to-lib-70ff513221f8a871.yaml index 6f7a41188..6f7a41188 100644 --- a/releasenotes/notes/14.0.0-add-cred-provider-abstract-class-to-lib-70ff513221f8a871.yaml +++ b/releasenotes/notes/14/14.0.0-add-cred-provider-abstract-class-to-lib-70ff513221f8a871.yaml diff --git a/releasenotes/notes/14.0.0-add-cred_client-to-tempest.lib-4d4af33f969c576f.yaml b/releasenotes/notes/14/14.0.0-add-cred_client-to-tempest.lib-4d4af33f969c576f.yaml index 432a6b155..432a6b155 100644 --- a/releasenotes/notes/14.0.0-add-cred_client-to-tempest.lib-4d4af33f969c576f.yaml +++ b/releasenotes/notes/14/14.0.0-add-cred_client-to-tempest.lib-4d4af33f969c576f.yaml diff --git a/releasenotes/notes/14.0.0-add-error-code-translation-to-versions-clients-acbc78292e24b014.yaml b/releasenotes/notes/14/14.0.0-add-error-code-translation-to-versions-clients-acbc78292e24b014.yaml index 57bf47c56..57bf47c56 100644 --- a/releasenotes/notes/14.0.0-add-error-code-translation-to-versions-clients-acbc78292e24b014.yaml +++ b/releasenotes/notes/14/14.0.0-add-error-code-translation-to-versions-clients-acbc78292e24b014.yaml diff --git a/releasenotes/notes/14.0.0-add-image-clients-af94564fb34ddca6.yaml b/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml index 7e40fd4d6..7e40fd4d6 100644 --- a/releasenotes/notes/14.0.0-add-image-clients-af94564fb34ddca6.yaml +++ b/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml diff --git a/releasenotes/notes/14.0.0-add-role-assignments-client-as-a-library-d34b4fdf376984ad.yaml b/releasenotes/notes/14/14.0.0-add-role-assignments-client-as-a-library-d34b4fdf376984ad.yaml index a1edcc5c3..a1edcc5c3 100644 --- a/releasenotes/notes/14.0.0-add-role-assignments-client-as-a-library-d34b4fdf376984ad.yaml +++ b/releasenotes/notes/14/14.0.0-add-role-assignments-client-as-a-library-d34b4fdf376984ad.yaml diff --git a/releasenotes/notes/14.0.0-add-service-provider-client-cbba77d424a30dd3.yaml b/releasenotes/notes/14/14.0.0-add-service-provider-client-cbba77d424a30dd3.yaml index b504c789a..b504c789a 100644 --- a/releasenotes/notes/14.0.0-add-service-provider-client-cbba77d424a30dd3.yaml +++ b/releasenotes/notes/14/14.0.0-add-service-provider-client-cbba77d424a30dd3.yaml diff --git a/releasenotes/notes/14.0.0-add-ssh-port-parameter-to-client-6d16c374ac4456c1.yaml b/releasenotes/notes/14/14.0.0-add-ssh-port-parameter-to-client-6d16c374ac4456c1.yaml index b2ad1995a..b2ad1995a 100644 --- a/releasenotes/notes/14.0.0-add-ssh-port-parameter-to-client-6d16c374ac4456c1.yaml +++ b/releasenotes/notes/14/14.0.0-add-ssh-port-parameter-to-client-6d16c374ac4456c1.yaml diff --git a/releasenotes/notes/14.0.0-deprecate-nova-api-extensions-df16b02485dae203.yaml b/releasenotes/notes/14/14.0.0-deprecate-nova-api-extensions-df16b02485dae203.yaml index c2d9a9bc9..c2d9a9bc9 100644 --- a/releasenotes/notes/14.0.0-deprecate-nova-api-extensions-df16b02485dae203.yaml +++ b/releasenotes/notes/14/14.0.0-deprecate-nova-api-extensions-df16b02485dae203.yaml diff --git a/releasenotes/notes/14.0.0-move-cinder-v3-to-lib-service-be3ba0c20753b594.yaml b/releasenotes/notes/14/14.0.0-move-cinder-v3-to-lib-service-be3ba0c20753b594.yaml index 9223ba566..9223ba566 100644 --- a/releasenotes/notes/14.0.0-move-cinder-v3-to-lib-service-be3ba0c20753b594.yaml +++ b/releasenotes/notes/14/14.0.0-move-cinder-v3-to-lib-service-be3ba0c20753b594.yaml diff --git a/releasenotes/notes/14.0.0-new-volume-limit-client-517c17d9090f4df4.yaml b/releasenotes/notes/14/14.0.0-new-volume-limit-client-517c17d9090f4df4.yaml index 033e14788..033e14788 100644 --- a/releasenotes/notes/14.0.0-new-volume-limit-client-517c17d9090f4df4.yaml +++ b/releasenotes/notes/14/14.0.0-new-volume-limit-client-517c17d9090f4df4.yaml diff --git a/releasenotes/notes/14.0.0-remo-stress-tests-81052b211ad95d2e.yaml b/releasenotes/notes/14/14.0.0-remo-stress-tests-81052b211ad95d2e.yaml index 389b29f76..389b29f76 100644 --- a/releasenotes/notes/14.0.0-remo-stress-tests-81052b211ad95d2e.yaml +++ b/releasenotes/notes/14/14.0.0-remo-stress-tests-81052b211ad95d2e.yaml diff --git a/releasenotes/notes/14.0.0-remove-baremetal-tests-65186d9e15d5b8fb.yaml b/releasenotes/notes/14/14.0.0-remove-baremetal-tests-65186d9e15d5b8fb.yaml index ca2635e16..ca2635e16 100644 --- a/releasenotes/notes/14.0.0-remove-baremetal-tests-65186d9e15d5b8fb.yaml +++ b/releasenotes/notes/14/14.0.0-remove-baremetal-tests-65186d9e15d5b8fb.yaml diff --git a/releasenotes/notes/14.0.0-remove-bootable-option-024f8944c056a3e0.yaml b/releasenotes/notes/14/14.0.0-remove-bootable-option-024f8944c056a3e0.yaml index e6e53aff2..e6e53aff2 100644 --- a/releasenotes/notes/14.0.0-remove-bootable-option-024f8944c056a3e0.yaml +++ b/releasenotes/notes/14/14.0.0-remove-bootable-option-024f8944c056a3e0.yaml diff --git a/releasenotes/notes/14.0.0-remove-negative-test-generator-1653f4c0f86ccf75.yaml b/releasenotes/notes/14/14.0.0-remove-negative-test-generator-1653f4c0f86ccf75.yaml index a734d1555..a734d1555 100644 --- a/releasenotes/notes/14.0.0-remove-negative-test-generator-1653f4c0f86ccf75.yaml +++ b/releasenotes/notes/14/14.0.0-remove-negative-test-generator-1653f4c0f86ccf75.yaml diff --git a/releasenotes/notes/14.0.0-remove-sahara-tests-1532c47c7df80e3a.yaml b/releasenotes/notes/14/14.0.0-remove-sahara-tests-1532c47c7df80e3a.yaml index b541cf902..b541cf902 100644 --- a/releasenotes/notes/14.0.0-remove-sahara-tests-1532c47c7df80e3a.yaml +++ b/releasenotes/notes/14/14.0.0-remove-sahara-tests-1532c47c7df80e3a.yaml diff --git a/releasenotes/notes/14.0.0-volume-clients-as-library-309030c7a16e62ab.yaml b/releasenotes/notes/14/14.0.0-volume-clients-as-library-309030c7a16e62ab.yaml index 6babd93f5..6babd93f5 100644 --- a/releasenotes/notes/14.0.0-volume-clients-as-library-309030c7a16e62ab.yaml +++ b/releasenotes/notes/14/14.0.0-volume-clients-as-library-309030c7a16e62ab.yaml diff --git a/releasenotes/notes/15.0.0-add-identity-v3-clients-as-a-library-d34b4fdf376984ad.yaml b/releasenotes/notes/15/15.0.0-add-identity-v3-clients-as-a-library-d34b4fdf376984ad.yaml index 1af193948..1af193948 100644 --- a/releasenotes/notes/15.0.0-add-identity-v3-clients-as-a-library-d34b4fdf376984ad.yaml +++ b/releasenotes/notes/15/15.0.0-add-identity-v3-clients-as-a-library-d34b4fdf376984ad.yaml diff --git a/releasenotes/notes/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml b/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml index eaab1f0b8..eaab1f0b8 100644 --- a/releasenotes/notes/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml +++ b/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml diff --git a/releasenotes/notes/15.0.0-add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml b/releasenotes/notes/15/15.0.0-add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml index 9116ef8b3..9116ef8b3 100644 --- a/releasenotes/notes/15.0.0-add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml +++ b/releasenotes/notes/15/15.0.0-add-implied-roles-to-roles-client-library-edf96408ad9ba82e.yaml diff --git a/releasenotes/notes/15.0.0-add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml b/releasenotes/notes/15/15.0.0-add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml index 9a4e6b195..9a4e6b195 100644 --- a/releasenotes/notes/15.0.0-add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml +++ b/releasenotes/notes/15/15.0.0-add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml diff --git a/releasenotes/notes/15.0.0-deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml b/releasenotes/notes/15/15.0.0-deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml index 4acdc6d2b..4acdc6d2b 100644 --- a/releasenotes/notes/15.0.0-deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml +++ b/releasenotes/notes/15/15.0.0-deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml diff --git a/releasenotes/notes/15.0.0-deprecate-identity-feature-enabled.reseller-84800a8232fe217f.yaml b/releasenotes/notes/15/15.0.0-deprecate-identity-feature-enabled.reseller-84800a8232fe217f.yaml index c0a06d16a..c0a06d16a 100644 --- a/releasenotes/notes/15.0.0-deprecate-identity-feature-enabled.reseller-84800a8232fe217f.yaml +++ b/releasenotes/notes/15/15.0.0-deprecate-identity-feature-enabled.reseller-84800a8232fe217f.yaml diff --git a/releasenotes/notes/15.0.0-deprecate-volume_feature_enabled.volume_services-dbe024ea067d5ab2.yaml b/releasenotes/notes/15/15.0.0-deprecate-volume_feature_enabled.volume_services-dbe024ea067d5ab2.yaml index c80f159d3..c80f159d3 100644 --- a/releasenotes/notes/15.0.0-deprecate-volume_feature_enabled.volume_services-dbe024ea067d5ab2.yaml +++ b/releasenotes/notes/15/15.0.0-deprecate-volume_feature_enabled.volume_services-dbe024ea067d5ab2.yaml diff --git a/releasenotes/notes/15.0.0-jsonschema-validator-2377ba131e12d3c7.yaml b/releasenotes/notes/15/15.0.0-jsonschema-validator-2377ba131e12d3c7.yaml index 8817ed438..8817ed438 100644 --- a/releasenotes/notes/15.0.0-jsonschema-validator-2377ba131e12d3c7.yaml +++ b/releasenotes/notes/15/15.0.0-jsonschema-validator-2377ba131e12d3c7.yaml diff --git a/releasenotes/notes/15.0.0-remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml b/releasenotes/notes/15/15.0.0-remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml index b1c0c6230..b1c0c6230 100644 --- a/releasenotes/notes/15.0.0-remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml +++ b/releasenotes/notes/15/15.0.0-remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml diff --git a/releasenotes/notes/15.0.0-remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml b/releasenotes/notes/15/15.0.0-remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml index 104bf2792..104bf2792 100644 --- a/releasenotes/notes/15.0.0-remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml +++ b/releasenotes/notes/15/15.0.0-remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml diff --git a/releasenotes/notes/15.0.0-remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml b/releasenotes/notes/15/15.0.0-remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml index 371c0614a..371c0614a 100644 --- a/releasenotes/notes/15.0.0-remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml +++ b/releasenotes/notes/15/15.0.0-remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml diff --git a/releasenotes/notes/15.0.0-remove-deprecated-network-config-options-f9ce276231578fe6.yaml b/releasenotes/notes/15/15.0.0-remove-deprecated-network-config-options-f9ce276231578fe6.yaml index e445fb3ff..e445fb3ff 100644 --- a/releasenotes/notes/15.0.0-remove-deprecated-network-config-options-f9ce276231578fe6.yaml +++ b/releasenotes/notes/15/15.0.0-remove-deprecated-network-config-options-f9ce276231578fe6.yaml diff --git a/releasenotes/notes/16.0.0-add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml b/releasenotes/notes/16/16.0.0-add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml index 6b4566605..6b4566605 100644 --- a/releasenotes/notes/16.0.0-add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml +++ b/releasenotes/notes/16/16.0.0-add-OAUTH-Consumer-Client-tempest-tests-db1df7aae4a9fd4e.yaml diff --git a/releasenotes/notes/16.0.0-add-additional-methods-to-roles-client-library-178d4a6000dec72d.yaml b/releasenotes/notes/16/16.0.0-add-additional-methods-to-roles-client-library-178d4a6000dec72d.yaml index 01136c6af..01136c6af 100644 --- a/releasenotes/notes/16.0.0-add-additional-methods-to-roles-client-library-178d4a6000dec72d.yaml +++ b/releasenotes/notes/16/16.0.0-add-additional-methods-to-roles-client-library-178d4a6000dec72d.yaml diff --git a/releasenotes/notes/16.0.0-add-cascade-parameter-to-volumes-client-ff4f7f12795003a4.yaml b/releasenotes/notes/16/16.0.0-add-cascade-parameter-to-volumes-client-ff4f7f12795003a4.yaml index 6801858f8..6801858f8 100644 --- a/releasenotes/notes/16.0.0-add-cascade-parameter-to-volumes-client-ff4f7f12795003a4.yaml +++ b/releasenotes/notes/16/16.0.0-add-cascade-parameter-to-volumes-client-ff4f7f12795003a4.yaml diff --git a/releasenotes/notes/16.0.0-add-compute-server-evaculate-client-as-a-library-ed76baf25f02c3ca.yaml b/releasenotes/notes/16/16.0.0-add-compute-server-evaculate-client-as-a-library-ed76baf25f02c3ca.yaml index 848a21bca..848a21bca 100644 --- a/releasenotes/notes/16.0.0-add-compute-server-evaculate-client-as-a-library-ed76baf25f02c3ca.yaml +++ b/releasenotes/notes/16/16.0.0-add-compute-server-evaculate-client-as-a-library-ed76baf25f02c3ca.yaml diff --git a/releasenotes/notes/16.0.0-add-content-type-without-spaces-b2c9b91b257814f3.yaml b/releasenotes/notes/16/16.0.0-add-content-type-without-spaces-b2c9b91b257814f3.yaml index 0075a361e..0075a361e 100644 --- a/releasenotes/notes/16.0.0-add-content-type-without-spaces-b2c9b91b257814f3.yaml +++ b/releasenotes/notes/16/16.0.0-add-content-type-without-spaces-b2c9b91b257814f3.yaml diff --git a/releasenotes/notes/16.0.0-add-list-auth-project-client-5905076d914a3943.yaml b/releasenotes/notes/16/16.0.0-add-list-auth-project-client-5905076d914a3943.yaml index 471f8f0c0..471f8f0c0 100644 --- a/releasenotes/notes/16.0.0-add-list-auth-project-client-5905076d914a3943.yaml +++ b/releasenotes/notes/16/16.0.0-add-list-auth-project-client-5905076d914a3943.yaml diff --git a/releasenotes/notes/16.0.0-add-list-glance-api-versions-ec5fc8081fc8a0ae.yaml b/releasenotes/notes/16/16.0.0-add-list-glance-api-versions-ec5fc8081fc8a0ae.yaml index acc7a4187..acc7a4187 100644 --- a/releasenotes/notes/16.0.0-add-list-glance-api-versions-ec5fc8081fc8a0ae.yaml +++ b/releasenotes/notes/16/16.0.0-add-list-glance-api-versions-ec5fc8081fc8a0ae.yaml diff --git a/releasenotes/notes/16.0.0-add-list-security-groups-by-servers-to-servers-client-library-088df48f6d81f4be.yaml b/releasenotes/notes/16/16.0.0-add-list-security-groups-by-servers-to-servers-client-library-088df48f6d81f4be.yaml index 67f954107..67f954107 100644 --- a/releasenotes/notes/16.0.0-add-list-security-groups-by-servers-to-servers-client-library-088df48f6d81f4be.yaml +++ b/releasenotes/notes/16/16.0.0-add-list-security-groups-by-servers-to-servers-client-library-088df48f6d81f4be.yaml diff --git a/releasenotes/notes/16.0.0-add-list-version-to-identity-client-944cb7396088a575.yaml b/releasenotes/notes/16/16.0.0-add-list-version-to-identity-client-944cb7396088a575.yaml index dd66ff5b6..dd66ff5b6 100644 --- a/releasenotes/notes/16.0.0-add-list-version-to-identity-client-944cb7396088a575.yaml +++ b/releasenotes/notes/16/16.0.0-add-list-version-to-identity-client-944cb7396088a575.yaml diff --git a/releasenotes/notes/16.0.0-add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml b/releasenotes/notes/16/16.0.0-add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml index 233cc287e..233cc287e 100644 --- a/releasenotes/notes/16.0.0-add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml +++ b/releasenotes/notes/16/16.0.0-add-list-version-to-volume-client-4769dd1bd4ab9c5e.yaml diff --git a/releasenotes/notes/16.0.0-add-quota-sets-detail-kwarg-74b72183295b3ce7.yaml b/releasenotes/notes/16/16.0.0-add-quota-sets-detail-kwarg-74b72183295b3ce7.yaml index 06f4fcd05..06f4fcd05 100644 --- a/releasenotes/notes/16.0.0-add-quota-sets-detail-kwarg-74b72183295b3ce7.yaml +++ b/releasenotes/notes/16/16.0.0-add-quota-sets-detail-kwarg-74b72183295b3ce7.yaml diff --git a/releasenotes/notes/16.0.0-add-tempest-lib-remote-client-adbeb3f42a36910b.yaml b/releasenotes/notes/16/16.0.0-add-tempest-lib-remote-client-adbeb3f42a36910b.yaml index 1b8cda2b8..1b8cda2b8 100644 --- a/releasenotes/notes/16.0.0-add-tempest-lib-remote-client-adbeb3f42a36910b.yaml +++ b/releasenotes/notes/16/16.0.0-add-tempest-lib-remote-client-adbeb3f42a36910b.yaml diff --git a/releasenotes/notes/16.0.0-add-tempest-run-combine-option-e94c1049ba8985d5.yaml b/releasenotes/notes/16/16.0.0-add-tempest-run-combine-option-e94c1049ba8985d5.yaml index 73900ca60..73900ca60 100644 --- a/releasenotes/notes/16.0.0-add-tempest-run-combine-option-e94c1049ba8985d5.yaml +++ b/releasenotes/notes/16/16.0.0-add-tempest-run-combine-option-e94c1049ba8985d5.yaml diff --git a/releasenotes/notes/16.0.0-add-update-encryption-type-to-encryption-types-client-f3093532a0bcf9a1.yaml b/releasenotes/notes/16/16.0.0-add-update-encryption-type-to-encryption-types-client-f3093532a0bcf9a1.yaml index c95e77c90..c95e77c90 100644 --- a/releasenotes/notes/16.0.0-add-update-encryption-type-to-encryption-types-client-f3093532a0bcf9a1.yaml +++ b/releasenotes/notes/16/16.0.0-add-update-encryption-type-to-encryption-types-client-f3093532a0bcf9a1.yaml diff --git a/releasenotes/notes/16.0.0-add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml b/releasenotes/notes/16/16.0.0-add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml index 34530501b..34530501b 100644 --- a/releasenotes/notes/16.0.0-add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml +++ b/releasenotes/notes/16/16.0.0-add-volume-manage-client-as-library-78ab198a1dc1bd41.yaml diff --git a/releasenotes/notes/16.0.0-create-server-tags-client-8c0042a77e859af6.yaml b/releasenotes/notes/16/16.0.0-create-server-tags-client-8c0042a77e859af6.yaml index 992797189..992797189 100644 --- a/releasenotes/notes/16.0.0-create-server-tags-client-8c0042a77e859af6.yaml +++ b/releasenotes/notes/16/16.0.0-create-server-tags-client-8c0042a77e859af6.yaml diff --git a/releasenotes/notes/16.0.0-deprecate-deactivate_image-config-7a282c471937bbcb.yaml b/releasenotes/notes/16/16.0.0-deprecate-deactivate_image-config-7a282c471937bbcb.yaml index 69c6bb6b4..69c6bb6b4 100644 --- a/releasenotes/notes/16.0.0-deprecate-deactivate_image-config-7a282c471937bbcb.yaml +++ b/releasenotes/notes/16/16.0.0-deprecate-deactivate_image-config-7a282c471937bbcb.yaml diff --git a/releasenotes/notes/16.0.0-deprecate-dvr_extra_resources-config-8c319d6dab7f7e5c.yaml b/releasenotes/notes/16/16.0.0-deprecate-dvr_extra_resources-config-8c319d6dab7f7e5c.yaml index c3e43ee77..c3e43ee77 100644 --- a/releasenotes/notes/16.0.0-deprecate-dvr_extra_resources-config-8c319d6dab7f7e5c.yaml +++ b/releasenotes/notes/16/16.0.0-deprecate-dvr_extra_resources-config-8c319d6dab7f7e5c.yaml diff --git a/releasenotes/notes/16.0.0-deprecate-glance-api-version-config-options-8370b63aea8e14cf.yaml b/releasenotes/notes/16/16.0.0-deprecate-glance-api-version-config-options-8370b63aea8e14cf.yaml index 788bc9590..788bc9590 100644 --- a/releasenotes/notes/16.0.0-deprecate-glance-api-version-config-options-8370b63aea8e14cf.yaml +++ b/releasenotes/notes/16/16.0.0-deprecate-glance-api-version-config-options-8370b63aea8e14cf.yaml diff --git a/releasenotes/notes/16.0.0-deprecate-resources-prefix-option-ad490c0a30a0266b.yaml b/releasenotes/notes/16/16.0.0-deprecate-resources-prefix-option-ad490c0a30a0266b.yaml index f6792086b..f6792086b 100644 --- a/releasenotes/notes/16.0.0-deprecate-resources-prefix-option-ad490c0a30a0266b.yaml +++ b/releasenotes/notes/16/16.0.0-deprecate-resources-prefix-option-ad490c0a30a0266b.yaml diff --git a/releasenotes/notes/16.0.0-deprecate-skip_unless_attr-decorator-450a1ed727494724.yaml b/releasenotes/notes/16/16.0.0-deprecate-skip_unless_attr-decorator-450a1ed727494724.yaml index 4d8b94157..4d8b94157 100644 --- a/releasenotes/notes/16.0.0-deprecate-skip_unless_attr-decorator-450a1ed727494724.yaml +++ b/releasenotes/notes/16/16.0.0-deprecate-skip_unless_attr-decorator-450a1ed727494724.yaml diff --git a/releasenotes/notes/16.0.0-deprecate-skip_unless_config-decorator-64c32d588043ab12.yaml b/releasenotes/notes/16/16.0.0-deprecate-skip_unless_config-decorator-64c32d588043ab12.yaml index 6285ea6a2..6285ea6a2 100644 --- a/releasenotes/notes/16.0.0-deprecate-skip_unless_config-decorator-64c32d588043ab12.yaml +++ b/releasenotes/notes/16/16.0.0-deprecate-skip_unless_config-decorator-64c32d588043ab12.yaml diff --git a/releasenotes/notes/16.0.0-deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml b/releasenotes/notes/16/16.0.0-deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml index 0660d9c1c..0660d9c1c 100644 --- a/releasenotes/notes/16.0.0-deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml +++ b/releasenotes/notes/16/16.0.0-deprecated-cinder-api-v1-option-df7d5a54d93db5cf.yaml diff --git a/releasenotes/notes/16.0.0-dreprecate_client_parameters-cb8d069e62957f7e.yaml b/releasenotes/notes/16/16.0.0-dreprecate_client_parameters-cb8d069e62957f7e.yaml index 4081f6a4f..4081f6a4f 100644 --- a/releasenotes/notes/16.0.0-dreprecate_client_parameters-cb8d069e62957f7e.yaml +++ b/releasenotes/notes/16/16.0.0-dreprecate_client_parameters-cb8d069e62957f7e.yaml diff --git a/releasenotes/notes/16.0.0-fix-volume-v2-service-clients-bugfix-1667354-73d2c3c8fedc08bf.yaml b/releasenotes/notes/16/16.0.0-fix-volume-v2-service-clients-bugfix-1667354-73d2c3c8fedc08bf.yaml index 6d3157648..6d3157648 100644 --- a/releasenotes/notes/16.0.0-fix-volume-v2-service-clients-bugfix-1667354-73d2c3c8fedc08bf.yaml +++ b/releasenotes/notes/16/16.0.0-fix-volume-v2-service-clients-bugfix-1667354-73d2c3c8fedc08bf.yaml diff --git a/releasenotes/notes/16.0.0-mitaka-eol-88ff8355fff81b55.yaml b/releasenotes/notes/16/16.0.0-mitaka-eol-88ff8355fff81b55.yaml index 24ec51274..24ec51274 100644 --- a/releasenotes/notes/16.0.0-mitaka-eol-88ff8355fff81b55.yaml +++ b/releasenotes/notes/16/16.0.0-mitaka-eol-88ff8355fff81b55.yaml diff --git a/releasenotes/notes/16.0.0-remove-call_until_true-of-test-de9c13bc8f969921.yaml b/releasenotes/notes/16/16.0.0-remove-call_until_true-of-test-de9c13bc8f969921.yaml index 56708211c..56708211c 100644 --- a/releasenotes/notes/16.0.0-remove-call_until_true-of-test-de9c13bc8f969921.yaml +++ b/releasenotes/notes/16/16.0.0-remove-call_until_true-of-test-de9c13bc8f969921.yaml diff --git a/releasenotes/notes/16.0.0-remove-cinder-v1-api-tests-71e266b8d55d475f.yaml b/releasenotes/notes/16/16.0.0-remove-cinder-v1-api-tests-71e266b8d55d475f.yaml index 710ad9ee3..710ad9ee3 100644 --- a/releasenotes/notes/16.0.0-remove-cinder-v1-api-tests-71e266b8d55d475f.yaml +++ b/releasenotes/notes/16/16.0.0-remove-cinder-v1-api-tests-71e266b8d55d475f.yaml diff --git a/releasenotes/notes/16.0.0-remove-deprecated-allow_port_security_disabled-option-d0ffaeb2e7817707.yaml b/releasenotes/notes/16/16.0.0-remove-deprecated-allow_port_security_disabled-option-d0ffaeb2e7817707.yaml index 9d7102fe0..9d7102fe0 100644 --- a/releasenotes/notes/16.0.0-remove-deprecated-allow_port_security_disabled-option-d0ffaeb2e7817707.yaml +++ b/releasenotes/notes/16/16.0.0-remove-deprecated-allow_port_security_disabled-option-d0ffaeb2e7817707.yaml diff --git a/releasenotes/notes/16.0.0-remove-deprecated-compute-validation-config-options-part-2-5cd17b6e0e6cb8a3.yaml b/releasenotes/notes/16/16.0.0-remove-deprecated-compute-validation-config-options-part-2-5cd17b6e0e6cb8a3.yaml index b4e4dd105..b4e4dd105 100644 --- a/releasenotes/notes/16.0.0-remove-deprecated-compute-validation-config-options-part-2-5cd17b6e0e6cb8a3.yaml +++ b/releasenotes/notes/16/16.0.0-remove-deprecated-compute-validation-config-options-part-2-5cd17b6e0e6cb8a3.yaml diff --git a/releasenotes/notes/16.0.0-remove-deprecated-dvr_extra_resources-option-e8c441c38eab7ddd.yaml b/releasenotes/notes/16/16.0.0-remove-deprecated-dvr_extra_resources-option-e8c441c38eab7ddd.yaml index 889e86275..889e86275 100644 --- a/releasenotes/notes/16.0.0-remove-deprecated-dvr_extra_resources-option-e8c441c38eab7ddd.yaml +++ b/releasenotes/notes/16/16.0.0-remove-deprecated-dvr_extra_resources-option-e8c441c38eab7ddd.yaml diff --git a/releasenotes/notes/16.0.0-remove-deprecated-identity-reseller-option-4411c7e3951f1094.yaml b/releasenotes/notes/16/16.0.0-remove-deprecated-identity-reseller-option-4411c7e3951f1094.yaml index 8085694f8..8085694f8 100644 --- a/releasenotes/notes/16.0.0-remove-deprecated-identity-reseller-option-4411c7e3951f1094.yaml +++ b/releasenotes/notes/16/16.0.0-remove-deprecated-identity-reseller-option-4411c7e3951f1094.yaml diff --git a/releasenotes/notes/16.0.0-remove-sahara-service-available-44a642aa9c634ab4.yaml b/releasenotes/notes/16/16.0.0-remove-sahara-service-available-44a642aa9c634ab4.yaml index c0dc7d71a..c0dc7d71a 100644 --- a/releasenotes/notes/16.0.0-remove-sahara-service-available-44a642aa9c634ab4.yaml +++ b/releasenotes/notes/16/16.0.0-remove-sahara-service-available-44a642aa9c634ab4.yaml diff --git a/releasenotes/notes/16.0.0-remove-volume_feature_enabled.volume_services-c6aa142cc1021297.yaml b/releasenotes/notes/16/16.0.0-remove-volume_feature_enabled.volume_services-c6aa142cc1021297.yaml index fc15995a3..fc15995a3 100644 --- a/releasenotes/notes/16.0.0-remove-volume_feature_enabled.volume_services-c6aa142cc1021297.yaml +++ b/releasenotes/notes/16/16.0.0-remove-volume_feature_enabled.volume_services-c6aa142cc1021297.yaml diff --git a/releasenotes/notes/16.0.0-use-keystone-v3-api-935860d30ddbb8e9.yaml b/releasenotes/notes/16/16.0.0-use-keystone-v3-api-935860d30ddbb8e9.yaml index dd6e92457..dd6e92457 100644 --- a/releasenotes/notes/16.0.0-use-keystone-v3-api-935860d30ddbb8e9.yaml +++ b/releasenotes/notes/16/16.0.0-use-keystone-v3-api-935860d30ddbb8e9.yaml diff --git a/releasenotes/notes/16.0.0-volume-transfers-client-e5ed3f5464c0cdc0.yaml b/releasenotes/notes/16/16.0.0-volume-transfers-client-e5ed3f5464c0cdc0.yaml index e5e479bf9..e5e479bf9 100644 --- a/releasenotes/notes/16.0.0-volume-transfers-client-e5ed3f5464c0cdc0.yaml +++ b/releasenotes/notes/16/16.0.0-volume-transfers-client-e5ed3f5464c0cdc0.yaml diff --git a/releasenotes/notes/add-params-to-v2-list-backups-api-c088d2b4bfe90247.yaml b/releasenotes/notes/add-params-to-v2-list-backups-api-c088d2b4bfe90247.yaml new file mode 100644 index 000000000..cee2d7663 --- /dev/null +++ b/releasenotes/notes/add-params-to-v2-list-backups-api-c088d2b4bfe90247.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + The ``list_backups`` method of the v2 ``BackupsClient`` class now has + an additional ``**params`` argument that enables passing additional + information in the query string of the HTTP request. diff --git a/releasenotes/notes/extra-compute-services-tests-92b6c0618972e02f.yaml b/releasenotes/notes/extra-compute-services-tests-92b6c0618972e02f.yaml new file mode 100644 index 000000000..414adf18b --- /dev/null +++ b/releasenotes/notes/extra-compute-services-tests-92b6c0618972e02f.yaml @@ -0,0 +1,6 @@ +--- +features: + - | + Add the ``disable_log_reason`` and the ``update_forced_down`` API endpoints + to the compute ``services_client``. + Add '2.11' compute validation schema for compute services API. diff --git a/releasenotes/notes/identity_client-635275d43abbb807.yaml b/releasenotes/notes/identity_client-635275d43abbb807.yaml new file mode 100644 index 000000000..6f984b74e --- /dev/null +++ b/releasenotes/notes/identity_client-635275d43abbb807.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Enhances the v3 identity client with the ``check_token_existence`` + endpoint, allowing users to check the existence of tokens diff --git a/releasenotes/notes/intermediate-pike-release-2ce492432ff8f012.yaml b/releasenotes/notes/intermediate-pike-release-2ce492432ff8f012.yaml new file mode 100644 index 000000000..bfebcd9ed --- /dev/null +++ b/releasenotes/notes/intermediate-pike-release-2ce492432ff8f012.yaml @@ -0,0 +1,4 @@ +--- +prelude: > + This is an intermediate release during the Pike development cycle to + make new functionality available to plugins and other consumers. diff --git a/releasenotes/notes/tempest-identity-catalog-client-f5c8589a9d7c1eb5.yaml b/releasenotes/notes/tempest-identity-catalog-client-f5c8589a9d7c1eb5.yaml new file mode 100644 index 000000000..dcaaceb5f --- /dev/null +++ b/releasenotes/notes/tempest-identity-catalog-client-f5c8589a9d7c1eb5.yaml @@ -0,0 +1,5 @@ +--- +features: + - Add a new identity catalog client. At this point, the new client + contains a single functionality, "show_catalog", which returns a + catalog object. diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst index d2be81435..db01da0a0 100644 --- a/releasenotes/source/index.rst +++ b/releasenotes/source/index.rst @@ -6,6 +6,7 @@ :maxdepth: 1 unreleased + v16.1.0 v16.0.0 v15.0.0 v14.0.0 diff --git a/releasenotes/source/v16.1.0.rst b/releasenotes/source/v16.1.0.rst new file mode 100644 index 000000000..e24a70fef --- /dev/null +++ b/releasenotes/source/v16.1.0.rst @@ -0,0 +1,6 @@ +===================== +v16.1.0 Release Notes +===================== + +.. release-notes:: 16.1.0 Release Notes + :version: 16.1.0 diff --git a/requirements.txt b/requirements.txt index 259a4cffc..b7ebf8ac9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,7 @@ testrepository>=0.0.18 # Apache-2.0/BSD oslo.concurrency>=3.8.0 # Apache-2.0 oslo.config!=4.3.0,!=4.4.0,>=4.0.0 # Apache-2.0 oslo.log>=3.22.0 # Apache-2.0 -oslo.serialization>=1.10.0 # Apache-2.0 +oslo.serialization!=2.19.1,>=1.10.0 # Apache-2.0 oslo.utils>=3.20.0 # Apache-2.0 six>=1.9.0 # MIT fixtures>=3.0.0 # Apache-2.0/BSD @@ -5,7 +5,7 @@ description-file = README.rst author = OpenStack author-email = openstack-dev@lists.openstack.org -home-page = http://docs.openstack.org/developer/tempest/ +home-page = https://docs.openstack.org/tempest/latest/ classifier = Intended Audience :: Information Technology Intended Audience :: System Administrators diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py index 3859e64b3..3f1bdce00 100644 --- a/tempest/api/compute/admin/test_live_migration.py +++ b/tempest/api/compute/admin/test_live_migration.py @@ -29,13 +29,13 @@ CONF = config.CONF LOG = logging.getLogger(__name__) -class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest): +class LiveMigrationTest(base.BaseV2ComputeAdminTest): max_microversion = '2.24' block_migration = None @classmethod def skip_checks(cls): - super(LiveBlockMigrationTestJSON, cls).skip_checks() + super(LiveMigrationTest, cls).skip_checks() if not CONF.compute_feature_enabled.live_migration: skip_msg = ("%s skipped as live-migration is " @@ -47,26 +47,9 @@ class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest): @classmethod def setup_clients(cls): - super(LiveBlockMigrationTestJSON, cls).setup_clients() - cls.admin_hosts_client = cls.os_admin.hosts_client + super(LiveMigrationTest, cls).setup_clients() cls.admin_migration_client = cls.os_admin.migrations_client - @classmethod - def _get_compute_hostnames(cls): - body = cls.admin_hosts_client.list_hosts()['hosts'] - return [ - host_record['host_name'] - for host_record in body - if host_record['service'] == 'compute' - ] - - def _get_server_details(self, server_id): - body = self.admin_servers_client.show_server(server_id)['server'] - return body - - def _get_host_for_server(self, server_id): - return self._get_server_details(server_id)['OS-EXT-SRV-ATTR:host'] - def _migrate_server_to(self, server_id, dest_host, volume_backed=False): kwargs = dict() block_migration = getattr(self, 'block_migration', None) @@ -79,11 +62,6 @@ class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest): server_id, host=dest_host, block_migration=block_migration, **kwargs) - def _get_host_other_than(self, host): - for target_host in self._get_compute_hostnames(): - if host != target_host: - return target_host - def _live_migrate(self, server_id, target_host, state, volume_backed=False): self._migrate_server_to(server_id, target_host, volume_backed) @@ -97,7 +75,7 @@ class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest): if (live_migration['instance_uuid'] == server_id): msg += "\n%s" % live_migration msg += "]" - self.assertEqual(target_host, self._get_host_for_server(server_id), + self.assertEqual(target_host, self.get_host_for_server(server_id), msg) def _test_live_migration(self, state='ACTIVE', volume_backed=False): @@ -114,8 +92,8 @@ class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest): # Live migrate an instance to another host server_id = self.create_test_server(wait_until="ACTIVE", volume_backed=volume_backed)['id'] - source_host = self._get_host_for_server(server_id) - destination_host = self._get_host_other_than(source_host) + source_host = self.get_host_for_server(server_id) + destination_host = self.get_host_other_than(server_id) if state == 'PAUSED': self.admin_servers_client.pause_server(server_id) @@ -158,8 +136,7 @@ class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest): def test_iscsi_volume(self): server = self.create_test_server(wait_until="ACTIVE") server_id = server['id'] - actual_host = self._get_host_for_server(server_id) - target_host = self._get_host_other_than(actual_host) + target_host = self.get_host_other_than(server_id) volume = self.create_volume() @@ -174,11 +151,11 @@ class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest): server = self.admin_servers_client.show_server(server_id)['server'] volume_id2 = server["os-extended-volumes:volumes_attached"][0]["id"] - self.assertEqual(target_host, self._get_host_for_server(server_id)) + self.assertEqual(target_host, self.get_host_for_server(server_id)) self.assertEqual(volume_id1, volume_id2) -class LiveBlockMigrationRemoteConsolesV26TestJson(LiveBlockMigrationTestJSON): +class LiveMigrationRemoteConsolesV26Test(LiveMigrationTest): min_microversion = '2.6' max_microversion = 'latest' @@ -201,8 +178,8 @@ class LiveBlockMigrationRemoteConsolesV26TestJson(LiveBlockMigrationTestJSON): hints = {'different_host': server01_id} server02_id = self.create_test_server(scheduler_hints=hints, wait_until='ACTIVE')['id'] - host01_id = self._get_host_for_server(server01_id) - host02_id = self._get_host_for_server(server02_id) + host01_id = self.get_host_for_server(server01_id) + host02_id = self.get_host_for_server(server02_id) self.assertNotEqual(host01_id, host02_id) # At this step we have 2 instances on different hosts, both with @@ -216,7 +193,7 @@ class LiveBlockMigrationRemoteConsolesV26TestJson(LiveBlockMigrationTestJSON): self._migrate_server_to(server01_id, host02_id) waiters.wait_for_server_status(self.servers_client, server01_id, 'ACTIVE') - self.assertEqual(host02_id, self._get_host_for_server(server01_id)) + self.assertEqual(host02_id, self.get_host_for_server(server01_id)) self._verify_console_interaction(server01_id) # At this point, both instances have a valid serial console # connection, which means the ports got updated. @@ -252,7 +229,7 @@ class LiveBlockMigrationRemoteConsolesV26TestJson(LiveBlockMigrationTestJSON): self.assertIn(data, console_output) -class LiveAutoBlockMigrationV225TestJSON(LiveBlockMigrationTestJSON): +class LiveAutoBlockMigrationV225Test(LiveMigrationTest): min_microversion = '2.25' max_microversion = 'latest' block_migration = 'auto' diff --git a/tempest/api/compute/admin/test_live_block_migration_negative.py b/tempest/api/compute/admin/test_live_migration_negative.py index ab6315435..deabbc2d3 100644 --- a/tempest/api/compute/admin/test_live_block_migration_negative.py +++ b/tempest/api/compute/admin/test_live_migration_negative.py @@ -23,10 +23,10 @@ from tempest.lib import exceptions as lib_exc CONF = config.CONF -class LiveBlockMigrationNegativeTestJSON(base.BaseV2ComputeAdminTest): +class LiveMigrationNegativeTest(base.BaseV2ComputeAdminTest): @classmethod def skip_checks(cls): - super(LiveBlockMigrationNegativeTestJSON, cls).skip_checks() + super(LiveMigrationNegativeTest, cls).skip_checks() if not CONF.compute_feature_enabled.live_migration: raise cls.skipException("Live migration is not enabled") @@ -47,3 +47,17 @@ class LiveBlockMigrationNegativeTestJSON(base.BaseV2ComputeAdminTest): server['id'], target_host) waiters.wait_for_server_status(self.servers_client, server['id'], 'ACTIVE') + + @decorators.attr(type=['negative']) + @decorators.idempotent_id('6e2f94f5-2ee8-4830-bef5-5bc95bb0795b') + def test_live_block_migration_suspended(self): + server = self.create_test_server(wait_until="ACTIVE") + + self.admin_servers_client.suspend_server(server['id']) + waiters.wait_for_server_status(self.servers_client, + server['id'], 'SUSPENDED') + + destination_host = self.get_host_other_than(server['id']) + + self.assertRaises(lib_exc.Conflict, self._migrate_server_to, + server['id'], destination_host) diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py index 9023759a4..36567707f 100644 --- a/tempest/api/compute/admin/test_servers_negative.py +++ b/tempest/api/compute/admin/test_servers_negative.py @@ -32,7 +32,6 @@ class ServersAdminNegativeTestJSON(base.BaseV2ComputeAdminTest): def setup_clients(cls): super(ServersAdminNegativeTestJSON, cls).setup_clients() cls.client = cls.os_admin.servers_client - cls.non_adm_client = cls.servers_client cls.quotas_client = cls.os_admin.quotas_client @classmethod diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py index ddb035dc1..feabe35d1 100644 --- a/tempest/api/compute/base.py +++ b/tempest/api/compute/base.py @@ -487,3 +487,21 @@ class BaseV2ComputeAdminTest(BaseV2ComputeTest): self.addCleanup(client.wait_for_resource_deletion, flavor['id']) self.addCleanup(client.delete_flavor, flavor['id']) return flavor + + def get_host_for_server(self, server_id): + server_details = self.admin_servers_client.show_server(server_id) + return server_details['server']['OS-EXT-SRV-ATTR:host'] + + def get_host_other_than(self, server_id): + source_host = self.get_host_for_server(server_id) + + list_hosts_resp = self.os_admin.hosts_client.list_hosts()['hosts'] + hosts = [ + host_record['host_name'] + for host_record in list_hosts_resp + if host_record['service'] == 'compute' + ] + + for target_host in hosts: + if source_host != target_host: + return target_host diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py index ffadd96c5..aa5c43d8d 100644 --- a/tempest/api/compute/servers/test_create_server.py +++ b/tempest/api/compute/servers/test_create_server.py @@ -28,6 +28,7 @@ CONF = config.CONF class ServersTestJSON(base.BaseV2ComputeTest): disk_config = 'AUTO' + volume_backed = False @classmethod def setup_credentials(cls): @@ -38,8 +39,6 @@ class ServersTestJSON(base.BaseV2ComputeTest): def setup_clients(cls): super(ServersTestJSON, cls).setup_clients() cls.client = cls.servers_client - cls.networks_client = cls.os_primary.networks_client - cls.subnets_client = cls.os_primary.subnets_client @classmethod def resource_setup(cls): @@ -59,24 +58,11 @@ class ServersTestJSON(base.BaseV2ComputeTest): accessIPv4=cls.accessIPv4, accessIPv6=cls.accessIPv6, disk_config=disk_config, - adminPass=cls.password) + adminPass=cls.password, + volume_backed=cls.volume_backed) cls.server = (cls.client.show_server(server_initial['id']) ['server']) - def _create_net_subnet_ret_net_from_cidr(self, cidr): - name_net = data_utils.rand_name(self.__class__.__name__) - net = self.networks_client.create_network(name=name_net) - self.addCleanup(self.networks_client.delete_network, - net['network']['id']) - - subnet = self.subnets_client.create_subnet( - network_id=net['network']['id'], - cidr=cidr, - ip_version=4) - self.addCleanup(self.subnets_client.delete_subnet, - subnet['subnet']['id']) - return net - @decorators.attr(type='smoke') @decorators.idempotent_id('5de47127-9977-400a-936f-abcfbec1218f') def test_verify_server_details(self): @@ -87,7 +73,11 @@ class ServersTestJSON(base.BaseV2ComputeTest): self.assertEqual(self.server['accessIPv6'], str(netaddr.IPAddress(self.accessIPv6))) self.assertEqual(self.name, self.server['name']) - self.assertEqual(self.image_ref, self.server['image']['id']) + if self.volume_backed: + # Image is an empty string as per documentation + self.assertEqual("", self.server['image']) + else: + self.assertEqual(self.image_ref, self.server['image']['id']) self.assertEqual(self.flavor_ref, self.server['flavor']['id']) self.assertEqual(self.meta, self.server['metadata']) @@ -158,73 +148,6 @@ class ServersTestJSON(base.BaseV2ComputeTest): ['server_group']) self.assertIn(server['id'], server_group['members']) - @decorators.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2') - @testtools.skipUnless(CONF.service_available.neutron, - 'Neutron service must be available.') - def test_verify_multiple_nics_order(self): - # Verify that the networks order given at the server creation is - # preserved within the server. - net1 = self._create_net_subnet_ret_net_from_cidr('19.80.0.0/24') - net2 = self._create_net_subnet_ret_net_from_cidr('19.86.0.0/24') - - networks = [{'uuid': net1['network']['id']}, - {'uuid': net2['network']['id']}] - - server_multi_nics = self.create_test_server( - networks=networks, wait_until='ACTIVE') - - # Cleanup server; this is needed in the test case because with the LIFO - # nature of the cleanups, if we don't delete the server first, the port - # will still be part of the subnet and we'll get a 409 from Neutron - # when trying to delete the subnet. The tear down in the base class - # will try to delete the server and get a 404 but it's ignored so - # we're OK. - self.addCleanup(self.delete_server, server_multi_nics['id']) - - addresses = (self.client.list_addresses(server_multi_nics['id']) - ['addresses']) - - # We can't predict the ip addresses assigned to the server on networks. - # Sometimes the assigned addresses are ['19.80.0.2', '19.86.0.2'], at - # other times ['19.80.0.3', '19.86.0.3']. So we check if the first - # address is in first network, similarly second address is in second - # network. - addr = [addresses[net1['network']['name']][0]['addr'], - addresses[net2['network']['name']][0]['addr']] - networks = [netaddr.IPNetwork('19.80.0.0/24'), - netaddr.IPNetwork('19.86.0.0/24')] - for address, network in zip(addr, networks): - self.assertIn(address, network) - - @decorators.idempotent_id('1678d144-ed74-43f8-8e57-ab10dbf9b3c2') - @testtools.skipUnless(CONF.service_available.neutron, - 'Neutron service must be available.') - def test_verify_duplicate_network_nics(self): - # Verify that server creation does not fail when more than one nic - # is created on the same network. - net1 = self._create_net_subnet_ret_net_from_cidr('19.80.0.0/24') - net2 = self._create_net_subnet_ret_net_from_cidr('19.86.0.0/24') - - networks = [{'uuid': net1['network']['id']}, - {'uuid': net2['network']['id']}, - {'uuid': net1['network']['id']}] - - server_multi_nics = self.create_test_server( - networks=networks, wait_until='ACTIVE') - self.addCleanup(self.delete_server, server_multi_nics['id']) - - addresses = (self.client.list_addresses(server_multi_nics['id']) - ['addresses']) - - addr = [addresses[net1['network']['name']][0]['addr'], - addresses[net2['network']['name']][0]['addr'], - addresses[net1['network']['name']][1]['addr']] - networks = [netaddr.IPNetwork('19.80.0.0/24'), - netaddr.IPNetwork('19.86.0.0/24'), - netaddr.IPNetwork('19.80.0.0/24')] - for address, network in zip(addr, networks): - self.assertIn(address, network) - class ServersTestManualDisk(ServersTestJSON): disk_config = 'MANUAL' @@ -235,3 +158,15 @@ class ServersTestManualDisk(ServersTestJSON): if not CONF.compute_feature_enabled.disk_config: msg = "DiskConfig extension not enabled." raise cls.skipException(msg) + + +class ServersTestBootFromVolume(ServersTestJSON): + """Run the `ServersTestJSON` tests with a volume backed VM""" + volume_backed = True + + @classmethod + def skip_checks(cls): + super(ServersTestBootFromVolume, cls).skip_checks() + if not test.get_service_list()['volume']: + msg = "Volume service not enabled." + raise cls.skipException(msg) diff --git a/tempest/api/compute/servers/test_create_server_multi_nic.py b/tempest/api/compute/servers/test_create_server_multi_nic.py new file mode 100644 index 000000000..3447d858d --- /dev/null +++ b/tempest/api/compute/servers/test_create_server_multi_nic.py @@ -0,0 +1,120 @@ +# Copyright 2012 OpenStack Foundation +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import netaddr +import testtools + +from tempest.api.compute import base +from tempest import config +from tempest.lib.common.utils import data_utils +from tempest.lib import decorators + +CONF = config.CONF + + +class ServersTestMultiNic(base.BaseV2ComputeTest): + + @classmethod + def setup_credentials(cls): + cls.prepare_instance_network() + super(ServersTestMultiNic, cls).setup_credentials() + + @classmethod + def setup_clients(cls): + super(ServersTestMultiNic, cls).setup_clients() + cls.client = cls.servers_client + cls.networks_client = cls.os_primary.networks_client + cls.subnets_client = cls.os_primary.subnets_client + + def _create_net_subnet_ret_net_from_cidr(self, cidr): + name_net = data_utils.rand_name(self.__class__.__name__) + net = self.networks_client.create_network(name=name_net) + self.addCleanup(self.networks_client.delete_network, + net['network']['id']) + + subnet = self.subnets_client.create_subnet( + network_id=net['network']['id'], + cidr=cidr, + ip_version=4) + self.addCleanup(self.subnets_client.delete_subnet, + subnet['subnet']['id']) + return net + + @decorators.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2') + @testtools.skipUnless(CONF.service_available.neutron, + 'Neutron service must be available.') + def test_verify_multiple_nics_order(self): + # Verify that the networks order given at the server creation is + # preserved within the server. + net1 = self._create_net_subnet_ret_net_from_cidr('19.80.0.0/24') + net2 = self._create_net_subnet_ret_net_from_cidr('19.86.0.0/24') + + networks = [{'uuid': net1['network']['id']}, + {'uuid': net2['network']['id']}] + + server_multi_nics = self.create_test_server( + networks=networks, wait_until='ACTIVE') + + # Cleanup server; this is needed in the test case because with the LIFO + # nature of the cleanups, if we don't delete the server first, the port + # will still be part of the subnet and we'll get a 409 from Neutron + # when trying to delete the subnet. The tear down in the base class + # will try to delete the server and get a 404 but it's ignored so + # we're OK. + self.addCleanup(self.delete_server, server_multi_nics['id']) + + addresses = (self.client.list_addresses(server_multi_nics['id']) + ['addresses']) + + # We can't predict the ip addresses assigned to the server on networks. + # Sometimes the assigned addresses are ['19.80.0.2', '19.86.0.2'], at + # other times ['19.80.0.3', '19.86.0.3']. So we check if the first + # address is in first network, similarly second address is in second + # network. + addr = [addresses[net1['network']['name']][0]['addr'], + addresses[net2['network']['name']][0]['addr']] + networks = [netaddr.IPNetwork('19.80.0.0/24'), + netaddr.IPNetwork('19.86.0.0/24')] + for address, network in zip(addr, networks): + self.assertIn(address, network) + + @decorators.idempotent_id('1678d144-ed74-43f8-8e57-ab10dbf9b3c2') + @testtools.skipUnless(CONF.service_available.neutron, + 'Neutron service must be available.') + def test_verify_duplicate_network_nics(self): + # Verify that server creation does not fail when more than one nic + # is created on the same network. + net1 = self._create_net_subnet_ret_net_from_cidr('19.80.0.0/24') + net2 = self._create_net_subnet_ret_net_from_cidr('19.86.0.0/24') + + networks = [{'uuid': net1['network']['id']}, + {'uuid': net2['network']['id']}, + {'uuid': net1['network']['id']}] + + server_multi_nics = self.create_test_server( + networks=networks, wait_until='ACTIVE') + self.addCleanup(self.delete_server, server_multi_nics['id']) + + addresses = (self.client.list_addresses(server_multi_nics['id']) + ['addresses']) + + addr = [addresses[net1['network']['name']][0]['addr'], + addresses[net2['network']['name']][0]['addr'], + addresses[net1['network']['name']][1]['addr']] + networks = [netaddr.IPNetwork('19.80.0.0/24'), + netaddr.IPNetwork('19.86.0.0/24'), + netaddr.IPNetwork('19.80.0.0/24')] + for address, network in zip(addr, networks): + self.assertIn(address, network) diff --git a/tempest/api/identity/admin/v3/test_endpoint_groups.py b/tempest/api/identity/admin/v3/test_endpoint_groups.py index 5cd456c9c..49dbba198 100644 --- a/tempest/api/identity/admin/v3/test_endpoint_groups.py +++ b/tempest/api/identity/admin/v3/test_endpoint_groups.py @@ -54,17 +54,17 @@ class EndPointGroupsTest(base.BaseIdentityV3AdminTest): super(EndPointGroupsTest, cls).resource_cleanup() @classmethod - def _create_service(self): + def _create_service(cls): s_name = data_utils.rand_name('service') s_type = data_utils.rand_name('type') s_description = data_utils.rand_name('description') service_data = ( - self.services_client.create_service(name=s_name, - type=s_type, - description=s_description)) + cls.services_client.create_service(name=s_name, + type=s_type, + description=s_description)) service_id = service_data['service']['id'] - self.service_ids.append(service_id) + cls.service_ids.append(service_id) return service_id @decorators.idempotent_id('7c69e7a1-f865-402d-a2ea-44493017315a') diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py index 1acc67df0..5c3cd2667 100644 --- a/tempest/api/identity/admin/v3/test_tokens.py +++ b/tempest/api/identity/admin/v3/test_tokens.py @@ -39,6 +39,7 @@ class TokensV3TestJSON(base.BaseIdentityV3AdminTest): resp = self.token.auth(user_id=user['id'], password=u_password).response subject_token = resp['x-subject-token'] + self.client.check_token_existence(subject_token) # Perform GET Token token_details = self.client.show_token(subject_token)['token'] self.assertEqual(resp['x-subject-token'], subject_token) @@ -46,7 +47,7 @@ class TokensV3TestJSON(base.BaseIdentityV3AdminTest): self.assertEqual(token_details['user']['name'], u_name) # Perform Delete Token self.client.delete_token(subject_token) - self.assertRaises(lib_exc.NotFound, self.client.show_token, + self.assertRaises(lib_exc.NotFound, self.client.check_token_existence, subject_token) @decorators.idempotent_id('565fa210-1da1-4563-999b-f7b5b67cf112') diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py index 4495cbf75..30d2a366a 100644 --- a/tempest/api/identity/base.py +++ b/tempest/api/identity/base.py @@ -187,6 +187,7 @@ class BaseIdentityV3Test(BaseIdentityTest): cls.non_admin_users_client = cls.os_primary.users_v3_client cls.non_admin_token = cls.os_primary.token_v3_client cls.non_admin_projects_client = cls.os_primary.projects_client + cls.non_admin_catalog_client = cls.os_primary.catalog_client cls.non_admin_versions_client =\ cls.os_primary.identity_versions_v3_client diff --git a/tempest/api/identity/v3/test_catalog.py b/tempest/api/identity/v3/test_catalog.py new file mode 100755 index 000000000..deec2dcf1 --- /dev/null +++ b/tempest/api/identity/v3/test_catalog.py @@ -0,0 +1,41 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.api.identity import base +from tempest import config +from tempest.lib import decorators + + +CONF = config.CONF + + +class IdentityCatalogTest(base.BaseIdentityV3Test): + + @decorators.idempotent_id('56b57ced-22b8-4127-9b8a-565dfb0207e2') + def test_catalog_standardization(self): + # http://git.openstack.org/cgit/openstack/service-types-authority + # /tree/service-types.yaml + standard_service_values = [{'name': 'keystone', 'type': 'identity'}, + {'name': 'nova', 'type': 'compute'}, + {'name': 'glance', 'type': 'image'}, + {'name': 'swift', 'type': 'object-store'}] + # next, we need to GET the catalog using the catalog client + catalog = self.non_admin_catalog_client.show_catalog()['catalog'] + # get list of the service types present in the catalog + catalog_services = [] + for service in catalog: + catalog_services.append(service['type']) + for service in standard_service_values: + # if service enabled, check if it has a standard typevalue + if service['name'] == 'keystone' or\ + getattr(CONF.service_available, service['name']): + self.assertIn(service['type'], catalog_services) diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py index 07c4157bf..f180cdaea 100644 --- a/tempest/api/network/admin/test_routers.py +++ b/tempest/api/network/admin/test_routers.py @@ -61,13 +61,6 @@ class RoutersAdminTest(base.BaseAdminNetworkTest): msg = "router extension not enabled." raise cls.skipException(msg) - @classmethod - def resource_setup(cls): - super(RoutersAdminTest, cls).resource_setup() - cls.tenant_cidr = (CONF.network.project_network_cidr - if cls._ip_version == 4 else - CONF.network.project_network_v6_cidr) - @decorators.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397') def test_create_router_setting_project_id(self): # Test creating router from admin user setting project_id. diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py index f358d7f7d..754104e04 100644 --- a/tempest/api/volume/admin/test_volume_quotas.py +++ b/tempest/api/volume/admin/test_volume_quotas.py @@ -36,7 +36,7 @@ class BaseVolumeQuotasAdminTestJSON(base.BaseVolumeAdminTest): def setup_credentials(cls): super(BaseVolumeQuotasAdminTestJSON, cls).setup_credentials() cls.demo_tenant_id = cls.os_primary.credentials.tenant_id - cls.alt_client = cls.os_alt.volumes_client + cls.alt_client = cls.os_alt.volumes_client_latest @classmethod def setup_clients(cls): diff --git a/tempest/api/volume/admin/test_volume_type_access.py b/tempest/api/volume/admin/test_volume_type_access.py index 297ab6e06..e93bcb5ff 100644 --- a/tempest/api/volume/admin/test_volume_type_access.py +++ b/tempest/api/volume/admin/test_volume_type_access.py @@ -30,7 +30,7 @@ class VolumeTypesAccessTest(base.BaseVolumeAdminTest): @classmethod def setup_clients(cls): super(VolumeTypesAccessTest, cls).setup_clients() - cls.alt_client = cls.os_alt.volumes_client + cls.alt_client = cls.os_alt.volumes_client_latest @decorators.idempotent_id('d4dd0027-835f-4554-a6e5-50903fb79184') def test_volume_type_access_add(self): diff --git a/tempest/api/volume/test_volumes_clone.py b/tempest/api/volume/test_volumes_clone.py index 4c1337582..927bfa5a2 100644 --- a/tempest/api/volume/test_volumes_clone.py +++ b/tempest/api/volume/test_volumes_clone.py @@ -30,6 +30,18 @@ class VolumesCloneTest(base.BaseVolumeTest): if not CONF.volume_feature_enabled.clone: raise cls.skipException("Cinder volume clones are disabled") + def _verify_volume_clone(self, source_volume, cloned_volume, + bootable='false', extra_size=0): + + cloned_vol_details = self.volumes_client.show_volume( + cloned_volume['id'])['volume'] + + self.assertEqual(source_volume['id'], + cloned_vol_details['source_volid']) + self.assertEqual(source_volume['size'] + extra_size, + cloned_vol_details['size']) + self.assertEqual(bootable, cloned_vol_details['bootable']) + @decorators.idempotent_id('9adae371-a257-43a5-9555-dc7c88e66e0e') def test_create_from_volume(self): # Creates a volume from another volume passing a size different from @@ -41,10 +53,7 @@ class VolumesCloneTest(base.BaseVolumeTest): dst_vol = self.create_volume(source_volid=src_vol['id'], size=src_size + 1) - volume = self.volumes_client.show_volume(dst_vol['id'])['volume'] - # Should allow - self.assertEqual(volume['source_volid'], src_vol['id']) - self.assertEqual(volume['size'], src_size + 1) + self._verify_volume_clone(src_vol, dst_vol, extra_size=1) @decorators.idempotent_id('cbbcd7c6-5a6c-481a-97ac-ca55ab715d16') @test.services('image') @@ -55,10 +64,5 @@ class VolumesCloneTest(base.BaseVolumeTest): # Create a volume from the bootable volume cloned_vol = self.create_volume(source_volid=src_vol['id']) - cloned_vol_details = self.volumes_client.show_volume( - cloned_vol['id'])['volume'] - # Verify cloned volume creation as expected - self.assertEqual('true', cloned_vol_details['bootable']) - self.assertEqual(src_vol['id'], cloned_vol_details['source_volid']) - self.assertEqual(src_vol['size'], cloned_vol_details['size']) + self._verify_volume_clone(src_vol, cloned_vol, bootable='true') diff --git a/tempest/clients.py b/tempest/clients.py index 467ef9cd5..85c2242fc 100644 --- a/tempest/clients.py +++ b/tempest/clients.py @@ -13,17 +13,13 @@ # License for the specific language governing permissions and limitations # under the License. -from oslo_log import log as logging - from tempest import config from tempest.lib import auth from tempest.lib import exceptions as lib_exc from tempest.lib.services import clients from tempest.services import object_storage -from tempest.services import orchestration CONF = config.CONF -LOG = logging.getLogger(__name__) class Manager(clients.ServiceClients): @@ -52,15 +48,6 @@ class Manager(clients.ServiceClients): self._set_image_clients() self._set_network_clients() - self.orchestration_client = orchestration.OrchestrationClient( - self.auth_provider, - CONF.orchestration.catalog_type, - CONF.orchestration.region or CONF.identity.region, - endpoint_type=CONF.orchestration.endpoint_type, - build_interval=CONF.orchestration.build_interval, - build_timeout=CONF.orchestration.build_timeout, - **self.default_params) - def _set_network_clients(self): self.network_agents_client = self.network.AgentsClient() self.network_extensions_client = self.network.ExtensionsClient() @@ -208,6 +195,7 @@ class Manager(clients.ServiceClients): self.identity_v3.EndPointsFilterClient(**params_v3) self.endpoint_groups_client = self.identity_v3.EndPointGroupsClient( **params_v3) + self.catalog_client = self.identity_v3.CatalogClient(**params_v3) # Token clients do not use the catalog. They only need default_params. # They read auth_url, so they should only be set if the corresponding @@ -229,49 +217,63 @@ class Manager(clients.ServiceClients): def _set_volume_clients(self): - self.volume_qos_client = self.volume_v1.QosSpecsClient() - self.volume_qos_v2_client = self.volume_v2.QosSpecsClient() - self.volume_services_client = self.volume_v1.ServicesClient() - self.volume_services_v2_client = self.volume_v2.ServicesClient() - self.backups_client = self.volume_v1.BackupsClient() - self.backups_v2_client = self.volume_v2.BackupsClient() - self.backups_v3_client = self.volume_v3.BackupsClient() - self.encryption_types_client = self.volume_v1.EncryptionTypesClient() - self.encryption_types_v2_client = \ - self.volume_v2.EncryptionTypesClient() - self.snapshot_manage_v2_client = self.volume_v2.SnapshotManageClient() - self.snapshots_client = self.volume_v1.SnapshotsClient() - self.snapshots_v2_client = self.volume_v2.SnapshotsClient() - self.volume_manage_v2_client = self.volume_v2.VolumeManageClient() - self.volumes_client = self.volume_v1.VolumesClient() - self.volumes_v2_client = self.volume_v2.VolumesClient() - self.volumes_v3_client = self.volume_v3.VolumesClient() - self.volume_v3_messages_client = self.volume_v3.MessagesClient() - self.volume_v3_versions_client = self.volume_v3.VersionsClient() - self.volume_types_client = self.volume_v1.TypesClient() - self.volume_types_v2_client = self.volume_v2.TypesClient() - self.volume_hosts_client = self.volume_v1.HostsClient() - self.volume_hosts_v2_client = self.volume_v2.HostsClient() - self.volume_quotas_client = self.volume_v1.QuotasClient() - self.volume_quotas_v2_client = self.volume_v2.QuotasClient() - self.volume_quota_classes_v2_client = \ - self.volume_v2.QuotaClassesClient() - self.volumes_extension_client = self.volume_v1.ExtensionsClient() - self.volumes_v2_extension_client = self.volume_v2.ExtensionsClient() - self.groups_v3_client = self.volume_v3.GroupsClient() - self.group_types_v3_client = self.volume_v3.GroupTypesClient() - self.volume_availability_zone_client = \ - self.volume_v1.AvailabilityZoneClient() - self.volume_v2_availability_zone_client = \ - self.volume_v2.AvailabilityZoneClient() - self.volume_limits_client = self.volume_v1.LimitsClient() - self.volume_v2_limits_client = self.volume_v2.LimitsClient() - self.volume_capabilities_v2_client = \ - self.volume_v2.CapabilitiesClient() - self.volume_scheduler_stats_v2_client = \ - self.volume_v2.SchedulerStatsClient() - self.volume_transfers_v2_client = \ - self.volume_v2.TransfersClient() + if CONF.volume_feature_enabled.api_v1: + self.backups_client = self.volume_v1.BackupsClient() + self.encryption_types_client = \ + self.volume_v1.EncryptionTypesClient() + self.snapshots_client = self.volume_v1.SnapshotsClient() + self.volume_availability_zone_client = \ + self.volume_v1.AvailabilityZoneClient() + self.volume_hosts_client = self.volume_v1.HostsClient() + self.volume_limits_client = self.volume_v1.LimitsClient() + self.volume_qos_client = self.volume_v1.QosSpecsClient() + self.volume_quotas_client = self.volume_v1.QuotasClient() + self.volume_services_client = self.volume_v1.ServicesClient() + self.volume_types_client = self.volume_v1.TypesClient() + self.volumes_client = self.volume_v1.VolumesClient() + self.volumes_extension_client = self.volume_v1.ExtensionsClient() + + if CONF.volume_feature_enabled.api_v2: + self.backups_v2_client = self.volume_v2.BackupsClient() + self.encryption_types_v2_client = \ + self.volume_v2.EncryptionTypesClient() + self.snapshot_manage_v2_client = \ + self.volume_v2.SnapshotManageClient() + self.snapshots_v2_client = self.volume_v2.SnapshotsClient() + self.volume_capabilities_v2_client = \ + self.volume_v2.CapabilitiesClient() + self.volume_manage_v2_client = self.volume_v2.VolumeManageClient() + self.volume_qos_v2_client = self.volume_v2.QosSpecsClient() + self.volume_services_v2_client = self.volume_v2.ServicesClient() + self.volume_types_v2_client = self.volume_v2.TypesClient() + self.volume_hosts_v2_client = self.volume_v2.HostsClient() + self.volume_quotas_v2_client = self.volume_v2.QuotasClient() + self.volume_quota_classes_v2_client = \ + self.volume_v2.QuotaClassesClient() + self.volume_scheduler_stats_v2_client = \ + self.volume_v2.SchedulerStatsClient() + self.volume_transfers_v2_client = \ + self.volume_v2.TransfersClient() + self.volume_v2_availability_zone_client = \ + self.volume_v2.AvailabilityZoneClient() + self.volume_v2_limits_client = self.volume_v2.LimitsClient() + self.volumes_v2_client = self.volume_v2.VolumesClient() + self.volumes_v2_extension_client = \ + self.volume_v2.ExtensionsClient() + + # Set default client for users that don't need explicit version + self.volumes_client_latest = self.volumes_v2_client + + if CONF.volume_feature_enabled.api_v3: + self.backups_v3_client = self.volume_v3.BackupsClient() + self.group_types_v3_client = self.volume_v3.GroupTypesClient() + self.groups_v3_client = self.volume_v3.GroupsClient() + self.volume_v3_messages_client = self.volume_v3.MessagesClient() + self.volume_v3_versions_client = self.volume_v3.VersionsClient() + self.volumes_v3_client = self.volume_v3.VolumesClient() + + # Set default client for users that don't need explicit version + self.volumes_client_latest = self.volumes_v3_client def _set_object_storage_clients(self): # NOTE(andreaf) Load configuration from config. Once object storage diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py index 172d9e156..a76123cdc 100755 --- a/tempest/cmd/account_generator.py +++ b/tempest/cmd/account_generator.py @@ -141,18 +141,10 @@ def get_credential_provider(opts): admin_creds = credentials_factory.get_credentials( fill_in=False, identity_version=identity_version, **admin_creds_dict) return dynamic_creds.DynamicCredentialProvider( - identity_version=identity_version, name=opts.tag, network_resources=network_resources, - neutron_available=CONF.service_available.neutron, - create_networks=CONF.auth.create_isolated_networks, - identity_admin_role=CONF.identity.admin_role, - identity_admin_domain_scope=CONF.identity.admin_domain_scope, - project_network_cidr=CONF.network.project_network_cidr, - project_network_mask_bits=CONF.network.project_network_mask_bits, - public_network_id=CONF.network.public_network_id, - admin_creds=admin_creds, - **credentials_factory.get_dynamic_provider_params()) + **credentials_factory.get_dynamic_provider_params( + identity_version, admin_creds=admin_creds)) def generate_resources(cred_provider, admin): diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py index f1c0a3eba..11cd4bb6b 100644 --- a/tempest/cmd/cleanup_service.py +++ b/tempest/cmd/cleanup_service.py @@ -213,7 +213,9 @@ class ServerGroupService(ServerService): class StackService(BaseService): def __init__(self, manager, **kwargs): super(StackService, self).__init__(kwargs) - self.client = manager.orchestration_client + params = config.service_client_config('orchestration') + self.client = manager.orchestration.OrchestrationClient( + manager.auth_provider, **params) def list(self): client = self.client diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py index 0972a3c88..2f4d120fc 100644 --- a/tempest/cmd/verify_tempest_config.py +++ b/tempest/cmd/verify_tempest_config.py @@ -95,7 +95,7 @@ def _get_api_versions(os, service): client_dict = { 'nova': os.servers_client, 'keystone': os.identity_client, - 'cinder': os.volumes_client, + 'cinder': os.volumes_client_latest, } if service != 'keystone' and service != 'cinder': # Since keystone and cinder may be listening on a path, diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py index e6b46ed1b..449c34389 100644 --- a/tempest/common/credentials_factory.py +++ b/tempest/common/credentials_factory.py @@ -39,19 +39,66 @@ to avoid circular dependencies.""" # Subset of the parameters of credential providers that depend on configuration -def get_common_provider_params(): +def _get_common_provider_params(identity_version): + if identity_version == 'v3': + identity_uri = CONF.identity.uri_v3 + elif identity_version == 'v2': + identity_uri = CONF.identity.uri return { + 'identity_version': identity_version, + 'identity_uri': identity_uri, 'credentials_domain': CONF.auth.default_credentials_domain_name, 'admin_role': CONF.identity.admin_role } -def get_dynamic_provider_params(): - return get_common_provider_params() +def get_dynamic_provider_params(identity_version, admin_creds=None): + """Dynamic provider parameters setup from config + + This helper returns a dict of parameter that can be used to initialise + a `DynamicCredentialProvider` according to tempest configuration. + Parameters that are not configuration specific (name, network_resources) + are not returned. + + :param identity_version: 'v2' or 'v3' + :param admin_creds: An object of type `auth.Credentials`. If None, it + is built from the configuration file as well. + :returns A dict with the parameters + """ + _common_params = _get_common_provider_params(identity_version) + admin_creds = admin_creds or get_configured_admin_credentials( + fill_in=True, identity_version=identity_version) + if identity_version == 'v3': + endpoint_type = CONF.identity.v3_endpoint_type + elif identity_version == 'v2': + endpoint_type = CONF.identity.v2_admin_endpoint_type + return dict(_common_params, **dict([ + ('admin_creds', admin_creds), + ('identity_admin_domain_scope', CONF.identity.admin_domain_scope), + ('identity_admin_role', CONF.identity.admin_role), + ('extra_roles', CONF.auth.tempest_roles), + ('neutron_available', CONF.service_available.neutron), + ('project_network_cidr', CONF.network.project_network_cidr), + ('project_network_mask_bits', CONF.network.project_network_mask_bits), + ('public_network_id', CONF.network.public_network_id), + ('create_networks', (CONF.auth.create_isolated_networks and not + CONF.network.shared_physical_network)), + ('resource_prefix', CONF.resources_prefix), + ('identity_admin_endpoint_type', endpoint_type) + ])) + + +def get_preprov_provider_params(identity_version): + """Pre-provisioned provider parameters setup from config + This helper returns a dict of parameter that can be used to initialise + a `PreProvisionedCredentialProvider` according to tempest configuration. + Parameters that are not configuration specific (name) are not returned. -def get_preprov_provider_params(): - _common_params = get_common_provider_params() + :param identity_version: 'v2' or 'v3' + :returns A dict with the parameters + """ + _common_params = _get_common_provider_params(identity_version) reseller_admin_role = CONF.object_storage.reseller_admin_role return dict(_common_params, **dict([ ('accounts_lock_dir', lockutils.get_lock_path(CONF)), @@ -61,42 +108,40 @@ def get_preprov_provider_params(): ])) -# Return the right implementation of CredentialProvider based on config -# Dropping interface and password, as they are never used anyways -# TODO(andreaf) Drop them from the CredentialsProvider interface completely def get_credentials_provider(name, network_resources=None, force_tenant_isolation=False, identity_version=None): + """Return the right implementation of CredentialProvider based on config + + This helper returns the right implementation of CredentialProvider based on + config and on the value of force_tenant_isolation. + + :param name: When provided, it makes it possible to associate credential + artifacts back to the owner (test class). + :param network_resources: Dictionary of network resources to be allocated + for each test account. Only valid for the dynamic + credentials provider. + :param force_tenant_isolation: Always return a `DynamicCredentialProvider`, + regardless of the configuration. + :param identity_version: Use the specified identity API version, regardless + of the configuration. Valid values are 'v2', 'v3'. + """ # If a test requires a new account to work, it can have it via forcing # dynamic credentials. A new account will be produced only for that test. # In case admin credentials are not available for the account creation, # the test should be skipped else it would fail. identity_version = identity_version or CONF.identity.auth_version if CONF.auth.use_dynamic_credentials or force_tenant_isolation: - admin_creds = get_configured_admin_credentials( - fill_in=True, identity_version=identity_version) return dynamic_creds.DynamicCredentialProvider( name=name, network_resources=network_resources, - identity_version=identity_version, - admin_creds=admin_creds, - identity_admin_domain_scope=CONF.identity.admin_domain_scope, - identity_admin_role=CONF.identity.admin_role, - extra_roles=CONF.auth.tempest_roles, - neutron_available=CONF.service_available.neutron, - project_network_cidr=CONF.network.project_network_cidr, - project_network_mask_bits=CONF.network.project_network_mask_bits, - public_network_id=CONF.network.public_network_id, - create_networks=(CONF.auth.create_isolated_networks and not - CONF.network.shared_physical_network), - resource_prefix=CONF.resources_prefix, - **get_dynamic_provider_params()) + **get_dynamic_provider_params(identity_version)) else: if CONF.auth.test_accounts_file: # Most params are not relevant for pre-created accounts return preprov_creds.PreProvisionedCredentialProvider( - name=name, identity_version=identity_version, - **get_preprov_provider_params()) + name=name, + **get_preprov_provider_params(identity_version)) else: raise exceptions.InvalidConfiguration( 'A valid credential provider is needed') @@ -115,8 +160,8 @@ def is_admin_available(identity_version): # Check whether test accounts file has the admin specified or not elif CONF.auth.test_accounts_file: check_accounts = preprov_creds.PreProvisionedCredentialProvider( - identity_version=identity_version, name='check_admin', - **get_preprov_provider_params()) + name='check_admin', + **get_preprov_provider_params(identity_version)) if not check_accounts.admin_available(): is_admin = False else: @@ -140,8 +185,8 @@ def is_alt_available(identity_version): # Check whether test accounts file has the admin specified or not if CONF.auth.test_accounts_file: check_accounts = preprov_creds.PreProvisionedCredentialProvider( - identity_version=identity_version, name='check_alt', - **get_preprov_provider_params()) + name='check_alt', + **get_preprov_provider_params(identity_version)) else: raise exceptions.InvalidConfiguration( 'A valid credential provider is needed') diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py index 88fe26c3c..90e67b4d4 100644 --- a/tempest/common/dynamic_creds.py +++ b/tempest/common/dynamic_creds.py @@ -12,15 +12,17 @@ # License for the specific language governing permissions and limitations # under the License. +import ipaddress + import netaddr from oslo_log import log as logging import six -from tempest import clients from tempest.lib.common import cred_client from tempest.lib.common import cred_provider from tempest.lib.common.utils import data_utils from tempest.lib import exceptions as lib_exc +from tempest.lib.services import clients LOG = logging.getLogger(__name__) @@ -33,7 +35,8 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): identity_admin_role='admin', extra_roles=None, neutron_available=False, create_networks=True, project_network_cidr=None, project_network_mask_bits=None, - public_network_id=None, resource_prefix=None): + public_network_id=None, resource_prefix=None, + identity_admin_endpoint_type='public', identity_uri=None): """Creates credentials dynamically for tests A credential provider that, based on an initial set of @@ -67,10 +70,14 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): :param project_network_mask_bits: The network mask bits to use for created project networks :param public_network_id: The id for the public network to use + :param identity_admin_endpoint_type: The endpoint type for identity + admin clients. Defaults to public. + :param identity_uri: Identity URI of the target cloud """ super(DynamicCredentialProvider, self).__init__( - identity_version=identity_version, admin_role=admin_role, - name=name, credentials_domain=credentials_domain, + identity_version=identity_version, identity_uri=identity_uri, + admin_role=admin_role, name=name, + credentials_domain=credentials_domain, network_resources=network_resources) self.network_resources = network_resources self._creds = {} @@ -84,6 +91,7 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): self.default_admin_creds = admin_creds self.identity_admin_domain_scope = identity_admin_domain_scope self.identity_admin_role = identity_admin_role or 'admin' + self.identity_admin_endpoint_type = identity_admin_endpoint_type self.extra_roles = extra_roles or [] (self.identity_admin_client, self.tenants_admin_client, @@ -94,7 +102,8 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): self.routers_admin_client, self.subnets_admin_client, self.ports_admin_client, - self.security_groups_admin_client) = self._get_admin_clients() + self.security_groups_admin_client) = self._get_admin_clients( + identity_admin_endpoint_type) # Domain where isolated credentials are provisioned (v3 only). # Use that of the admin account is None is configured. self.creds_domain_name = None @@ -110,32 +119,43 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): self.domains_admin_client, self.creds_domain_name) - def _get_admin_clients(self): + def _get_admin_clients(self, endpoint_type): """Returns a tuple with instances of the following admin clients (in this order): identity network """ - os = clients.Manager(self.default_admin_creds) + os = clients.ServiceClients(self.default_admin_creds, + self.identity_uri) + params = {'endpoint_type': endpoint_type} if self.identity_version == 'v2': - return (os.identity_client, os.tenants_client, os.users_client, - os.roles_client, None, - os.networks_client, os.routers_client, os.subnets_client, - os.ports_client, os.security_groups_client) + return (os.identity_v2.IdentityClient(**params), + os.identity_v2.TenantsClient(**params), + os.identity_v2.UsersClient(**params), + os.identity_v2.RolesClient(**params), None, + os.network.NetworksClient(), + os.network.RoutersClient(), + os.network.SubnetsClient(), + os.network.PortsClient(), + os.network.SecurityGroupsClient()) else: # We use a dedicated client manager for identity client in case we # need a different token scope for them. scope = 'domain' if self.identity_admin_domain_scope else 'project' - identity_os = clients.Manager(self.default_admin_creds, - scope=scope) - return (identity_os.identity_v3_client, - identity_os.projects_client, - identity_os.users_v3_client, identity_os.roles_v3_client, - identity_os.domains_client, - os.networks_client, os.routers_client, - os.subnets_client, os.ports_client, - os.security_groups_client) + identity_os = clients.ServiceClients(self.default_admin_creds, + self.identity_uri, + scope=scope) + return (identity_os.identity_v3.IdentityClient(**params), + identity_os.identity_v3.ProjectsClient(**params), + identity_os.identity_v3.UsersClient(**params), + identity_os.identity_v3.RolesClient(**params), + identity_os.identity_v3.DomainsClient(**params), + os.network.NetworksClient(), + os.network.RoutersClient(), + os.network.SubnetsClient(), + os.network.PortsClient(), + os.network.SecurityGroupsClient()) def _create_creds(self, admin=False, roles=None): """Create credentials with random name. @@ -275,14 +295,16 @@ class DynamicCredentialProvider(cred_provider.CredentialProvider): name=subnet_name, tenant_id=tenant_id, enable_dhcp=self.network_resources['dhcp'], - ip_version=4) + ip_version=(ipaddress.ip_network( + six.text_type(subnet_cidr)).version)) else: resp_body = self.subnets_admin_client.\ create_subnet(network_id=network_id, cidr=str(subnet_cidr), name=subnet_name, tenant_id=tenant_id, - ip_version=4) + ip_version=(ipaddress.ip_network( + six.text_type(subnet_cidr)).version)) break except lib_exc.BadRequest as e: if 'overlaps with another subnet' not in str(e): diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py index 8053cacf3..64cabb766 100644 --- a/tempest/common/preprov_creds.py +++ b/tempest/common/preprov_creds.py @@ -20,12 +20,12 @@ from oslo_log import log as logging import six import yaml -from tempest import clients from tempest.common import fixed_network from tempest import exceptions from tempest.lib import auth from tempest.lib.common import cred_provider from tempest.lib import exceptions as lib_exc +from tempest.lib.services import clients LOG = logging.getLogger(__name__) @@ -51,7 +51,7 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): def __init__(self, identity_version, test_accounts_file, accounts_lock_dir, name=None, credentials_domain=None, admin_role=None, object_storage_operator_role=None, - object_storage_reseller_admin_role=None): + object_storage_reseller_admin_role=None, identity_uri=None): """Credentials provider using pre-provisioned accounts This credentials provider loads the details of pre-provisioned @@ -79,10 +79,12 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): (if no domain is configured) :param object_storage_operator_role: name of the role :param object_storage_reseller_admin_role: name of the role + :param identity_uri: Identity URI of the target cloud """ super(PreProvisionedCredentialProvider, self).__init__( identity_version=identity_version, name=name, - admin_role=admin_role, credentials_domain=credentials_domain) + admin_role=admin_role, credentials_domain=credentials_domain, + identity_uri=identity_uri) self.test_accounts_file = test_accounts_file if test_accounts_file: accounts = read_accounts_yaml(self.test_accounts_file) @@ -341,8 +343,9 @@ class PreProvisionedCredentialProvider(cred_provider.CredentialProvider): auth_url=None, fill_in=False, identity_version=self.identity_version, **creds_dict) net_creds = cred_provider.TestResources(credential) - net_clients = clients.Manager(credentials=credential) - compute_network_client = net_clients.compute_networks_client + net_clients = clients.ServiceClients(credentials=credential, + identity_uri=self.identity_uri) + compute_network_client = net_clients.compute.NetworksClient() net_name = self.hash_dict['networks'].get(hash, None) try: network = fixed_network.get_network_from_name( diff --git a/tempest/lib/api_schema/response/compute/v2_1/servers.py b/tempest/lib/api_schema/response/compute/v2_1/servers.py index 73603967a..2954de005 100644 --- a/tempest/lib/api_schema/response/compute/v2_1/servers.py +++ b/tempest/lib/api_schema/response/compute/v2_1/servers.py @@ -420,8 +420,13 @@ instance_action_events = { 'properties': { 'event': {'type': 'string'}, 'start_time': parameter_types.date_time, - 'finish_time': parameter_types.date_time, - 'result': {'type': 'string'}, + # The finish_time, result and optionally traceback are all + # possibly None (null) until the event is actually finished. + # The traceback would only be set if there was an error, but + # when the event is complete both finish_time and result will + # be set. + 'finish_time': parameter_types.date_time_or_null, + 'result': {'type': ['string', 'null']}, 'traceback': {'type': ['string', 'null']} }, 'additionalProperties': False, diff --git a/tempest/lib/api_schema/response/compute/v2_1/services.py b/tempest/lib/api_schema/response/compute/v2_1/services.py index 6949f8626..3b58ece48 100644 --- a/tempest/lib/api_schema/response/compute/v2_1/services.py +++ b/tempest/lib/api_schema/response/compute/v2_1/services.py @@ -65,3 +65,25 @@ enable_disable_service = { 'required': ['service'] } } + +disable_log_reason = { + 'status_code': [200], + 'response_body': { + 'type': 'object', + 'properties': { + 'service': { + 'type': 'object', + 'properties': { + 'disabled_reason': {'type': 'string'}, + 'binary': {'type': 'string'}, + 'host': {'type': 'string'}, + 'status': {'type': 'string'} + }, + 'additionalProperties': False, + 'required': ['disabled_reason', 'binary', 'host', 'status'] + } + }, + 'additionalProperties': False, + 'required': ['service'] + } +} diff --git a/tempest/lib/api_schema/response/compute/v2_11/__init__.py b/tempest/lib/api_schema/response/compute/v2_11/__init__.py new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/tempest/lib/api_schema/response/compute/v2_11/__init__.py diff --git a/tempest/lib/api_schema/response/compute/v2_11/services.py b/tempest/lib/api_schema/response/compute/v2_11/services.py new file mode 100644 index 000000000..18b833bd2 --- /dev/null +++ b/tempest/lib/api_schema/response/compute/v2_11/services.py @@ -0,0 +1,46 @@ +# Copyright 2017 AT&T Corporation. +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import copy + +from tempest.lib.api_schema.response.compute.v2_1 import services + + +list_services = copy.deepcopy(services.list_services) +list_services['response_body']['properties']['services']['items'][ + 'properties']['forced_down'] = {'type': 'boolean'} +list_services['response_body']['properties']['services']['items'][ + 'required'].append('forced_down') + +update_forced_down = { + 'status_code': [200], + 'response_body': { + 'type': 'object', + 'properties': { + 'service': { + 'type': 'object', + 'properties': { + 'binary': {'type': 'string'}, + 'host': {'type': 'string'}, + 'forced_down': {'type': 'boolean'} + }, + 'additionalProperties': False, + 'required': ['binary', 'host', 'forced_down'] + } + }, + 'additionalProperties': False, + 'required': ['service'] + } +} diff --git a/tempest/lib/common/cred_provider.py b/tempest/lib/common/cred_provider.py index 1b450ab9f..42ed41b39 100644 --- a/tempest/lib/common/cred_provider.py +++ b/tempest/lib/common/cred_provider.py @@ -22,8 +22,9 @@ from tempest.lib import exceptions @six.add_metaclass(abc.ABCMeta) class CredentialProvider(object): - def __init__(self, identity_version, name=None, network_resources=None, - credentials_domain=None, admin_role=None): + def __init__(self, identity_version, name=None, + network_resources=None, credentials_domain=None, + admin_role=None, identity_uri=None): """A CredentialProvider supplies credentials to test classes. :param identity_version: Identity version of the credentials provided @@ -33,8 +34,11 @@ class CredentialProvider(object): credentials :param credentials_domain: Domain credentials belong to :param admin_role: Name of the role of the admin account + :param identity_uri: Identity URI of the target cloud. This *must* be + specified for anything to work. """ self.identity_version = identity_version + self.identity_uri = identity_uri self.name = name or "test_creds" self.network_resources = network_resources self.credentials_domain = credentials_domain or 'Default' diff --git a/tempest/lib/services/compute/services_client.py b/tempest/lib/services/compute/services_client.py index 77ac82fee..857c435a6 100644 --- a/tempest/lib/services/compute/services_client.py +++ b/tempest/lib/services/compute/services_client.py @@ -18,12 +18,18 @@ from oslo_serialization import jsonutils as json from six.moves.urllib import parse as urllib from tempest.lib.api_schema.response.compute.v2_1 import services as schema +from tempest.lib.api_schema.response.compute.v2_11 import services \ + as schemav211 from tempest.lib.common import rest_client from tempest.lib.services.compute import base_compute_client class ServicesClient(base_compute_client.BaseComputeClient): + schema_versions_info = [ + {'min': None, 'max': '2.10', 'schema': schema}, + {'min': '2.11', 'max': None, 'schema': schemav211}] + def list_services(self, **params): """Lists all running Compute services for a tenant. @@ -37,7 +43,8 @@ class ServicesClient(base_compute_client.BaseComputeClient): resp, body = self.get(url) body = json.loads(body) - self.validate_response(schema.list_services, resp, body) + _schema = self.get_schema(self.schema_versions_info) + self.validate_response(_schema.list_services, resp, body) return rest_client.ResponseBody(resp, body) def enable_service(self, **kwargs): @@ -65,3 +72,31 @@ class ServicesClient(base_compute_client.BaseComputeClient): body = json.loads(body) self.validate_response(schema.enable_disable_service, resp, body) return rest_client.ResponseBody(resp, body) + + def disable_log_reason(self, **kwargs): + """Disables scheduling for a Compute service and logs reason. + + For a full list of available parameters, please refer to the official + API reference: + https://developer.openstack.org/api-ref/compute/#log-disabled-compute-service-information + """ + post_body = json.dumps(kwargs) + resp, body = self.put('os-services/disable-log-reason', post_body) + body = json.loads(body) + self.validate_response(schema.disable_log_reason, resp, body) + return rest_client.ResponseBody(resp, body) + + def update_forced_down(self, **kwargs): + """Set or unset ``forced_down`` flag for the service. + + For a full list of available parameters, please refer to the official + API reference: + https://developer.openstack.org/api-ref/compute/#update-forced-down + """ + post_body = json.dumps(kwargs) + resp, body = self.put('os-services/force-down', post_body) + body = json.loads(body) + # NOTE: Use schemav211.update_forced_down directly because there is no + # update_forced_down schema for <2.11. + self.validate_response(schemav211.update_forced_down, resp, body) + return rest_client.ResponseBody(resp, body) diff --git a/tempest/lib/services/identity/v3/__init__.py b/tempest/lib/services/identity/v3/__init__.py index e271a58e1..a539d08c0 100644 --- a/tempest/lib/services/identity/v3/__init__.py +++ b/tempest/lib/services/identity/v3/__init__.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations under # the License. +from tempest.lib.services.identity.v3.catalog_client import \ + CatalogClient from tempest.lib.services.identity.v3.credentials_client import \ CredentialsClient from tempest.lib.services.identity.v3.domain_configuration_client \ @@ -42,10 +44,11 @@ from tempest.lib.services.identity.v3.trusts_client import TrustsClient from tempest.lib.services.identity.v3.users_client import UsersClient from tempest.lib.services.identity.v3.versions_client import VersionsClient -__all__ = ['CredentialsClient', 'DomainsClient', 'DomainConfigurationClient', - 'EndPointGroupsClient', 'EndPointsClient', 'EndPointsFilterClient', - 'GroupsClient', 'IdentityClient', 'InheritedRolesClient', - 'OAUTHConsumerClient', 'OAUTHTokenClient', 'PoliciesClient', - 'ProjectsClient', 'RegionsClient', 'RoleAssignmentsClient', - 'RolesClient', 'ServicesClient', 'V3TokenClient', 'TrustsClient', - 'UsersClient', 'VersionsClient'] +__all__ = ['CatalogClient', 'CredentialsClient', 'DomainsClient', + 'DomainConfigurationClient', 'EndPointGroupsClient', + 'EndPointsClient', 'EndPointsFilterClient', 'GroupsClient', + 'IdentityClient', 'InheritedRolesClient', 'OAUTHConsumerClient', + 'OAUTHTokenClient', 'PoliciesClient', 'ProjectsClient', + 'RegionsClient', 'RoleAssignmentsClient', 'RolesClient', + 'ServicesClient', 'V3TokenClient', 'TrustsClient', 'UsersClient', + 'VersionsClient'] diff --git a/tempest/lib/services/identity/v3/catalog_client.py b/tempest/lib/services/identity/v3/catalog_client.py new file mode 100644 index 000000000..0f9d48543 --- /dev/null +++ b/tempest/lib/services/identity/v3/catalog_client.py @@ -0,0 +1,30 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +""" +https://developer.openstack.org/api-ref/identity/v3/index.html#\ +get-service-catalog +""" + +from oslo_serialization import jsonutils as json + +from tempest.lib.common import rest_client + + +class CatalogClient(rest_client.RestClient): + api_version = "v3" + + def show_catalog(self): + resp, body = self.get('auth/catalog') + self.expected_success(200, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) diff --git a/tempest/lib/services/identity/v3/endpoint_groups_client.py b/tempest/lib/services/identity/v3/endpoint_groups_client.py index 723aeaa09..ce9938953 100644 --- a/tempest/lib/services/identity/v3/endpoint_groups_client.py +++ b/tempest/lib/services/identity/v3/endpoint_groups_client.py @@ -1,78 +1,78 @@ -# Copyright 2017 AT&T Corporation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from oslo_serialization import jsonutils as json
-
-from tempest.lib.common import rest_client
-
-
-class EndPointGroupsClient(rest_client.RestClient):
- api_version = "v3"
-
- def create_endpoint_group(self, **kwargs):
- """Create endpoint group.
-
- For a full list of available parameters, please refer to the
- official API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/#create-endpoint-group
- """
- post_body = json.dumps({'endpoint_group': kwargs})
- resp, body = self.post('OS-EP-FILTER/endpoint_groups', post_body)
- self.expected_success(201, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def update_endpoint_group(self, endpoint_group_id, **kwargs):
- """Update endpoint group.
-
- For a full list of available parameters, please refer to the
- official API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/#update-endpoint-group
- """
- post_body = json.dumps({'endpoint_group': kwargs})
- resp, body = self.patch(
- 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id, post_body)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def delete_endpoint_group(self, endpoint_group_id):
- """Delete endpoint group."""
- resp_header, resp_body = self.delete(
- 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id)
- self.expected_success(204, resp_header.status)
- return rest_client.ResponseBody(resp_header, resp_body)
-
- def show_endpoint_group(self, endpoint_group_id):
- """Get endpoint group."""
- resp_header, resp_body = self.get(
- 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id)
- self.expected_success(200, resp_header.status)
- resp_body = json.loads(resp_body)
- return rest_client.ResponseBody(resp_header, resp_body)
-
- def check_endpoint_group(self, endpoint_group_id):
- """Check endpoint group."""
- resp_header, resp_body = self.head(
- 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id)
- self.expected_success(200, resp_header.status)
- return rest_client.ResponseBody(resp_header, resp_body)
-
- def list_endpoint_groups(self):
- """Get endpoint groups."""
- resp_header, resp_body = self.get('OS-EP-FILTER/endpoint_groups')
- self.expected_success(200, resp_header.status)
- resp_body = json.loads(resp_body)
- return rest_client.ResponseBody(resp_header, resp_body)
+# Copyright 2017 AT&T Corporation. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_serialization import jsonutils as json + +from tempest.lib.common import rest_client + + +class EndPointGroupsClient(rest_client.RestClient): + api_version = "v3" + + def create_endpoint_group(self, **kwargs): + """Create endpoint group. + + For a full list of available parameters, please refer to the + official API reference: + https://developer.openstack.org/api-ref/identity/v3-ext/#create-endpoint-group + """ + post_body = json.dumps({'endpoint_group': kwargs}) + resp, body = self.post('OS-EP-FILTER/endpoint_groups', post_body) + self.expected_success(201, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) + + def update_endpoint_group(self, endpoint_group_id, **kwargs): + """Update endpoint group. + + For a full list of available parameters, please refer to the + official API reference: + https://developer.openstack.org/api-ref/identity/v3-ext/#update-endpoint-group + """ + post_body = json.dumps({'endpoint_group': kwargs}) + resp, body = self.patch( + 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id, post_body) + self.expected_success(200, resp.status) + body = json.loads(body) + return rest_client.ResponseBody(resp, body) + + def delete_endpoint_group(self, endpoint_group_id): + """Delete endpoint group.""" + resp_header, resp_body = self.delete( + 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id) + self.expected_success(204, resp_header.status) + return rest_client.ResponseBody(resp_header, resp_body) + + def show_endpoint_group(self, endpoint_group_id): + """Get endpoint group.""" + resp_header, resp_body = self.get( + 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id) + self.expected_success(200, resp_header.status) + resp_body = json.loads(resp_body) + return rest_client.ResponseBody(resp_header, resp_body) + + def check_endpoint_group(self, endpoint_group_id): + """Check endpoint group.""" + resp_header, resp_body = self.head( + 'OS-EP-FILTER/endpoint_groups/%s' % endpoint_group_id) + self.expected_success(200, resp_header.status) + return rest_client.ResponseBody(resp_header, resp_body) + + def list_endpoint_groups(self): + """Get endpoint groups.""" + resp_header, resp_body = self.get('OS-EP-FILTER/endpoint_groups') + self.expected_success(200, resp_header.status) + resp_body = json.loads(resp_body) + return rest_client.ResponseBody(resp_header, resp_body) diff --git a/tempest/lib/services/identity/v3/identity_client.py b/tempest/lib/services/identity/v3/identity_client.py index 755c14b2c..2512a3edc 100644 --- a/tempest/lib/services/identity/v3/identity_client.py +++ b/tempest/lib/services/identity/v3/identity_client.py @@ -44,6 +44,13 @@ class IdentityClient(rest_client.RestClient): self.expected_success(204, resp.status) return rest_client.ResponseBody(resp, body) + def check_token_existence(self, resp_token): + """Validates a token.""" + headers = {'X-Subject-Token': resp_token} + resp, body = self.head("auth/tokens", headers=headers) + self.expected_success(200, resp.status) + return rest_client.ResponseBody(resp, body) + def list_auth_projects(self): """Get available project scopes.""" resp, body = self.get("auth/projects") diff --git a/tempest/lib/services/volume/v2/backups_client.py b/tempest/lib/services/volume/v2/backups_client.py index a44ed0b74..830fb82fe 100644 --- a/tempest/lib/services/volume/v2/backups_client.py +++ b/tempest/lib/services/volume/v2/backups_client.py @@ -14,6 +14,7 @@ # under the License. from oslo_serialization import jsonutils as json +from six.moves.urllib import parse as urllib from tempest.lib.common import rest_client from tempest.lib import exceptions as lib_exc @@ -64,11 +65,19 @@ class BackupsClient(base_client.BaseClient): self.expected_success(200, resp.status) return rest_client.ResponseBody(resp, body) - def list_backups(self, detail=False): - """Information for all the tenant's backups.""" + def list_backups(self, detail=False, **params): + """List all the tenant's backups. + + For a full list of available parameters, please refer to the official + API reference: + http://developer.openstack.org/api-ref/block-storage/v2/#list-backups + http://developer.openstack.org/api-ref/block-storage/v2/#list-backups-with-details + """ url = "backups" if detail: url += "/detail" + if params: + url += '?%s' % urllib.urlencode(params) resp, body = self.get(url) body = json.loads(body) self.expected_success(200, resp.status) diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py index aecb3741e..9b8c7a01f 100644 --- a/tempest/scenario/manager.py +++ b/tempest/scenario/manager.py @@ -238,9 +238,26 @@ class ScenarioTest(tempest.test.BaseTestCase): volume = self.volumes_client.show_volume(volume['id'])['volume'] return volume + def create_volume_snapshot(self, volume_id, name=None, description=None, + metadata=None, force=False): + name = name or data_utils.rand_name( + self.__class__.__name__ + '-snapshot') + snapshot = self.snapshots_client.create_snapshot( + volume_id=volume_id, + force=force, + display_name=name, + description=description, + metadata=metadata)['snapshot'] + self.addCleanup(self.snapshots_client.wait_for_resource_deletion, + snapshot['id']) + self.addCleanup(self.snapshots_client.delete_snapshot, snapshot['id']) + waiters.wait_for_volume_resource_status(self.snapshots_client, + snapshot['id'], 'available') + return snapshot + def create_volume_type(self, client=None, name=None, backend_name=None): if not client: - client = self.admin_volume_types_client + client = self.os_admin.volume_types_v2_client if not name: class_name = self.__class__.__name__ name = data_utils.rand_name(class_name + '-volume-type') diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py index debd664f8..363264859 100644 --- a/tempest/scenario/test_stamp_pattern.py +++ b/tempest/scenario/test_stamp_pattern.py @@ -16,9 +16,7 @@ from oslo_log import log as logging import testtools -from tempest.common import waiters from tempest import config -from tempest.lib.common.utils import data_utils from tempest.lib.common.utils import test_utils from tempest.lib import decorators from tempest.lib import exceptions as lib_exc @@ -57,20 +55,6 @@ class TestStampPattern(manager.ScenarioTest): if not CONF.volume_feature_enabled.snapshot: raise cls.skipException("Cinder volume snapshots are disabled") - def _create_volume_snapshot(self, volume): - snapshot_name = data_utils.rand_name('scenario-snapshot') - snapshot = self.snapshots_client.create_snapshot( - volume_id=volume['id'], display_name=snapshot_name)['snapshot'] - self.addCleanup(self.snapshots_client.wait_for_resource_deletion, - snapshot['id']) - self.addCleanup(self.snapshots_client.delete_snapshot, snapshot['id']) - waiters.wait_for_volume_resource_status(self.volumes_client, - volume['id'], 'available') - waiters.wait_for_volume_resource_status(self.snapshots_client, - snapshot['id'], 'available') - self.assertEqual(snapshot_name, snapshot['name']) - return snapshot - def _wait_for_volume_available_on_the_system(self, ip_address, private_key): ssh = self.get_remote_client(ip_address, private_key=private_key) @@ -116,7 +100,7 @@ class TestStampPattern(manager.ScenarioTest): self.nova_volume_detach(server, volume) # snapshot the volume - volume_snapshot = self._create_volume_snapshot(volume) + volume_snapshot = self.create_volume_snapshot(volume['id']) # snapshot the instance snapshot_image = self.create_server_snapshot(server=server) diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py index 96d047469..b6f3b38cf 100644 --- a/tempest/scenario/test_volume_boot_pattern.py +++ b/tempest/scenario/test_volume_boot_pattern.py @@ -69,21 +69,6 @@ class TestVolumeBootPattern(manager.EncryptionScenarioTest): return self.create_server(image_id='', **create_kwargs) - def _create_snapshot_from_volume(self, vol_id): - snap_name = data_utils.rand_name( - self.__class__.__name__ + '-snapshot') - snap = self.snapshots_client.create_snapshot( - volume_id=vol_id, - force=True, - display_name=snap_name)['snapshot'] - self.addCleanup( - self.snapshots_client.wait_for_resource_deletion, snap['id']) - self.addCleanup(self.snapshots_client.delete_snapshot, snap['id']) - waiters.wait_for_volume_resource_status(self.snapshots_client, - snap['id'], 'available') - self.assertEqual(snap_name, snap['name']) - return snap - def _delete_server(self, server): self.servers_client.delete_server(server['id']) waiters.wait_for_server_termination(self.servers_client, server['id']) @@ -147,7 +132,7 @@ class TestVolumeBootPattern(manager.EncryptionScenarioTest): # snapshot a volume LOG.info("Creating snapshot from volume: %s", volume_origin['id']) - snapshot = self._create_snapshot_from_volume(volume_origin['id']) + snapshot = self.create_volume_snapshot(volume_origin['id'], force=True) # create a 3rd instance from snapshot LOG.info("Creating third instance from snapshot: %s", snapshot['id']) @@ -177,7 +162,7 @@ class TestVolumeBootPattern(manager.EncryptionScenarioTest): boot_volume = self._create_volume_from_image() # Create a snapshot - boot_snapshot = self._create_snapshot_from_volume(boot_volume['id']) + boot_snapshot = self.create_volume_snapshot(boot_volume['id']) # Create a server from a volume snapshot server = self._boot_instance_from_resource( @@ -229,9 +214,8 @@ class TestVolumeBootPattern(manager.EncryptionScenarioTest): self._delete_server(instance) @decorators.idempotent_id('cb78919a-e553-4bab-b73b-10cf4d2eb125') - @testtools.skipIf(CONF.volume.storage_protocol.lower() in ['ceph', 'nfs'], - 'Currently, {} does not support volume encryption' - .format(CONF.volume.storage_protocol)) + @testtools.skipUnless(CONF.compute_feature_enabled.attach_encrypted_volume, + 'Encrypted volume attach is not supported') @test.services('compute', 'volume') def test_boot_server_from_encrypted_volume_luks(self): # Create an encrypted volume diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py index 81b71b19c..5667fbb74 100644 --- a/tempest/scenario/test_volume_migrate_attached.py +++ b/tempest/scenario/test_volume_migrate_attached.py @@ -40,7 +40,6 @@ class TestVolumeMigrateRetypeAttached(manager.ScenarioTest): @classmethod def setup_clients(cls): super(TestVolumeMigrateRetypeAttached, cls).setup_clients() - cls.admin_volume_types_client = cls.os_admin.volume_types_v2_client cls.admin_volumes_client = cls.os_admin.volumes_v2_client @classmethod diff --git a/tempest/services/object_storage/bulk_middleware_client.py b/tempest/services/object_storage/bulk_middleware_client.py index c194ea909..83d2d80eb 100644 --- a/tempest/services/object_storage/bulk_middleware_client.py +++ b/tempest/services/object_storage/bulk_middleware_client.py @@ -24,7 +24,7 @@ class BulkMiddlewareClient(rest_client.RestClient): To extract containers and objects on Swift cluster from uploaded archived file. For More information please check: - http://docs.openstack.org/developer/swift/middleware.html#module-swift.common.middleware.bulk + https://docs.openstack.org/swift/latest/middleware.html#module-swift.common.middleware.bulk """ url = '%s?extract-archive=%s' % (upload_path, archive_file_format) if headers is None: @@ -37,7 +37,7 @@ class BulkMiddlewareClient(rest_client.RestClient): """Delete multiple objects or containers from their account. For More information please check: - http://docs.openstack.org/developer/swift/middleware.html#module-swift.common.middleware.bulk + https://docs.openstack.org/swift/latest/middleware.html#module-swift.common.middleware.bulk """ url = '?bulk-delete' @@ -51,7 +51,7 @@ class BulkMiddlewareClient(rest_client.RestClient): """Delete multiple objects or containers with POST request. For More information please check: - http://docs.openstack.org/developer/swift/middleware.html#module-swift.common.middleware.bulk + https://docs.openstack.org/swift/latest/middleware.html#module-swift.common.middleware.bulk """ url = '?bulk-delete' diff --git a/tempest/test.py b/tempest/test.py index a81b5d7e0..fc846ffab 100644 --- a/tempest/test.py +++ b/tempest/test.py @@ -63,7 +63,14 @@ def get_service_list(): 'compute': CONF.service_available.nova, 'image': CONF.service_available.glance, 'volume': CONF.service_available.cinder, + # NOTE(masayukig): We have two network services which are neutron and + # nova-network. And we have no way to know whether nova-network is + # available or not. After the pending removal of nova-network from + # nova, we can treat the network/neutron case in the same manner as + # the other services. 'network': True, + # NOTE(masayukig): Tempest tests always require the identity service. + # So we should set this True here. 'identity': True, 'object_storage': CONF.service_available.swift, } diff --git a/tempest/tests/cmd/test_account_generator.py b/tempest/tests/cmd/test_account_generator.py index 6773b2f39..248cfb0e9 100644 --- a/tempest/tests/cmd/test_account_generator.py +++ b/tempest/tests/cmd/test_account_generator.py @@ -20,7 +20,6 @@ from tempest.cmd import account_generator from tempest import config from tempest.tests import base from tempest.tests import fake_config -from tempest.tests.lib import fake_identity class FakeOpts(object): @@ -85,14 +84,10 @@ class MockHelpersMixin(object): class TestAccountGeneratorV2(base.TestCase, MockHelpersMixin): identity_version = 2 - identity_response = fake_identity._fake_v2_response def setUp(self): super(TestAccountGeneratorV2, self).setUp() self.mock_config_and_opts(self.identity_version) - self.useFixture(fixtures.MockPatch( - 'tempest.lib.auth.AuthProvider.set_auth', - return_value=self.identity_response)) def test_get_credential_provider(self): cp = account_generator.get_credential_provider(self.opts) @@ -115,7 +110,6 @@ class TestAccountGeneratorV2(base.TestCase, MockHelpersMixin): class TestAccountGeneratorV3(TestAccountGeneratorV2): identity_version = 3 - identity_response = fake_identity._fake_v3_response def setUp(self): super(TestAccountGeneratorV3, self).setUp() @@ -145,16 +139,12 @@ class TestAccountGeneratorV3(TestAccountGeneratorV2): class TestGenerateResourcesV2(base.TestCase, MockHelpersMixin): identity_version = 2 - identity_response = fake_identity._fake_v2_response cred_client = 'tempest.lib.common.cred_client.V2CredsClient' dynamic_creds = 'tempest.common.dynamic_creds.DynamicCredentialProvider' def setUp(self): super(TestGenerateResourcesV2, self).setUp() self.mock_config_and_opts(self.identity_version) - self.useFixture(fixtures.MockPatch( - 'tempest.lib.auth.AuthProvider.set_auth', - return_value=self.identity_response)) self.cred_provider = account_generator.get_credential_provider( self.opts) self.mock_resource_creation() @@ -244,7 +234,6 @@ class TestGenerateResourcesV2(base.TestCase, MockHelpersMixin): class TestGenerateResourcesV3(TestGenerateResourcesV2): identity_version = 3 - identity_response = fake_identity._fake_v3_response cred_client = 'tempest.lib.common.cred_client.V3CredsClient' def setUp(self): @@ -255,7 +244,6 @@ class TestGenerateResourcesV3(TestGenerateResourcesV2): class TestDumpAccountsV2(base.TestCase, MockHelpersMixin): identity_version = 2 - identity_response = fake_identity._fake_v2_response cred_client = 'tempest.lib.common.cred_client.V2CredsClient' dynamic_creds = 'tempest.common.dynamic_creds.DynamicCredentialProvider' domain_is_in = False @@ -263,9 +251,6 @@ class TestDumpAccountsV2(base.TestCase, MockHelpersMixin): def setUp(self): super(TestDumpAccountsV2, self).setUp() self.mock_config_and_opts(self.identity_version) - self.useFixture(fixtures.MockPatch( - 'tempest.lib.auth.AuthProvider.set_auth', - return_value=self.identity_response)) self.cred_provider = account_generator.get_credential_provider( self.opts) self.mock_resource_creation() @@ -337,7 +322,6 @@ class TestDumpAccountsV2(base.TestCase, MockHelpersMixin): class TestDumpAccountsV3(TestDumpAccountsV2): identity_version = 3 - identity_response = fake_identity._fake_v3_response cred_client = 'tempest.lib.common.cred_client.V3CredsClient' domain_is_in = True diff --git a/tempest/tests/common/test_dynamic_creds.py b/tempest/tests/common/test_dynamic_creds.py index c73961930..cf131eb79 100644 --- a/tempest/tests/common/test_dynamic_creds.py +++ b/tempest/tests/common/test_dynamic_creds.py @@ -46,7 +46,8 @@ class TestDynamicCredentialProvider(base.TestCase): fixed_params = {'name': 'test class', 'identity_version': 'v2', - 'admin_role': 'admin'} + 'admin_role': 'admin', + 'identity_uri': 'fake_uri'} token_client = v2_token_client iden_client = v2_iden_client @@ -619,7 +620,8 @@ class TestDynamicCredentialProviderV3(TestDynamicCredentialProvider): fixed_params = {'name': 'test class', 'identity_version': 'v3', - 'admin_role': 'admin'} + 'admin_role': 'admin', + 'identity_uri': 'fake_uri'} token_client = v3_token_client iden_client = v3_iden_client diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py index 414b1064f..d894c5ed5 100644 --- a/tempest/tests/common/test_preprov_creds.py +++ b/tempest/tests/common/test_preprov_creds.py @@ -38,6 +38,7 @@ class TestPreProvisionedCredentials(base.TestCase): fixed_params = {'name': 'test class', 'identity_version': 'v2', + 'identity_uri': 'fake_uri', 'test_accounts_file': 'fake_accounts_file', 'accounts_lock_dir': 'fake_locks_dir', 'admin_role': 'admin', @@ -91,6 +92,9 @@ class TestPreProvisionedCredentials(base.TestCase): return_value=self.test_accounts)) self.useFixture(fixtures.MockPatch( 'os.path.isfile', return_value=True)) + # NOTE(andreaf) Ensure config is loaded so service clients are + # registered in the registry before tests + config.service_client_config() def tearDown(self): super(TestPreProvisionedCredentials, self).tearDown() @@ -436,6 +440,7 @@ class TestPreProvisionedCredentialsV3(TestPreProvisionedCredentials): fixed_params = {'name': 'test class', 'identity_version': 'v3', + 'identity_uri': 'fake_uri', 'test_accounts_file': 'fake_accounts_file', 'accounts_lock_dir': 'fake_locks_dir_v3', 'admin_role': 'admin', diff --git a/tempest/tests/lib/services/compute/test_services_client.py b/tempest/tests/lib/services/compute/test_services_client.py index 41da39ce7..2dd981c00 100644 --- a/tempest/tests/lib/services/compute/test_services_client.py +++ b/tempest/tests/lib/services/compute/test_services_client.py @@ -14,6 +14,9 @@ import copy +import mock + +from tempest.lib.services.compute import base_compute_client from tempest.lib.services.compute import services_client from tempest.tests.lib import fake_auth_provider from tempest.tests.lib.services import base @@ -44,11 +47,21 @@ class TestServicesClient(base.BaseServiceTest): } } + FAKE_UPDATE_FORCED_DOWN = { + "service": + { + "forced_down": True, + "binary": "nova-conductor", + "host": "controller" + } + } + def setUp(self): super(TestServicesClient, self).setUp() fake_auth = fake_auth_provider.FakeAuthProvider() self.client = services_client.ServicesClient( fake_auth, 'compute', 'regionOne') + self.addCleanup(mock.patch.stopall) def test_list_services_with_str_body(self): self.check_service_client_function( @@ -68,7 +81,7 @@ class TestServicesClient(base.BaseServiceTest): 'tempest.lib.common.rest_client.RestClient.put', self.FAKE_SERVICE, bytes_body, - host_name="nova-conductor", binary="controller") + host="nova-conductor", binary="controller") def test_enable_service_with_str_body(self): self._test_enable_service() @@ -85,10 +98,49 @@ class TestServicesClient(base.BaseServiceTest): 'tempest.lib.common.rest_client.RestClient.put', fake_service, bytes_body, - host_name="nova-conductor", binary="controller") + host="nova-conductor", binary="controller") def test_disable_service_with_str_body(self): self._test_disable_service() def test_disable_service_with_bytes_body(self): self._test_disable_service(bytes_body=True) + + def _test_log_reason_disabled_service(self, bytes_body=False): + resp_body = copy.deepcopy(self.FAKE_SERVICE) + resp_body['service']['disabled_reason'] = 'test reason' + + self.check_service_client_function( + self.client.disable_log_reason, + 'tempest.lib.common.rest_client.RestClient.put', + resp_body, + bytes_body, + host="nova-conductor", + binary="controller", + disabled_reason='test reason') + + def test_log_reason_disabled_service_with_str_body(self): + self._test_log_reason_disabled_service() + + def test_log_reason_disabled_service_with_bytes_body(self): + self._test_log_reason_disabled_service(bytes_body=True) + + def _test_update_forced_down(self, bytes_body=False): + self.check_service_client_function( + self.client.update_forced_down, + 'tempest.lib.common.rest_client.RestClient.put', + self.FAKE_UPDATE_FORCED_DOWN, + bytes_body, + host="nova-conductor", + binary="controller", + forced_down=True) + + @mock.patch.object(base_compute_client, 'COMPUTE_MICROVERSION', + new_callable=mock.PropertyMock(return_value='2.11')) + def test_update_forced_down_with_str_body(self, _): + self._test_update_forced_down() + + @mock.patch.object(base_compute_client, 'COMPUTE_MICROVERSION', + new_callable=mock.PropertyMock(return_value='2.11')) + def test_update_forced_down_with_bytes_body(self, _): + self._test_update_forced_down(bytes_body=True) diff --git a/tempest/tests/lib/services/identity/v3/test_catalog_client.py b/tempest/tests/lib/services/identity/v3/test_catalog_client.py new file mode 100644 index 000000000..0ac8fe426 --- /dev/null +++ b/tempest/tests/lib/services/identity/v3/test_catalog_client.py @@ -0,0 +1,86 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from tempest.lib.services.identity.v3 import catalog_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestCatalogClient(base.BaseServiceTest): + FAKE_CATALOG_INFO = { + 'catalog': [ + { + 'endpoints': [ + { + 'id': '39dc322ce86c4111b4f06c2eeae0841b', + 'interface': 'public', + 'region': 'RegionOne', + 'url': 'http://localhost:5000' + }, + ], + 'id': 'ac58672276f848a7b1727850b3ebe826', + 'type': 'compute', + 'name': 'nova' + }, + { + 'endpoints': [ + { + 'id': '39dc322ce86c4111b4f06c2eeae0841b', + 'interface': 'public', + 'region': 'RegionOne', + 'url': 'http://localhost:5000' + }, + ], + 'id': 'b7c5ed2b486a46dbb4c221499d22991c', + 'type': 'image', + 'name': 'glance' + }, + { + 'endpoints': [ + { + 'id': '39dc322ce86c4111b4f06c2eeae0841b', + 'interface': 'public', + 'region': 'RegionOne', + 'url': 'http://localhost:5000' + }, + ], + 'id': '4363ae44bdf34a3981fde3b823cb9aa2', + 'type': 'identity', + 'name': 'keystone' + } + + ], + 'links': { + 'self': 'http://localhost/identity/v3/catalog', + 'previous': None, + 'next': None + } + } + + def setUp(self): + super(TestCatalogClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = catalog_client.CatalogClient(fake_auth, 'identity', + 'RegionOne') + + def test_show_catalog_with_bytes_body(self): + self._test_show_catalog(bytes_body=True) + + def test_show_catalog_with_str_body(self): + self._test_show_catalog() + + def _test_show_catalog(self, bytes_body=False): + self.check_service_client_function( + self.client.show_catalog, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_CATALOG_INFO, + bytes_body) diff --git a/tempest/tests/lib/services/identity/v3/test_endpoint_groups_client.py b/tempest/tests/lib/services/identity/v3/test_endpoint_groups_client.py index 8b034e6d0..c724f0a33 100644 --- a/tempest/tests/lib/services/identity/v3/test_endpoint_groups_client.py +++ b/tempest/tests/lib/services/identity/v3/test_endpoint_groups_client.py @@ -1,162 +1,162 @@ -# Copyright 2017 AT&T Corporation.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.lib.services.identity.v3 import endpoint_groups_client
-from tempest.tests.lib import fake_auth_provider
-from tempest.tests.lib.services import base
-
-
-class TestEndPointGroupsClient(base.BaseServiceTest):
- FAKE_CREATE_ENDPOINT_GROUP = {
- "endpoint_group": {
- "id": 1,
- "name": "FAKE_ENDPOINT_GROUP",
- "description": "FAKE SERVICE ENDPOINT GROUP",
- "filters": {
- "service_id": 1
- }
- }
- }
-
- FAKE_ENDPOINT_GROUP_INFO = {
- "endpoint_group": {
- "id": 1,
- "name": "FAKE_ENDPOINT_GROUP",
- "description": "FAKE SERVICE ENDPOINT GROUP",
- "links": {
- "self": "http://example.com/identity/v3/OS-EP-FILTER/" +
- "endpoint_groups/1"
- },
- "filters": {
- "service_id": 1
- }
- }
- }
-
- FAKE_LIST_ENDPOINT_GROUPS = {
- "endpoint_groups": [
- {
- "id": 1,
- "name": "SERVICE_GROUP1",
- "description": "FAKE SERVICE ENDPOINT GROUP",
- "links": {
- "self": "http://example.com/identity/v3/OS-EP-FILTER/" +
- "endpoint_groups/1"
- },
- "filters": {
- "service_id": 1
- }
- },
- {
- "id": 2,
- "name": "SERVICE_GROUP2",
- "description": "FAKE SERVICE ENDPOINT GROUP",
- "links": {
- "self": "http://example.com/identity/v3/OS-EP-FILTER/" +
- "endpoint_groups/2"
- },
- "filters": {
- "service_id": 2
- }
- }
- ]
- }
-
- def setUp(self):
- super(TestEndPointGroupsClient, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = endpoint_groups_client.EndPointGroupsClient(
- fake_auth, 'identity', 'regionOne')
-
- def _test_create_endpoint_group(self, bytes_body=False):
- self.check_service_client_function(
- self.client.create_endpoint_group,
- 'tempest.lib.common.rest_client.RestClient.post',
- self.FAKE_CREATE_ENDPOINT_GROUP,
- bytes_body,
- status=201,
- name="FAKE_ENDPOINT_GROUP",
- filters={'service_id': "1"})
-
- def _test_show_endpoint_group(self, bytes_body=False):
- self.check_service_client_function(
- self.client.show_endpoint_group,
- 'tempest.lib.common.rest_client.RestClient.get',
- self.FAKE_ENDPOINT_GROUP_INFO,
- bytes_body,
- endpoint_group_id="1")
-
- def _test_check_endpoint_group(self, bytes_body=False):
- self.check_service_client_function(
- self.client.check_endpoint_group,
- 'tempest.lib.common.rest_client.RestClient.head',
- {},
- bytes_body,
- status=200,
- endpoint_group_id="1")
-
- def _test_update_endpoint_group(self, bytes_body=False):
- self.check_service_client_function(
- self.client.update_endpoint_group,
- 'tempest.lib.common.rest_client.RestClient.patch',
- self.FAKE_ENDPOINT_GROUP_INFO,
- bytes_body,
- endpoint_group_id="1",
- name="NewName")
-
- def _test_list_endpoint_groups(self, bytes_body=False):
- self.check_service_client_function(
- self.client.list_endpoint_groups,
- 'tempest.lib.common.rest_client.RestClient.get',
- self.FAKE_LIST_ENDPOINT_GROUPS,
- bytes_body)
-
- def test_create_endpoint_group_with_str_body(self):
- self._test_create_endpoint_group()
-
- def test_create_endpoint_group_with_bytes_body(self):
- self._test_create_endpoint_group(bytes_body=True)
-
- def test_show_endpoint_group_with_str_body(self):
- self._test_show_endpoint_group()
-
- def test_show_endpoint_group_with_bytes_body(self):
- self._test_show_endpoint_group(bytes_body=True)
-
- def test_check_endpoint_group_with_str_body(self):
- self._test_check_endpoint_group()
-
- def test_check_endpoint_group_with_bytes_body(self):
- self._test_check_endpoint_group(bytes_body=True)
-
- def test_list_endpoint_groups_with_str_body(self):
- self._test_list_endpoint_groups()
-
- def test_list_endpoint_groups_with_bytes_body(self):
- self._test_list_endpoint_groups(bytes_body=True)
-
- def test_update_endpoint_group_with_str_body(self):
- self._test_update_endpoint_group()
-
- def test_update_endpoint_group_with_bytes_body(self):
- self._test_update_endpoint_group(bytes_body=True)
-
- def test_delete_endpoint_group(self):
- self.check_service_client_function(
- self.client.delete_endpoint_group,
- 'tempest.lib.common.rest_client.RestClient.delete',
- {},
- endpoint_group_id="1",
- status=204)
+# Copyright 2017 AT&T Corporation. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.lib.services.identity.v3 import endpoint_groups_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestEndPointGroupsClient(base.BaseServiceTest): + FAKE_CREATE_ENDPOINT_GROUP = { + "endpoint_group": { + "id": 1, + "name": "FAKE_ENDPOINT_GROUP", + "description": "FAKE SERVICE ENDPOINT GROUP", + "filters": { + "service_id": 1 + } + } + } + + FAKE_ENDPOINT_GROUP_INFO = { + "endpoint_group": { + "id": 1, + "name": "FAKE_ENDPOINT_GROUP", + "description": "FAKE SERVICE ENDPOINT GROUP", + "links": { + "self": "http://example.com/identity/v3/OS-EP-FILTER/" + + "endpoint_groups/1" + }, + "filters": { + "service_id": 1 + } + } + } + + FAKE_LIST_ENDPOINT_GROUPS = { + "endpoint_groups": [ + { + "id": 1, + "name": "SERVICE_GROUP1", + "description": "FAKE SERVICE ENDPOINT GROUP", + "links": { + "self": "http://example.com/identity/v3/OS-EP-FILTER/" + + "endpoint_groups/1" + }, + "filters": { + "service_id": 1 + } + }, + { + "id": 2, + "name": "SERVICE_GROUP2", + "description": "FAKE SERVICE ENDPOINT GROUP", + "links": { + "self": "http://example.com/identity/v3/OS-EP-FILTER/" + + "endpoint_groups/2" + }, + "filters": { + "service_id": 2 + } + } + ] + } + + def setUp(self): + super(TestEndPointGroupsClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = endpoint_groups_client.EndPointGroupsClient( + fake_auth, 'identity', 'regionOne') + + def _test_create_endpoint_group(self, bytes_body=False): + self.check_service_client_function( + self.client.create_endpoint_group, + 'tempest.lib.common.rest_client.RestClient.post', + self.FAKE_CREATE_ENDPOINT_GROUP, + bytes_body, + status=201, + name="FAKE_ENDPOINT_GROUP", + filters={'service_id': "1"}) + + def _test_show_endpoint_group(self, bytes_body=False): + self.check_service_client_function( + self.client.show_endpoint_group, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_ENDPOINT_GROUP_INFO, + bytes_body, + endpoint_group_id="1") + + def _test_check_endpoint_group(self, bytes_body=False): + self.check_service_client_function( + self.client.check_endpoint_group, + 'tempest.lib.common.rest_client.RestClient.head', + {}, + bytes_body, + status=200, + endpoint_group_id="1") + + def _test_update_endpoint_group(self, bytes_body=False): + self.check_service_client_function( + self.client.update_endpoint_group, + 'tempest.lib.common.rest_client.RestClient.patch', + self.FAKE_ENDPOINT_GROUP_INFO, + bytes_body, + endpoint_group_id="1", + name="NewName") + + def _test_list_endpoint_groups(self, bytes_body=False): + self.check_service_client_function( + self.client.list_endpoint_groups, + 'tempest.lib.common.rest_client.RestClient.get', + self.FAKE_LIST_ENDPOINT_GROUPS, + bytes_body) + + def test_create_endpoint_group_with_str_body(self): + self._test_create_endpoint_group() + + def test_create_endpoint_group_with_bytes_body(self): + self._test_create_endpoint_group(bytes_body=True) + + def test_show_endpoint_group_with_str_body(self): + self._test_show_endpoint_group() + + def test_show_endpoint_group_with_bytes_body(self): + self._test_show_endpoint_group(bytes_body=True) + + def test_check_endpoint_group_with_str_body(self): + self._test_check_endpoint_group() + + def test_check_endpoint_group_with_bytes_body(self): + self._test_check_endpoint_group(bytes_body=True) + + def test_list_endpoint_groups_with_str_body(self): + self._test_list_endpoint_groups() + + def test_list_endpoint_groups_with_bytes_body(self): + self._test_list_endpoint_groups(bytes_body=True) + + def test_update_endpoint_group_with_str_body(self): + self._test_update_endpoint_group() + + def test_update_endpoint_group_with_bytes_body(self): + self._test_update_endpoint_group(bytes_body=True) + + def test_delete_endpoint_group(self): + self.check_service_client_function( + self.client.delete_endpoint_group, + 'tempest.lib.common.rest_client.RestClient.delete', + {}, + endpoint_group_id="1", + status=204) diff --git a/tempest/tests/lib/services/identity/v3/test_identity_client.py b/tempest/tests/lib/services/identity/v3/test_identity_client.py index e435fe294..6572947fe 100644 --- a/tempest/tests/lib/services/identity/v3/test_identity_client.py +++ b/tempest/tests/lib/services/identity/v3/test_identity_client.py @@ -109,6 +109,14 @@ class TestIdentityClient(base.BaseServiceTest): resp_token="cbc36478b0bd8e67e89", status=204) + def test_check_token_existence(self): + self.check_service_client_function( + self.client.check_token_existence, + 'tempest.lib.common.rest_client.RestClient.head', + {}, + resp_token="cbc36478b0bd8e67e89", + status=200) + def test_list_auth_projects_with_str_body(self): self._test_list_auth_projects() diff --git a/tempest/tests/lib/services/identity/v3/test_oauth_token_client.py b/tempest/tests/lib/services/identity/v3/test_oauth_token_client.py index b9b9b15f2..420ea5f24 100644 --- a/tempest/tests/lib/services/identity/v3/test_oauth_token_client.py +++ b/tempest/tests/lib/services/identity/v3/test_oauth_token_client.py @@ -13,7 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. -from oslotest import mockpatch +import fixtures from tempest.lib.services.identity.v3 import oauth_token_client from tempest.tests.lib import fake_auth_provider @@ -137,7 +137,7 @@ class TestOAUTHTokenClient(base.BaseServiceTest): def test_create_request_token(self): mock_resp = self._mock_token_response(self.FAKE_CREATE_REQUEST_TOKEN) resp = fake_http.fake_http_response(None, status=201), mock_resp - self.useFixture(mockpatch.Patch( + self.useFixture(fixtures.MockPatch( 'tempest.lib.common.rest_client.RestClient.post', return_value=resp)) @@ -157,7 +157,7 @@ class TestOAUTHTokenClient(base.BaseServiceTest): mock_resp = self._mock_token_response(self.FAKE_CREATE_ACCESS_TOKEN) req_secret = self.FAKE_CREATE_REQUEST_TOKEN['oauth_token_secret'] resp = fake_http.fake_http_response(None, status=201), mock_resp - self.useFixture(mockpatch.Patch( + self.useFixture(fixtures.MockPatch( 'tempest.lib.common.rest_client.RestClient.post', return_value=resp)) diff --git a/tempest/tests/lib/services/volume/v2/test_backups_client.py b/tempest/tests/lib/services/volume/v2/test_backups_client.py new file mode 100644 index 000000000..14e5fb0be --- /dev/null +++ b/tempest/tests/lib/services/volume/v2/test_backups_client.py @@ -0,0 +1,117 @@ +# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from tempest.lib.services.volume.v2 import backups_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestBackupsClient(base.BaseServiceTest): + + FAKE_BACKUP_LIST = { + "backups": [ + { + "id": "2ef47aee-8844-490c-804d-2a8efe561c65", + "links": [ + { + "href": "fake-url-1", + "rel": "self" + }, + { + "href": "fake-url-2", + "rel": "bookmark" + } + ], + "name": "backup001" + } + ] + } + + FAKE_BACKUP_LIST_WITH_DETAIL = { + "backups": [ + { + "availability_zone": "az1", + "container": "volumebackups", + "created_at": "2013-04-02T10:35:27.000000", + "description": None, + "fail_reason": None, + "id": "2ef47aee-8844-490c-804d-2a8efe561c65", + "links": [ + { + "href": "fake-url-1", + "rel": "self" + }, + { + "href": "fake-url-2", + "rel": "bookmark" + } + ], + "name": "backup001", + "object_count": 22, + "size": 1, + "status": "available", + "volume_id": "e5185058-943a-4cb4-96d9-72c184c337d6", + "is_incremental": True, + "has_dependent_backups": False + } + ] + } + + def setUp(self): + super(TestBackupsClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = backups_client.BackupsClient(fake_auth, + 'volume', + 'regionOne') + + def _test_list_backups(self, detail=False, mock_args='backups', + bytes_body=False, **params): + if detail: + resp_body = self.FAKE_BACKUP_LIST_WITH_DETAIL + else: + resp_body = self.FAKE_BACKUP_LIST + self.check_service_client_function( + self.client.list_backups, + 'tempest.lib.common.rest_client.RestClient.get', + resp_body, + to_utf=bytes_body, + mock_args=[mock_args], + detail=detail, + **params) + + def test_list_backups_with_str_body(self): + self._test_list_backups() + + def test_list_backups_with_bytes_body(self): + self._test_list_backups(bytes_body=True) + + def test_list_backups_with_detail_with_str_body(self): + mock_args = "backups/detail" + self._test_list_backups(detail=True, mock_args=mock_args) + + def test_list_backups_with_detail_with_bytes_body(self): + mock_args = "backups/detail" + self._test_list_backups(detail=True, mock_args=mock_args, + bytes_body=True) + + def test_list_backups_with_params(self): + # Run the test separately for each param, to avoid assertion error + # resulting from randomized params order. + mock_args = 'backups?sort_key=name' + self._test_list_backups(mock_args=mock_args, sort_key='name') + + mock_args = 'backups/detail?limit=10' + self._test_list_backups(detail=True, mock_args=mock_args, + bytes_body=True, limit=10) diff --git a/tempest/tests/lib/services/volume/v2/test_snapshot_manage_client.py b/tempest/tests/lib/services/volume/v2/test_snapshot_manage_client.py new file mode 100644 index 000000000..3fe8970a8 --- /dev/null +++ b/tempest/tests/lib/services/volume/v2/test_snapshot_manage_client.py @@ -0,0 +1,83 @@ +# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from oslo_serialization import jsonutils as json + +from tempest.lib.services.volume.v2 import snapshot_manage_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestSnapshotManageClient(base.BaseServiceTest): + + SNAPSHOT_MANAGE_REQUEST = { + "snapshot": { + "description": "snapshot-manage-description", + "metadata": None, + "ref": { + "source-name": "_snapshot-22b71da0-94f9-4aca-ad45-7522b3fa96bb" + }, + "name": "snapshot-managed", + "volume_id": "7c064b34-1e4b-40bd-93ca-4ac5a973661b" + } + } + + SNAPSHOT_MANAGE_RESPONSE = { + "snapshot": { + "status": "creating", + "description": "snapshot-manage-description", + "updated_at": None, + "volume_id": "32bafcc8-7109-42cd-8342-70d8de2bedef", + "id": "8fd6eb9d-0a82-456d-b1ec-dea4ac7f1ee2", + "size": 1, + "name": "snapshot-managed", + "created_at": "2017-07-11T10:07:58.000000", + "metadata": {} + } + } + + def setUp(self): + super(TestSnapshotManageClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = snapshot_manage_client.SnapshotManageClient(fake_auth, + 'volume', + 'regionOne') + + def _test_manage_snapshot(self, bytes_body=False): + payload = json.dumps(self.SNAPSHOT_MANAGE_REQUEST, sort_keys=True) + json_dumps = json.dumps + + # NOTE: Use sort_keys for json.dumps so that the expected and actual + # payloads are guaranteed to be identical for mock_args assert check. + with mock.patch.object(snapshot_manage_client.json, + 'dumps') as mock_dumps: + mock_dumps.side_effect = lambda d: json_dumps(d, sort_keys=True) + + self.check_service_client_function( + self.client.manage_snapshot, + 'tempest.lib.common.rest_client.RestClient.post', + self.SNAPSHOT_MANAGE_RESPONSE, + to_utf=bytes_body, + status=202, + mock_args=['os-snapshot-manage', payload], + **self.SNAPSHOT_MANAGE_REQUEST['snapshot']) + + def test_manage_snapshot_with_str_body(self): + self._test_manage_snapshot() + + def test_manage_snapshot_with_bytes_body(self): + self._test_manage_snapshot(bytes_body=True) diff --git a/tempest/tests/lib/services/volume/v2/test_transfers_client.py b/tempest/tests/lib/services/volume/v2/test_transfers_client.py index 0c59bf2c6..84f499283 100644 --- a/tempest/tests/lib/services/volume/v2/test_transfers_client.py +++ b/tempest/tests/lib/services/volume/v2/test_transfers_client.py @@ -13,6 +13,11 @@ # License for the specific language governing permissions and limitations # under the License. +import copy + +import mock +from oslo_serialization import jsonutils as json + from tempest.lib.services.volume.v2 import transfers_client from tempest.tests.lib import fake_auth_provider from tempest.tests.lib.services import base @@ -20,11 +25,14 @@ from tempest.tests.lib.services import base class TestTransfersClient(base.BaseServiceTest): - FAKE_LIST_VOLUME_TRANSFERS_WITH_DETAIL = { - "transfers": [{ - "created_at": "2017-04-18T09:10:03.000000", + FAKE_VOLUME_TRANSFER_ID = "0e89cdd1-6249-421b-96d8-25fac0623d42" + + FAKE_VOLUME_TRANSFER_INFO = { + "transfer": { + "id": FAKE_VOLUME_TRANSFER_ID, + "name": "fake-volume-transfer", "volume_id": "47bf04ef-1ea5-4c5f-a375-430a086d6747", - "id": "0e89cdd1-6249-421b-96d8-25fac0623d42", + "created_at": "2017-04-18T09:10:03.000000", "links": [ { "href": "fake-url-1", @@ -34,9 +42,8 @@ class TestTransfersClient(base.BaseServiceTest): "href": "fake-url-2", "rel": "bookmark" } - ], - "name": "fake-volume-transfer" - }] + ] + } } def setUp(self): @@ -46,16 +53,106 @@ class TestTransfersClient(base.BaseServiceTest): 'volume', 'regionOne') - def _test_list_volume_transfers_with_detail(self, bytes_body=False): + def _test_create_volume_transfer(self, bytes_body=False): + resp_body = copy.deepcopy(self.FAKE_VOLUME_TRANSFER_INFO) + resp_body['transfer'].update({"auth_key": "fake-auth-key"}) + kwargs = {"name": "fake-volume-transfer", + "volume_id": "47bf04ef-1ea5-4c5f-a375-430a086d6747"} + payload = json.dumps({"transfer": kwargs}, sort_keys=True) + json_dumps = json.dumps + + # NOTE: Use sort_keys for json.dumps so that the expected and actual + # payloads are guaranteed to be identical for mock_args assert check. + with mock.patch.object(transfers_client.json, 'dumps') as mock_dumps: + mock_dumps.side_effect = lambda d: json_dumps(d, sort_keys=True) + + self.check_service_client_function( + self.client.create_volume_transfer, + 'tempest.lib.common.rest_client.RestClient.post', + resp_body, + to_utf=bytes_body, + status=202, + mock_args=['os-volume-transfer', payload], + **kwargs) + + def _test_accept_volume_transfer(self, bytes_body=False): + resp_body = copy.deepcopy(self.FAKE_VOLUME_TRANSFER_INFO) + resp_body['transfer'].pop('created_at') + kwargs = {"auth_key": "fake-auth-key"} + payload = json.dumps({"accept": kwargs}, sort_keys=True) + json_dumps = json.dumps + + # NOTE: Use sort_keys for json.dumps so that the expected and actual + # payloads are guaranteed to be identical for mock_args assert check. + with mock.patch.object(transfers_client.json, 'dumps') as mock_dumps: + mock_dumps.side_effect = lambda d: json_dumps(d, sort_keys=True) + + self.check_service_client_function( + self.client.accept_volume_transfer, + 'tempest.lib.common.rest_client.RestClient.post', + resp_body, + to_utf=bytes_body, + status=202, + mock_args=['os-volume-transfer/%s/accept' % + self.FAKE_VOLUME_TRANSFER_ID, payload], + transfer_id=self.FAKE_VOLUME_TRANSFER_ID, + **kwargs) + + def _test_show_volume_transfer(self, bytes_body=False): + resp_body = self.FAKE_VOLUME_TRANSFER_INFO + self.check_service_client_function( + self.client.show_volume_transfer, + 'tempest.lib.common.rest_client.RestClient.get', + resp_body, + to_utf=bytes_body, + transfer_id="0e89cdd1-6249-421b-96d8-25fac0623d42") + + def _test_list_volume_transfers(self, detail=False, bytes_body=False): + resp_body = copy.deepcopy(self.FAKE_VOLUME_TRANSFER_INFO) + if not detail: + resp_body['transfer'].pop('created_at') + resp_body = {"transfers": [resp_body['transfer']]} self.check_service_client_function( self.client.list_volume_transfers, 'tempest.lib.common.rest_client.RestClient.get', - self.FAKE_LIST_VOLUME_TRANSFERS_WITH_DETAIL, - bytes_body, - detail=True) + resp_body, + to_utf=bytes_body, + detail=detail) + + def test_create_volume_transfer_with_str_body(self): + self._test_create_volume_transfer() + + def test_create_volume_transfer_with_bytes_body(self): + self._test_create_volume_transfer(bytes_body=True) + + def test_accept_volume_transfer_with_str_body(self): + self._test_accept_volume_transfer() + + def test_accept_volume_transfer_with_bytes_body(self): + self._test_accept_volume_transfer(bytes_body=True) + + def test_show_volume_transfer_with_str_body(self): + self._test_show_volume_transfer() + + def test_show_volume_transfer_with_bytes_body(self): + self._test_show_volume_transfer(bytes_body=True) + + def test_list_volume_transfers_with_str_body(self): + self._test_list_volume_transfers() + + def test_list_volume_transfers_with_bytes_body(self): + self._test_list_volume_transfers(bytes_body=True) def test_list_volume_transfers_with_detail_with_str_body(self): - self._test_list_volume_transfers_with_detail() + self._test_list_volume_transfers(detail=True) def test_list_volume_transfers_with_detail_with_bytes_body(self): - self._test_list_volume_transfers_with_detail(bytes_body=True) + self._test_list_volume_transfers(detail=True, bytes_body=True) + + def test_delete_volume_transfer(self): + self.check_service_client_function( + self.client.delete_volume_transfer, + 'tempest.lib.common.rest_client.RestClient.delete', + {}, + status=202, + transfer_id="0e89cdd1-6249-421b-96d8-25fac0623d42") diff --git a/tempest/tests/lib/services/volume/v2/test_volume_manage_client.py b/tempest/tests/lib/services/volume/v2/test_volume_manage_client.py new file mode 100644 index 000000000..ea4a9f996 --- /dev/null +++ b/tempest/tests/lib/services/volume/v2/test_volume_manage_client.py @@ -0,0 +1,111 @@ +# Copyright 2017 FiberHome Telecommunication Technologies CO.,LTD +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from oslo_serialization import jsonutils as json + +from tempest.lib.services.volume.v2 import volume_manage_client +from tempest.tests.lib import fake_auth_provider +from tempest.tests.lib.services import base + + +class TestVolumeManageClient(base.BaseServiceTest): + + VOLUME_MANAGE_REQUEST = { + "volume": { + "host": "controller1@rbd#rbd", + "name": "volume-managed", + "availability_zone": "nova", + "bootable": False, + "metadata": None, + "ref": { + "source-name": "volume-2ce6ca46-e6c1-4fe5-8268-3a1c536fcbf3" + }, + "volume_type": None, + "description": "volume-manage-description" + } + } + + VOLUME_MANAGE_RESPONSE = { + "volume": { + "migration_status": None, + "attachments": [], + "links": [ + { + "href": "fake-url-1", + "rel": "self" + }, + { + "href": "fake-url-2", + "rel": "bookmark" + } + ], + "availability_zone": "nova", + "os-vol-host-attr:host": "controller1@rbd#rbd", + "encrypted": False, + "updated_at": None, + "replication_status": None, + "snapshot_id": None, + "id": "c07cd4a4-b52b-4511-a176-fbaa2011a227", + "size": 0, + "user_id": "142d8663efce464c89811c63e45bd82e", + "os-vol-tenant-attr:tenant_id": "f21a9c86d7114bf99c711f4874d80474", + "os-vol-mig-status-attr:migstat": None, + "metadata": {}, + "status": "creating", + "description": "volume-manage-description", + "multiattach": False, + "source_volid": None, + "consistencygroup_id": None, + "os-vol-mig-status-attr:name_id": None, + "name": "volume-managed", + "bootable": "false", + "created_at": "2017-07-11T09:14:01.000000", + "volume_type": None + } + } + + def setUp(self): + super(TestVolumeManageClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = volume_manage_client.VolumeManageClient(fake_auth, + 'volume', + 'regionOne') + + def _test_manage_volume(self, bytes_body=False): + payload = json.dumps(self.VOLUME_MANAGE_REQUEST, sort_keys=True) + json_dumps = json.dumps + + # NOTE: Use sort_keys for json.dumps so that the expected and actual + # payloads are guaranteed to be identical for mock_args assert check. + with mock.patch.object(volume_manage_client.json, + 'dumps') as mock_dumps: + mock_dumps.side_effect = lambda d: json_dumps(d, sort_keys=True) + + self.check_service_client_function( + self.client.manage_volume, + 'tempest.lib.common.rest_client.RestClient.post', + self.VOLUME_MANAGE_RESPONSE, + to_utf=bytes_body, + status=202, + mock_args=['os-volume-manage', payload], + **self.VOLUME_MANAGE_REQUEST['volume']) + + def test_manage_volume_with_str_body(self): + self._test_manage_volume() + + def test_manage_volume_with_bytes_body(self): + self._test_manage_volume(bytes_body=True) diff --git a/tools/tempest-plugin-sanity.sh b/tools/tempest-plugin-sanity.sh new file mode 100644 index 000000000..a4f706e01 --- /dev/null +++ b/tools/tempest-plugin-sanity.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash + +# Copyright 2017 Red Hat, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# This script is intended to check the sanity of tempest plugins against +# tempest master. +# What it does: +# * Creates the virtualenv +# * Install tempest +# * Retrive the project lists having tempest plugin if project name is +# given. +# * For each project in a list, It does: +# * Clone the Project +# * Install the Project and also installs dependencies from +# test-requirements.txt. +# * Create Tempest workspace +# * List tempest plugins +# * List tempest plugins tests +# * Uninstall the project and its dependencies +# * Again Install tempest +# * Again repeat the step from cloning project +# +# If one of the step fails, The script will exit with failure. + +if [ "$1" == "-h" ]; then + echo -e "This script performs the sanity of tempest plugins to find +configuration and dependency issues with the tempest.\n +Usage: sh ./tools/tempest-plugin-sanity.sh [Run sanity on tempest plugins]" + exit 0 +fi + +set -ex + +# retrieve a list of projects having tempest plugins +PROJECT_LIST="$(python tools/generate-tempest-plugins-list.py)" +# List of projects having tempest plugin stale or unmaintained from long time +BLACKLIST="trio2o" + +# Function to clone project using zuul-cloner or from git +function clone_project() { + if [ -e /usr/zuul-env/bin/zuul-cloner ]; then + /usr/zuul-env/bin/zuul-cloner --cache-dir /opt/git \ + git://git.openstack.org \ + openstack/"$1" + + elif [ -e /usr/bin/git ]; then + /usr/bin/git clone git://git.openstack.org/openstack/"$1" \ + openstack/"$1" + + fi +} + +# Create virtualenv to perform sanity operation +SANITY_DIR=$(pwd) +virtualenv "$SANITY_DIR"/.venv +export TVENV="$SANITY_DIR/tools/with_venv.sh" +cd "$SANITY_DIR" + +# Install tempest in a venv +"$TVENV" pip install . + +# Function to install project +function install_project() { + "$TVENV" pip install "$SANITY_DIR"/openstack/"$1" + # Check for test-requirements.txt file in a project then install it. + if [ -e "$SANITY_DIR"/openstack/"$1"/test-requirements.txt ]; then + "$TVENV" pip install -r "$SANITY_DIR"/openstack/"$1"/test-requirements.txt + fi +} + +# Function to perform sanity checking on Tempest plugin +function tempest_sanity() { + "$TVENV" tempest init "$SANITY_DIR"/tempest_sanity + cd "$SANITY_DIR"/tempest_sanity + "$TVENV" tempest list-plugins + "$TVENV" tempest run -l + # Delete tempest workspace + "$TVENV" tempest workspace remove --name tempest_sanity --rmdir + cd "$SANITY_DIR" +} + +# Function to uninstall project +function uninstall_project() { + "$TVENV" pip uninstall -y "$SANITY_DIR"/openstack/"$1" + # Check for *requirements.txt file in a project then uninstall it. + if [ -e "$SANITY_DIR"/openstack/"$1"/*requirements.txt ]; then + "$TVENV" pip uninstall -y -r "$SANITY_DIR"/openstack/"$1"/*requirements.txt + fi + # Remove the project directory after sanity run + rm -fr "$SANITY_DIR"/openstack/"$1" +} + +# Function to run sanity check on each project +function plugin_sanity_check() { + clone_project "$1" && install_project "$1" && tempest_sanity "$1" \ + && uninstall_project "$1" && "$TVENV" pip install . +} + +# Log status +passed_plugin='' +failed_plugin='' +# Perform sanity on all tempest plugin projects +for project in $PROJECT_LIST; do + # Remove blacklisted tempest plugins + if ! [[ `echo $BLACKLIST | grep -c $project ` -gt 0 ]]; then + plugin_sanity_check $project && passed_plugin+=", $project" || \ + failed_plugin+=", $project" + fi +done @@ -20,7 +20,7 @@ setenv = PYTHONWARNINGS=default::DeprecationWarning BRANCH_NAME=master CLIENT_NAME=tempest -passenv = OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_TEST_TIMEOUT OS_TEST_LOCK_PATH OS_TEST_PATH TEMPEST_CONFIG TEMPEST_CONFIG_DIR http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY ZUUL_CACHE_DIR REQUIREMENTS_PIP_LOCATION +passenv = OS_STDOUT_CAPTURE OS_STDERR_CAPTURE OS_TEST_TIMEOUT OS_TEST_LOCK_PATH OS_TEST_PATH TEMPEST_CONFIG TEMPEST_CONFIG_DIR http_proxy HTTP_PROXY https_proxy HTTPS_PROXY no_proxy NO_PROXY ZUUL_CACHE_DIR REQUIREMENTS_PIP_LOCATION GENERATE_TEMPEST_PLUGIN_LIST usedevelop = True install_command = {toxinidir}/tools/tox_install.sh {env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt} {opts} {packages} @@ -185,3 +185,9 @@ commands= # separately, outside of the requirements files. deps = bindep commands = bindep test + +[testenv:plugin-sanity-check] +# perform tempest plugin sanity +whitelist_externals = bash +commands = + bash tools/tempest-plugin-sanity.sh |