Merge "Add 'single core approve' policy for plugins sanity jobs failure"
diff --git a/.gitignore b/.gitignore
index 06a2281..9767e52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,9 @@
+# Don't add patterns to exclude files created by preferred personal tools
+# (editors, IDEs, your operating system itself even). These should instead be
+# maintained outside the repository, for example in a ~/.gitignore file added
+# with:
+#
+# git config --global core.excludesfile '~/.gitignore'
AUTHORS
ChangeLog
*.pyc
diff --git a/.zuul.yaml b/.zuul.yaml
index be38318..d893483 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -7,12 +7,12 @@
This Tempest job provides the base for both the single and multi-node
test setup. To run a multi-node test inherit from devstack-tempest and
set the nodeset to a multi-node one.
- required-projects:
+ required-projects: &base_required-projects
- opendev.org/openstack/tempest
timeout: 7200
- roles:
+ roles: &base_roles
- zuul: opendev.org/openstack/devstack
- vars:
+ vars: &base_vars
devstack_services:
tempest: true
devstack_local_conf:
@@ -53,37 +53,37 @@
name: devstack-tempest-ipv6
parent: devstack-ipv6
description: |
- Base Tempest IPv6 job.
- required-projects:
- - opendev.org/openstack/tempest
+ Base Tempest IPv6 job. This job is derived from 'devstack-ipv6'
+ which set the IPv6-only setting for OpenStack services. As part of
+ run phase, this job will verify the IPv6 setting and check the services
+ endpoints and listen addresses are IPv6. Basically it will run the script
+ ./tool/verify-ipv6-only-deployments.sh
+
+ Child jobs of this job can run their own set of tests and can
+ add post-run playebooks to extend the IPv6 verification specific
+ to their deployed services.
+ Check the wiki page for more details about project jobs setup
+ - https://wiki.openstack.org/wiki/Goal-IPv6-only-deployments-and-testing
+ required-projects: *base_required-projects
timeout: 7200
- roles:
- - zuul: opendev.org/openstack/devstack
- vars:
- devstack_services:
- tempest: true
- devstack_local_conf:
- test-config:
- $TEMPEST_CONFIG:
- compute:
- min_compute_nodes: "{{ groups['compute'] | default(['controller']) | length }}"
- test_results_stage_name: test_results
- zuul_copy_output:
- '{{ devstack_base_dir }}/tempest/etc/tempest.conf': logs
- '{{ devstack_base_dir }}/tempest/etc/accounts.yaml': logs
- '{{ devstack_base_dir }}/tempest/tempest.log': logs
- '{{ stage_dir }}/{{ test_results_stage_name }}.subunit': logs
- '{{ stage_dir }}/{{ test_results_stage_name }}.html': logs
- '{{ stage_dir }}/stackviz': logs
- extensions_to_txt:
- conf: true
- log: true
- yaml: true
- yml: true
- run: playbooks/devstack-tempest.yaml
+ roles: *base_roles
+ vars: *base_vars
+ run: playbooks/devstack-tempest-ipv6.yaml
post-run: playbooks/post-tempest.yaml
- job:
+ name: tempest-ipv6-only
+ parent: devstack-tempest-ipv6
+ # This currently works from stable/pike on.
+ branches: ^(?!stable/ocata).*$
+ description: |
+ Integration test of IPv6-only deployments. This job runs
+ smoke and IPv6 relates tests only. Basic idea is to test
+ whether OpenStack Services listen on IPv6 addrress or not.
+ vars:
+ tox_envlist: ipv6-only
+
+- job:
name: tempest-full
parent: devstack-tempest
# This currently works from stable/pike on.
@@ -172,6 +172,99 @@
c-bak: false
- job:
+ name: tempest-integrated-networking
+ parent: devstack-tempest
+ branches: ^(?!stable/ocata).*$
+ description: |
+ This job runs integration tests for networking. This is subset of
+ 'tempest-full' job and run only Neutron and Nova related tests.
+ This is meant to be run on neutron gate only.
+ vars:
+ tox_envlist: integrated-network
+ devstack_localrc:
+ USE_PYTHON3: true
+ FORCE_CONFIG_DRIVE: true
+ devstack_services:
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
+ c-bak: false
+
+- job:
+ name: tempest-integrated-compute
+ parent: devstack-tempest
+ branches: ^(?!stable/ocata).*$
+ description: |
+ This job runs integration tests for compute. This is
+ subset of 'tempest-full' job and run Nova, Neutron, Cinder (except backup tests)
+ and Glance related tests. This is meant to be run on Nova gate only.
+ vars:
+ tox_envlist: integrated-compute
+ devstack_localrc:
+ USE_PYTHON3: true
+ FORCE_CONFIG_DRIVE: true
+ ENABLE_VOLUME_MULTIATTACH: true
+ devstack_services:
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
+ c-bak: false
+
+- job:
+ name: tempest-integrated-placement
+ parent: devstack-tempest
+ branches: ^(?!stable/ocata).*$
+ description: |
+ This job runs integration tests for placement. This is
+ subset of 'tempest-full' job and run Nova and Neutron
+ related tests. This is meant to be run on Placement gate only.
+ vars:
+ tox_envlist: integrated-placement
+ devstack_localrc:
+ USE_PYTHON3: true
+ FORCE_CONFIG_DRIVE: true
+ ENABLE_VOLUME_MULTIATTACH: true
+ devstack_services:
+ s-account: false
+ s-container: false
+ s-object: false
+ s-proxy: false
+ c-bak: false
+
+- job:
+ name: tempest-integrated-storage
+ parent: devstack-tempest
+ branches: ^(?!stable/ocata).*$
+ description: |
+ This job runs integration tests for image & block storage. This is
+ subset of 'tempest-full' job and run Cinder, Glance, Swift and Nova
+ related tests. This is meant to be run on Cinder and Glance gate only.
+ vars:
+ tox_envlist: integrated-storage
+ devstack_localrc:
+ USE_PYTHON3: true
+ FORCE_CONFIG_DRIVE: true
+ ENABLE_VOLUME_MULTIATTACH: true
+
+- job:
+ name: tempest-integrated-object-storage
+ parent: devstack-tempest
+ branches: ^(?!stable/ocata).*$
+ description: |
+ This job runs integration tests for object storage. This is
+ subset of 'tempest-full' job and run Swift, Cinder and Glance
+ related tests. This is meant to be run on Swift gate only.
+ vars:
+ tox_envlist: integrated-object-storage
+ devstack_localrc:
+ # NOTE(gmann): swift is not ready on python3 yet and devstack
+ # install it on python2.7 only. But settting the USE_PYTHON3
+ # for future once swift is ready on py3.
+ USE_PYTHON3: true
+
+- job:
name: tempest-full-py3-ipv6
parent: devstack-tempest-ipv6
# This currently works from stable/pike on.
@@ -273,6 +366,21 @@
devstack_localrc:
CINDER_ENABLED_BACKENDS: lvm:lvmdriver-1,lvm:lvmdriver-2
ENABLE_VOLUME_MULTIATTACH: true
+ devstack_plugins:
+ neutron: https://opendev.org/openstack/neutron
+ devstack_services:
+ neutron-placement: true
+ neutron-qos: true
+ devstack_local_conf:
+ post-config:
+ "/$NEUTRON_CORE_PLUGIN_CONF":
+ ovs:
+ bridge_mappings: public:br-ex
+ resource_provider_bandwidths: br-ex:1000000:1000000
+ test-config:
+ $TEMPEST_CONFIG:
+ network-feature-enabled:
+ qos_placement_physnet: public
tempest_concurrency: 2
group-vars:
# NOTE(mriedem): The ENABLE_VOLUME_MULTIATTACH variable is used on both
@@ -331,12 +439,6 @@
override-checkout: stable/queens
- job:
- name: tempest-full-pike
- parent: tempest-full
- nodeset: openstack-single-node-xenial
- override-checkout: stable/pike
-
-- job:
name: tempest-tox-plugin-sanity-check
parent: tox
description: |
@@ -345,90 +447,6 @@
vars:
tox_envlist: plugin-sanity-check
timeout: 5000
- irrelevant-files:
- - ^.*\.rst$
- - ^doc/.*$
- - ^etc/.*$
- - ^releasenotes/.*$
- - ^tempest/hacking/.*$
- - ^tempest/tests/.*$
- required-projects:
- - opendev.org/airship/tempest-plugin
- - opendev.org/x/almanach
- - opendev.org/openstack/aodh
- - opendev.org/openstack/barbican-tempest-plugin
- - opendev.org/openstack/blazar-tempest-plugin
- - opendev.org/openstack/ceilometer
- - opendev.org/openstack/cinder-tempest-plugin
- - opendev.org/openstack/cloudkitty-tempest-plugin
- - opendev.org/openstack/congress-tempest-plugin
- - opendev.org/openstack/cyborg-tempest-plugin
- - opendev.org/openstack/designate-tempest-plugin
- - opendev.org/openstack/ec2api-tempest-plugin
- - opendev.org/openstack/freezer
- - opendev.org/openstack/freezer-api
- - opendev.org/openstack/freezer-tempest-plugin
- - opendev.org/x/gabbi-tempest
- - opendev.org/x/gce-api
- - opendev.org/x/glare
- - opendev.org/openstack/heat-tempest-plugin
- - opendev.org/x/intel-nfv-ci-tests
- - opendev.org/openstack/ironic-tempest-plugin
- - opendev.org/openstack/ironic-inspector
- - opendev.org/openstack/keystone-tempest-plugin
- - opendev.org/x/kingbird
- - opendev.org/openstack/kuryr-tempest-plugin
- - opendev.org/openstack/magnum
- - opendev.org/openstack/magnum-tempest-plugin
- - opendev.org/openstack/manila
- - opendev.org/openstack/manila-tempest-plugin
- - opendev.org/openstack/mistral-tempest-plugin
- - opendev.org/x/mogan
- - opendev.org/openstack/monasca-api
- - opendev.org/openstack/monasca-log-api
- - opendev.org/openstack/monasca-tempest-plugin
- - opendev.org/openstack/murano-tempest-plugin
- - opendev.org/x/networking-ansible
- - opendev.org/openstack/networking-bgpvpn
- - opendev.org/x/networking-cisco
- - opendev.org/x/networking-fortinet
- - opendev.org/openstack/networking-generic-switch
- - opendev.org/openstack/networking-l2gw-tempest-plugin
- - opendev.org/openstack/networking-midonet
- - opendev.org/openstack/networking-sfc
- - opendev.org/x/networking-spp
- - opendev.org/openstack/neutron
- - opendev.org/openstack/neutron-dynamic-routing
- - opendev.org/openstack/neutron-fwaas
- - opendev.org/openstack/neutron-lbaas
- - opendev.org/openstack/neutron-tempest-plugin
- - opendev.org/openstack/neutron-vpnaas
- - opendev.org/x/nova-lxd
- - opendev.org/x/novajoin-tempest-plugin
- - opendev.org/openstack/octavia-tempest-plugin
- - opendev.org/openstack/oswin-tempest-plugin
- - opendev.org/openstack/panko
- - opendev.org/openstack/patrole
- - opendev.org/openstack/python-watcherclient
- - opendev.org/openstack/qinling
- - opendev.org/openstack/requirements
- - opendev.org/openstack/sahara-tests
- - opendev.org/openstack/senlin
- - opendev.org/openstack/senlin-tempest-plugin
- - opendev.org/openstack/solum-tempest-plugin
- - opendev.org/x/tap-as-a-service
- - opendev.org/openstack/telemetry-tempest-plugin
- - opendev.org/openstack/tempest-horizon
- - opendev.org/x/tobiko
- - opendev.org/x/trio2o
- - opendev.org/openstack/tripleo-common-tempest-plugin
- - opendev.org/openstack/trove-tempest-plugin
- - opendev.org/x/valet
- - opendev.org/openstack/vitrage-tempest-plugin
- - opendev.org/x/vmware-nsx-tempest-plugin
- - opendev.org/openstack/watcher-tempest-plugin
- - opendev.org/openstack/zaqar-tempest-plugin
- - opendev.org/openstack/zun-tempest-plugin
- job:
name: tempest-cinder-v2-api
@@ -481,6 +499,85 @@
ENABLE_FILE_INJECTION: true
DATABASE_TYPE: postgresql
+- project-template:
+ name: integrated-gate-networking
+ description: |
+ Run the python3 Tempest network integration tests (Nova and Neutron related)
+ in check and gate for the neutron integrated gate. This is meant to be
+ run on neutron gate only.
+ check:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-networking
+ gate:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-networking
+
+- project-template:
+ name: integrated-gate-compute
+ description: |
+ Run the python3 Tempest compute integration tests
+ (Nova, Neutron, Cinder and Glance related) in check and gate
+ for the Nova integrated gate. This is meant to be
+ run on Nova gate only.
+ check:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-compute
+ gate:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-compute
+
+- project-template:
+ name: integrated-gate-placement
+ description: |
+ Run the python3 Tempest placement integration tests
+ (Nova and Neutron related) in check and gate
+ for the Placement integrated gate. This is meant to be
+ run on Placement gate only.
+ check:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-placement
+ gate:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-placement
+
+- project-template:
+ name: integrated-gate-storage
+ description: |
+ Run the python3 Tempest image & block storage integration tests
+ (Cinder, Glance, Swift and Nova related) in check and gate
+ for the neutron integrated gate. This is meant to be
+ run on Cinder and Glance gate only.
+ check:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-storage
+ gate:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-storage
+
+- project-template:
+ name: integrated-gate-object-storage
+ description: |
+ Run the python3 Tempest object storage integration tests
+ (Swift, Cinder and Glance related) in check and gate
+ for the swift integrated gate. This is meant to be
+ run on swift gate only.
+ check:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-object-storage
+ gate:
+ jobs:
+ - grenade-py3
+ - tempest-integrated-object-storage
+
- project:
templates:
- check-requirements
@@ -489,8 +586,7 @@
- openstack-cover-jobs
- openstack-python-jobs
- openstack-python35-jobs
- - openstack-python36-jobs
- - openstack-python37-jobs
+ - openstack-python3-train-jobs
- publish-openstack-docs-pti
- release-notes-jobs-python3
check:
@@ -517,6 +613,10 @@
- ^tempest/hacking/.*$
- ^tempest/tests/.*$
- ^tools/.*$
+ - ^.coveragerc$
+ - ^.gitignore$
+ - ^.gitreview$
+ - ^.mailmap$
- tempest-full-py3:
irrelevant-files: *tempest-irrelevant-files
- tempest-full-py3-ipv6:
@@ -534,14 +634,12 @@
irrelevant-files: *tempest-irrelevant-files
- tempest-full-queens-py3:
irrelevant-files: *tempest-irrelevant-files
- - tempest-full-pike:
- irrelevant-files: *tempest-irrelevant-files
- tempest-multinode-full:
irrelevant-files: *tempest-irrelevant-files
- tempest-multinode-full-py3:
irrelevant-files: *tempest-irrelevant-files
- tempest-tox-plugin-sanity-check:
- irrelevant-files:
+ irrelevant-files: &tempest-irrelevant-files-2
- ^.*\.rst$
- ^doc/.*$
- ^etc/.*$
@@ -549,7 +647,13 @@
- ^setup.cfg$
- ^tempest/hacking/.*$
- ^tempest/tests/.*$
+ - ^.coveragerc$
+ - ^.gitignore$
+ - ^.gitreview$
+ - ^.mailmap$
# tools/ is not here since this relies on a script in tools/.
+ - tempest-ipv6-only:
+ irrelevant-files: *tempest-irrelevant-files-2
- tempest-slow:
irrelevant-files: *tempest-irrelevant-files
- tempest-slow-py3:
@@ -590,6 +694,7 @@
- tempest-full-test-account-no-admin-py3:
voting: false
irrelevant-files: *tempest-irrelevant-files
+ - openstack-tox-bashate
gate:
jobs:
- tempest-slow-py3:
@@ -602,6 +707,8 @@
irrelevant-files: *tempest-irrelevant-files
- grenade-py3:
irrelevant-files: *tempest-irrelevant-files
+ - tempest-ipv6-only:
+ irrelevant-files: *tempest-irrelevant-files-2
experimental:
jobs:
- tempest-cinder-v2-api:
@@ -612,8 +719,6 @@
irrelevant-files: *tempest-irrelevant-files
- neutron-tempest-dvr-ha-multinode-full:
irrelevant-files: *tempest-irrelevant-files
- - nova-cells-v1:
- irrelevant-files: *tempest-irrelevant-files
- nova-tempest-v2-api:
irrelevant-files: *tempest-irrelevant-files
- legacy-tempest-dsvm-lvm-multibackend:
@@ -632,8 +737,6 @@
- tempest-full-rocky-py3
- tempest-full-queens
- tempest-full-queens-py3
- - tempest-full-pike
- - legacy-periodic-tempest-dsvm-neutron-full-ocata
periodic:
jobs:
- tempest-all
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
new file mode 100644
index 0000000..a89ad94
--- /dev/null
+++ b/CONTRIBUTING.rst
@@ -0,0 +1,17 @@
+If you would like to contribute to the development of OpenStack, you must
+follow the steps in this page:
+
+ https://docs.openstack.org/infra/manual/developers.html
+
+If you already have a good understanding of how the system works and your
+OpenStack accounts are set up, you can skip to the development workflow
+section of this documentation to learn how changes to OpenStack should be
+submitted for review via the Gerrit tool:
+
+ https://docs.openstack.org/infra/manual/developers.html#development-workflow
+
+Pull requests submitted through GitHub will be ignored.
+
+Bugs should be filed on Launchpad, not GitHub:
+
+ https://bugs.launchpad.net/tempest
diff --git a/HACKING.rst b/HACKING.rst
index 1559fc6..204b3c7 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -457,7 +457,7 @@
by modifying Tempest's `lib installation script`_ for previous branches
(because DevStack is branched).
-.. _lib installation script: https://git.openstack.org/cgit/openstack-dev/devstack/tree/lib/tempest
+.. _lib installation script: https://opendev.org/openstack/devstack/src/branch/master/lib/tempest
2. Bug fix on core project needing Tempest changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/README.rst b/README.rst
index 73930f1..3cde2bf 100644
--- a/README.rst
+++ b/README.rst
@@ -10,274 +10,15 @@
Tempest - The OpenStack Integration Test Suite
==============================================
-The documentation for Tempest is officially hosted at:
-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,
scenarios, and other specific tests useful in validating an OpenStack
deployment.
-Design Principles
------------------
-Tempest Design Principles that we strive to live by.
+ * Documentation: https://docs.openstack.org/tempest/latest/
+ * Features: https://specs.openstack.org/openstack/qa-specs/#tempest
+ * Bugs: https://bugs.launchpad.net/tempest/
+ * Release Notes: https://docs.openstack.org/releasenotes/tempest
-- Tempest should be able to run against any OpenStack cloud, be it a
- one node DevStack install, a 20 node LXC cloud, or a 1000 node KVM
- cloud.
-- Tempest should be explicit in testing features. It is easy to auto
- discover features of a cloud incorrectly, and give people an
- incorrect assessment of their cloud. Explicit is always better.
-- Tempest uses OpenStack public interfaces. Tests in Tempest should
- only touch public OpenStack APIs.
-- Tempest should not touch private or implementation specific
- interfaces. This means not directly going to the database, not
- directly hitting the hypervisors, not testing extensions not
- included in the OpenStack base. If there are some features of
- OpenStack that are not verifiable through standard interfaces, this
- should be considered a possible enhancement.
-- Tempest strives for complete coverage of the OpenStack API and
- common scenarios that demonstrate a working cloud.
-- Tempest drives load in an OpenStack cloud. By including a broad
- array of API and scenario tests Tempest can be reused in whole or in
- parts as load generation for an OpenStack cloud.
-- Tempest should attempt to clean up after itself, whenever possible
- we should tear down resources when done.
-- Tempest should be self-testing.
-
-Quickstart
-----------
-
-To run Tempest, you first need to create a configuration file that will tell
-Tempest where to find the various OpenStack services and other testing behavior
-switches. Where the configuration file lives and how you interact with it
-depends on how you'll be running Tempest. There are 2 methods of using Tempest.
-The first, which is a newer and recommended workflow treats Tempest as a system
-installed program. The second older method is to run Tempest assuming your
-working dir is the actually Tempest source repo, and there are a number of
-assumptions related to that. For this section we'll only cover the newer method
-as it is simpler, and quicker to work with.
-
-#. You first need to install Tempest. This is done with pip after you check out
- the Tempest repo::
-
- $ git clone https://git.openstack.org/openstack/tempest
- $ pip install tempest/
-
- This can be done within a venv, but the assumption for this guide is that
- the Tempest CLI entry point will be in your shell's PATH.
-
-#. Installing Tempest may create a ``/etc/tempest dir``, however if one isn't
- created you can create one or use ``~/.tempest/etc`` or ``~/.config/tempest`` in
- place of ``/etc/tempest``. If none of these dirs are created Tempest will create
- ``~/.tempest/etc`` when it's needed. The contents of this dir will always
- automatically be copied to all ``etc/`` dirs in local workspaces as an initial
- setup step. So if there is any common configuration you'd like to be shared
- between local Tempest workspaces it's recommended that you pre-populate it
- before running ``tempest init``.
-
-#. Setup a local Tempest workspace. This is done by using the tempest init
- command::
-
- $ tempest init cloud-01
-
- which also works the same as::
-
- $ mkdir cloud-01 && cd cloud-01 && tempest init
-
- This will create a new directory for running a single Tempest configuration.
- If you'd like to run Tempest against multiple OpenStack deployments the idea
- is that you'll create a new working directory for each to maintain separate
- configuration files and local artifact storage for each.
-
-#. Then ``cd`` into the newly created working dir and also modify the local
- config files located in the ``etc/`` subdir created by the ``tempest init``
- command. Tempest is expecting a ``tempest.conf`` file in etc/ so if only a
- sample exists you must rename or copy it to tempest.conf before making
- any changes to it otherwise Tempest will not know how to load it. For
- details on configuring Tempest refer to the
- `Tempest Configuration <https://docs.openstack.org/tempest/latest/configuration.html#tempest-configuration>`_
-
-#. Once the configuration is done you're now ready to run Tempest. This can
- be done using the `Tempest Run <https://docs.openstack.org/tempest/latest/run.html#tempest-run>`_
- command. This can be done by either
- running::
-
- $ tempest run
-
- from the Tempest workspace directory. Or you can use the ``--workspace``
- argument to run in the workspace you created regardless of your current
- working directory. For example::
-
- $ tempest run --workspace cloud-01
-
- There is also the option to use `stestr`_ directly. For example, from
- the workspace dir run::
-
- $ stestr run --black-regex '\[.*\bslow\b.*\]' '^tempest\.(api|scenario)'
-
- will run the same set of tests as the default gate jobs. Or you can
- use `unittest`_ compatible test runners such as `testr`_, `pytest`_ etc.
-
-.. _unittest: https://docs.python.org/3/library/unittest.html
-.. _testr: https://testrepository.readthedocs.org/en/latest/MANUAL.html
-.. _stestr: https://stestr.readthedocs.org/en/latest/MANUAL.html
-.. _pytest: https://docs.pytest.org/en/latest/
-
-Library
--------
-Tempest exposes a library interface. This interface is a stable interface and
-should be backwards compatible (including backwards compatibility with the
-old tempest-lib package, with the exception of the import). If you plan to
-directly consume Tempest in your project you should only import code from the
-Tempest library interface, other pieces of Tempest do not have the same
-stable interface and there are no guarantees on the Python API unless otherwise
-stated.
-
-For more details refer to the `library documentation
-<https://docs.openstack.org/tempest/latest/library.html#library>`_
-
-Release Versioning
-------------------
-`Tempest Release Notes <https://docs.openstack.org/releasenotes/tempest>`_
-shows what changes have been released on each version.
-
-Tempest's released versions are broken into 2 sets of information. Depending on
-how you intend to consume Tempest you might need
-
-The version is a set of 3 numbers:
-
-X.Y.Z
-
-While this is almost `semver`_ like, the way versioning is handled is slightly
-different:
-
-X is used to represent the supported OpenStack releases for Tempest tests
-in-tree, and to signify major feature changes to Tempest. It's a monotonically
-increasing integer where each version either indicates a new supported OpenStack
-release, the drop of support for an OpenStack release (which will coincide with
-the upstream stable branch going EOL), or a major feature lands (or is removed)
-from Tempest.
-
-Y.Z is used to represent library interface changes. This is treated the same
-way as minor and patch versions from `semver`_ but only for the library
-interface. When Y is incremented we've added functionality to the library
-interface and when Z is incremented it's a bug fix release for the library.
-Also note that both Y and Z are reset to 0 at each increment of X.
-
-.. _semver: https://semver.org/
-
-Configuration
--------------
-
-Detailed configuration of Tempest is beyond the scope of this
-document, see `Tempest Configuration Documentation
-<https://docs.openstack.org/tempest/latest/configuration.html#tempest-configuration>`_
-for more details on configuring Tempest.
-The ``etc/tempest.conf.sample`` attempts to be a self-documenting
-version of the configuration.
-
-You can generate a new sample tempest.conf file, run the following
-command from the top level of the Tempest directory::
-
- $ tox -e genconfig
-
-The most important pieces that are needed are the user ids, OpenStack
-endpoints, and basic flavors and images needed to run tests.
-
-Unit Tests
-----------
-
-Tempest also has a set of unit tests which test the Tempest code itself. These
-tests can be run by specifying the test discovery path::
-
- $ stestr --test-path ./tempest/tests run
-
-By setting ``--test-path`` option to ./tempest/tests it specifies that test discover
-should only be run on the unit test directory. The default value of ``test_path``
-is ``test_path=./tempest/test_discover`` which will only run test discover on the
-Tempest suite.
-
-Alternatively, there are the py27 and py36 tox jobs which will run the unit
-tests with the corresponding version of python.
-
-One common activity is to just run a single test, you can do this with tox
-simply by specifying to just run py27 or py36 tests against a single test::
-
- $ tox -e py36 -- -n tempest.tests.test_microversions.TestMicroversionsTestsClass.test_config_version_none_23
-
-Or all tests in the test_microversions.py file::
-
- $ tox -e py36 -- -n tempest.tests.test_microversions
-
-You may also use regular expressions to run any matching tests::
-
- $ tox -e py36 -- test_microversions
-
-Additionally, when running a single test, or test-file, the ``-n/--no-discover``
-argument is no longer required, however it may perform faster if included.
-
-For more information on these options and details about stestr, please see the
-`stestr documentation <https://stestr.readthedocs.io/en/latest/MANUAL.html>`_.
-
-Python 3.x
-----------
-
-Starting during the Pike cycle Tempest has a gating CI job that runs Tempest
-with Python 3. Any Tempest release after 15.0.0 should fully support running
-under Python 3 as well as Python 2.7.
-
-Legacy run method
------------------
-
-The legacy method of running Tempest is to just treat the Tempest source code
-as a python unittest repository and run directly from the source repo. When
-running in this way you still start with a Tempest config file and the steps
-are basically the same except that it expects you know where the Tempest code
-lives on your system and requires a bit more manual interaction to get Tempest
-running. For example, when running Tempest this way things like a lock file
-directory do not get generated automatically and the burden is on the user to
-create and configure that.
-
-To start you need to create a configuration file. The easiest way to create a
-configuration file is to generate a sample in the ``etc/`` directory ::
-
- $ cd $TEMPEST_ROOT_DIR
- $ oslo-config-generator --config-file \
- tempest/cmd/config-generator.tempest.conf \
- --output-file etc/tempest.conf
-
-After that, open up the ``etc/tempest.conf`` file and edit the
-configuration variables to match valid data in your environment.
-This includes your Keystone endpoint, a valid user and credentials,
-and reference data to be used in testing.
-
-.. note::
-
- If you have a running DevStack environment, Tempest will be
- automatically configured and placed in ``/opt/stack/tempest``. It
- will have a configuration file already set up to work with your
- DevStack installation.
-
-Tempest is not tied to any single test runner, but `testr`_ is the most commonly
-used tool. Also, the nosetests test runner is **not** recommended to run Tempest.
-
-After setting up your configuration file, you can execute the set of Tempest
-tests by using ``testr`` ::
-
- $ testr run --parallel
-
-To run one single test serially ::
-
- $ testr run tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server
-
-Tox also contains several existing job configurations. For example::
-
- $ tox -e full
-
-which will run the same set of tests as the OpenStack gate. (it's exactly how
-the gate invokes Tempest) Or::
-
- $ tox -e smoke
-
-to run the tests tagged as smoke.
+Get in touch via `email <mailto:openstack-discuss@lists.openstack.org>`_. Use
+[tempest] in your subject.
diff --git a/REVIEWING.rst b/REVIEWING.rst
index 87847ae..e07e358 100644
--- a/REVIEWING.rst
+++ b/REVIEWING.rst
@@ -190,4 +190,4 @@
Note that such a policy should be used judiciously, as we should strive to
have two +2's on each patch set, prior to approval.
-.. _example: https://review.openstack.org/#/c/611032/
+.. _example: https://review.opendev.org/#/c/611032/
diff --git a/doc/requirements.txt b/doc/requirements.txt
index d959d44..2194dc4 100644
--- a/doc/requirements.txt
+++ b/doc/requirements.txt
@@ -1,6 +1,8 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-openstackdocstheme>=1.18.1 # Apache-2.0
+openstackdocstheme>=1.20.0 # Apache-2.0
reno>=2.5.0 # Apache-2.0
-sphinx!=1.6.6,!=1.6.7,>=1.6.2 # BSD
+sphinx!=1.6.6,!=1.6.7,>=1.6.2,<2.0.0;python_version=='2.7' # BSD
+sphinx!=1.6.6,!=1.6.7,!=2.1.0,>=1.6.2;python_version>='3.4' # BSD
+sphinxcontrib-svg2pdfconverter>=0.1.0 # BSD
diff --git a/doc/source/conf.py b/doc/source/conf.py
index c2ea628..7ce431e 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -52,6 +52,7 @@
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.viewcode',
+ 'sphinxcontrib.rsvgconverter',
'openstackdocstheme',
'oslo_config.sphinxconfiggen',
]
@@ -66,9 +67,6 @@
bug_project = 'tempest'
bug_tag = 'doc'
-# Must set this variable to include year, month, day, hours, and minutes.
-html_last_updated_fmt = '%Y-%m-%d %H:%M'
-
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -82,7 +80,6 @@
master_doc = 'index'
# General information about the project.
-project = u'Tempest'
copyright = u'2013, OpenStack QA Team'
# The language for content autogenerated by Sphinx. Refer to documentation
@@ -196,3 +193,16 @@
# A list of warning types to suppress arbitrary warning messages.
suppress_warnings = ['image.nonlocal_uri']
+
+# -- Options for LaTeX output -------------------------------------------------
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass
+# [howto/manual]).
+latex_documents = [
+ ('index', 'doc-tempest.tex', u'Tempest Testing Project',
+ u'OpenStack Foundation', 'manual'),
+]
+
+# Disable usage of xindy https://bugzilla.redhat.com/show_bug.cgi?id=1643664
+latex_use_xindy = False
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 2e5f706..36828e0 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -108,12 +108,12 @@
insufficient for certain use cases because of the admin credentials requirement
to create the credential sets on demand. To get around that the accounts.yaml
file was introduced and with that a new internal credential provider to enable
-using the list of credentials instead of creating them on demand. With locking
-test accounts each test class will reserve a set of credentials from the
-accounts.yaml before executing any of its tests so that each class is isolated
-like with dynamic credentials.
+using the list of credentials instead of creating them on demand. With
+pre-provisioned credentials (also known as locking test accounts) each test
+class will reserve a set of credentials from the accounts.yaml before executing
+any of its tests so that each class is isolated like with dynamic credentials.
-To enable and use locking test accounts you need do a few things:
+To enable and use pre-provisioned credentials you need do a few things:
#. Create an accounts.yaml file which contains the set of pre-existing
credentials to use for testing. To make sure you don't have a credentials
diff --git a/doc/source/data/tempest-blacklisted-plugins-registry.header b/doc/source/data/tempest-blacklisted-plugins-registry.header
new file mode 100644
index 0000000..6b6af11
--- /dev/null
+++ b/doc/source/data/tempest-blacklisted-plugins-registry.header
@@ -0,0 +1,7 @@
+Blacklisted Plugins
+===================
+
+List of Tempest plugin projects that are stale or unmaintained for a long
+time (6 months or more). They can be moved out of blacklist state once one
+of the relevant patches gets merged:
+https://review.opendev.org/#/q/topic:tempest-sanity-gate+%28status:open%29
diff --git a/doc/source/index.rst b/doc/source/index.rst
index fecf98a..7acfd62 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -88,7 +88,12 @@
stable_branch_support_policy
-Indices and tables
-==================
+Search
+======
-* :ref:`search`
+.. only:: html
+
+ * :ref:`Tempest document search <search>`: Search the contents of this document.
+
+* `OpenStack wide search <https://docs.openstack.org>`_: Search the wider
+ set of OpenStack documentation, including forums.
\ No newline at end of file
diff --git a/doc/source/microversion_testing.rst b/doc/source/microversion_testing.rst
index 4b1c145..b4f06e3 100644
--- a/doc/source/microversion_testing.rst
+++ b/doc/source/microversion_testing.rst
@@ -406,6 +406,14 @@
.. _2.63: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id57
+ * `2.70`_
+
+ .. _2.70: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id63
+
+ * `2.71`_
+
+ .. _2.71: https://docs.openstack.org/nova/latest/reference/api-microversion-history.html#id64
+
* Volume
* `3.3`_
diff --git a/doc/source/overview.rst b/doc/source/overview.rst
deleted file mode 120000
index c768ff7..0000000
--- a/doc/source/overview.rst
+++ /dev/null
@@ -1 +0,0 @@
-../../README.rst
\ No newline at end of file
diff --git a/doc/source/overview.rst b/doc/source/overview.rst
new file mode 100644
index 0000000..423214d
--- /dev/null
+++ b/doc/source/overview.rst
@@ -0,0 +1,282 @@
+Tempest - The OpenStack Integration Test Suite
+==============================================
+
+The documentation for Tempest is officially hosted at:
+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,
+scenarios, and other specific tests useful in validating an OpenStack
+deployment.
+
+Team and repository tags
+------------------------
+
+.. image:: https://governance.openstack.org/tc/badges/tempest.svg
+ :target: https://governance.openstack.org/tc/reference/tags/index.html
+
+.. Change things from this point on
+
+Design Principles
+-----------------
+Tempest Design Principles that we strive to live by.
+
+- Tempest should be able to run against any OpenStack cloud, be it a
+ one node DevStack install, a 20 node LXC cloud, or a 1000 node KVM
+ cloud.
+- Tempest should be explicit in testing features. It is easy to auto
+ discover features of a cloud incorrectly, and give people an
+ incorrect assessment of their cloud. Explicit is always better.
+- Tempest uses OpenStack public interfaces. Tests in Tempest should
+ only touch public OpenStack APIs.
+- Tempest should not touch private or implementation specific
+ interfaces. This means not directly going to the database, not
+ directly hitting the hypervisors, not testing extensions not
+ included in the OpenStack base. If there are some features of
+ OpenStack that are not verifiable through standard interfaces, this
+ should be considered a possible enhancement.
+- Tempest strives for complete coverage of the OpenStack API and
+ common scenarios that demonstrate a working cloud.
+- Tempest drives load in an OpenStack cloud. By including a broad
+ array of API and scenario tests Tempest can be reused in whole or in
+ parts as load generation for an OpenStack cloud.
+- Tempest should attempt to clean up after itself, whenever possible
+ we should tear down resources when done.
+- Tempest should be self-testing.
+
+Quickstart
+----------
+
+To run Tempest, you first need to create a configuration file that will tell
+Tempest where to find the various OpenStack services and other testing behavior
+switches. Where the configuration file lives and how you interact with it
+depends on how you'll be running Tempest. There are 2 methods of using Tempest.
+The first, which is a newer and recommended workflow treats Tempest as a system
+installed program. The second older method is to run Tempest assuming your
+working dir is the actually Tempest source repo, and there are a number of
+assumptions related to that. For this section we'll only cover the newer method
+as it is simpler, and quicker to work with.
+
+#. You first need to install Tempest. This is done with pip after you check out
+ the Tempest repo::
+
+ $ git clone https://opendev.org/openstack/tempest
+ $ pip install tempest/
+
+ This can be done within a venv, but the assumption for this guide is that
+ the Tempest CLI entry point will be in your shell's PATH.
+
+#. Installing Tempest may create a ``/etc/tempest dir``, however if one isn't
+ created you can create one or use ``~/.tempest/etc`` or ``~/.config/tempest`` in
+ place of ``/etc/tempest``. If none of these dirs are created Tempest will create
+ ``~/.tempest/etc`` when it's needed. The contents of this dir will always
+ automatically be copied to all ``etc/`` dirs in local workspaces as an initial
+ setup step. So if there is any common configuration you'd like to be shared
+ between local Tempest workspaces it's recommended that you pre-populate it
+ before running ``tempest init``.
+
+#. Setup a local Tempest workspace. This is done by using the tempest init
+ command::
+
+ $ tempest init cloud-01
+
+ which also works the same as::
+
+ $ mkdir cloud-01 && cd cloud-01 && tempest init
+
+ This will create a new directory for running a single Tempest configuration.
+ If you'd like to run Tempest against multiple OpenStack deployments the idea
+ is that you'll create a new working directory for each to maintain separate
+ configuration files and local artifact storage for each.
+
+#. Then ``cd`` into the newly created working dir and also modify the local
+ config files located in the ``etc/`` subdir created by the ``tempest init``
+ command. Tempest is expecting a ``tempest.conf`` file in etc/ so if only a
+ sample exists you must rename or copy it to tempest.conf before making
+ any changes to it otherwise Tempest will not know how to load it. For
+ details on configuring Tempest refer to the
+ `Tempest Configuration <https://docs.openstack.org/tempest/latest/configuration.html#tempest-configuration>`_
+
+#. Once the configuration is done you're now ready to run Tempest. This can
+ be done using the `Tempest Run <https://docs.openstack.org/tempest/latest/run.html#tempest-run>`_
+ command. This can be done by either
+ running::
+
+ $ tempest run
+
+ from the Tempest workspace directory. Or you can use the ``--workspace``
+ argument to run in the workspace you created regardless of your current
+ working directory. For example::
+
+ $ tempest run --workspace cloud-01
+
+ There is also the option to use `stestr`_ directly. For example, from
+ the workspace dir run::
+
+ $ stestr run --black-regex '\[.*\bslow\b.*\]' '^tempest\.(api|scenario)'
+
+ will run the same set of tests as the default gate jobs. Or you can
+ use `unittest`_ compatible test runners such as `testr`_, `pytest`_ etc.
+
+ Tox also contains several existing job configurations. For example::
+
+ $ tox -e full
+
+ which will run the same set of tests as the OpenStack gate. (it's exactly how
+ the gate invokes Tempest) Or::
+
+ $ tox -e smoke
+
+ to run the tests tagged as smoke.
+
+.. _unittest: https://docs.python.org/3/library/unittest.html
+.. _testr: https://testrepository.readthedocs.org/en/latest/MANUAL.html
+.. _stestr: https://stestr.readthedocs.org/en/latest/MANUAL.html
+.. _pytest: https://docs.pytest.org/en/latest/
+
+Library
+-------
+Tempest exposes a library interface. This interface is a stable interface and
+should be backwards compatible (including backwards compatibility with the
+old tempest-lib package, with the exception of the import). If you plan to
+directly consume Tempest in your project you should only import code from the
+Tempest library interface, other pieces of Tempest do not have the same
+stable interface and there are no guarantees on the Python API unless otherwise
+stated.
+
+For more details refer to the `library documentation
+<https://docs.openstack.org/tempest/latest/library.html#library>`_
+
+Release Versioning
+------------------
+`Tempest Release Notes <https://docs.openstack.org/releasenotes/tempest>`_
+shows what changes have been released on each version.
+
+Tempest's released versions are broken into 2 sets of information. Depending on
+how you intend to consume Tempest you might need
+
+The version is a set of 3 numbers:
+
+X.Y.Z
+
+While this is almost `semver`_ like, the way versioning is handled is slightly
+different:
+
+X is used to represent the supported OpenStack releases for Tempest tests
+in-tree, and to signify major feature changes to Tempest. It's a monotonically
+increasing integer where each version either indicates a new supported OpenStack
+release, the drop of support for an OpenStack release (which will coincide with
+the upstream stable branch going EOL), or a major feature lands (or is removed)
+from Tempest.
+
+Y.Z is used to represent library interface changes. This is treated the same
+way as minor and patch versions from `semver`_ but only for the library
+interface. When Y is incremented we've added functionality to the library
+interface and when Z is incremented it's a bug fix release for the library.
+Also note that both Y and Z are reset to 0 at each increment of X.
+
+.. _semver: https://semver.org/
+
+Configuration
+-------------
+
+Detailed configuration of Tempest is beyond the scope of this
+document, see `Tempest Configuration Documentation
+<https://docs.openstack.org/tempest/latest/configuration.html#tempest-configuration>`_
+for more details on configuring Tempest.
+The ``etc/tempest.conf.sample`` attempts to be a self-documenting
+version of the configuration.
+
+You can generate a new sample tempest.conf file, run the following
+command from the top level of the Tempest directory::
+
+ $ tox -e genconfig
+
+The most important pieces that are needed are the user ids, OpenStack
+endpoints, and basic flavors and images needed to run tests.
+
+Unit Tests
+----------
+
+Tempest also has a set of unit tests which test the Tempest code itself. These
+tests can be run by specifying the test discovery path::
+
+ $ stestr --test-path ./tempest/tests run
+
+By setting ``--test-path`` option to ./tempest/tests it specifies that test discover
+should only be run on the unit test directory. The default value of ``test_path``
+is ``test_path=./tempest/test_discover`` which will only run test discover on the
+Tempest suite.
+
+Alternatively, there are the py27 and py36 tox jobs which will run the unit
+tests with the corresponding version of python.
+
+One common activity is to just run a single test, you can do this with tox
+simply by specifying to just run py27 or py36 tests against a single test::
+
+ $ tox -e py36 -- -n tempest.tests.test_microversions.TestMicroversionsTestsClass.test_config_version_none_23
+
+Or all tests in the test_microversions.py file::
+
+ $ tox -e py36 -- -n tempest.tests.test_microversions
+
+You may also use regular expressions to run any matching tests::
+
+ $ tox -e py36 -- test_microversions
+
+Additionally, when running a single test, or test-file, the ``-n/--no-discover``
+argument is no longer required, however it may perform faster if included.
+
+For more information on these options and details about stestr, please see the
+`stestr documentation <https://stestr.readthedocs.io/en/latest/MANUAL.html>`_.
+
+Python 3.x
+----------
+
+Starting during the Pike cycle Tempest has a gating CI job that runs Tempest
+with Python 3. Any Tempest release after 15.0.0 should fully support running
+under Python 3 as well as Python 2.7.
+
+Legacy run method
+-----------------
+
+The legacy method of running Tempest is to just treat the Tempest source code
+as a python unittest repository and run directly from the source repo. When
+running in this way you still start with a Tempest config file and the steps
+are basically the same except that it expects you know where the Tempest code
+lives on your system and requires a bit more manual interaction to get Tempest
+running. For example, when running Tempest this way things like a lock file
+directory do not get generated automatically and the burden is on the user to
+create and configure that.
+
+To start you need to create a configuration file. The easiest way to create a
+configuration file is to generate a sample in the ``etc/`` directory ::
+
+ $ cd $TEMPEST_ROOT_DIR
+ $ oslo-config-generator --config-file \
+ tempest/cmd/config-generator.tempest.conf \
+ --output-file etc/tempest.conf
+
+After that, open up the ``etc/tempest.conf`` file and edit the
+configuration variables to match valid data in your environment.
+This includes your Keystone endpoint, a valid user and credentials,
+and reference data to be used in testing.
+
+.. note::
+
+ If you have a running DevStack environment, Tempest will be
+ automatically configured and placed in ``/opt/stack/tempest``. It
+ will have a configuration file already set up to work with your
+ DevStack installation.
+
+Tempest is not tied to any single test runner, but `testr`_ is the most commonly
+used tool. Also, the nosetests test runner is **not** recommended to run Tempest.
+
+After setting up your configuration file, you can execute the set of Tempest
+tests by using ``testr`` ::
+
+ $ testr run --parallel
+
+To run one single test serially ::
+
+ $ testr run tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server
diff --git a/doc/source/plugin.rst b/doc/source/plugin.rst
index dc0e94c..a9e2059 100644
--- a/doc/source/plugin.rst
+++ b/doc/source/plugin.rst
@@ -43,7 +43,7 @@
In order to create the basic structure with base classes and test directories
you can use the tempest-plugin-cookiecutter project::
- > pip install -U cookiecutter && cookiecutter https://git.openstack.org/openstack/tempest-plugin-cookiecutter
+ > pip install -U cookiecutter && cookiecutter https://opendev.org/openstack/tempest-plugin-cookiecutter
Cloning into 'tempest-plugin-cookiecutter'...
remote: Counting objects: 17, done.
diff --git a/playbooks/devstack-tempest-ipv6.yaml b/playbooks/devstack-tempest-ipv6.yaml
new file mode 100644
index 0000000..5f72345
--- /dev/null
+++ b/playbooks/devstack-tempest-ipv6.yaml
@@ -0,0 +1,24 @@
+# Changes that run through devstack-tempest-ipv6 are likely to have an impact on
+# the devstack part of the job, so we keep devstack in the main play to
+# avoid zuul retrying on legitimate failures.
+- hosts: all
+ roles:
+ - orchestrate-devstack
+
+# We run tests only on one node, regardless how many nodes are in the system
+- hosts: tempest
+ environment:
+ # This enviroment variable is used by the optional tempest-gabbi
+ # job provided by the gabbi-tempest plugin. It can be safely ignored
+ # if that plugin is not being used.
+ GABBI_TEMPEST_PATH: "{{ gabbi_tempest_path | default('') }}"
+ roles:
+ - setup-tempest-run-dir
+ - setup-tempest-data-dir
+ - acl-devstack-files
+ # Verify the IPv6-only deployments. This role will perform check for
+ # IPv6 only env for example Devstack IPv6 settings and services listen
+ # address is IPv6 etc. This is invoked before tests are run so that we can
+ # fail early if anything missing the IPv6 settings or deployments.
+ - ipv6-only-deployments-verification
+ - run-tempest
diff --git a/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml b/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
index 092014e..8787e0c 100644
--- a/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
+++ b/releasenotes/notes/12/12.1.0-add_subunit_describe_calls-5498a37e6cd66c4b.yaml
@@ -4,5 +4,5 @@
Adds subunit-describe-calls. A parser for subunit streams to determine what
REST API calls are made inside of a test and in what order they are called.
- * Input can be piped in or a file can be specified
- * Output is shortened for stdout, the output file has more information
+ * Input can be piped in or a file can be specified
+ * Output is shortened for stdout, the output file has more information
diff --git a/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml b/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
index f9173a0..b857db8 100644
--- a/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
+++ b/releasenotes/notes/12/12.1.0-identity-clients-as-library-e663c6132fcac6c2.yaml
@@ -6,8 +6,8 @@
so the other projects can use these modules as stable libraries without
any maintenance changes.
- * endpoints_client(v2)
- * roles_client(v2)
- * services_client(v2)
- * tenants_client(v2)
- * users_client(v2)
+ * endpoints_client(v2)
+ * roles_client(v2)
+ * services_client(v2)
+ * tenants_client(v2)
+ * users_client(v2)
diff --git a/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml b/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
index 1fa4ddd..492aac8 100644
--- a/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
+++ b/releasenotes/notes/12/12.1.0-image-clients-as-library-86d17caa26ce3961.yaml
@@ -6,10 +6,10 @@
so the other projects can use these modules as stable libraries
without any maintenance changes.
- * image_members_client(v1)
- * images_client(v1)
- * image_members_client(v2)
- * images_client(v2)
- * namespaces_client(v2)
- * resource_types_client(v2)
- * schemas_client(v2)
+ * image_members_client(v1)
+ * images_client(v1)
+ * image_members_client(v2)
+ * images_client(v2)
+ * namespaces_client(v2)
+ * resource_types_client(v2)
+ * schemas_client(v2)
diff --git a/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml b/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
index 3ec8b56..6e08743 100644
--- a/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
+++ b/releasenotes/notes/12/12.2.0-add-new-identity-clients-3c3afd674a395bde.yaml
@@ -6,8 +6,8 @@
so the other projects can use these modules as stable libraries without
any maintenance changes.
- * endpoints_client(v3)
- * policies_client (v3)
- * regions_client(v3)
- * services_client(v3)
- * projects_client(v3)
+ * endpoints_client(v3)
+ * policies_client (v3)
+ * regions_client(v3)
+ * services_client(v3)
+ * projects_client(v3)
diff --git a/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml b/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
index cf504ad..32cd182 100644
--- a/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
+++ b/releasenotes/notes/12/12.2.0-volume-clients-as-library-9a3444dd63c134b3.yaml
@@ -6,13 +6,13 @@
so the other projects can use these modules as stable libraries
without any maintenance changes.
- * availability_zone_client(v1)
- * availability_zone_client(v2)
- * extensions_client(v1)
- * extensions_client(v2)
- * hosts_client(v1)
- * hosts_client(v2)
- * quotas_client(v1)
- * quotas_client(v2)
- * services_client(v1)
- * services_client(v2)
+ * availability_zone_client(v1)
+ * availability_zone_client(v2)
+ * extensions_client(v1)
+ * extensions_client(v2)
+ * hosts_client(v1)
+ * hosts_client(v2)
+ * quotas_client(v1)
+ * quotas_client(v2)
+ * services_client(v1)
+ * services_client(v2)
diff --git a/releasenotes/notes/13/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 9e828f6..a0de2c3 100644
--- a/releasenotes/notes/13/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
@@ -5,11 +5,11 @@
Add new service clients to the library interface so the other projects can use these modules as stable libraries without
any maintenance changes.
- * identity_client(v2)
- * groups_client(v3)
- * trusts_client(v3)
- * users_client(v3)
- * identity_client(v3)
- * roles_client(v3)
- * inherited_roles_client(v3)
- * credentials_client(v3)
+ * identity_client(v2)
+ * groups_client(v3)
+ * trusts_client(v3)
+ * users_client(v3)
+ * identity_client(v3)
+ * roles_client(v3)
+ * inherited_roles_client(v3)
+ * credentials_client(v3)
diff --git a/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml b/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml
index 7e40fd4..6346156 100644
--- a/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml
+++ b/releasenotes/notes/14/14.0.0-add-image-clients-af94564fb34ddca6.yaml
@@ -5,5 +5,5 @@
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html,
there are some apis are not included, add them.
- * namespace_properties_client(v2)
+ * namespace_properties_client(v2)
diff --git a/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml b/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml
index eaab1f0..a4e5791 100644
--- a/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml
+++ b/releasenotes/notes/15/15.0.0-add-image-clients-tests-49dbc0a0a4281a77.yaml
@@ -5,6 +5,6 @@
http://developer.openstack.org/api-ref/image/v2/metadefs-index.html,
there are some apis are not included, add them.
- * namespace_objects_client(v2)
- * namespace_tags_client(v2)
+ * namespace_objects_client(v2)
+ * namespace_tags_client(v2)
diff --git a/releasenotes/notes/QoS-client-for-placement-based-minimum-bw-allocation-8e5854d5754cec68.yaml b/releasenotes/notes/QoS-client-for-placement-based-minimum-bw-allocation-8e5854d5754cec68.yaml
new file mode 100644
index 0000000..b66ea3a
--- /dev/null
+++ b/releasenotes/notes/QoS-client-for-placement-based-minimum-bw-allocation-8e5854d5754cec68.yaml
@@ -0,0 +1,25 @@
+---
+features:
+ - |
+ Add ``qos-policies`` and ``qos-minimum-bandwidth-rule`` clients
+ to Tempest to make possible the testing of the placement based
+ bandwidth allocation feature.
+ The following API calls are available for tempest from now:
+
+ ``QoS policies`` client:
+
+ * GET /qos/policies
+ * POST /qos/policies
+ * GET /qos/policies/{policy_id}
+ * PUT /qos/policies/{policy_id}
+ * DELETE /qos/policies/{policy_id}
+
+
+ ``QoS minimum bandwidth rules`` client:
+
+ * GET qos/policies/{policy_id}/minimum_bandwidth_rules
+ * POST /qos/policies/{policy_id}/minimum_bandwidth_rules
+ * GET qos/policies/{policy_id}/minimum_bandwidth_rules/{rule_id}
+ * PUT qos/policies/{policy_id}/minimum_bandwidth_rules/{rule_id}
+ * DELETE /qos/policies/{policy_id}/minimum_bandwidth_rules/{rule_id}
+
diff --git a/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml b/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
index 87a6af9..85e5f5f 100644
--- a/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
+++ b/releasenotes/notes/add-domain-param-in-cliclient-a270fcf35c8f09e6.yaml
@@ -3,10 +3,10 @@
- |
Allow to specify new domain parameters:
- * `user_domain_name`
- * `user_domain_id`
- * `project_domain_name`
- * `project_domain_id`
+ * ``user_domain_name``
+ * ``user_domain_id``
+ * ``project_domain_name``
+ * ``project_domain_id``
for CLIClient class, whose values will be substituted to
``--os-user-domain-name``, ``--os-user-domain-id``,
diff --git a/releasenotes/notes/add-show-api-v3-details-api-to-v3-versions-client-4b408427379cabfe.yaml b/releasenotes/notes/add-show-api-v3-details-api-to-v3-versions-client-4b408427379cabfe.yaml
new file mode 100644
index 0000000..50f10fa
--- /dev/null
+++ b/releasenotes/notes/add-show-api-v3-details-api-to-v3-versions-client-4b408427379cabfe.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ Add show api version details function to v3
+ versions_client library for cinder.
+
+ * show_version
\ No newline at end of file
diff --git a/releasenotes/notes/add-show-default-group-type-detail-api-to-v3-group-types-client-65f717878cf52da0.yaml b/releasenotes/notes/add-show-default-group-type-detail-api-to-v3-group-types-client-65f717878cf52da0.yaml
new file mode 100644
index 0000000..1419e66
--- /dev/null
+++ b/releasenotes/notes/add-show-default-group-type-detail-api-to-v3-group-types-client-65f717878cf52da0.yaml
@@ -0,0 +1,6 @@
+---
+features:
+ - |
+ Add show default group type details API to v3 group_types_client library.
+
+ * show_default_group_type
diff --git a/releasenotes/notes/bug-1647999-7aeda50a8d082d4c.yaml b/releasenotes/notes/bug-1647999-7aeda50a8d082d4c.yaml
new file mode 100644
index 0000000..384f916
--- /dev/null
+++ b/releasenotes/notes/bug-1647999-7aeda50a8d082d4c.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - |
+ A new parameter, compute/compute_volume_common_az is introduced to
+ specify availability zone where tempest creates instances and volumes
+ for scenario tests, to allow us to run scenario tests in the deployment
+ which has multiple availability zones and cinder/cross_az_attach in
+ nova.conf is set to False.
diff --git a/releasenotes/notes/config_image_certificate_compute_feature-c56efb520d54aff5.yaml b/releasenotes/notes/config_image_certificate_compute_feature-c56efb520d54aff5.yaml
new file mode 100644
index 0000000..8475f50
--- /dev/null
+++ b/releasenotes/notes/config_image_certificate_compute_feature-c56efb520d54aff5.yaml
@@ -0,0 +1,8 @@
+---
+other:
+ - |
+ New configuration options ``[compute]/certified_image_ref`` and
+ ``[compute]/certified_image_trusted_certs`` have been introduced. These
+ are required in order to run the ``ServerShowV263Test`` test and allow a
+ signed image with the required img_signature_* properties set along
+ with a list of trusted certificates to be used during the test.
diff --git a/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml b/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml
index 7510d47..2830aa2 100644
--- a/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml
+++ b/releasenotes/notes/correct-port-profile-config-option-d67f5cb31f1bc34c.yaml
@@ -1,7 +1,7 @@
---
fixes:
- |
- Patch https://review.openstack.org/#/c/499575/ introduced
+ Patch https://review.opendev.org/#/c/499575/ introduced
support creating Neutron port with certain capabilities.
Currently capabilities list interpreted as string this change
fix it.
diff --git a/releasenotes/notes/deprecate-dns_servers-option-0xf2f297ee47a5ff.yaml b/releasenotes/notes/deprecate-dns_servers-option-0xf2f297ee47a5ff.yaml
new file mode 100644
index 0000000..30551cb
--- /dev/null
+++ b/releasenotes/notes/deprecate-dns_servers-option-0xf2f297ee47a5ff.yaml
@@ -0,0 +1,6 @@
+---
+deprecations:
+ - |
+ The config option ``CONF.network.dns_servers`` is no longer used
+ anywhere, so it is deprecated and will be removed in the future.
+
diff --git a/releasenotes/notes/deprecate-vnc-server-header-529f07d592aefb62.yaml b/releasenotes/notes/deprecate-vnc-server-header-529f07d592aefb62.yaml
new file mode 100644
index 0000000..d7e144d
--- /dev/null
+++ b/releasenotes/notes/deprecate-vnc-server-header-529f07d592aefb62.yaml
@@ -0,0 +1,12 @@
+---
+deprecations:
+ - |
+ The config option ``CONF.compute.vnc_server_header`` is deprecated because
+ it has become obsolete with the usage of different response header fields
+ to accomplish the same goal in accordance with RFC7231 Section 6.2.2.
+
+fixes:
+ - |
+ Adequately validates WebSocket upgrade in test_novnc and removes unneeded
+ configuration complexity. Closes bug #1838777 and #1840788.
+
diff --git a/releasenotes/notes/intermediate-train-release-0146c624cff9a57f.yaml b/releasenotes/notes/intermediate-train-release-0146c624cff9a57f.yaml
new file mode 100644
index 0000000..7940846
--- /dev/null
+++ b/releasenotes/notes/intermediate-train-release-0146c624cff9a57f.yaml
@@ -0,0 +1,12 @@
+---
+prelude: |
+ This is an intermediate release during the Train development cycle to
+ mark the end of support for Pike in Tempest.
+ After this release, Tempest will support below OpenStack Releases:
+
+ * Stein
+ * Rocky
+ * Queens
+
+ Current development of Tempest is for OpenStack Train development
+ cycle.
diff --git a/releasenotes/notes/lib_api_microversion_fixture-f52308fc6b6b89f2.yaml b/releasenotes/notes/lib_api_microversion_fixture-f52308fc6b6b89f2.yaml
new file mode 100644
index 0000000..d707fc7
--- /dev/null
+++ b/releasenotes/notes/lib_api_microversion_fixture-f52308fc6b6b89f2.yaml
@@ -0,0 +1,7 @@
+---
+features:
+ - |
+ New library interface to set the API microversion on Service Clients.
+ ``APIMicroversionFixture,`` can be used to set the API microversion
+ on multiple services. This Fixture will take care of reseting the service
+ microversion to None once test is finished.
diff --git a/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml b/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
index 2bba952..37eeec5 100644
--- a/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
+++ b/releasenotes/notes/make-object-storage-client-as-stable-interface-d1b07c7e8f17bef6.yaml
@@ -6,6 +6,6 @@
other projects can use these modules as stable libraries
without any maintenance changes.
- * account_client
- * container_client
- * object_client
+ * account_client
+ * container_client
+ * object_client
diff --git a/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml b/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml
index 72b8e26..00829b9 100644
--- a/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml
+++ b/releasenotes/notes/migrate-object-storage-as-stable-interface-42014c7b43ecb254.yaml
@@ -6,5 +6,5 @@
other projects can use these modules as stable libraries
without any maintenance changes.
- * bulk_middleware_client
- * capabilities_client
+ * bulk_middleware_client
+ * capabilities_client
diff --git a/releasenotes/notes/remove-some-deprecated-auth-and-identity-options-xa1xd9b8fb948g4f.yaml b/releasenotes/notes/remove-some-deprecated-auth-and-identity-options-xa1xd9b8fb948g4f.yaml
new file mode 100644
index 0000000..fa21afd
--- /dev/null
+++ b/releasenotes/notes/remove-some-deprecated-auth-and-identity-options-xa1xd9b8fb948g4f.yaml
@@ -0,0 +1,8 @@
+upgrade:
+ - |
+ Remove deprecated config option ``endpoint_type`` from
+ ``identity`` group. Use ``v2_public_endpoint_type`` from
+ ``identity`` group instead.
+ Remove deprecated config option ``tenant_isolation_domain_name``
+ from ``auth`` group. Use ``default_credentials_domain_name`` from
+ ``auth`` group instead.
diff --git a/releasenotes/notes/remove-some-deprecated-identity-options-0ffxd1b8db928e43.yaml b/releasenotes/notes/remove-some-deprecated-identity-options-0ffxd1b8db928e43.yaml
new file mode 100644
index 0000000..e9e9444
--- /dev/null
+++ b/releasenotes/notes/remove-some-deprecated-identity-options-0ffxd1b8db928e43.yaml
@@ -0,0 +1,11 @@
+upgrade:
+ - |
+ Remove deprecated config option ``admin_username`` from
+ ``identity`` groups. Use ``admin_username`` from ``auth`` instead.
+ Remove deprecated config option ``admin_tenant_name`` from
+ ``auth`` and ``identity`` groups. Use ``admin_project_name`` from
+ ``auth`` instead.
+ Remove deprecated config option ``admin_password`` from
+ ``identity`` groups. Use ``admin_password`` from ``auth`` instead.
+ Remove deprecated config option ``admin_domain_name`` from
+ ``identity`` groups. Use ``admin_domain_name`` from ``auth`` instead.
\ No newline at end of file
diff --git a/releasenotes/notes/segments-client-866f02948f40d4ff.yaml b/releasenotes/notes/segments-client-866f02948f40d4ff.yaml
new file mode 100644
index 0000000..90ac3e8
--- /dev/null
+++ b/releasenotes/notes/segments-client-866f02948f40d4ff.yaml
@@ -0,0 +1,12 @@
+---
+features:
+ - |
+ Add ``segments`` client to Tempest to make possible the testing of the
+ Routed Provider Networks feature.
+ The following API calls are available for tempest from now:
+
+ * POST /segments
+ * PUT /segments/{segment_id}
+ * GET /segment/{segment_id}
+ * DELETE /segments/{segment_id}
+ * GET /segments
diff --git a/releasenotes/notes/support-microversion-in-scenario-test-b4fbfdd3a977fc58.yaml b/releasenotes/notes/support-microversion-in-scenario-test-b4fbfdd3a977fc58.yaml
new file mode 100644
index 0000000..4d0a3dd
--- /dev/null
+++ b/releasenotes/notes/support-microversion-in-scenario-test-b4fbfdd3a977fc58.yaml
@@ -0,0 +1,14 @@
+---
+features:
+ - |
+ Add microversion support for scenario tests. Scenario test calls
+ multiple service API within same test and many services like compute,
+ volume and placement etc support API microversion. With microversion
+ support in scenario test, we can call different service API with
+ different microvesion. Which means we can implement scenario tests
+ for microversion also.
+ Currently Scenario manager support below services microversion:
+
+ * Compute
+ * Volume
+ * Placement
diff --git a/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml b/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
index e9c77a6..8406be6 100644
--- a/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
+++ b/releasenotes/notes/tempest-rocky-release-0fc3312053923380.yaml
@@ -1,12 +1,12 @@
---
-prelude: >
+prelude: |
This release is to tag the Tempest for OpenStack Rocky release.
After this release, Tempest will support below OpenStack Releases:
- * Rocky
- * Queens
- * Pike
- * Ocata
+ * Rocky
+ * Queens
+ * Pike
+ * Ocata
Current development of Tempest is for OpenStack Stein development
cycle. Every Tempest commit is also tested against master during
diff --git a/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml b/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml
index 212cf7d..c3537fc 100644
--- a/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml
+++ b/releasenotes/notes/tempest-stein-release-18bad34136a2e6ef.yaml
@@ -1,14 +1,14 @@
---
-prelude: >
+prelude: |
This release is to tag the Tempest for OpenStack Stein release.
This release marks the start of Stein release support in Tempest and
the end of support for Ocata in Tempest.
After this release, Tempest will support below OpenStack Releases:
- * Stein
- * Rocky
- * Queens
- * Pike
+ * Stein
+ * Rocky
+ * Queens
+ * Pike
Current development of Tempest is for OpenStack Train development
cycle. Every Tempest commit is also tested against master during
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 57ec7e1..92df4c4 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -46,9 +46,6 @@
bug_project = 'tempest'
bug_tag = ''
-# Must set this variable to include year, month, day, hours, and minutes.
-html_last_updated_fmt = '%Y-%m-%d %H:%M'
-
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
@@ -62,7 +59,6 @@
master_doc = 'index'
# General information about the project.
-project = u'tempest Release Notes'
copyright = u'2016, tempest Developers'
# Release do not need a version number in the title, they
@@ -193,17 +189,6 @@
# -- Options for LaTeX output ---------------------------------------------
-latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- # 'papersize': 'letterpaper',
-
- # The font size ('10pt', '11pt' or '12pt').
- # 'pointsize': '10pt',
-
- # Additional stuff for the LaTeX preamble.
- # 'preamble': '',
-}
-
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index e5d5bfe..1d0d914 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,7 @@
:maxdepth: 1
unreleased
+ v21.0.0
v20.0.0
v19.0.0
v18.0.0
diff --git a/releasenotes/source/v21.0.0.rst b/releasenotes/source/v21.0.0.rst
new file mode 100644
index 0000000..9ea8120
--- /dev/null
+++ b/releasenotes/source/v21.0.0.rst
@@ -0,0 +1,6 @@
+=====================
+v21.0.0 Release Notes
+=====================
+
+.. release-notes:: 21.0.0 Release Notes
+ :version: 21.0.0
diff --git a/roles/ipv6-only-deployments-verification/README.rst b/roles/ipv6-only-deployments-verification/README.rst
new file mode 100644
index 0000000..400a8da
--- /dev/null
+++ b/roles/ipv6-only-deployments-verification/README.rst
@@ -0,0 +1,16 @@
+Verify the IPv6-only deployments
+
+This role needs to be invoked from a playbook that
+run tests. This role verifies the IPv6 setting on
+devstack side and devstack deploy services on IPv6.
+This role is invoked before tests are run so that
+if any missing IPv6 setting or deployments can fail
+the job early.
+
+
+**Role Variables**
+
+.. zuul:rolevar:: devstack_base_dir
+ :default: /opt/stack
+
+ The devstack base directory.
diff --git a/roles/ipv6-only-deployments-verification/defaults/main.yaml b/roles/ipv6-only-deployments-verification/defaults/main.yaml
new file mode 100644
index 0000000..fea05c8
--- /dev/null
+++ b/roles/ipv6-only-deployments-verification/defaults/main.yaml
@@ -0,0 +1 @@
+devstack_base_dir: /opt/stack
diff --git a/roles/ipv6-only-deployments-verification/tasks/main.yaml b/roles/ipv6-only-deployments-verification/tasks/main.yaml
new file mode 100644
index 0000000..d73c79c
--- /dev/null
+++ b/roles/ipv6-only-deployments-verification/tasks/main.yaml
@@ -0,0 +1,4 @@
+- name: Verify the ipv6-only deployments
+ become: true
+ become_user: stack
+ shell: "{{ devstack_base_dir }}/tempest/tools/verify-ipv6-only-deployments.sh"
diff --git a/roles/run-tempest/README.rst b/roles/run-tempest/README.rst
index e1787b6..d4b253a 100644
--- a/roles/run-tempest/README.rst
+++ b/roles/run-tempest/README.rst
@@ -67,3 +67,8 @@
::
vars:
tox_extra_args: --sitepackages
+
+.. zuul:rolevar:: tempest_test_timeout
+ :default: ''
+
+ The timeout (in seconds) for each test.
diff --git a/roles/run-tempest/defaults/main.yaml b/roles/run-tempest/defaults/main.yaml
index 06918b5..79df3e1 100644
--- a/roles/run-tempest/defaults/main.yaml
+++ b/roles/run-tempest/defaults/main.yaml
@@ -3,3 +3,4 @@
tox_envlist: smoke
tempest_black_regex: ''
tox_extra_args: ''
+tempest_test_timeout: ''
diff --git a/roles/run-tempest/tasks/main.yaml b/roles/run-tempest/tasks/main.yaml
index 16086aa..24bd4db 100644
--- a/roles/run-tempest/tasks/main.yaml
+++ b/roles/run-tempest/tasks/main.yaml
@@ -42,3 +42,4 @@
chdir: "{{devstack_base_dir}}/tempest"
become: true
become_user: tempest
+ environment: '{{ {"OS_TEST_TIMEOUT": tempest_test_timeout} if tempest_test_timeout else {} }}'
diff --git a/setup.cfg b/setup.cfg
index fcbe956..5c1d24c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -17,6 +17,8 @@
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.5
+ Programming Language :: Python :: 3.6
+ Programming Language :: Python :: 3.7
[files]
packages =
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 99907a8..33b23b5 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -24,7 +24,7 @@
"""Tests Nova Networks API that usually requires admin privileges.
API docs:
- https://developer.openstack.org/api-ref/compute/#networks-os-networks-deprecated
+ https://docs.openstack.org/api-ref/compute/#networks-os-networks-deprecated
"""
max_microversion = '2.35'
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 624a99e..aaf7a5a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -17,11 +17,11 @@
from oslo_log import log as logging
-from tempest.api.compute import api_microversion_fixture
from tempest.common import compute
from tempest.common import waiters
from tempest import config
from tempest import exceptions
+from tempest.lib.common import api_microversion_fixture
from tempest.lib.common import api_version_request
from tempest.lib.common import api_version_utils
from tempest.lib.common.utils import data_utils
@@ -470,7 +470,7 @@
def setUp(self):
super(BaseV2ComputeTest, self).setUp()
self.useFixture(api_microversion_fixture.APIMicroversionFixture(
- self.request_microversion))
+ compute_microversion=self.request_microversion))
@classmethod
def create_volume(cls, image_ref=None, **kwargs):
@@ -487,6 +487,9 @@
kwargs['display_name'] = vol_name
if image_ref is not None:
kwargs['imageRef'] = image_ref
+ if CONF.compute.compute_volume_common_az:
+ kwargs.setdefault('availability_zone',
+ CONF.compute.compute_volume_common_az)
volume = cls.volumes_client.create_volume(**kwargs)['volume']
cls.addClassResourceCleanup(
cls.volumes_client.wait_for_resource_deletion, volume['id'])
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
index 3a474e6..235049a 100644
--- a/tempest/api/compute/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -70,9 +70,7 @@
self.assertEqual(min_img_ram, image['min_ram'])
# Try to create server with flavor of insufficient ram size
- self.assertRaisesRegex(lib_exc.BadRequest,
- "Flavor's memory is too small for "
- "requested image",
- self.create_test_server,
- image_id=image['id'],
- flavor=flavor['id'])
+ self.assertRaises(lib_exc.BadRequest,
+ self.create_test_server,
+ image_id=image['id'],
+ flavor=flavor['id'])
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index c8221c2..7cf26fb 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -47,6 +47,10 @@
def test_delete_saving_image(self):
server = self.create_test_server(wait_until='ACTIVE')
self.addCleanup(self.servers_client.delete_server, server['id'])
+ # wait for server active to avoid conflict when deleting server
+ # in task_state image_snapshot
+ self.addCleanup(waiters.wait_for_server_status, self.servers_client,
+ server['id'], 'ACTIVE')
image = self.create_image_from_server(server['id'],
wait_until='SAVING')
self.client.delete_image(image['id'])
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 3c152c9..b811421 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -15,7 +15,6 @@
from tempest.api.compute import base
from tempest import config
-from tempest.lib.common import api_version_utils
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -101,11 +100,5 @@
# will return 400(Bad Request) if we attempt to send a name which has
# 4 byte utf-8 character.
utf8_name = data_utils.rand_name(b'\xe2\x82\xa1'.decode('utf-8'))
- body = self.compute_images_client.create_image(
- self.server_id, name=utf8_name)
- if api_version_utils.compare_version_header_to_response(
- "OpenStack-API-Version", "compute 2.45", body.response, "lt"):
- image_id = body['image_id']
- else:
- image_id = data_utils.parse_image_id(body.response['location'])
- self.addCleanup(self.client.delete_image, image_id)
+ self.create_image_from_server(self.server_id, name=utf8_name,
+ wait_until='ACTIVE')
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index eeb58d6..df8da07 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -15,6 +15,7 @@
import time
+from oslo_log import log
import six
from tempest.api.compute import base
@@ -23,6 +24,7 @@
from tempest.common.utils import net_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils.linux import remote_client
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -30,6 +32,8 @@
CONF = config.CONF
+LOG = log.getLogger(__name__)
+
class AttachInterfacesTestBase(base.BaseV2ComputeTest):
@@ -75,6 +79,9 @@
validatable=True,
validation_resources=validation_resources,
wait_until='ACTIVE')
+ # NOTE(mgoddard): Get detailed server to ensure addresses are present
+ # in fixed IP case.
+ server = self.servers_client.show_server(server['id'])['server']
# NOTE(artom) self.create_test_server adds cleanups, but this is
# apparently not enough? Add cleanup here.
self.addCleanup(self.delete_server, server['id'])
@@ -147,7 +154,9 @@
def _test_create_interface_by_port_id(self, server, ifs):
network_id = ifs[0]['net_id']
- port = self.ports_client.create_port(network_id=network_id)
+ port = self.ports_client.create_port(
+ network_id=network_id,
+ name=data_utils.rand_name(self.__class__.__name__))
port_id = port['port']['id']
self.addCleanup(self.ports_client.delete_port, port_id)
iface = self.interfaces_client.create_interface(
@@ -288,7 +297,9 @@
"""
network = self.get_tenant_network()
network_id = network['id']
- port = self.ports_client.create_port(network_id=network_id)
+ port = self.ports_client.create_port(
+ network_id=network_id,
+ name=data_utils.rand_name(self.__class__.__name__))
port_id = port['port']['id']
self.addCleanup(self.ports_client.delete_port, port_id)
@@ -311,6 +322,9 @@
self.addCleanup(self.delete_server, server['id'])
for server in servers:
+ # NOTE(mgoddard): Get detailed server to ensure addresses are
+ # present in fixed IP case.
+ server = self.servers_client.show_server(server['id'])['server']
self._wait_for_validation(server, validation_resources)
# attach the port to the server
iface = self.interfaces_client.create_interface(
@@ -364,10 +378,34 @@
self.servers_client.add_fixed_ip(server['id'], networkId=network_id)
# Wait for the ips count to increase by one.
+ def _get_server_floating_ips():
+ _floating_ips = []
+ _server = self.os_primary.servers_client.show_server(
+ server['id'])['server']
+ for _ip_set in _server['addresses']:
+ for _ip in _server['addresses'][_ip_set]:
+ if _ip['OS-EXT-IPS:type'] == 'floating':
+ _floating_ips.append(_ip['addr'])
+ return _floating_ips
+
def _wait_for_ip_increase():
_addresses = self.os_primary.servers_client.list_addresses(
server['id'])['addresses']
- return len(list(_addresses.values())[0]) == original_ip_count + 1
+ _ips = [addr['addr'] for addr in list(_addresses.values())[0]]
+ LOG.debug("Wait for IP increase. All IPs still associated to "
+ "the server %(id)s: %(ips)s",
+ {'id': server['id'], 'ips': _ips})
+ if len(_ips) == original_ip_count + 1:
+ return True
+ elif len(_ips) == original_ip_count:
+ return False
+ # If not, lets remove any floating IP from the list and check again
+ _fips = _get_server_floating_ips()
+ _ips = [_ip for _ip in _ips if _ip not in _fips]
+ LOG.debug("Wait for IP increase. Fixed IPs still associated to "
+ "the server %(id)s: %(ips)s",
+ {'id': server['id'], 'ips': _ips})
+ return len(_ips) == original_ip_count + 1
if not test_utils.call_until_true(
_wait_for_ip_increase, CONF.compute.build_timeout,
@@ -394,7 +432,19 @@
def _wait_for_ip_decrease():
_addresses = self.os_primary.servers_client.list_addresses(
server['id'])['addresses']
- return len(list(_addresses.values())[0]) == original_ip_count
+ _ips = [addr['addr'] for addr in list(_addresses.values())[0]]
+ LOG.debug("Wait for IP decrease. All IPs still associated to "
+ "the server %(id)s: %(ips)s",
+ {'id': server['id'], 'ips': _ips})
+ if len(_ips) == original_ip_count:
+ return True
+ # If not, lets remove any floating IP from the list and check again
+ _fips = _get_server_floating_ips()
+ _ips = [_ip for _ip in _ips if _ip not in _fips]
+ LOG.debug("Wait for IP decrease. Fixed IPs still associated to "
+ "the server %(id)s: %(ips)s",
+ {'id': server['id'], 'ips': _ips})
+ return len(_ips) == original_ip_count
if not test_utils.call_until_true(
_wait_for_ip_decrease, CONF.compute.build_timeout,
diff --git a/tempest/api/compute/servers/test_create_server_multi_nic.py b/tempest/api/compute/servers/test_create_server_multi_nic.py
index 3447d85..d0f53fe 100644
--- a/tempest/api/compute/servers/test_create_server_multi_nic.py
+++ b/tempest/api/compute/servers/test_create_server_multi_nic.py
@@ -14,7 +14,6 @@
# under the License.
import netaddr
-import testtools
from tempest.api.compute import base
from tempest import config
@@ -27,6 +26,12 @@
class ServersTestMultiNic(base.BaseV2ComputeTest):
@classmethod
+ def skip_checks(cls):
+ super(ServersTestMultiNic, cls).skip_checks()
+ if not CONF.service_available.neutron:
+ raise cls.skipException('Neutron service must be available.')
+
+ @classmethod
def setup_credentials(cls):
cls.prepare_instance_network()
super(ServersTestMultiNic, cls).setup_credentials()
@@ -53,8 +58,6 @@
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.
@@ -91,8 +94,6 @@
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.
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index e817587..8aab574 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -175,11 +175,13 @@
# Create ports
self.port1 = self.ports_client.create_port(
network_id=net1['id'],
+ name=data_utils.rand_name(self.__class__.__name__),
fixed_ips=[{'subnet_id': subnet1['id']}])['port']
self.addCleanup(self.ports_client.delete_port, self.port1['id'])
self.port2 = self.ports_client.create_port(
network_id=net1['id'],
+ name=data_utils.rand_name(self.__class__.__name__),
fixed_ips=[{'subnet_id': subnet1['id']}])['port']
self.addCleanup(self.ports_client.delete_port, self.port2['id'])
@@ -359,6 +361,10 @@
networks=[{'uuid': self.get_tenant_network()['id']}])
self.addCleanup(self.delete_server, server['id'])
+ # NOTE(mgoddard): Get detailed server to ensure addresses are present
+ # in fixed IP case.
+ server = self.servers_client.show_server(server['id'])['server']
+
# Attach tagged nic and volume
interface = self.interfaces_client.create_interface(
server['id'], net_id=net['id'],
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index daf6a06..7cf6d83 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -16,6 +16,7 @@
import struct
import six
+import six.moves.urllib.parse as urlparse
import urllib3
from tempest.api.compute import base
@@ -73,8 +74,9 @@
'initial call: ' + six.text_type(resp.status))
# Do some basic validation to make sure it is an expected HTML document
resp_data = resp.data.decode()
- self.assertIn('<html>', resp_data,
- 'Not a valid html document in the response.')
+ # This is needed in the case of example: <html lang="en">
+ self.assertRegex(resp_data, '<html.*>',
+ 'Not a valid html document in the response.')
self.assertIn('</html>', resp_data,
'Not a valid html document in the response.')
# Just try to make sure we got JavaScript back for noVNC, since we
@@ -154,22 +156,24 @@
data[20:24])[0] + 24))
def _validate_websocket_upgrade(self):
+ """Verify that the websocket upgrade was successful.
+
+ Parses response and ensures that required response
+ fields are present and accurate.
+ (https://tools.ietf.org/html/rfc7231#section-6.2.2)
+ """
+
self.assertTrue(
self._websocket.response.startswith(b'HTTP/1.1 101 Switching '
- b'Protocols\r\n'),
- 'Did not get the expected 101 on the {} call: {}'.format(
- CONF.compute_feature_enabled.vnc_server_header,
+ b'Protocols'),
+ 'Incorrect HTTP return status code: {}'.format(
six.text_type(self._websocket.response)
)
)
- # Since every other server type returns Headers with different case
- # (for example 'nginx'), lowercase must be applied to eliminate issues.
- _desired_header = "server: {0}".format(
- CONF.compute_feature_enabled.vnc_server_header
- ).lower()
+ _required_header = 'upgrade: websocket'
_response = six.text_type(self._websocket.response).lower()
self.assertIn(
- _desired_header,
+ _required_header,
_response,
'Did not get the expected WebSocket HTTP Response.'
)
@@ -204,7 +208,18 @@
type='novnc')['console']
self.assertEqual('novnc', body['type'])
# Do the WebSockify HTTP Request to novncproxy with a bad token
- url = body['url'].replace('token=', 'token=bad')
+ parts = urlparse.urlparse(body['url'])
+ qparams = urlparse.parse_qs(parts.query)
+ if 'path' in qparams:
+ qparams['path'] = urlparse.unquote(qparams['path'][0]).replace(
+ 'token=', 'token=bad')
+ elif 'token' in qparams:
+ qparams['token'] = 'bad' + qparams['token'][0]
+ new_query = urlparse.urlencode(qparams)
+ new_parts = urlparse.ParseResult(parts.scheme, parts.netloc,
+ parts.path, parts.params, new_query,
+ parts.fragment)
+ url = urlparse.urlunparse(new_parts)
self._websocket = compute.create_websocket(url)
# Make sure the novncproxy rejected the connection and closed it
data = self._websocket.receive_frame()
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f6c3e73..0e469c7 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -345,6 +345,9 @@
# from setUp is not volume-backed.
server = self.create_test_server(
volume_backed=True, wait_until='ACTIVE')
+ # NOTE(mgoddard): Get detailed server to ensure addresses are present
+ # in fixed IP case.
+ server = self.servers_client.show_server(server['id'])['server']
self._test_resize_server_confirm(server['id'])
if CONF.compute_feature_enabled.console_output:
# Now do something interactive with the guest like get its console
@@ -417,10 +420,7 @@
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
# Make sure everything still looks OK.
server = self.client.show_server(self.server_id)['server']
- # The flavor id is not returned in the server response after
- # microversion 2.46 so handle that gracefully.
- if server['flavor'].get('id'):
- self.assertEqual(self.flavor_ref, server['flavor']['id'])
+ self.assert_flavor_equal(self.flavor_ref, server['flavor'])
attached_volumes = server['os-extended-volumes:volumes_attached']
self.assertEqual(1, len(attached_volumes))
self.assertEqual(volume['id'], attached_volumes[0]['id'])
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index e8b1161..1e3e966 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -186,10 +186,17 @@
min_microversion = '2.63'
max_microversion = 'latest'
+ @testtools.skipUnless(CONF.compute.certified_image_ref,
+ '``[compute]/certified_image_ref`` required to test '
+ 'image certificate validation.')
+ @testtools.skipUnless(CONF.compute.certified_image_trusted_certs,
+ '``[compute]/certified_image_trusted_certs`` '
+ 'required to test image certificate validation.')
@decorators.idempotent_id('71b8e3d5-11d2-494f-b917-b094a4afed3c')
def test_show_update_rebuild_list_server(self):
- trusted_certs = ['test-cert-1', 'test-cert-2']
+ trusted_certs = CONF.compute.certified_image_trusted_certs
server = self.create_test_server(
+ image_id=CONF.compute.certified_image_ref,
trusted_image_certificates=trusted_certs,
wait_until='ACTIVE')
@@ -202,7 +209,8 @@
server['id'], 'ACTIVE')
# Check rebuild API response schema
- self.servers_client.rebuild_server(server['id'], self.image_ref_alt)
+ self.servers_client.rebuild_server(
+ server['id'], CONF.compute.certified_image_ref)
waiters.wait_for_server_status(self.servers_client,
server['id'], 'ACTIVE')
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index 34faf5f..12e7fea 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -37,7 +37,7 @@
ext = CONF.compute_feature_enabled.api_extensions[0]
# Log extensions list
- extension_list = map(lambda x: x['alias'], extensions)
+ extension_list = [x['alias'] for x in extensions]
LOG.debug("Nova extensions: %s", ','.join(extension_list))
if ext == 'all':
diff --git a/tempest/api/compute/volumes/test_volume_snapshots.py b/tempest/api/compute/volumes/test_volume_snapshots.py
index b8ca81d..f3ccf8d 100644
--- a/tempest/api/compute/volumes/test_volume_snapshots.py
+++ b/tempest/api/compute/volumes/test_volume_snapshots.py
@@ -27,7 +27,7 @@
# These tests will fail with a 404 starting from microversion 2.36. For
# more information, see:
- # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ # https://docs.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
max_microversion = '2.35'
@classmethod
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index d83d49e..0d23c1f 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -28,7 +28,7 @@
# These tests will fail with a 404 starting from microversion 2.36. For
# more information, see:
- # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ # https://docs.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
max_microversion = '2.35'
@classmethod
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index b2aebe7..28bc174 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -29,7 +29,7 @@
# These tests will fail with a 404 starting from microversion 2.36. For
# more information, see:
- # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ # https://docs.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
max_microversion = '2.35'
@classmethod
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index 87f7d8a..444ce93 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -26,7 +26,7 @@
# These tests will fail with a 404 starting from microversion 2.36. For
# more information, see:
- # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ # https://docs.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
max_microversion = '2.35'
@classmethod
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 2cd8906..366d6a0 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -44,11 +44,14 @@
cls.addClassResourceCleanup(
cls.services_client.delete_service, service['id'])
- region = data_utils.rand_name('region')
+ region_name = data_utils.rand_name('region')
url = data_utils.rand_url()
endpoint = cls.client.create_endpoint(
service_id=cls.service_ids[i], interface=interfaces[i],
- url=url, region=region, enabled=True)['endpoint']
+ url=url, region=region_name, enabled=True)['endpoint']
+ region = cls.regions_client.show_region(region_name)['region']
+ cls.addClassResourceCleanup(
+ cls.regions_client.delete_region, region['id'])
cls.addClassResourceCleanup(
cls.client.delete_endpoint, endpoint['id'])
cls.setup_endpoint_ids.append(endpoint['id'])
@@ -108,17 +111,19 @@
@decorators.idempotent_id('0e2446d2-c1fd-461b-a729-b9e73e3e3b37')
def test_create_list_show_delete_endpoint(self):
- region = data_utils.rand_name('region')
+ region_name = data_utils.rand_name('region')
url = data_utils.rand_url()
interface = 'public'
endpoint = self.client.create_endpoint(service_id=self.service_ids[0],
interface=interface,
- url=url, region=region,
+ url=url, region=region_name,
enabled=True)['endpoint']
+ region = self.regions_client.show_region(region_name)['region']
+ self.addCleanup(self.regions_client.delete_region, region['id'])
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.client.delete_endpoint, endpoint['id'])
# Asserting Create Endpoint response body
- self.assertEqual(region, endpoint['region'])
+ self.assertEqual(region_name, endpoint['region'])
self.assertEqual(url, endpoint['url'])
# Checking if created endpoint is present in the list of endpoints
@@ -133,7 +138,7 @@
self.assertEqual(self.service_ids[0], fetched_endpoint['service_id'])
self.assertEqual(interface, fetched_endpoint['interface'])
self.assertEqual(url, fetched_endpoint['url'])
- self.assertEqual(region, fetched_endpoint['region'])
+ self.assertEqual(region_name, fetched_endpoint['region'])
self.assertEqual(True, fetched_endpoint['enabled'])
# Deleting the endpoint created in this method
@@ -161,28 +166,33 @@
self.addCleanup(self.services_client.delete_service, service2['id'])
# Creating an endpoint so as to check update endpoint with new values
- region1 = data_utils.rand_name('region')
+ region1_name = data_utils.rand_name('region')
url1 = data_utils.rand_url()
interface1 = 'public'
endpoint_for_update = (
self.client.create_endpoint(service_id=self.service_ids[0],
interface=interface1,
- url=url1, region=region1,
+ url=url1, region=region1_name,
enabled=True)['endpoint'])
- self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
+ region1 = self.regions_client.show_region(region1_name)['region']
+ self.addCleanup(self.regions_client.delete_region, region1['id'])
# Updating endpoint with new values
- region2 = data_utils.rand_name('region')
+ region2_name = data_utils.rand_name('region')
url2 = data_utils.rand_url()
interface2 = 'internal'
endpoint = self.client.update_endpoint(endpoint_for_update['id'],
service_id=service2['id'],
interface=interface2,
- url=url2, region=region2,
+ url=url2, region=region2_name,
enabled=False)['endpoint']
+ region2 = self.regions_client.show_region(region2_name)['region']
+ self.addCleanup(self.regions_client.delete_region, region2['id'])
+ self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
+
# Asserting if the attributes of endpoint are updated
self.assertEqual(service2['id'], endpoint['service_id'])
self.assertEqual(interface2, endpoint['interface'])
self.assertEqual(url2, endpoint['url'])
- self.assertEqual(region2, endpoint['region'])
+ self.assertEqual(region2_name, endpoint['region'])
self.assertEqual(False, endpoint['enabled'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 4c3eb1c..164b577 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -70,14 +70,16 @@
def _assert_update_raises_bad_request(self, enabled):
# Create an endpoint
- region1 = data_utils.rand_name('region')
+ region1_name = data_utils.rand_name('region')
url1 = data_utils.rand_url()
interface1 = 'public'
endpoint_for_update = (
self.client.create_endpoint(service_id=self.service_id,
interface=interface1,
- url=url1, region=region1,
+ url=url1, region=region1_name,
enabled=True)['endpoint'])
+ region1 = self.regions_client.show_region(region1_name)['region']
+ self.addCleanup(self.regions_client.delete_region, region1['id'])
self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
self.assertRaises(lib_exc.BadRequest, self.client.update_endpoint,
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index 299a618..cb8ea11 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -44,29 +44,24 @@
@classmethod
def resource_setup(cls):
super(ListProjectsTestJSON, cls).resource_setup()
- cls.project_ids = list()
- cls.domain_id = cls.os_admin.credentials.domain_id
+ domain_id = cls.os_admin.credentials.domain_id
# Create project with domain
- cls.p1_name = data_utils.rand_name('project')
+ p1_name = data_utils.rand_name(cls.__name__)
cls.p1 = cls.projects_client.create_project(
- cls.p1_name, enabled=False,
- domain_id=cls.domain_id)['project']
+ p1_name, enabled=False, domain_id=domain_id)['project']
cls.addClassResourceCleanup(cls.projects_client.delete_project,
cls.p1['id'])
- cls.project_ids.append(cls.p1['id'])
# Create default project
- p2_name = data_utils.rand_name('project')
+ p2_name = data_utils.rand_name(cls.__name__)
cls.p2 = cls.projects_client.create_project(p2_name)['project']
cls.addClassResourceCleanup(cls.projects_client.delete_project,
cls.p2['id'])
- cls.project_ids.append(cls.p2['id'])
# Create a new project (p3) using p2 as parent project
- p3_name = data_utils.rand_name('project')
+ p3_name = data_utils.rand_name(cls.__name__)
cls.p3 = cls.projects_client.create_project(
p3_name, parent_id=cls.p2['id'])['project']
cls.addClassResourceCleanup(cls.projects_client.delete_project,
cls.p3['id'])
- cls.project_ids.append(cls.p3['id'])
@decorators.idempotent_id('0fe7a334-675a-4509-b00e-1c4b95d5dae8')
def test_list_projects_with_enabled(self):
@@ -94,40 +89,43 @@
@classmethod
def resource_setup(cls):
super(ListProjectsStaticTestJSON, cls).resource_setup()
- cls.domain_id = CONF.identity.default_domain_id
- cls.project_ids = list()
- cls.p1_name = cls.os_primary.credentials.project_name
+ # Fetch an existing project from os_primary
cls.p1 = cls.projects_client.show_project(
cls.os_primary.credentials.project_id)['project']
- cls.project_ids.append(cls.p1['id'])
- p2_name = data_utils.rand_name('project')
+ # Create a test project
+ p2_name = data_utils.rand_name(cls.__name__)
+ p2_domain_id = CONF.identity.default_domain_id
cls.p2 = cls.projects_client.create_project(
- p2_name, domain_id=cls.domain_id)['project']
+ p2_name, domain_id=p2_domain_id)['project']
cls.addClassResourceCleanup(cls.projects_client.delete_project,
cls.p2['id'])
- cls.project_ids.append(cls.p2['id'])
@decorators.idempotent_id('1d830662-22ad-427c-8c3e-4ec854b0af44')
def test_list_projects(self):
# List projects
list_projects = self.projects_client.list_projects()['projects']
- for p in self.project_ids:
- show_project = self.projects_client.show_project(p)['project']
+ for p in [self.p1, self.p2]:
+ show_project = self.projects_client.show_project(p['id'])[
+ 'project']
self.assertIn(show_project, list_projects)
@decorators.idempotent_id('fa178524-4e6d-4925-907c-7ab9f42c7e26')
def test_list_projects_with_name(self):
# List projects with name
self._list_projects_with_params(
- [self.p1], [self.p2], {'name': self.p1_name}, 'name')
+ [self.p1], [self.p2], {'name': self.p1['name']}, 'name')
@decorators.idempotent_id('fab13f3c-f6a6-4b9f-829b-d32fd44fdf10')
def test_list_projects_with_domains(self):
- # List projects with domain
+ # Verify project list filtered by domain
key = 'domain_id'
- params = {key: self.domain_id}
- # Verify both projects are in the self.domain_id which is the default
- # domain
- self._list_projects_with_params(
- [self.p1, self.p2], [], params, key)
+ for p in [self.p1, self.p2]:
+ params = {key: p[key]}
+ # Verify filter shows both projects in their respective domains
+ self._list_projects_with_params([p], [], params, key)
+ # Verify filter excludes projects that are filtered out
+ if self.p1[key] != self.p2[key]:
+ exclude = [self.p2]
+ params = {key: self.p1[key]}
+ self._list_projects_with_params([self.p1], exclude, params, key)
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index c69e4c8..5aec931 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -34,6 +34,14 @@
map(lambda x: x[key], body))
@classmethod
+ def skip_checks(cls):
+ super(UsersV3TestJSON, cls).skip_checks()
+ if CONF.identity_feature_enabled.immutable_user_source:
+ raise cls.skipException('Skipped because environment has an '
+ 'immutable user source and solely '
+ 'provides read-only access to users.')
+
+ @classmethod
def resource_setup(cls):
super(UsersV3TestJSON, cls).resource_setup()
alt_user = data_utils.rand_name('test_user')
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index 0b85b19..e46145d 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -230,8 +230,14 @@
_projects = self.projects_client.list_projects()['projects']
project_list = next(x for x in _projects if x['id'] == project['id'])
- # Assert the list of fields is correct (one is enough to check here)
- self.assertSetEqual(set(fields), set(project_get.keys()))
+ # Assert the expected fields exist. More fields than expected may
+ # be in this list. This is for future proofind as keystone does not
+ # and has no plans to support microservices. Any fields in the future
+ # that are added to the response of the API should eventually be added
+ # to the expected fields. The expected fields must be a subset of
+ # the project_get fields (all keys in fields must exist in project_get,
+ # but project_get.keys() may have additional fields)
+ self.assertTrue(set(fields).issubset(project_get.keys()))
# Ensure the set of tags is identical and match the expected one
get_tags = set(project_get.pop("tags"))
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 54a5ab7..78e3cce 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -33,6 +33,10 @@
super(TrustsV3TestJSON, cls).skip_checks()
if not CONF.identity_feature_enabled.trust:
raise cls.skipException("Trusts aren't enabled")
+ if CONF.identity_feature_enabled.immutable_user_source:
+ raise cls.skipException('Skipped because environment has an '
+ 'immutable user source and solely '
+ 'provides read-only access to users.')
def setUp(self):
super(TrustsV3TestJSON, self).setUp()
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
index 158dfb3..2eea860 100644
--- a/tempest/api/identity/v2/test_users.py
+++ b/tempest/api/identity/v2/test_users.py
@@ -15,6 +15,8 @@
import time
+import testtools
+
from tempest.api.identity import base
from tempest import config
from tempest.lib.common.utils import data_utils
@@ -78,6 +80,10 @@
self.non_admin_users_client.auth_provider.set_auth()
@decorators.idempotent_id('165859c9-277f-4124-9479-a7d1627b0ca7')
+ @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
+ 'Skipped because environment has an '
+ 'immutable user source and solely '
+ 'provides read-only access to users.')
def test_user_update_own_password(self):
old_pass = self.creds.password
old_token = self.non_admin_users_client.token
diff --git a/tempest/api/identity/v3/test_api_discovery.py b/tempest/api/identity/v3/test_api_discovery.py
index c04c21b..e87d1cd 100644
--- a/tempest/api/identity/v3/test_api_discovery.py
+++ b/tempest/api/identity/v3/test_api_discovery.py
@@ -14,12 +14,24 @@
# under the License.
from tempest.api.identity import base
+from tempest import config
from tempest.lib import decorators
+CONF = config.CONF
+
+
class TestApiDiscovery(base.BaseIdentityV3Test):
"""Tests for API discovery features."""
+ @decorators.idempotent_id('79aec9ae-710f-4c54-a4fc-3aa25b4feac3')
+ def test_identity_v3_existence(self):
+ versions = self.non_admin_versions_client.list_versions()
+ found = any(
+ "v3" in version.get('id')
+ for version in versions['versions']['values'])
+ self.assertEqual(CONF.identity_feature_enabled.api_v3, found)
+
@decorators.idempotent_id('721f480f-35b6-46c7-846e-047e6acea0dc')
@decorators.attr(type='smoke')
def test_list_api_versions(self):
diff --git a/tempest/api/identity/v3/test_catalog.py b/tempest/api/identity/v3/test_catalog.py
index deec2dc..bc95f0d 100644
--- a/tempest/api/identity/v3/test_catalog.py
+++ b/tempest/api/identity/v3/test_catalog.py
@@ -22,8 +22,8 @@
@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
+ # https://opendev.org/openstack/service-types-authority
+ # /src/branch/master/service-types.yaml
standard_service_values = [{'name': 'keystone', 'type': 'identity'},
{'name': 'nova', 'type': 'compute'},
{'name': 'glance', 'type': 'image'},
diff --git a/tempest/api/identity/v3/test_tokens.py b/tempest/api/identity/v3/test_tokens.py
index f13aa10..fa1c47f 100644
--- a/tempest/api/identity/v3/test_tokens.py
+++ b/tempest/api/identity/v3/test_tokens.py
@@ -43,7 +43,15 @@
self.assertEqual(authenticated_token, token_body)
# test to see if token has been properly authenticated
self.assertEqual(authenticated_token['user']['id'], user_id)
- self.assertEqual(authenticated_token['user']['name'], username)
+ # NOTE: resource name that are case-sensitive in keystone
+ # depends on backends such as MySQL or LDAP which are
+ # case-insensitive, case-preserving. Resource name is
+ # returned as it is stored in the backend, not as it is
+ # requested. Verifying the username with both lower-case to
+ # avoid failure on different backends
+ self.assertEqual(
+ authenticated_token['user']['name'].lower(), username.lower())
+
self.non_admin_client.delete_token(subject_token)
self.assertRaises(
lib_exc.NotFound, self.non_admin_client.show_token, subject_token)
@@ -84,10 +92,17 @@
self.assertIsNotNone(subject_id, 'Expected user ID in token.')
subject_name = resp['user']['name']
+
if username:
- self.assertEqual(subject_name, username)
+ # NOTE: resource name that are case-sensitive in keystone
+ # depends on backends such as MySQL or LDAP which are
+ # case-insensitive, case-preserving. Resource name is
+ # returned as it is stored in the backend, not as it is
+ # requested. Verifying the username with both lower-case to
+ # avoid failure on different backends
+ self.assertEqual(subject_name.lower(), username.lower())
else:
- # Expect a user name, but don't know what it will be.
+ # Expect a user name, but don't know what it will be
self.assertIsNotNone(subject_name, 'Expected user name in token.')
self.assertEqual(resp['methods'][0], 'password')
@@ -110,7 +125,15 @@
subject_token)['token']
self.assertEqual(resp['x-subject-token'], subject_token)
self.assertEqual(token_details['user']['id'], user.user_id)
- self.assertEqual(token_details['user']['name'], user.username)
+ # NOTE: resource name that are case-sensitive in keystone
+ # depends on backends such as MySQL or LDAP which are
+ # case-insensitive, case-preserving. Resource name is
+ # returned as it is stored in the backend, not as it is
+ # requested. Verifying the username with both lower-case to
+ # avoid failure on different backends
+ self.assertEqual(
+ token_details['user']['name'].lower(),
+ user.username.lower())
# Perform Delete Token
self.non_admin_client.delete_token(subject_token)
self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index 13b5161..d4e7612 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -77,6 +77,10 @@
self.non_admin_users_client.auth_provider.set_auth()
@decorators.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
+ @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
+ 'Skipped because environment has an '
+ 'immutable user source and solely '
+ 'provides read-only access to users.')
def test_user_update_own_password(self):
old_pass = self.creds.password
old_token = self.non_admin_client.token
@@ -102,6 +106,10 @@
@testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
'Security compliance not available.')
@decorators.idempotent_id('941784ee-5342-4571-959b-b80dd2cea516')
+ @testtools.skipIf(CONF.identity_feature_enabled.immutable_user_source,
+ 'Skipped because environment has an '
+ 'immutable user source and solely '
+ 'provides read-only access to users.')
def test_password_history_check_self_service_api(self):
old_pass = self.creds.password
new_pass1 = data_utils.rand_password()
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 7e8cc8e..5bd3fce 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -36,6 +36,7 @@
body = self.admin_networks_client.create_network(**post_body)
network = body['network']
self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
self.admin_networks_client.delete_network, network['id'])
return network
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
index 0709d2a..da32f2d 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -16,6 +16,7 @@
from tempest.api.network import base
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
@@ -50,5 +51,6 @@
# create a port which will internally create an instance-ip
self.assertRaises(lib_exc.Conflict,
self.admin_ports_client.create_port,
+ name=data_utils.rand_name(self.__class__.__name__),
network_id=CONF.network.public_network_id,
fixed_ips=fixed_ips)
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index be0c4c6..adc4dda 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -16,6 +16,7 @@
from tempest.api.network import base
from tempest.common import utils
from tempest import config
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
CONF = config.CONF
@@ -57,14 +58,18 @@
# Create floating ip from admin user
floating_ip_admin = self.admin_floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id)
- self.addCleanup(self.admin_floating_ips_client.delete_floatingip,
- floating_ip_admin['floatingip']['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.admin_floating_ips_client.delete_floatingip,
+ floating_ip_admin['floatingip']['id'])
# Create floating ip from alt user
body = self.alt_floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id)
floating_ip_alt = body['floatingip']
- self.addCleanup(self.alt_floating_ips_client.delete_floatingip,
- floating_ip_alt['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.alt_floating_ips_client.delete_floatingip,
+ floating_ip_alt['id'])
# List floating ips from admin
body = self.admin_floating_ips_client.list_floatingips()
floating_ip_ids_admin = [f['id'] for f in body['floatingips']]
@@ -91,8 +96,10 @@
tenant_id=self.network['tenant_id'],
port_id=self.port['id'])
created_floating_ip = body['floatingip']
- self.addCleanup(self.floating_ips_client.delete_floatingip,
- created_floating_ip['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.floating_ips_client.delete_floatingip,
+ created_floating_ip['id'])
self.assertIsNotNone(created_floating_ip['id'])
self.assertIsNotNone(created_floating_ip['tenant_id'])
self.assertIsNotNone(created_floating_ip['floating_ip_address'])
diff --git a/tempest/api/network/admin/test_negative_quotas.py b/tempest/api/network/admin/test_negative_quotas.py
index 9d1e2a7..0db038d 100644
--- a/tempest/api/network/admin/test_negative_quotas.py
+++ b/tempest/api/network/admin/test_negative_quotas.py
@@ -17,6 +17,7 @@
from tempest.common import identity
from tempest.common import utils
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
@@ -58,11 +59,13 @@
# Create two networks
n1 = self.admin_networks_client.create_network(
tenant_id=self.project['id'])
- self.addCleanup(self.admin_networks_client.delete_network,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_networks_client.delete_network,
n1['network']['id'])
n2 = self.admin_networks_client.create_network(
tenant_id=self.project['id'])
- self.addCleanup(self.admin_networks_client.delete_network,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_networks_client.delete_network,
n2['network']['id'])
# Try to create a third network while the quota is two
@@ -71,5 +74,6 @@
r"Quota exceeded for resources: \['network'\].*"):
n3 = self.admin_networks_client.create_network(
tenant_id=self.project['id'])
- self.addCleanup(self.admin_networks_client.delete_network,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_networks_client.delete_network,
n3['network']['id'])
diff --git a/tempest/api/network/admin/test_ports.py b/tempest/api/network/admin/test_ports.py
index 05363db..289e577 100644
--- a/tempest/api/network/admin/test_ports.py
+++ b/tempest/api/network/admin/test_ports.py
@@ -14,8 +14,14 @@
# under the License.
from tempest.api.network import base
+from tempest.common import utils
+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
+CONF = config.CONF
+
class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
@@ -28,26 +34,35 @@
def resource_setup(cls):
super(PortsAdminExtendedAttrsTestJSON, cls).resource_setup()
cls.network = cls.create_network()
- hyper_list = cls.hyper_client.list_hypervisors()
- cls.host_id = hyper_list['hypervisors'][0]['hypervisor_hostname']
+ if CONF.service_available.nova:
+ hyper_list = cls.hyper_client.list_hypervisors()
+ cls.host_id = hyper_list['hypervisors'][0]['hypervisor_hostname']
@decorators.idempotent_id('8e8569c1-9ac7-44db-8bc1-f5fb2814f29b')
+ @utils.services('compute')
def test_create_port_binding_ext_attr(self):
post_body = {"network_id": self.network['id'],
- "binding:host_id": self.host_id}
+ "binding:host_id": self.host_id,
+ "name": data_utils.rand_name(self.__class__.__name__)}
body = self.admin_ports_client.create_port(**post_body)
port = body['port']
- self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.admin_ports_client.delete_port, port['id'])
host_id = port['binding:host_id']
self.assertIsNotNone(host_id)
self.assertEqual(self.host_id, host_id)
@decorators.idempotent_id('6f6c412c-711f-444d-8502-0ac30fbf5dd5')
+ @utils.services('compute')
def test_update_port_binding_ext_attr(self):
- post_body = {"network_id": self.network['id']}
+ post_body = {"network_id": self.network['id'],
+ "name": data_utils.rand_name(self.__class__.__name__)}
body = self.admin_ports_client.create_port(**post_body)
port = body['port']
- self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.admin_ports_client.delete_port, port['id'])
update_body = {"binding:host_id": self.host_id}
body = self.admin_ports_client.update_port(port['id'], **update_body)
updated_port = body['port']
@@ -56,12 +71,16 @@
self.assertEqual(self.host_id, host_id)
@decorators.idempotent_id('1c82a44a-6c6e-48ff-89e1-abe7eaf8f9f8')
+ @utils.services('compute')
def test_list_ports_binding_ext_attr(self):
# Create a new port
- post_body = {"network_id": self.network['id']}
+ post_body = {"network_id": self.network['id'],
+ "name": data_utils.rand_name(self.__class__.__name__)}
body = self.admin_ports_client.create_port(**post_body)
port = body['port']
- self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.admin_ports_client.delete_port, port['id'])
# Update the port's binding attributes so that is now 'bound'
# to a host
@@ -83,9 +102,11 @@
@decorators.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
def test_show_port_binding_ext_attr(self):
body = self.admin_ports_client.create_port(
+ name=data_utils.rand_name(self.__class__.__name__),
network_id=self.network['id'])
port = body['port']
- self.addCleanup(self.admin_ports_client.delete_port, port['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_ports_client.delete_port, port['id'])
body = self.admin_ports_client.show_port(port['id'])
show_port = body['port']
self.assertEqual(port['binding:host_id'],
diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py
index 6ce86fb..a4a057c 100644
--- a/tempest/api/network/admin/test_routers.py
+++ b/tempest/api/network/admin/test_routers.py
@@ -20,6 +20,7 @@
from tempest.common import utils
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
CONF = config.CONF
@@ -38,7 +39,8 @@
# associate a cleanup with created routers to avoid quota limits
router = self.create_router(name, admin_state_up,
external_network_id, enable_snat)
- self.addCleanup(self._cleanup_router, router)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self._cleanup_router, router)
return router
@classmethod
@@ -62,7 +64,8 @@
name = data_utils.rand_name('router-')
create_body = self.admin_routers_client.create_router(
name=name, tenant_id=project_id)
- self.addCleanup(self.admin_routers_client.delete_router,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_routers_client.delete_router,
create_body['router']['id'])
self.assertEqual(project_id, create_body['router']['tenant_id'])
@@ -92,7 +95,8 @@
'enable_snat': enable_snat}
create_body = self.admin_routers_client.create_router(
name=name, external_gateway_info=external_gateway_info)
- self.addCleanup(self.admin_routers_client.delete_router,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_routers_client.delete_router,
create_body['router']['id'])
# Verify snat attributes after router creation
self._verify_router_gateway(create_body['router']['id'],
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
index 93478e6..270f802 100644
--- a/tempest/api/network/admin/test_routers_dvr.py
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -18,6 +18,7 @@
from tempest.api.network import base
from tempest.common import utils
from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -62,7 +63,8 @@
name = data_utils.rand_name('router')
router = self.admin_routers_client.create_router(name=name,
distributed=True)
- self.addCleanup(self.admin_routers_client.delete_router,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_routers_client.delete_router,
router['router']['id'])
self.assertTrue(router['router']['distributed'])
@@ -82,7 +84,8 @@
name = data_utils.rand_name('router')
router = self.admin_routers_client.create_router(name=name,
distributed=False)
- self.addCleanup(self.admin_routers_client.delete_router,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_routers_client.delete_router,
router['router']['id'])
self.assertFalse(router['router']['distributed'])
@@ -112,8 +115,8 @@
ha=False,
tenant_id=tenant_id)
router_id = router['router']['id']
- self.addCleanup(self.admin_routers_client.delete_router,
- router_id)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_routers_client.delete_router, router_id)
self.assertFalse(router['router']['distributed'])
router = self.admin_routers_client.update_router(
router_id, distributed=True)
diff --git a/tempest/api/network/admin/test_routers_negative.py b/tempest/api/network/admin/test_routers_negative.py
index 9356bcc..f605945 100644
--- a/tempest/api/network/admin/test_routers_negative.py
+++ b/tempest/api/network/admin/test_routers_negative.py
@@ -18,6 +18,8 @@
from tempest.api.network import base
from tempest.common import utils
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
@@ -41,8 +43,10 @@
def test_router_set_gateway_used_ip_returns_409(self):
# At first create a address from public_network_id
port = self.admin_ports_client.create_port(
+ name=data_utils.rand_name(self.__class__.__name__),
network_id=CONF.network.public_network_id)['port']
- self.addCleanup(self.admin_ports_client.delete_port,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_ports_client.delete_port,
port_id=port['id'])
# Add used ip and subnet_id in external_fixed_ips
fixed_ip = {
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 9032fdc..b6bf369 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -156,6 +156,8 @@
@classmethod
def create_port(cls, network, **kwargs):
+ if 'name' not in kwargs:
+ kwargs['name'] = data_utils.rand_name(cls.__name__)
"""Wrapper utility that returns a test port."""
body = cls.ports_client.create_port(network_id=network['id'],
**kwargs)
diff --git a/tempest/api/network/base_security_groups.py b/tempest/api/network/base_security_groups.py
index b8d677a..32f2cdd 100644
--- a/tempest/api/network/base_security_groups.py
+++ b/tempest/api/network/base_security_groups.py
@@ -15,6 +15,7 @@
from tempest.api.network import base
from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
class BaseSecGroupTest(base.BaseNetworkTest):
@@ -24,7 +25,8 @@
name = data_utils.rand_name('secgroup-')
group_create_body = (
self.security_groups_client.create_security_group(name=name))
- self.addCleanup(self._delete_security_group,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self._delete_security_group,
group_create_body['security_group']['id'])
self.assertEqual(group_create_body['security_group']['name'], name)
return group_create_body, name
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index dec3413..639defb 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -17,6 +17,8 @@
from tempest.api.network import base
from tempest.common import utils
+from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -60,9 +62,11 @@
'mac_address': self.mac_address}]
body = self.ports_client.create_port(
network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__),
allowed_address_pairs=allowed_address_pairs)
port_id = body['port']['id']
- self.addCleanup(self.ports_client.delete_port, port_id)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port_id)
# Confirm port was created with allowed address pair attribute
body = self.ports_client.list_ports()
@@ -74,9 +78,12 @@
def _update_port_with_address(self, address, mac_address=None, **kwargs):
# Create a port without allowed address pair
- body = self.ports_client.create_port(network_id=self.network['id'])
+ body = self.ports_client.create_port(
+ network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
port_id = body['port']['id']
- self.addCleanup(self.ports_client.delete_port, port_id)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port_id)
if mac_address is None:
mac_address = self.mac_address
@@ -104,9 +111,12 @@
@decorators.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
def test_update_port_with_multiple_ip_mac_address_pair(self):
# Create an ip _address and mac_address through port create
- resp = self.ports_client.create_port(network_id=self.network['id'])
+ resp = self.ports_client.create_port(
+ network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
newportid = resp['port']['id']
- self.addCleanup(self.ports_client.delete_port, newportid)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, newportid)
ipaddress = resp['port']['fixed_ips'][0]['ip_address']
macaddress = resp['port']['mac_address']
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 0d42033..d363081 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -16,6 +16,7 @@
from tempest.api.network import base
from tempest.common import utils
from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -60,9 +61,11 @@
# Create a port with Extra DHCP Options
body = self.ports_client.create_port(
network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__),
extra_dhcp_opts=self.extra_dhcp_opts)
port_id = body['port']['id']
- self.addCleanup(self.ports_client.delete_port, port_id)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port_id)
# Confirm port created has Extra DHCP Options
body = self.ports_client.list_ports()
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 504bfa8..aaa5497 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -18,6 +18,7 @@
from tempest.common.utils import data_utils
from tempest.common.utils import net_utils
from tempest import config
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
CONF = config.CONF
@@ -77,8 +78,10 @@
floating_network_id=self.ext_net_id,
port_id=self.ports[0]['id'])
created_floating_ip = body['floatingip']
- self.addCleanup(self.floating_ips_client.delete_floatingip,
- created_floating_ip['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.floating_ips_client.delete_floatingip,
+ created_floating_ip['id'])
self.assertIsNotNone(created_floating_ip['id'])
self.assertIsNotNone(created_floating_ip['tenant_id'])
self.assertIsNotNone(created_floating_ip['floating_ip_address'])
@@ -125,16 +128,23 @@
self.assertIsNone(updated_floating_ip['fixed_ip_address'])
self.assertIsNone(updated_floating_ip['router_id'])
+ # Explicity test deletion of floating IP
+ self.floating_ips_client.delete_floatingip(created_floating_ip['id'])
+
@decorators.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
def test_floating_ip_delete_port(self):
# Create a floating IP
body = self.floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id)
created_floating_ip = body['floatingip']
- self.addCleanup(self.floating_ips_client.delete_floatingip,
- created_floating_ip['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.floating_ips_client.delete_floatingip,
+ created_floating_ip['id'])
# Create a port
- port = self.ports_client.create_port(network_id=self.network['id'])
+ port = self.ports_client.create_port(
+ network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
created_port = port['port']
floating_ip = self.floating_ips_client.update_floatingip(
created_floating_ip['id'],
@@ -158,24 +168,36 @@
floating_network_id=self.ext_net_id,
port_id=self.ports[1]['id'])
created_floating_ip = body['floatingip']
- self.addCleanup(self.floating_ips_client.delete_floatingip,
- created_floating_ip['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.floating_ips_client.delete_floatingip,
+ created_floating_ip['id'])
self.assertEqual(created_floating_ip['router_id'], self.router['id'])
network_name = data_utils.rand_name(self.__class__.__name__)
network2 = self.networks_client.create_network(
name=network_name)['network']
- self.addCleanup(self.networks_client.delete_network,
- network2['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network,
+ network2['id'])
subnet2 = self.create_subnet(network2)
- self.addCleanup(self.subnets_client.delete_subnet, subnet2['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.subnets_client.delete_subnet, subnet2['id'])
router2 = self.create_router(external_network_id=self.ext_net_id)
- self.addCleanup(self.routers_client.delete_router, router2['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.routers_client.delete_router, router2['id'])
self.create_router_interface(router2['id'], subnet2['id'])
- self.addCleanup(self.routers_client.remove_router_interface,
- router2['id'], subnet_id=subnet2['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.routers_client.remove_router_interface,
+ router2['id'], subnet_id=subnet2['id'])
port_other_router = self.create_port(network2)
- self.addCleanup(self.ports_client.delete_port,
- port_other_router['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port,
+ port_other_router['id'])
# Associate floating IP to the other port on another router
floating_ip = self.floating_ips_client.update_floatingip(
created_floating_ip['id'],
@@ -194,8 +216,10 @@
port_id=self.ports[1]['id'],
fixed_ip_address=self.ports[1]['fixed_ips'][0]['ip_address'])
created_floating_ip = body['floatingip']
- self.addCleanup(self.floating_ips_client.delete_floatingip,
- created_floating_ip['id'])
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.floating_ips_client.delete_floatingip,
+ created_floating_ip['id'])
self.assertIsNotNone(created_floating_ip['id'])
self.assertEqual(created_floating_ip['fixed_ip_address'],
self.ports[1]['fixed_ips'][0]['ip_address'])
@@ -215,17 +239,21 @@
2)
fixed_ips = [{'ip_address': list_ips[0]}, {'ip_address': list_ips[1]}]
# Create port
- body = self.ports_client.create_port(network_id=self.network['id'],
- fixed_ips=fixed_ips)
+ body = self.ports_client.create_port(
+ network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__),
+ fixed_ips=fixed_ips)
port = body['port']
- self.addCleanup(self.ports_client.delete_port, port['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port['id'])
# Create floating ip
body = self.floating_ips_client.create_floatingip(
floating_network_id=self.ext_net_id,
port_id=port['id'],
fixed_ip_address=list_ips[0])
floating_ip = body['floatingip']
- self.addCleanup(self.floating_ips_client.delete_floatingip,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.floating_ips_client.delete_floatingip,
floating_ip['id'])
self.assertIsNotNone(floating_ip['id'])
self.assertEqual(floating_ip['fixed_ip_address'], list_ips[0])
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index e904a81..1688c9d 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -17,6 +17,7 @@
from tempest.api.network import base
from tempest.common import utils
from tempest import config
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
@@ -81,6 +82,7 @@
floating_network_id=self.ext_net_id)
floating_ip = body['floatingip']
self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
self.floating_ips_client.delete_floatingip, floating_ip['id'])
# Associate floating IP to the other port
self.assertRaises(
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index ed8eb52..eba1f6c 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -160,7 +160,8 @@
def test_create_update_delete_network_subnet(self):
# Create a network
network = self.create_network()
- self.addCleanup(self.networks_client.delete_network, network['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network, network['id'])
net_id = network['id']
self.assertEqual('ACTIVE', network['status'])
# Verify network update
@@ -176,6 +177,8 @@
body = self.subnets_client.update_subnet(subnet_id, name=new_name)
updated_subnet = body['subnet']
self.assertEqual(updated_subnet['name'], new_name)
+ # Verify network delete
+ self.networks_client.delete_network(network['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
@@ -313,7 +316,8 @@
@decorators.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
def test_update_subnet_gw_dns_host_routes_dhcp(self):
network = self.create_network()
- self.addCleanup(self.networks_client.delete_network, network['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(
network, **self.subnet_dict(['gateway', 'host_routes',
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index bc4f41f..3af67dd 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -79,7 +79,8 @@
non_exist_net_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound,
self.ports_client.create_port,
- network_id=non_exist_net_id)
+ network_id=non_exist_net_id,
+ name=data_utils.rand_name(self.__class__.__name__))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('cf8eef21-4351-4f53-adcd-cc5cb1e76b92')
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 25976ce..56b5509 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -23,6 +23,7 @@
from tempest.common import custom_matchers
from tempest.common import utils
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
@@ -52,7 +53,8 @@
def _create_subnet(self, network, gateway='',
cidr=None, mask_bits=None, **kwargs):
subnet = self.create_subnet(network, gateway, cidr, mask_bits)
- self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.subnets_client.delete_subnet, subnet['id'])
return subnet
def _create_network(self, network_name=None, **kwargs):
@@ -60,7 +62,8 @@
self.__class__.__name__)
network = self.networks_client.create_network(
name=network_name, **kwargs)['network']
- self.addCleanup(self.networks_client.delete_network,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network,
network['id'])
return network
@@ -68,7 +71,9 @@
@decorators.idempotent_id('c72c1c0c-2193-4aca-aaa4-b1442640f51c')
def test_create_update_delete_port(self):
# Verify port creation
- body = self.ports_client.create_port(network_id=self.network['id'])
+ body = self.ports_client.create_port(
+ network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
port = body['port']
# Schedule port deletion with verification upon test completion
self.addCleanup(self._delete_port, port['id'])
@@ -115,14 +120,18 @@
self._create_subnet(network, cidr=address,
mask_bits=address.prefixlen,
**allocation_pools)
- body = self.ports_client.create_port(network_id=net_id)
- self.addCleanup(self.ports_client.delete_port, body['port']['id'])
+ body = self.ports_client.create_port(
+ network_id=net_id,
+ name=data_utils.rand_name(self.__class__.__name__))
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, body['port']['id'])
port = body['port']
ip_address = port['fixed_ips'][0]['ip_address']
start_ip_address = allocation_pools['allocation_pools'][0]['start']
end_ip_address = allocation_pools['allocation_pools'][0]['end']
ip_range = netaddr.IPRange(start_ip_address, end_ip_address)
self.assertIn(ip_address, ip_range)
+ self.ports_client.delete_port(port['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('c9a685bd-e83f-499c-939f-9f7863ca259f')
@@ -167,10 +176,16 @@
network = self._create_network()
self._create_subnet(network)
# Create two ports
- port_1 = self.ports_client.create_port(network_id=network['id'])
- self.addCleanup(self.ports_client.delete_port, port_1['port']['id'])
- port_2 = self.ports_client.create_port(network_id=network['id'])
- self.addCleanup(self.ports_client.delete_port, port_2['port']['id'])
+ port_1 = self.ports_client.create_port(
+ network_id=network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port_1['port']['id'])
+ port_2 = self.ports_client.create_port(
+ network_id=network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port_2['port']['id'])
# List ports filtered by fixed_ips
port_1_fixed_ip = port_1['port']['fixed_ips'][0]['ip_address']
fixed_ips = 'ip_address=' + port_1_fixed_ip
@@ -217,13 +232,19 @@
# Create two ports
fixed_ips = [{'subnet_id': subnet['id'], 'ip_address': ip_address_1}]
- port_1 = self.ports_client.create_port(network_id=network['id'],
- fixed_ips=fixed_ips)
- self.addCleanup(self.ports_client.delete_port, port_1['port']['id'])
+ port_1 = self.ports_client.create_port(
+ network_id=network['id'],
+ name=data_utils.rand_name(self.__class__.__name__),
+ fixed_ips=fixed_ips)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port_1['port']['id'])
fixed_ips = [{'subnet_id': subnet['id'], 'ip_address': ip_address_2}]
- port_2 = self.ports_client.create_port(network_id=network['id'],
- fixed_ips=fixed_ips)
- self.addCleanup(self.ports_client.delete_port, port_2['port']['id'])
+ port_2 = self.ports_client.create_port(
+ network_id=network['id'],
+ name=data_utils.rand_name(self.__class__.__name__),
+ fixed_ips=fixed_ips)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port_2['port']['id'])
# Scenario 1: List port1 (port2 is filtered out)
if ip_address_1[:-1] != ip_address_2[:-1]:
@@ -272,12 +293,16 @@
network = self._create_network()
self._create_subnet(network)
router = self.create_router()
- self.addCleanup(self.routers_client.delete_router, router['id'])
- port = self.ports_client.create_port(network_id=network['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.routers_client.delete_router, router['id'])
+ port = self.ports_client.create_port(
+ network_id=network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
# Add router interface to port created above
self.routers_client.add_router_interface(router['id'],
port_id=port['port']['id'])
- self.addCleanup(self.routers_client.remove_router_interface,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.routers_client.remove_router_interface,
router['id'], port_id=port['port']['id'])
# List ports filtered by router_id
port_list = self.ports_client.list_ports(device_id=router['id'])
@@ -311,7 +336,8 @@
# Create a port with multiple IP addresses
port = self.create_port(network,
fixed_ips=fixed_ips)
- self.addCleanup(self.ports_client.delete_port, port['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port['id'])
self.assertEqual(2, len(port['fixed_ips']))
check_fixed_ips = [subnet_1['id'], subnet_2['id']]
for item in port['fixed_ips']:
@@ -334,7 +360,8 @@
for name in security_groups_names:
group_create_body = sec_grps_client.create_security_group(
name=name)
- self.addCleanup(self.security_groups_client.delete_security_group,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.security_groups_client.delete_security_group,
group_create_body['security_group']['id'])
security_groups_list.append(group_create_body['security_group']
['id'])
@@ -342,25 +369,28 @@
sec_grp_name = data_utils.rand_name('secgroup')
security_group = sec_grps_client.create_security_group(
name=sec_grp_name)
- self.addCleanup(self.security_groups_client.delete_security_group,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.security_groups_client.delete_security_group,
security_group['security_group']['id'])
post_body = {
- "name": data_utils.rand_name('port-'),
+ "name": data_utils.rand_name(self.__class__.__name__),
"security_groups": [security_group['security_group']['id']],
"network_id": self.network['id'],
"admin_state_up": True,
"fixed_ips": fixed_ip_1}
body = self.ports_client.create_port(**post_body)
- self.addCleanup(self.ports_client.delete_port, body['port']['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, body['port']['id'])
port = body['port']
# Update the port with security groups
subnet_2 = self.create_subnet(self.network)
fixed_ip_2 = [{'subnet_id': subnet_2['id']}]
- update_body = {"name": data_utils.rand_name('port-'),
- "admin_state_up": False,
- "fixed_ips": fixed_ip_2,
- "security_groups": security_groups_list}
+ update_body = {
+ "name": data_utils.rand_name(self.__class__.__name__),
+ "admin_state_up": False,
+ "fixed_ips": fixed_ip_2,
+ "security_groups": security_groups_list}
body = self.ports_client.update_port(port['id'], **update_body)
port_show = body['port']
# Verify the security groups and other attributes updated to port
@@ -395,14 +425,19 @@
@decorators.idempotent_id('13e95171-6cbd-489c-9d7c-3f9c58215c18')
def test_create_show_delete_port_user_defined_mac(self):
# Create a port for a legal mac
- body = self.ports_client.create_port(network_id=self.network['id'])
+ body = self.ports_client.create_port(
+ network_id=self.network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
old_port = body['port']
free_mac_address = old_port['mac_address']
self.ports_client.delete_port(old_port['id'])
# Create a new port with user defined mac
- body = self.ports_client.create_port(network_id=self.network['id'],
- mac_address=free_mac_address)
- self.addCleanup(self.ports_client.delete_port, body['port']['id'])
+ body = self.ports_client.create_port(
+ network_id=self.network['id'],
+ mac_address=free_mac_address,
+ name=data_utils.rand_name(self.__class__.__name__))
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, body['port']['id'])
port = body['port']
body = self.ports_client.show_port(port['id'])
show_port = body['port']
@@ -418,7 +453,8 @@
network = self._create_network()
self._create_subnet(network)
port = self.create_port(network, security_groups=[])
- self.addCleanup(self.ports_client.delete_port, port['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.ports_client.delete_port, port['id'])
self.assertIsNotNone(port['security_groups'])
self.assertEmpty(port['security_groups'])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index be3cf65..ad316d1 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -20,6 +20,7 @@
from tempest.common import utils
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
CONF = config.CONF
@@ -89,10 +90,11 @@
network_name = data_utils.rand_name(self.__class__.__name__)
network = self.networks_client.create_network(
name=network_name)['network']
- self.addCleanup(self.networks_client.delete_network,
- network['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(network)
- self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.subnets_client.delete_subnet, subnet['id'])
router = self.create_router()
self.addCleanup(self.delete_router, router)
# Add router interface with subnet id
@@ -114,19 +116,21 @@
network_name = data_utils.rand_name(self.__class__.__name__)
network = self.networks_client.create_network(
name=network_name)['network']
- self.addCleanup(self.networks_client.delete_network,
- network['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(network)
self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
router = self.create_router()
self.addCleanup(self.delete_router, router)
port_body = self.ports_client.create_port(
- network_id=network['id'])
+ network_id=network['id'],
+ name=data_utils.rand_name(self.__class__.__name__))
# add router interface to port created above
interface = self.routers_client.add_router_interface(
router['id'],
port_id=port_body['port']['id'])
- self.addCleanup(self.routers_client.remove_router_interface,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.routers_client.remove_router_interface,
router['id'], port_id=port_body['port']['id'])
self.assertIn('subnet_id', interface.keys())
self.assertIn('port_id', interface.keys())
@@ -135,6 +139,8 @@
interface['port_id'])
self.assertEqual(show_port_body['port']['device_id'],
router['id'])
+ self.routers_client.remove_router_interface(
+ router['id'], port_id=port_body['port']['id'])
@decorators.idempotent_id('cbe42f84-04c2-11e7-8adb-fa163e4fa634')
@utils.requires_ext(extension='ext-gw-mode', service='network')
@@ -145,6 +151,7 @@
# Don't know public_network_address, so at first create address
# from public_network and delete
port = self.admin_ports_client.create_port(
+ name=data_utils.rand_name(self.__class__.__name__),
network_id=CONF.network.public_network_id)['port']
self.admin_ports_client.delete_port(port_id=port['id'])
@@ -160,7 +167,8 @@
# Create a router and set gateway to fixed_ip
router = self.admin_routers_client.create_router(
external_gateway_info=external_gateway_info)['router']
- self.addCleanup(self.admin_routers_client.delete_router,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.admin_routers_client.delete_router,
router_id=router['id'])
# Examine router's gateway is equal to fixed_ip
self.assertEqual(router['external_gateway_info'][
@@ -188,10 +196,12 @@
network_name = data_utils.rand_name(self.__class__.__name__)
network = self.networks_client.create_network(
name=network_name)['network']
- self.addCleanup(self.networks_client.delete_network,
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network,
network['id'])
subnet = self.create_subnet(network, cidr=next_cidr)
- self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.subnets_client.delete_subnet, subnet['id'])
next_cidr = next_cidr.next()
# Add router interface with subnet id
@@ -254,18 +264,20 @@
network_name = data_utils.rand_name(self.__class__.__name__)
network01 = self.networks_client.create_network(
name=network_name)['network']
- self.addCleanup(self.networks_client.delete_network,
- network01['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network, network01['id'])
network_name = data_utils.rand_name(self.__class__.__name__)
network02 = self.networks_client.create_network(
name=network_name)['network']
- self.addCleanup(self.networks_client.delete_network,
- network02['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network, network02['id'])
subnet01 = self.create_subnet(network01)
- self.addCleanup(self.subnets_client.delete_subnet, subnet01['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.subnets_client.delete_subnet, subnet01['id'])
sub02_cidr = self.cidr.next()
subnet02 = self.create_subnet(network02, cidr=sub02_cidr)
- self.addCleanup(self.subnets_client.delete_subnet, subnet02['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.subnets_client.delete_subnet, subnet02['id'])
router = self.create_router()
self.addCleanup(self.delete_router, router)
interface01 = self._add_router_interface_with_subnet_id(router['id'],
@@ -282,10 +294,11 @@
network_name = data_utils.rand_name(self.__class__.__name__)
network = self.networks_client.create_network(
name=network_name)['network']
- self.addCleanup(self.networks_client.delete_network,
- network['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(network)
- self.addCleanup(self.subnets_client.delete_subnet, subnet['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.subnets_client.delete_subnet, subnet['id'])
router = self.create_router()
self.addCleanup(self.delete_router, router)
fixed_ip = [{'subnet_id': subnet['id']}]
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index ffc1fca..ef19122 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -16,6 +16,7 @@
from tempest.api.network import base_security_groups as base
from tempest.common import utils
from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
@@ -49,8 +50,8 @@
)
sec_group_rule = rule_create_body['security_group_rule']
- self.addCleanup(self._delete_security_group_rule,
- sec_group_rule['id'])
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self._delete_security_group_rule, sec_group_rule['id'])
expected = {'direction': direction, 'protocol': protocol,
'ethertype': ethertype, 'port_range_min': port_range_min,
@@ -104,6 +105,8 @@
self.assertEqual(show_body['security_group']['name'], new_name)
self.assertEqual(show_body['security_group']['description'],
new_description)
+ # Delete security group
+ self._delete_security_group(group_create_body['security_group']['id'])
@decorators.attr(type='smoke')
@decorators.idempotent_id('cfb99e0e-7410-4a3d-8a0c-959a63ee77e9')
@@ -138,6 +141,8 @@
for rule in rule_list_body['security_group_rules']]
self.assertIn(rule_create_body['security_group_rule']['id'],
rule_list)
+ self._delete_security_group_rule(
+ rule_create_body['security_group_rule']['id'])
@decorators.idempotent_id('87dfbcf9-1849-43ea-b1e4-efa3eeae9f71')
def test_create_security_group_rule_with_additional_args(self):
@@ -170,7 +175,14 @@
sg_id = group_create_body['security_group']['id']
direction = 'ingress'
- protocol = 'icmp'
+ # The Neutron API accepts 'icmp', 'icmpv6' and 'ipv6-icmp' for
+ # IPv6 ICMP protocol names, but the latter is preferred and the
+ # others considered "legacy". Use 'ipv6-icmp' as the API could
+ # change to return only that value, see
+ # https://review.opendev.org/#/c/453346/
+ # The neutron-tempest-plugin API tests pass all three and verify
+ # the output, so there is no need to duplicate that here.
+ protocol = 'ipv6-icmp' if self._ip_version == 6 else 'icmp'
icmp_type_codes = [(3, 2), (3, 0), (8, 0), (0, 0), (11, None)]
for icmp_type, icmp_code in icmp_type_codes:
self._create_verify_security_group_rule(sg_id, direction,
diff --git a/tempest/api/volume/admin/test_backends_capabilities.py b/tempest/api/volume/admin/test_backends_capabilities.py
index affed6b..1351704 100644
--- a/tempest/api/volume/admin/test_backends_capabilities.py
+++ b/tempest/api/volume/admin/test_backends_capabilities.py
@@ -21,17 +21,6 @@
class BackendsCapabilitiesAdminTestsJSON(base.BaseVolumeAdminTest):
- CAPABILITIES = ('namespace',
- 'vendor_name',
- 'volume_backend_name',
- 'pool_name',
- 'driver_version',
- 'storage_protocol',
- 'display_name',
- 'description',
- 'visibility',
- 'properties')
-
@classmethod
def resource_setup(cls):
super(BackendsCapabilitiesAdminTestsJSON, cls).resource_setup()
@@ -44,12 +33,8 @@
@decorators.idempotent_id('3750af44-5ea2-4cd4-bc3e-56e7e6caf854')
def test_get_capabilities_backend(self):
# Test backend properties
- backend = self.admin_capabilities_client.show_backend_capabilities(
- self.hosts[0])
-
- # Verify getting capabilities parameters from a backend
- for key in self.CAPABILITIES:
- self.assertIn(key, backend)
+ # Check response schema
+ self.admin_capabilities_client.show_backend_capabilities(self.hosts[0])
@decorators.idempotent_id('a9035743-d46a-47c5-9cb7-3c80ea16dea0')
def test_compare_volume_stats_values(self):
diff --git a/tempest/api/volume/admin/test_user_messages.py b/tempest/api/volume/admin/test_user_messages.py
index 9907497..8048017 100644
--- a/tempest/api/volume/admin/test_user_messages.py
+++ b/tempest/api/volume/admin/test_user_messages.py
@@ -20,18 +20,6 @@
CONF = config.CONF
-MESSAGE_KEYS = [
- 'created_at',
- 'event_id',
- 'guaranteed_until',
- 'id',
- 'message_level',
- 'request_id',
- 'resource_type',
- 'resource_uuid',
- 'user_message',
- 'links']
-
class UserMessagesTest(base.BaseVolumeAdminTest):
_api_version = 3
@@ -66,18 +54,11 @@
message_id = self._create_user_message()
self.addCleanup(self.messages_client.delete_message, message_id)
- # show message
- message = self.messages_client.show_message(message_id)['message']
- for key in MESSAGE_KEYS:
- self.assertIn(key, message.keys(), 'Missing expected key %s' % key)
+ # show message, check response schema
+ self.messages_client.show_message(message_id)
- # list messages
- messages = self.messages_client.list_messages()['messages']
- self.assertIsInstance(messages, list)
- for message in messages:
- for key in MESSAGE_KEYS:
- self.assertIn(key, message.keys(),
- 'Missing expected key %s' % key)
+ # list messages, check response schema
+ self.messages_client.list_messages()
@decorators.idempotent_id('c6eb6901-cdcc-490f-b735-4fe251842aed')
def test_delete_message(self):
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 7e53ce8..83c27e1 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -26,13 +26,6 @@
"The count of volume hosts is < 2, "
"response of list hosts is: %s" % hosts)
- # Check elements in volume hosts list
- host_list_keys = ['service', 'host_name', 'last-update',
- 'zone', 'service-status', 'service-state']
- for host in hosts:
- for key in host_list_keys:
- self.assertIn(key, host)
-
@decorators.idempotent_id('21168d57-b373-4b71-a3ac-f2c88f0c5d31')
def test_show_host(self):
hosts = self.admin_hosts_client.list_hosts()['hosts']
@@ -53,12 +46,6 @@
"all hosts that found are: %s" % hosts)
# Check each cinder-volume host.
- host_detail_keys = ['project', 'volume_count', 'snapshot_count',
- 'host', 'total_volume_gb', 'total_snapshot_gb']
for host in c_vol_hosts:
host_details = self.admin_hosts_client.show_host(host)['host']
self.assertNotEmpty(host_details)
- for detail in host_details:
- self.assertIn('resource', detail)
- for key in host_detail_keys:
- self.assertIn(key, detail['resource'])
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 053a7d9..b073604 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -19,7 +19,6 @@
QUOTA_KEYS = ['gigabytes', 'snapshots', 'volumes', 'backups',
'backup_gigabytes', 'per_volume_gigabytes']
-QUOTA_USAGE_KEYS = ['reserved', 'limit', 'in_use']
class VolumeQuotasAdminTestJSON(base.BaseVolumeAdminTest):
@@ -55,17 +54,13 @@
@decorators.idempotent_id('59eada70-403c-4cef-a2a3-a8ce2f1b07a0')
def test_list_quotas(self):
- quotas = (self.admin_quotas_client.show_quota_set(self.demo_tenant_id)
- ['quota_set'])
- for key in QUOTA_KEYS:
- self.assertIn(key, quotas)
+ # Check response schema
+ self.admin_quotas_client.show_quota_set(self.demo_tenant_id)
@decorators.idempotent_id('2be020a2-5fdd-423d-8d35-a7ffbc36e9f7')
def test_list_default_quotas(self):
- quotas = self.admin_quotas_client.show_default_quota_set(
- self.demo_tenant_id)['quota_set']
- for key in QUOTA_KEYS:
- self.assertIn(key, quotas)
+ # Check response schema
+ self.admin_quotas_client.show_default_quota_set(self.demo_tenant_id)
@decorators.idempotent_id('3d45c99e-cc42-4424-a56e-5cbd212b63a6')
def test_update_all_quota_resources_for_tenant(self):
@@ -92,13 +87,9 @@
@decorators.idempotent_id('18c51ae9-cb03-48fc-b234-14a19374dbed')
def test_show_quota_usage(self):
- quota_usage = self.admin_quotas_client.show_quota_set(
- self.os_admin.credentials.tenant_id,
- params={'usage': True})['quota_set']
- for key in QUOTA_KEYS:
- self.assertIn(key, quota_usage)
- for usage_key in QUOTA_USAGE_KEYS:
- self.assertIn(usage_key, quota_usage[key])
+ # Check response schema
+ self.admin_quotas_client.show_quota_set(
+ self.os_admin.credentials.tenant_id, params={'usage': True})
@decorators.idempotent_id('874b35a9-51f1-4258-bec5-cd561b6690d3')
def test_delete_quota(self):
diff --git a/tempest/api/volume/admin/test_volume_retype.py b/tempest/api/volume/admin/test_volume_retype.py
index 9136139..18e0b9b 100644
--- a/tempest/api/volume/admin/test_volume_retype.py
+++ b/tempest/api/volume/admin/test_volume_retype.py
@@ -94,7 +94,7 @@
super(VolumeRetypeTest, cls).skip_checks()
if not CONF.volume_feature_enabled.multi_backend:
- raise cls.skipException("Cinder multi-backend feature disabled.")
+ raise cls.skipException("Cinder multi-backend feature disabled")
if len(set(CONF.volume.backend_names)) < 2:
raise cls.skipException("Requires at least two different "
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 64fe29a..1bfd075 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -124,6 +124,10 @@
name = data_utils.rand_name(cls.__name__ + '-Volume')
kwargs['name'] = name
+ if CONF.compute.compute_volume_common_az:
+ kwargs.setdefault('availability_zone',
+ CONF.compute.compute_volume_common_az)
+
volume = cls.volumes_client.create_volume(**kwargs)['volume']
cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
cls.delete_volume, cls.volumes_client,
diff --git a/tempest/api/volume/test_versions.py b/tempest/api/volume/test_versions.py
index b4d48db..b602032 100644
--- a/tempest/api/volume/test_versions.py
+++ b/tempest/api/volume/test_versions.py
@@ -27,3 +27,15 @@
# with JSON-Schema validation. It is enough to just call
# the API here.
self.versions_client.list_versions()
+
+ @decorators.idempotent_id('7f755ae2-caa9-4049-988c-331d8f7a579f')
+ def test_show_version(self):
+ # NOTE: The version data is checked on service client side
+ # with JSON-Schema validation. So we will loop through each
+ # version and call show version.
+ versions = self.versions_client.list_versions()['versions']
+ for version_dict in versions:
+ version = version_dict['id']
+ major_version = version.split('.')[0]
+ response = self.versions_client.show_version(major_version)
+ self.assertEqual(version, response['versions'][0]['id'])
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index c85e0bc..4cdf898 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -63,8 +63,6 @@
# Accept a volume transfer by alt_tenant
body = self.alt_client.accept_volume_transfer(
transfer_id, auth_key=auth_key)['transfer']
- for key in ['id', 'name', 'links', 'volume_id']:
- self.assertIn(key, body)
waiters.wait_for_volume_resource_status(self.alt_volumes_client,
volume['id'], 'available')
accepted_volume = self.alt_volumes_client.show_volume(
@@ -95,8 +93,6 @@
# elements, and look for the created transfer.
transfers = self.client.list_volume_transfers(detail=True)['transfers']
self.assertNotEmpty(transfers)
- for transfer in transfers:
- self.assertIn('created_at', transfer)
volume_list = [transfer['volume_id'] for transfer in transfers]
self.assertIn(volume['id'], volume_list,
'Transfer not found for volume %s' % volume['id'])
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index ac9a9c7..c3f44e2 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -32,7 +32,7 @@
@decorators.idempotent_id('9a36df71-a257-43a5-9555-dc7c88e66e0e')
def test_volume_extend(self):
# Extend Volume Test.
- volume = self.create_volume(image_ref=self.image_ref)
+ volume = self.create_volume(imageRef=self.image_ref)
extend_size = volume['size'] * 2
self.volumes_client.extend_volume(volume['id'],
new_size=extend_size)
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index d5358ab..2345698 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -17,7 +17,7 @@
import operator
import random
-from six.moves.urllib import parse
+from six.moves.urllib.parse import urlparse
from testtools import matchers
from tempest.api.volume import base
@@ -333,7 +333,19 @@
# If the current iteration is from a 'next' link, check that the
# absolute url is the same as the one used for this request
if next:
- self.assertEqual(next, response.response['content-location'])
+ curr = response.response['content-location']
+ currparsed = urlparse(curr)
+ nextparsed = urlparse(next)
+ # Depending on the environment, certain fields are omitted
+ # from url (ie port). The fields to check are defined here.
+ fieldscheck = ['scheme', 'hostname', 'path', 'query', 'params',
+ 'fragment']
+ for field in fieldscheck:
+ self.assertEqual(getattr(currparsed, field),
+ getattr(nextparsed, field),
+ 'Incorrect link to next page. URLs do '
+ 'not match at %s:\n%s\n%s' % (field, curr,
+ next))
# Get next from response
next = None
@@ -352,7 +364,7 @@
# If we can follow to the next page, get params from url to make
# request in the form of a relative URL
if next:
- params = parse.urlparse(next).query
+ params = urlparse(next).query
# If cannot follow make sure it's because we have finished
else:
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 1855386..72e7290 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -44,7 +44,7 @@
server = self.create_server()
# NOTE(zhufl) Here we create volume from self.image_ref for adding
# coverage for "creating snapshot from non-blank volume".
- volume = self.create_volume(image_ref=self.image_ref)
+ volume = self.create_volume(imageRef=self.image_ref)
self.attach_volume(server['id'], volume['id'])
# Snapshot a volume which attached to an instance with force=False
diff --git a/tempest/clients.py b/tempest/clients.py
index 0506646..6aed92e 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -69,6 +69,9 @@
self.network_versions_client = self.network.NetworkVersionsClient()
self.service_providers_client = self.network.ServiceProvidersClient()
self.tags_client = self.network.TagsClient()
+ self.qos_client = self.network.QosClient()
+ self.qos_min_bw_client = self.network.QosMinimumBandwidthRulesClient()
+ self.segments_client = self.network.SegmentsClient()
def _set_image_clients(self):
if CONF.service_available.glance:
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index e6db2e9..645a952 100644
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
# Copyright 2014 Dell Inc.
# 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
@@ -72,6 +70,15 @@
deleted unless the ``--delete-tempest-conf-objects`` flag is used to
force their deletion.
+.. note::
+
+ If during execution of ``tempest cleanup`` NotImplemented exception
+ occurres, ``tempest cleanup`` won't fail on that, it will be logged only.
+ NotImplemented errors are ignored because they are an outcome of some
+ extensions being disabled and ``tempest cleanup`` is not checking their
+ availability as it tries to clean up as much as possible without any
+ complicated logic.
+
"""
import sys
import traceback
@@ -85,6 +92,7 @@
from tempest.common import credentials_factory as credentials
from tempest.common import identity
from tempest import config
+from tempest.lib import exceptions
SAVED_STATE_JSON = "saved_state.json"
DRY_RUN_JSON = "dry_run.json"
@@ -94,6 +102,8 @@
class TempestCleanup(command.Command):
+ GOT_EXCEPTIONS = []
+
def take_action(self, parsed_args):
try:
self.init(parsed_args)
@@ -103,6 +113,14 @@
LOG.exception("Failure during cleanup")
traceback.print_exc()
raise
+ # ignore NotImplemented errors as those are an outcome of some
+ # extensions being disabled and cleanup is not checking their
+ # availability as it tries to clean up as much as possible without
+ # any complicated logic
+ critical_exceptions = [ex for ex in self.GOT_EXCEPTIONS if
+ not isinstance(ex, exceptions.NotImplemented)]
+ if critical_exceptions:
+ raise Exception(self.GOT_EXCEPTIONS)
def init(self, parsed_args):
cleanup_service.init_conf()
@@ -159,7 +177,8 @@
'is_dry_run': is_dry_run,
'saved_state_json': self.json_data,
'is_preserve': is_preserve,
- 'is_save_state': is_save_state}
+ 'is_save_state': is_save_state,
+ 'got_exceptions': self.GOT_EXCEPTIONS}
for service in self.global_services:
svc = service(admin_mgr, **kwargs)
svc.run()
@@ -200,7 +219,8 @@
'saved_state_json': self.json_data,
'is_preserve': is_preserve,
'is_save_state': False,
- 'project_id': project_id}
+ 'project_id': project_id,
+ 'got_exceptions': self.GOT_EXCEPTIONS}
for service in self.project_services:
svc = service(mgr, **kwargs)
svc.run()
@@ -300,7 +320,8 @@
'is_dry_run': False,
'saved_state_json': data,
'is_preserve': False,
- 'is_save_state': True}
+ 'is_save_state': True,
+ 'got_exceptions': self.GOT_EXCEPTIONS}
for service in self.global_services:
svc = service(admin_mgr, **kwargs)
svc.run()
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 104958a..8b625d0 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
# Copyright 2015 Dell Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -22,6 +20,7 @@
from tempest.common import utils
from tempest.common.utils import net_info
from tempest import config
+from tempest.lib import exceptions
LOG = logging.getLogger(__name__)
CONF = config.CONF
@@ -127,12 +126,23 @@
pass
def run(self):
- if self.is_dry_run:
- self.dry_run()
- elif self.is_save_state:
- self.save_state()
- else:
- self.delete()
+ try:
+ if self.is_dry_run:
+ self.dry_run()
+ elif self.is_save_state:
+ self.save_state()
+ else:
+ self.delete()
+ except exceptions.NotImplemented as exc:
+ # Many OpenStack services use extensions logic to implement the
+ # features or resources. Tempest cleanup tries to clean up the test
+ # resources without having much logic of extensions checks etc.
+ # If any of the extension is missing then, service will return
+ # NotImplemented error.
+ msg = ("Got NotImplemented error in %s, full exception: %s" %
+ (str(self.__class__), str(exc)))
+ LOG.exception(msg)
+ self.got_exceptions.append(exc)
class SnapshotService(BaseService):
@@ -843,7 +853,7 @@
def __init__(self, manager, **kwargs):
super(RoleService, self).__init__(kwargs)
- self.client = manager.roles_client
+ self.client = manager.roles_v3_client
def list(self):
try:
diff --git a/tempest/cmd/list_plugins.py b/tempest/cmd/list_plugins.py
index 86732da..51decc7 100644
--- a/tempest/cmd/list_plugins.py
+++ b/tempest/cmd/list_plugins.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-
# 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
diff --git a/tempest/cmd/run.py b/tempest/cmd/run.py
index 77d4496..f9ca2c7 100644
--- a/tempest/cmd/run.py
+++ b/tempest/cmd/run.py
@@ -19,11 +19,11 @@
==============
Tempest run has several options:
- * **--regex/-r**: This is a selection regex like what stestr uses. It will run
- any tests that match on re.match() with the regex
- * **--smoke/-s**: Run all the tests tagged as smoke
- * **--black-regex**: It allows to do simple test exclusion via passing a
- rejection/black regexp
+* ``--regex/-r``: This is a selection regex like what stestr uses. It will run
+ any tests that match on re.match() with the regex
+* ``--smoke/-s``: Run all the tests tagged as smoke
+* ``--black-regex``: It allows to do simple test exclusion via passing a
+ rejection/black regexp
There are also the ``--blacklist-file`` and ``--whitelist-file`` options that
let you pass a filepath to tempest run with the file format being a line
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 1489e60..cd85ede 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -167,6 +167,9 @@
params = {'name': volume_name,
'imageRef': image_id,
'size': CONF.volume.volume_size}
+ if CONF.compute.compute_volume_common_az:
+ params.setdefault('availability_zone',
+ CONF.compute.compute_volume_common_az)
volume = volumes_client.create_volume(**params)
try:
waiters.wait_for_volume_resource_status(volumes_client,
@@ -193,6 +196,9 @@
# to be specified.
image_id = ''
+ if CONF.compute.compute_volume_common_az:
+ kwargs.setdefault('availability_zone',
+ CONF.compute.compute_volume_common_az)
body = clients.servers_client.create_server(name=name, imageRef=image_id,
flavorRef=flavor,
**kwargs)
@@ -392,8 +398,11 @@
def _upgrade(self, url):
"""Upgrade the HTTP connection to a WebSocket and verify."""
- # The real request goes to the /websockify URI always
- reqdata = 'GET /websockify HTTP/1.1\r\n'
+ # It is possible to pass the path as a query parameter in the request,
+ # so use it if present
+ qparams = urlparse.parse_qs(url.query)
+ path = qparams['path'][0] if 'path' in qparams else '/websockify'
+ reqdata = 'GET %s HTTP/1.1\r\n' % path
reqdata += 'Host: %s' % url.hostname
# Add port only if we have one specified
if url.port:
@@ -402,7 +411,7 @@
reqdata += '\r\n'
# Tell the HTTP Server to Upgrade the connection to a WebSocket
reqdata += 'Upgrade: websocket\r\nConnection: Upgrade\r\n'
- # The token=xxx is sent as a Cookie not in the URI
+ # The token=xxx is sent as a Cookie not in the URI for noVNC < v1.1.0
reqdata += 'Cookie: %s\r\n' % url.query
# Use a hard-coded WebSocket key since a test program
reqdata += 'Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n'
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 49d9742..dad710c 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -148,7 +148,7 @@
self.exec_command('sudo umount %s' % mount_path)
def make_fs(self, dev_name, fs='ext4'):
- cmd_mkfs = 'sudo /usr/sbin/mke2fs -t %s /dev/%s' % (fs, dev_name)
+ cmd_mkfs = 'sudo mke2fs -t %s /dev/%s' % (fs, dev_name)
try:
self.exec_command(cmd_mkfs)
except tempest.lib.exceptions.SSHExecCommandFailed:
@@ -156,3 +156,53 @@
cmd_why = 'sudo ls -lR /dev'
LOG.info("Contents of /dev: %s", self.exec_command(cmd_why))
raise
+
+ def nc_listen_host(self, port=80, protocol='tcp'):
+ """Creates persistent nc server listening on the given TCP / UDP port
+
+ :port: the port to start listening on.
+ :protocol: the protocol used by the server. TCP by default.
+ """
+ udp = '-u' if protocol.lower() == 'udp' else ''
+ cmd = "sudo nc %(udp)s -p %(port)s -lk -e echo foolish &" % {
+ 'udp': udp, 'port': port}
+ return self.exec_command(cmd)
+
+ def nc_host(self, host, port=80, protocol='tcp', expected_response=None):
+ """Check connectivity to TCP / UDP port at host via nc
+
+ :host: an IP against which the connectivity will be tested.
+ :port: the port to check connectivity against.
+ :protocol: the protocol used by nc to send packets. TCP by default.
+ :expected_response: string representing the expected response
+ from server.
+ :raises SSHExecCommandFailed: if an expected response is given and it
+ does not match the actual server response.
+ """
+ udp = '-u' if protocol.lower() == 'udp' else ''
+ cmd = 'echo "bar" | nc -w 1 %(udp)s %(host)s %(port)s' % {
+ 'udp': udp, 'host': host, 'port': port}
+ response = self.exec_command(cmd)
+
+ # sending an UDP packet will always succeed. we need to check
+ # the response.
+ if (expected_response is not None and
+ expected_response != response.strip()):
+ raise tempest.lib.exceptions.SSHExecCommandFailed(
+ command=cmd, exit_status=0, stdout=response, stderr='')
+ return response
+
+ def icmp_check(self, host, nic=None):
+ """Wrapper for icmp connectivity checks"""
+ return self.ping_host(host, nic=nic)
+
+ def udp_check(self, host, **kwargs):
+ """Wrapper for udp connectivity checks."""
+ kwargs.pop('nic', None)
+ return self.nc_host(host, protocol='udp', expected_response='foolish',
+ **kwargs)
+
+ def tcp_check(self, host, **kwargs):
+ """Wrapper for tcp connectivity checks."""
+ kwargs.pop('nic', None)
+ return self.nc_host(host, **kwargs)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 77ec0f8..11f3bf9 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -121,7 +121,9 @@
'/'.join((server_status, str(task_state))),
time.time() - start_time)
if server_status == 'ERROR' and not ignore_error:
- raise lib_exc.DeleteErrorException(resource_id=server_id)
+ raise lib_exc.DeleteErrorException(
+ "Server %s failed to delete and is in ERROR status" %
+ server_id)
if int(time.time()) - start_time >= client.build_timeout:
raise lib_exc.TimeoutException
@@ -202,6 +204,8 @@
resource_name=resource_name, resource_id=resource_id)
if resource_name == 'volume' and resource_status == 'error_restoring':
raise exceptions.VolumeRestoreErrorException(volume_id=resource_id)
+ if resource_status == 'error_extending' and resource_status != status:
+ raise exceptions.VolumeExtendErrorException(volume_id=resource_id)
if int(time.time()) - start >= client.build_timeout:
message = ('%s %s failed to reach %s status (current %s) '
diff --git a/tempest/config.py b/tempest/config.py
index 24ae3ae..d67d3e0 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -69,10 +69,7 @@
cfg.StrOpt('default_credentials_domain_name',
default='Default',
help="Default domain used when getting v3 credentials. "
- "This is the name keystone uses for v2 compatibility.",
- deprecated_opts=[cfg.DeprecatedOpt(
- 'tenant_isolation_domain_name',
- group='auth')]),
+ "This is the name keystone uses for v2 compatibility."),
cfg.BoolOpt('create_isolated_networks',
default=True,
help="If use_dynamic_credentials is set to True and Neutron "
@@ -84,27 +81,20 @@
cfg.StrOpt('admin_username',
help="Username for an administrative user. This is needed for "
"authenticating requests made by project isolation to "
- "create users and projects",
- deprecated_group='identity'),
+ "create users and projects"),
cfg.StrOpt('admin_project_name',
help="Project name to use for an administrative user. This is "
"needed for authenticating requests made by project "
- "isolation to create users and projects",
- deprecated_opts=[cfg.DeprecatedOpt('admin_tenant_name',
- group='auth'),
- cfg.DeprecatedOpt('admin_tenant_name',
- group='identity')]),
+ "isolation to create users and projects"),
cfg.StrOpt('admin_password',
help="Password to use for an administrative user. This is "
"needed for authenticating requests made by project "
"isolation to create users and projects",
- secret=True,
- deprecated_group='identity'),
+ secret=True),
cfg.StrOpt('admin_domain_name',
default='Default',
help="Admin domain name for authentication (Keystone V3). "
- "The same domain applies to user and project",
- deprecated_group='identity'),
+ "The same domain applies to user and project"),
]
identity_group = cfg.OptGroup(name='identity',
@@ -146,9 +136,7 @@
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The public endpoint type to use for OpenStack Identity "
- "(Keystone) API v2",
- deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
- group='identity')]),
+ "(Keystone) API v2"),
cfg.StrOpt('v3_endpoint_type',
default='adminURL',
choices=['public', 'admin', 'internal',
@@ -283,6 +271,17 @@
help="Valid secondary image reference to be used in tests. "
"This is a required option, but if only one image is "
"available duplicate the value of image_ref above"),
+ cfg.StrOpt('certified_image_ref',
+ help="Valid image reference to be used in image certificate "
+ "validation tests when enabled. This image must also "
+ "have the required img_signature_* properties set. "
+ "Additional details available within the following Nova "
+ "documentation: https://docs.openstack.org/nova/latest/"
+ "user/certificate-validation.html"),
+ cfg.ListOpt('certified_image_trusted_certs',
+ help="A list of trusted certificates to be used when the "
+ "image certificate validation compute feature is "
+ "enabled."),
cfg.StrOpt('flavor_ref',
default="1",
help="Valid primary flavor to use in tests."),
@@ -364,6 +363,19 @@
"If both values are not specified, Tempest avoids tests "
"which require a microversion. Valid values are string "
"with format 'X.Y' or string 'latest'"),
+ cfg.StrOpt('compute_volume_common_az',
+ default=None,
+ help='AZ to be used for Cinder and Nova. Set this parameter '
+ 'when the cloud has nova.conf: cinder.cross_az_attach '
+ 'set to false. Which means volumes attached to an '
+ 'instance must be in the same availability zone in Cinder '
+ 'as the instance availability zone in Nova. Set the '
+ 'common availability zone in this config which will be '
+ 'used to boot an instance as well as creating a volume. '
+ 'NOTE: If that AZ is not in Cinder (or '
+ 'allow_availability_zone_fallback=False in cinder.conf), '
+ 'the volume create request will fail and the instance '
+ 'will fail the build request.'),
]
placement_group = cfg.OptGroup(name='placement',
@@ -471,7 +483,12 @@
cfg.StrOpt('vnc_server_header',
default='WebSockify',
help='Expected VNC server name (WebSockify, nginx, etc) '
- 'in response header.'),
+ 'in response header.',
+ deprecated_for_removal=True,
+ deprecated_reason='This option will be ignored because the '
+ 'usage of different response header fields '
+ 'to accomplish the same goal (in accordance '
+ 'with RFC7231 S6.2.2) makes it obsolete.'),
cfg.BoolOpt('spice_console',
default=False,
help='Enable Spice console. This configuration value should '
@@ -523,9 +540,8 @@
default=True,
help='Enable special configuration drive with metadata.'),
cfg.ListOpt('scheduler_enabled_filters',
- default=["RetryFilter", "AvailabilityZoneFilter",
- "ComputeFilter", "ComputeCapabilitiesFilter",
- "ImagePropertiesFilter",
+ default=["AvailabilityZoneFilter", "ComputeFilter",
+ "ComputeCapabilitiesFilter", "ImagePropertiesFilter",
"ServerGroupAntiAffinityFilter",
"ServerGroupAffinityFilter"],
help="A list of enabled filters that Nova will accept as "
@@ -685,7 +701,10 @@
cfg.ListOpt('dns_servers',
default=["8.8.8.8", "8.8.4.4"],
help="List of dns servers which should be used"
- " for subnet creation"),
+ " for subnet creation",
+ deprecated_for_removal=True,
+ deprecated_reason="This config option is no longer "
+ "used anywhere, so it can be removed."),
cfg.StrOpt('port_vnic_type',
choices=[None, 'normal', 'direct', 'macvtap'],
help="vnic_type to use when launching instances"
@@ -735,7 +754,13 @@
help="Does the test environment support port security?"),
cfg.BoolOpt('floating_ips',
default=True,
- help='Does the test environment support floating_ips')
+ help='Does the test environment support floating_ips'),
+ cfg.StrOpt('qos_placement_physnet', default=None,
+ help='Name of the physnet for placement based minimum '
+ 'bandwidth allocation.'),
+ cfg.StrOpt('provider_net_base_segmentation_id', default=3000,
+ help='Base segmentation ID to create provider networks. '
+ 'This value will be increased in case of conflict.')
]
validation_group = cfg.OptGroup(name='validation',
@@ -786,7 +811,7 @@
default="password",
help="Password used to authenticate to an instance."),
cfg.StrOpt('ssh_shell_prologue',
- default="set -eu -o pipefail; PATH=$$PATH:/sbin;",
+ default="set -eu -o pipefail; PATH=$$PATH:/sbin:/usr/sbin;",
help="Shell fragments to use before executing a command "
"when sshing to a guest."),
cfg.IntOpt('ping_size',
@@ -1049,7 +1074,12 @@
choices=["udhcpc", "dhclient", ""],
help='DHCP client used by images to renew DCHP lease. '
'If left empty, update operation will be skipped. '
- 'Supported clients: "udhcpc", "dhclient"')
+ 'Supported clients: "udhcpc", "dhclient"'),
+ cfg.StrOpt('protocol',
+ default='icmp',
+ choices=('icmp', 'tcp', 'udp'),
+ help='The protocol used in security groups tests to check '
+ 'connectivity.'),
]
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
old mode 100644
new mode 100755
index a430d5d..c05e7a6
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -42,6 +42,11 @@
message = "Volume %(volume_id)s failed to restore and is in ERROR status"
+class VolumeExtendErrorException(exceptions.TempestException):
+ message = ("Volume %(volume_id)s failed to extend and "
+ "is in error_extending status")
+
+
class StackBuildErrorException(exceptions.TempestException):
message = ("Stack %(stack_identifier)s is in %(stack_status)s status "
"due to '%(stack_status_reason)s'")
diff --git a/tempest/lib/api_schema/response/compute/v2_16/servers.py b/tempest/lib/api_schema/response/compute/v2_16/servers.py
index 72b84f5..fc81ff7 100644
--- a/tempest/lib/api_schema/response/compute/v2_16/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_16/servers.py
@@ -168,3 +168,6 @@
servers.rebuild_server_with_admin_pass)
show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
get_remote_consoles = copy.deepcopy(servers.get_remote_consoles)
+attach_volume = copy.deepcopy(servers.attach_volume)
+show_volume_attachment = copy.deepcopy(servers.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_19/servers.py b/tempest/lib/api_schema/response/compute/v2_19/servers.py
index e3e8ad1..b6c3c14 100644
--- a/tempest/lib/api_schema/response/compute/v2_19/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_19/servers.py
@@ -58,3 +58,6 @@
list_servers = copy.deepcopy(serversv216.list_servers)
show_server_diagnostics = copy.deepcopy(serversv216.show_server_diagnostics)
get_remote_consoles = copy.deepcopy(serversv216.get_remote_consoles)
+attach_volume = copy.deepcopy(serversv216.attach_volume)
+show_volume_attachment = copy.deepcopy(serversv216.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(serversv216.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_26/servers.py b/tempest/lib/api_schema/response/compute/v2_26/servers.py
index 8e62dc3..5a0f987 100644
--- a/tempest/lib/api_schema/response/compute/v2_26/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_26/servers.py
@@ -101,3 +101,6 @@
list_servers = copy.deepcopy(servers219.list_servers)
show_server_diagnostics = copy.deepcopy(servers219.show_server_diagnostics)
get_remote_consoles = copy.deepcopy(servers219.get_remote_consoles)
+attach_volume = copy.deepcopy(servers219.attach_volume)
+show_volume_attachment = copy.deepcopy(servers219.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers219.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_3/servers.py b/tempest/lib/api_schema/response/compute/v2_3/servers.py
index 18fb352..1674c1b 100644
--- a/tempest/lib/api_schema/response/compute/v2_3/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_3/servers.py
@@ -173,3 +173,6 @@
rebuild_server_with_admin_pass = copy.deepcopy(
servers.rebuild_server_with_admin_pass)
show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
+attach_volume = copy.deepcopy(servers.attach_volume)
+show_volume_attachment = copy.deepcopy(servers.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_47/servers.py b/tempest/lib/api_schema/response/compute/v2_47/servers.py
index 0fbacd3..d580f2c 100644
--- a/tempest/lib/api_schema/response/compute/v2_47/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_47/servers.py
@@ -66,3 +66,6 @@
update_tag = copy.deepcopy(servers226.update_tag)
delete_tag = copy.deepcopy(servers226.delete_tag)
list_servers = copy.deepcopy(servers226.list_servers)
+attach_volume = copy.deepcopy(servers226.attach_volume)
+show_volume_attachment = copy.deepcopy(servers226.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers226.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_48/servers.py b/tempest/lib/api_schema/response/compute/v2_48/servers.py
index 84b5a2a..e2e45bc 100644
--- a/tempest/lib/api_schema/response/compute/v2_48/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_48/servers.py
@@ -129,3 +129,6 @@
rebuild_server = copy.deepcopy(servers247.rebuild_server)
rebuild_server_with_admin_pass = copy.deepcopy(
servers247.rebuild_server_with_admin_pass)
+attach_volume = copy.deepcopy(servers247.attach_volume)
+show_volume_attachment = copy.deepcopy(servers247.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers247.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_54/servers.py b/tempest/lib/api_schema/response/compute/v2_54/servers.py
index 099e1b8..2c2bff0 100644
--- a/tempest/lib/api_schema/response/compute/v2_54/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_54/servers.py
@@ -55,3 +55,6 @@
check_tag_existence = copy.deepcopy(servers248.check_tag_existence)
update_tag = copy.deepcopy(servers248.update_tag)
delete_tag = copy.deepcopy(servers248.delete_tag)
+attach_volume = copy.deepcopy(servers248.attach_volume)
+show_volume_attachment = copy.deepcopy(servers248.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers248.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_57/servers.py b/tempest/lib/api_schema/response/compute/v2_57/servers.py
index 0099a2b..aa57d25 100644
--- a/tempest/lib/api_schema/response/compute/v2_57/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_57/servers.py
@@ -59,3 +59,6 @@
check_tag_existence = copy.deepcopy(servers254.check_tag_existence)
update_tag = copy.deepcopy(servers254.update_tag)
delete_tag = copy.deepcopy(servers254.delete_tag)
+attach_volume = copy.deepcopy(servers254.attach_volume)
+show_volume_attachment = copy.deepcopy(servers254.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers254.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_6/servers.py b/tempest/lib/api_schema/response/compute/v2_6/servers.py
index d5774de..922bf79 100644
--- a/tempest/lib/api_schema/response/compute/v2_6/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_6/servers.py
@@ -28,6 +28,9 @@
rebuild_server_with_admin_pass = copy.deepcopy(
servers.rebuild_server_with_admin_pass)
show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
+attach_volume = copy.deepcopy(servers.attach_volume)
+show_volume_attachment = copy.deepcopy(servers.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers.list_volume_attachments)
# NOTE: The consolidated remote console API got introduced with v2.6
# with bp/consolidate-console-api. See Nova commit 578bafeda
diff --git a/tempest/lib/api_schema/response/compute/v2_63/servers.py b/tempest/lib/api_schema/response/compute/v2_63/servers.py
index 3c3d41c..01910aa 100644
--- a/tempest/lib/api_schema/response/compute/v2_63/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_63/servers.py
@@ -73,3 +73,6 @@
check_tag_existence = copy.deepcopy(servers257.check_tag_existence)
update_tag = copy.deepcopy(servers257.update_tag)
delete_tag = copy.deepcopy(servers257.delete_tag)
+attach_volume = copy.deepcopy(servers257.attach_volume)
+show_volume_attachment = copy.deepcopy(servers257.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers257.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_70/__init__.py b/tempest/lib/api_schema/response/compute/v2_70/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_70/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_70/servers.py b/tempest/lib/api_schema/response/compute/v2_70/servers.py
new file mode 100644
index 0000000..5ca4cc8
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_70/servers.py
@@ -0,0 +1,80 @@
+# 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 servers as servers2_1
+from tempest.lib.api_schema.response.compute.v2_63 import servers as servers263
+
+
+###########################################################################
+#
+# 2.70:
+#
+# Exposes virtual device tags for volume attachments and virtual interfaces
+# (ports). A tag parameter is added to the response body for the following
+# APIs:
+#
+# Volumes
+#
+# - GET /servers/{server_id}/os-volume_attachments (list)
+# - GET /servers/{server_id}/os-volume_attachments/{volume_id} (show)
+# - POST /servers/{server_id}/os-volume_attachments (attach)
+#
+# Ports
+#
+# - GET /servers/{server_id}/os-interface (list)
+# - GET /servers/{server_id}/os-interface/{port_id} (show)
+# - POST /servers/{server_id}/os-interface (attach)
+#
+###########################################################################
+
+attach_volume = copy.deepcopy(servers2_1.attach_volume)
+attach_volume['response_body']['properties']['volumeAttachment'][
+ 'properties'].update({'tag': {'type': ['string', 'null']}})
+attach_volume['response_body']['properties']['volumeAttachment'][
+ 'required'].append('tag')
+
+show_volume_attachment = copy.deepcopy(servers2_1.show_volume_attachment)
+show_volume_attachment['response_body']['properties']['volumeAttachment'][
+ 'properties'].update({'tag': {'type': ['string', 'null']}})
+show_volume_attachment['response_body']['properties'][
+ 'volumeAttachment']['required'].append('tag')
+
+list_volume_attachments = copy.deepcopy(servers2_1.list_volume_attachments)
+list_volume_attachments['response_body']['properties']['volumeAttachments'][
+ 'items']['properties'].update({'tag': {'type': ['string', 'null']}})
+list_volume_attachments['response_body']['properties'][
+ 'volumeAttachments']['items']['required'].append('tag')
+
+# TODO(mriedem): Handle the os-interface changes when there is a test that
+# needs them from this microversion onward.
+
+# NOTE(lajoskatona): Below are the unchanged schema in this microversion. We
+# need to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.63 ***
+list_servers_detail = copy.deepcopy(servers263.list_servers_detail)
+rebuild_server = copy.deepcopy(servers263.rebuild_server)
+rebuild_server_with_admin_pass = copy.deepcopy(
+ servers263.rebuild_server_with_admin_pass)
+update_server = copy.deepcopy(servers263.update_server)
+get_server = copy.deepcopy(servers263.get_server)
+list_servers = copy.deepcopy(servers263.list_servers)
+show_server_diagnostics = copy.deepcopy(servers263.show_server_diagnostics)
+get_remote_consoles = copy.deepcopy(servers263.get_remote_consoles)
+list_tags = copy.deepcopy(servers263.list_tags)
+update_all_tags = copy.deepcopy(servers263.update_all_tags)
+delete_all_tags = copy.deepcopy(servers263.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers263.check_tag_existence)
+update_tag = copy.deepcopy(servers263.update_tag)
+delete_tag = copy.deepcopy(servers263.delete_tag)
diff --git a/tempest/lib/api_schema/response/compute/v2_71/__init__.py b/tempest/lib/api_schema/response/compute/v2_71/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_71/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_71/servers.py b/tempest/lib/api_schema/response/compute/v2_71/servers.py
new file mode 100644
index 0000000..0c526fb
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_71/servers.py
@@ -0,0 +1,81 @@
+# 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_70 import servers as servers270
+
+
+###########################################################################
+#
+# 2.71:
+#
+# The server_groups parameter will be in the response body of the following
+# APIs to list the server groups to which the server belongs:
+#
+# - GET /servers/{server_id} (show)
+# - PUT /servers/{server_id} (update)
+# - POST /servers/{server_id}/action (rebuild)
+#
+###########################################################################
+
+# The "server_groups" parameter will always be present and contain at most one
+# UUID entry.
+server_groups = {
+ 'type': 'array',
+ 'minItems': 0,
+ 'maxItems': 1,
+ 'items': {
+ 'type': 'string',
+ 'format': 'uuid'
+ }
+}
+
+rebuild_server = copy.deepcopy(servers270.rebuild_server)
+rebuild_server['response_body']['properties']['server'][
+ 'properties'].update({'server_groups': server_groups})
+rebuild_server['response_body']['properties']['server'][
+ 'required'].append('server_groups')
+
+rebuild_server_with_admin_pass = copy.deepcopy(
+ servers270.rebuild_server_with_admin_pass)
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+ 'properties'].update({'server_groups': server_groups})
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+ 'required'].append('server_groups')
+
+update_server = copy.deepcopy(servers270.update_server)
+update_server['response_body']['properties']['server'][
+ 'properties'].update({'server_groups': server_groups})
+update_server['response_body']['properties']['server'][
+ 'required'].append('server_groups')
+
+get_server = copy.deepcopy(servers270.get_server)
+get_server['response_body']['properties']['server'][
+ 'properties'].update({'server_groups': server_groups})
+get_server['response_body']['properties']['server'][
+ 'required'].append('server_groups')
+
+# NOTE(lajoskatona): Below are the unchanged schema in this microversion. We
+# need to keep this schema in this file to have the generic way to select the
+# right schema based on self.schema_versions_info mapping in service client.
+# ****** Schemas unchanged since microversion 2.70 ***
+list_servers_details = copy.deepcopy(servers270.list_servers_detail)
+list_servers = copy.deepcopy(servers270.list_servers)
+show_server_diagnostics = copy.deepcopy(servers270.show_server_diagnostics)
+get_remote_consoles = copy.deepcopy(servers270.get_remote_consoles)
+list_tags = copy.deepcopy(servers270.list_tags)
+update_all_tags = copy.deepcopy(servers270.update_all_tags)
+delete_all_tags = copy.deepcopy(servers270.delete_all_tags)
+check_tag_existence = copy.deepcopy(servers270.check_tag_existence)
+update_tag = copy.deepcopy(servers270.update_tag)
+delete_tag = copy.deepcopy(servers270.delete_tag)
diff --git a/tempest/lib/api_schema/response/compute/v2_8/servers.py b/tempest/lib/api_schema/response/compute/v2_8/servers.py
index df7847f..3dbab3f 100644
--- a/tempest/lib/api_schema/response/compute/v2_8/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_8/servers.py
@@ -35,3 +35,6 @@
rebuild_server_with_admin_pass = copy.deepcopy(
servers.rebuild_server_with_admin_pass)
show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
+attach_volume = copy.deepcopy(servers.attach_volume)
+show_volume_attachment = copy.deepcopy(servers.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/compute/v2_9/servers.py b/tempest/lib/api_schema/response/compute/v2_9/servers.py
index 55f8e75..ee0313d 100644
--- a/tempest/lib/api_schema/response/compute/v2_9/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_9/servers.py
@@ -54,3 +54,6 @@
list_servers = copy.deepcopy(servers.list_servers)
show_server_diagnostics = copy.deepcopy(servers.show_server_diagnostics)
get_remote_consoles = copy.deepcopy(servers.get_remote_consoles)
+attach_volume = copy.deepcopy(servers.attach_volume)
+show_volume_attachment = copy.deepcopy(servers.show_volume_attachment)
+list_volume_attachments = copy.deepcopy(servers.list_volume_attachments)
diff --git a/tempest/lib/api_schema/response/volume/capabilities.py b/tempest/lib/api_schema/response/volume/capabilities.py
new file mode 100644
index 0000000..ec60fc3
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/capabilities.py
@@ -0,0 +1,55 @@
+# Copyright 2018 ZTE 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.
+
+property_info = {
+ 'type': 'object',
+ 'properties': {
+ 'type': {'type': 'string'},
+ 'description': {'type': 'string'},
+ 'title': {'type': 'string'}
+ },
+ 'additionalProperties': False,
+ 'required': ['type', 'description', 'title']
+}
+
+show_backend_capabilities = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'pool_name': {'type': ['string', 'null']},
+ 'description': {'type': ['string', 'null']},
+ 'volume_backend_name': {'type': 'string'},
+ 'namespace': {'type': 'string',
+ 'pattern': '^OS::Storage::Capabilities::.+$'},
+ 'visibility': {'type': ['string', 'null']},
+ 'driver_version': {'type': 'string'},
+ 'vendor_name': {'type': 'string'},
+ 'properties': {
+ 'type': 'object',
+ 'properties': {
+ '^.+$': property_info
+ },
+ },
+ 'storage_protocol': {'type': 'string'},
+ 'replication_targets': {'type': 'array'},
+ 'display_name': {'type': ['string', 'null']}
+ },
+ 'additionalProperties': False,
+ 'required': ['pool_name', 'volume_backend_name', 'namespace',
+ 'visibility', 'driver_version', 'vendor_name',
+ 'properties', 'storage_protocol', 'replication_targets',
+ 'display_name', 'description']
+ }
+}
diff --git a/tempest/lib/api_schema/response/volume/extensions.py b/tempest/lib/api_schema/response/volume/extensions.py
new file mode 100644
index 0000000..8dcb07d
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/extensions.py
@@ -0,0 +1,43 @@
+# Copyright 2018 ZTE 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.api_schema.response.compute.v2_1 import parameter_types
+
+list_extensions = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'extensions': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'updated': parameter_types.date_time,
+ 'description': {'type': 'string'},
+ 'links': {'type': 'array'},
+ 'namespace': {'type': 'string'},
+ 'alias': {'type': 'string'},
+ 'name': {'type': 'string'}
+ },
+ 'additionalProperties': False,
+ 'required': ['updated', 'links', 'alias', 'name',
+ 'description']
+ }
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['extensions'],
+ }
+}
diff --git a/tempest/lib/api_schema/response/volume/hosts.py b/tempest/lib/api_schema/response/volume/hosts.py
new file mode 100644
index 0000000..ce67e9f
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/hosts.py
@@ -0,0 +1,81 @@
+# Copyright 2018 ZTE 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.api_schema.response.compute.v2_1 import parameter_types
+
+show_host = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'host': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'resource': {
+ 'type': 'object',
+ 'properties': {
+ 'volume_count': {'type': 'string'},
+ 'total_volume_gb': {'type': 'string'},
+ 'total_snapshot_gb': {'type': 'string'},
+ 'project': {'type': 'string'},
+ 'host': {'type': 'string'},
+ 'snapshot_count': {'type': 'string'},
+ },
+ 'additionalProperties': False,
+ 'required': ['volume_count', 'total_volume_gb',
+ 'total_snapshot_gb', 'project',
+ 'host', 'snapshot_count'],
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['resource']
+ }
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['host']
+ }
+}
+
+list_hosts = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'hosts': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'service-status': {
+ 'enum': ['available', 'unavailable']},
+ 'service': {'type': 'string'},
+ 'zone': {'type': 'string'},
+ 'service-state': {
+ 'enum': ['enabled', 'disabled']},
+ 'host_name': {'type': 'string'},
+ 'last-update': parameter_types.date_time_or_null
+ },
+ 'additionalProperties': False,
+ 'required': ['service-status', 'service', 'zone',
+ 'service-state', 'host_name', 'last-update']
+ }
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['hosts']
+ }
+}
diff --git a/tempest/lib/api_schema/response/volume/manage_snapshot.py b/tempest/lib/api_schema/response/volume/manage_snapshot.py
new file mode 100644
index 0000000..bbb9ee2
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/manage_snapshot.py
@@ -0,0 +1,49 @@
+# Copyright 2015 NEC 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.api_schema.response.compute.v2_1 import parameter_types
+
+manage_snapshot = {
+ 'status_code': [202],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'snapshot': {
+ 'type': 'object',
+ 'properties': {
+ 'status': {'type': 'string'},
+ 'size': {'type': 'integer'},
+ 'metadata': {
+ 'type': 'object',
+ 'patternProperties': {
+ '^.+$': {'type': 'string'}
+ }
+ },
+ 'name': {'type': ['string', 'null']},
+ 'volume_id': {'type': 'string', 'format': 'uuid'},
+ 'created_at': parameter_types.date_time,
+ 'description': {'type': ['string', 'null']},
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'updated_at': parameter_types.date_time_or_null
+ },
+ 'additionalProperties': False,
+ 'required': ['status', 'size', 'volume_id',
+ 'created_at', 'description', 'id', 'updated_at']
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['snapshot']
+ }
+}
diff --git a/tempest/lib/api_schema/response/volume/messages.py b/tempest/lib/api_schema/response/volume/messages.py
new file mode 100644
index 0000000..381f542
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/messages.py
@@ -0,0 +1,64 @@
+# Copyright 2018 ZTE 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.api_schema.response.compute.v2_1 import parameter_types
+
+delete_message = {
+ 'status_code': [204],
+}
+
+common_show_message = {
+ 'type': 'object',
+ 'properties': {
+ 'request_id': {'type': 'string'},
+ 'message_level': {'type': 'string'},
+ 'links': parameter_types.links,
+ 'event_id': {'type': 'string'},
+ 'created_at': parameter_types.date_time,
+ 'guaranteed_until': parameter_types.date_time,
+ 'resource_uuid': {'type': 'string', 'format': 'uuid'},
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'resource_type': {'type': 'string'},
+ 'user_message': {'type': 'string'}},
+ 'additionalProperties': False,
+ 'required': ['request_id', 'message_level', 'event_id', 'created_at',
+ 'id', 'user_message'],
+}
+
+show_message = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'message': common_show_message
+ },
+ 'additionalProperties': False,
+ 'required': ['message']
+ }
+}
+
+list_messages = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'messages': {
+ 'type': 'array',
+ 'items': common_show_message
+ },
+ },
+ 'additionalProperties': False,
+ 'required': ['messages']
+ }
+}
diff --git a/tempest/lib/api_schema/response/volume/quotas.py b/tempest/lib/api_schema/response/volume/quotas.py
new file mode 100644
index 0000000..4be584c
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/quotas.py
@@ -0,0 +1,92 @@
+# Copyright 2019 ZTE 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
+
+delete_quota_set = {
+ 'status_code': [200],
+}
+
+quota_usage_info = {
+ 'type': 'object',
+ 'properties': {
+ 'reserved': {'type': 'integer'},
+ 'allocated': {'type': 'integer'},
+ 'limit': {'type': 'integer'},
+ 'in_use': {'type': 'integer'}
+ },
+ 'additionalProperties': False,
+ # 'allocated' attribute is available only when nested quota is enabled.
+ 'required': ['reserved', 'limit', 'in_use'],
+}
+
+show_quota_set = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'quota_set': {
+ 'type': 'object',
+ 'properties': {
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'volumes': {'type': 'integer'},
+ 'snapshots': {'type': 'integer'},
+ 'backups': {'type': 'integer'},
+ 'groups': {'type': 'integer'},
+ 'per_volume_gigabytes': {'type': 'integer'},
+ 'gigabytes': {'type': 'integer'},
+ 'backup_gigabytes': {'type': 'integer'},
+ },
+ # for volumes_{volume_type}, etc
+ "additionalProperties": {'type': 'integer'},
+ 'required': ['id', 'volumes', 'snapshots', 'backups',
+ 'per_volume_gigabytes', 'gigabytes',
+ 'backup_gigabytes', 'groups'],
+ }
+ },
+ 'required': ['quota_set']
+ }
+}
+
+update_quota_set = copy.deepcopy(show_quota_set)
+update_quota_set['response_body']['properties']['quota_set'][
+ 'required'].remove('id')
+
+show_quota_set_usage = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'quota_set': {
+ 'type': 'object',
+ 'properties': {
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'volumes': quota_usage_info,
+ 'snapshots': quota_usage_info,
+ 'backups': quota_usage_info,
+ 'groups': quota_usage_info,
+ 'per_volume_gigabytes': quota_usage_info,
+ 'gigabytes': quota_usage_info,
+ 'backup_gigabytes': quota_usage_info,
+ },
+ # for volumes_{volume_type}, etc
+ "additionalProperties": quota_usage_info,
+ 'required': ['id', 'volumes', 'snapshots', 'backups',
+ 'per_volume_gigabytes', 'gigabytes',
+ 'backup_gigabytes', 'groups'],
+ }
+ },
+ 'required': ['quota_set']
+ }
+}
diff --git a/tempest/lib/api_schema/response/volume/services.py b/tempest/lib/api_schema/response/volume/services.py
new file mode 100644
index 0000000..70de878
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/services.py
@@ -0,0 +1,92 @@
+# Copyright 2018 ZTE 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 parameter_types
+
+list_services = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'services': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'binary': {'type': 'string'},
+ 'disabled_reason': {'type': ['string', 'null']},
+ 'host': {'type': 'string'},
+ 'state': {'enum': ['up', 'down']},
+ 'status': {'enum': ['enabled', 'disabled']},
+ 'frozen': {'type': 'boolean'},
+ 'updated_at': parameter_types.date_time,
+ 'zone': {'type': 'string'},
+ # TODO(zhufl): cluster is added in 3.7, we should move
+ # it to the 3.7 schema file when microversion is
+ # supported in volume interfaces
+ 'cluster': {'type': 'string'},
+ 'replication_status': {'type': 'string'},
+ 'active_backend_id': {'type': ['string', 'null']},
+ 'backend_state': {'type': 'string'},
+ },
+ 'additionalProperties': False,
+ 'required': ['binary', 'disabled_reason', 'host', 'state',
+ 'status', 'updated_at', 'zone']
+ }
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['services']
+ }
+}
+
+enable_service = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'disabled': {'type': 'boolean'},
+ 'status': {'enum': ['enabled', 'disabled']},
+ 'host': {'type': 'string'},
+ 'service': {'type': 'string'},
+ 'binary': {'type': 'string'},
+ 'disabled_reason': {'type': ['string', 'null']}
+ },
+ 'additionalProperties': False,
+ 'required': ['disabled', 'status', 'host', 'service',
+ 'binary', 'disabled_reason']
+ }
+}
+
+disable_service = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'disabled': {'type': 'boolean'},
+ 'status': {'enum': ['enabled', 'disabled']},
+ 'host': {'type': 'string'},
+ 'service': {'type': 'string'},
+ 'binary': {'type': 'string'},
+ },
+ 'additionalProperties': False,
+ 'required': ['disabled', 'status', 'host', 'service', 'binary']
+ }
+}
+
+disable_log_reason = copy.deepcopy(enable_service)
+
+freeze_host = {'status_code': [200]}
+thaw_host = {'status_code': [200]}
diff --git a/tempest/lib/api_schema/response/volume/transfers.py b/tempest/lib/api_schema/response/volume/transfers.py
new file mode 100644
index 0000000..d1d1b68
--- /dev/null
+++ b/tempest/lib/api_schema/response/volume/transfers.py
@@ -0,0 +1,129 @@
+# Copyright 2015 NEC 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.api_schema.response.compute.v2_1 import parameter_types
+
+create_volume_transfer = {
+ 'status_code': [202],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'transfer': {
+ 'type': 'object',
+ 'properties': {
+ 'auth_key': {'type': 'string'},
+ 'links': parameter_types.links,
+ 'created_at': parameter_types.date_time,
+ 'volume_id': {'type': 'string', 'format': 'uuid'},
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'name': {'type': ['string', 'null']}
+ },
+ 'additionalProperties': False,
+ 'required': ['auth_key', 'links', 'created_at',
+ 'volume_id', 'id', 'name']
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['transfer']
+ }
+}
+
+common_show_volume_transfer = {
+ 'type': 'object',
+ 'properties': {
+ 'links': parameter_types.links,
+ 'created_at': parameter_types.date_time,
+ 'volume_id': {'type': 'string', 'format': 'uuid'},
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'name': {'type': ['string', 'null']}
+ },
+ 'additionalProperties': False,
+ 'required': ['links', 'created_at', 'volume_id', 'id', 'name']
+}
+
+show_volume_transfer = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'transfer': common_show_volume_transfer
+ },
+ 'additionalProperties': False,
+ 'required': ['transfer']
+ }
+}
+
+list_volume_transfers_no_detail = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'transfers': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'volume_id': {'type': 'string', 'format': 'uuid'},
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'links': parameter_types.links,
+ 'name': {'type': ['string', 'null']}
+ },
+ 'additionalProperties': False,
+ 'required': ['volume_id', 'id', 'links', 'name']
+ }
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['transfers'],
+ }
+}
+
+list_volume_transfers_with_detail = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'transfers': {
+ 'type': 'array',
+ 'items': common_show_volume_transfer
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['transfers'],
+ }
+}
+
+delete_volume_transfer = {'status_code': [202]}
+
+accept_volume_transfer = {
+ 'status_code': [202],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'transfer': {
+ 'type': 'object',
+ 'properties': {
+ 'links': parameter_types.links,
+ 'volume_id': {'type': 'string', 'format': 'uuid'},
+ 'id': {'type': 'string', 'format': 'uuid'},
+ 'name': {'type': ['string', 'null']}
+ },
+ 'additionalProperties': False,
+ 'required': ['links', 'volume_id', 'id', 'name']
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['transfer']
+ }
+}
diff --git a/tempest/lib/api_schema/response/volume/versions.py b/tempest/lib/api_schema/response/volume/versions.py
old mode 100644
new mode 100755
index 2391a8c..c845f7f
--- a/tempest/lib/api_schema/response/volume/versions.py
+++ b/tempest/lib/api_schema/response/volume/versions.py
@@ -58,3 +58,49 @@
'required': ['versions'],
}
}
+
+volume_api_version_details = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'versions': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'status': {'type': 'string'},
+ 'updated': {'type': 'string'},
+ 'id': {'type': 'string'},
+ 'links': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'href': {'type': 'string',
+ 'format': 'uri'},
+ 'rel': {'type': 'string'},
+ 'type': {'type': 'string'},
+ },
+ 'required': ['href', 'rel']
+ }
+ },
+ 'min_version': {'type': 'string'},
+ 'version': {'type': 'string'},
+ 'media-types': {
+ 'type': 'array',
+ 'properties': {
+ 'base': {'type': 'string'},
+ 'type': {'type': 'string'}
+ },
+ 'required': ['base', 'type']
+ }
+ },
+ 'required': ['status', 'updated', 'id', 'links',
+ 'min_version', 'version', 'media-types']
+ }
+ }
+ },
+ 'required': ['versions'],
+ }
+}
diff --git a/tempest/lib/common/api_microversion_fixture.py b/tempest/lib/common/api_microversion_fixture.py
new file mode 100644
index 0000000..3837138
--- /dev/null
+++ b/tempest/lib/common/api_microversion_fixture.py
@@ -0,0 +1,82 @@
+# Copyright 2019 NEC 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 fixtures
+
+from tempest.lib.services.compute import base_compute_client
+from tempest.lib.services.placement import base_placement_client
+from tempest.lib.services.volume import base_client as base_volume_client
+
+
+class APIMicroversionFixture(fixtures.Fixture):
+ """API Microversion Fixture to set service microversion.
+
+ This class provides the fixture to set and reset the microversion
+ on service client. Service client has global variable to set the
+ microversion for that service API request.
+ For example: base_compute_client.COMPUTE_MICROVERSION
+ Global variable is always risky to set directly which can affect the
+ other test's API request also. This class provides a way to reset the
+ service microversion once test finish the API request.
+ This class can be used with useFixture: Example::
+
+ def setUp(self):
+ super(BaseV2ComputeTest, self).setUp()
+ self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+ compute_microversion=self.compute_request_microversion))
+
+ Or you can set microversion on multiple services together::
+
+ def setUp(self):
+ super(ScenarioTest, self).setUp()
+ self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+ compute_microversion=self.compute_request_microversion,
+ volume_microversion=self.volume_request_microversion))
+
+ Current supported services:
+ - Compute
+ - Volume
+ - Placement
+
+ :param str compute_microversion: microvesion to be set on compute
+ service clients
+ :param str volume_microversion: microvesion to be set on volume
+ service clients
+ :param str placement_microversion: microvesion to be set on placement
+ service clients
+ """
+
+ def __init__(self, compute_microversion=None, volume_microversion=None,
+ placement_microversion=None):
+ self.compute_microversion = compute_microversion
+ self.volume_microversion = volume_microversion
+ self.placement_microversion = placement_microversion
+
+ def _setUp(self):
+ super(APIMicroversionFixture, self)._setUp()
+ if self.compute_microversion:
+ base_compute_client.COMPUTE_MICROVERSION = (
+ self.compute_microversion)
+ if self.volume_microversion:
+ base_volume_client.VOLUME_MICROVERSION = self.volume_microversion
+ if self.placement_microversion:
+ base_placement_client.PLACEMENT_MICROVERSION = (
+ self.placement_microversion)
+
+ self.addCleanup(self._reset_microversion)
+
+ def _reset_microversion(self):
+ base_compute_client.COMPUTE_MICROVERSION = None
+ base_volume_client.VOLUME_MICROVERSION = None
+ base_placement_client.PLACEMENT_MICROVERSION = None
diff --git a/tempest/lib/services/compute/agents_client.py b/tempest/lib/services/compute/agents_client.py
index 408f75d..12b3900 100644
--- a/tempest/lib/services/compute/agents_client.py
+++ b/tempest/lib/services/compute/agents_client.py
@@ -28,7 +28,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-agent-builds
+ https://docs.openstack.org/api-ref/compute/#list-agent-builds
"""
url = 'os-agents'
if params:
@@ -43,7 +43,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-agent-build
+ https://docs.openstack.org/api-ref/compute/#create-agent-build
"""
post_body = json.dumps({'agent': kwargs})
resp, body = self.post('os-agents', post_body)
@@ -56,7 +56,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-agent-build
+ https://docs.openstack.org/api-ref/compute/#delete-agent-build
"""
resp, body = self.delete("os-agents/%s" % agent_id)
self.validate_response(schema.delete_agent, resp, body)
@@ -67,7 +67,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-agent-build
+ https://docs.openstack.org/api-ref/compute/#update-agent-build
"""
put_body = json.dumps({'para': kwargs})
resp, body = self.put('os-agents/%s' % agent_id, put_body)
diff --git a/tempest/lib/services/compute/aggregates_client.py b/tempest/lib/services/compute/aggregates_client.py
index 57f5e4e..c21cc16 100644
--- a/tempest/lib/services/compute/aggregates_client.py
+++ b/tempest/lib/services/compute/aggregates_client.py
@@ -51,7 +51,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-aggregate
+ https://docs.openstack.org/api-ref/compute/#create-aggregate
"""
post_body = json.dumps({'aggregate': kwargs})
resp, body = self.post('os-aggregates', post_body)
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-aggregate
+ https://docs.openstack.org/api-ref/compute/#update-aggregate
"""
put_body = json.dumps({'aggregate': kwargs})
resp, body = self.put('os-aggregates/%s' % aggregate_id, put_body)
@@ -100,7 +100,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#add-host
+ https://docs.openstack.org/api-ref/compute/#add-host
"""
post_body = json.dumps({'add_host': kwargs})
resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
@@ -115,7 +115,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#remove-host
+ https://docs.openstack.org/api-ref/compute/#remove-host
"""
post_body = json.dumps({'remove_host': kwargs})
resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
@@ -130,7 +130,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-or-update-aggregate-metadata
+ https://docs.openstack.org/api-ref/compute/#create-or-update-aggregate-metadata
"""
post_body = json.dumps({'set_metadata': kwargs})
resp, body = self.post('os-aggregates/%s/action' % aggregate_id,
diff --git a/tempest/lib/services/compute/baremetal_nodes_client.py b/tempest/lib/services/compute/baremetal_nodes_client.py
index e44c195..3efdbce 100644
--- a/tempest/lib/services/compute/baremetal_nodes_client.py
+++ b/tempest/lib/services/compute/baremetal_nodes_client.py
@@ -29,7 +29,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-bare-metal-nodes
+ https://docs.openstack.org/api-ref/compute/#list-bare-metal-nodes
"""
url = 'os-baremetal-nodes'
if params:
@@ -43,7 +43,7 @@
"""Show the details of a single baremetal node.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/compute/#show-bare-metal-node-details
+ https://docs.openstack.org/api-ref/compute/#show-bare-metal-node-details
"""
url = 'os-baremetal-nodes/%s' % baremetal_node_id
resp, body = self.get(url)
diff --git a/tempest/lib/services/compute/fixed_ips_client.py b/tempest/lib/services/compute/fixed_ips_client.py
index 968646c..098c856 100644
--- a/tempest/lib/services/compute/fixed_ips_client.py
+++ b/tempest/lib/services/compute/fixed_ips_client.py
@@ -34,7 +34,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#reserve-or-release-a-fixed-ip
+ https://docs.openstack.org/api-ref/compute/#reserve-or-release-a-fixed-ip
"""
url = "os-fixed-ips/%s/action" % fixed_ip
resp, body = self.post(url, json.dumps(kwargs))
diff --git a/tempest/lib/services/compute/flavors_client.py b/tempest/lib/services/compute/flavors_client.py
index 5d2dd46..e22b5b2 100644
--- a/tempest/lib/services/compute/flavors_client.py
+++ b/tempest/lib/services/compute/flavors_client.py
@@ -41,8 +41,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-flavors
- https://developer.openstack.org/api-ref/compute/#list-flavors-with-details
+ https://docs.openstack.org/api-ref/compute/#list-flavors
+ https://docs.openstack.org/api-ref/compute/#list-flavors-with-details
"""
url = 'flavors'
schema = self.get_schema(self.schema_versions_info)
@@ -64,7 +64,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-flavor-details
+ https://docs.openstack.org/api-ref/compute/#show-flavor-details
"""
resp, body = self.get("flavors/%s" % flavor_id)
body = json.loads(body)
@@ -78,7 +78,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-flavor
+ https://docs.openstack.org/api-ref/compute/#create-flavor
"""
if 'ephemeral' in kwargs:
kwargs['OS-FLV-EXT-DATA:ephemeral'] = kwargs.pop('ephemeral')
@@ -99,7 +99,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-flavor-description
+ https://docs.openstack.org/api-ref/compute/#update-flavor-description
"""
put_body = json.dumps({'flavor': kwargs})
resp, body = self.put("flavors/%s" % flavor_id, put_body)
@@ -115,7 +115,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-flavor
+ https://docs.openstack.org/api-ref/compute/#delete-flavor
"""
resp, body = self.delete("flavors/{0}".format(flavor_id))
self.validate_response(schema.delete_flavor, resp, body)
@@ -141,7 +141,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-extra-specs-for-a-flavor
+ https://docs.openstack.org/api-ref/compute/#create-extra-specs-for-a-flavor
"""
post_body = json.dumps({'extra_specs': kwargs})
resp, body = self.post('flavors/%s/os-extra_specs' % flavor_id,
@@ -156,7 +156,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-extra-specs-for-a-flavor
+ https://docs.openstack.org/api-ref/compute/#list-extra-specs-for-a-flavor
"""
resp, body = self.get('flavors/%s/os-extra_specs' % flavor_id)
body = json.loads(body)
@@ -169,7 +169,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-an-extra-spec-for-a-flavor
+ https://docs.openstack.org/api-ref/compute/#show-an-extra-spec-for-a-flavor
"""
resp, body = self.get('flavors/%s/os-extra_specs/%s' % (flavor_id,
key))
@@ -184,7 +184,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-an-extra-spec-for-a-flavor
+ https://docs.openstack.org/api-ref/compute/#update-an-extra-spec-for-a-flavor
"""
resp, body = self.put('flavors/%s/os-extra_specs/%s' %
(flavor_id, key), json.dumps(kwargs))
@@ -201,7 +201,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-an-extra-spec-for-a-flavor
+ https://docs.openstack.org/api-ref/compute/#delete-an-extra-spec-for-a-flavor
"""
resp, body = self.delete('flavors/%s/os-extra_specs/%s' %
(flavor_id, key))
@@ -214,7 +214,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-flavor-access-information-for-given-flavor
+ https://docs.openstack.org/api-ref/compute/#list-flavor-access-information-for-given-flavor
"""
resp, body = self.get('flavors/%s/os-flavor-access' % flavor_id)
body = json.loads(body)
@@ -227,7 +227,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#add-flavor-access-to-tenant-addtenantaccess-action
+ https://docs.openstack.org/api-ref/compute/#add-flavor-access-to-tenant-addtenantaccess-action
"""
post_body = {
'addTenantAccess': {
@@ -246,7 +246,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#remove-flavor-access-from-tenant-removetenantaccess-action
+ https://docs.openstack.org/api-ref/compute/#remove-flavor-access-from-tenant-removetenantaccess-action
"""
post_body = {
'removeTenantAccess': {
diff --git a/tempest/lib/services/compute/floating_ips_client.py b/tempest/lib/services/compute/floating_ips_client.py
index 5364d97..d7a1a9b 100644
--- a/tempest/lib/services/compute/floating_ips_client.py
+++ b/tempest/lib/services/compute/floating_ips_client.py
@@ -29,7 +29,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-floating-ip-addresses
+ https://docs.openstack.org/api-ref/compute/#list-floating-ip-addresses
"""
url = 'os-floating-ips'
if params:
@@ -45,7 +45,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-floating-ip-address-details
+ https://docs.openstack.org/api-ref/compute/#show-floating-ip-address-details
"""
url = "os-floating-ips/%s" % floating_ip_id
resp, body = self.get(url)
@@ -58,7 +58,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-allocate-floating-ip-address
+ https://docs.openstack.org/api-ref/compute/#create-allocate-floating-ip-address
"""
url = 'os-floating-ips'
post_body = json.dumps(kwargs)
@@ -72,7 +72,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-deallocate-floating-ip-address
+ https://docs.openstack.org/api-ref/compute/#delete-deallocate-floating-ip-address
"""
url = "os-floating-ips/%s" % floating_ip_id
resp, body = self.delete(url)
diff --git a/tempest/lib/services/compute/hosts_client.py b/tempest/lib/services/compute/hosts_client.py
index 1fdd907..743b4ec 100644
--- a/tempest/lib/services/compute/hosts_client.py
+++ b/tempest/lib/services/compute/hosts_client.py
@@ -27,7 +27,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-hosts
+ https://docs.openstack.org/api-ref/compute/#list-hosts
"""
url = 'os-hosts'
@@ -52,7 +52,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-host-status
+ https://docs.openstack.org/api-ref/compute/#update-host-status
"""
request_body = {
diff --git a/tempest/lib/services/compute/images_client.py b/tempest/lib/services/compute/images_client.py
index 0f4eb42..b252ee9 100644
--- a/tempest/lib/services/compute/images_client.py
+++ b/tempest/lib/services/compute/images_client.py
@@ -34,7 +34,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-image-createimage-action
+ https://docs.openstack.org/api-ref/compute/#create-image-createimage-action
"""
post_body = {'createImage': kwargs}
@@ -52,8 +52,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-images
- https://developer.openstack.org/api-ref/compute/#list-images-with-details
+ https://docs.openstack.org/api-ref/compute/#list-images
+ https://docs.openstack.org/api-ref/compute/#list-images-with-details
"""
url = 'images'
_schema = schema.list_images
@@ -94,7 +94,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-image-metadata
+ https://docs.openstack.org/api-ref/compute/#update-image-metadata
"""
post_body = json.dumps({'metadata': meta})
resp, body = self.put('images/%s/metadata' % image_id, post_body)
@@ -107,7 +107,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-image-metadata
+ https://docs.openstack.org/api-ref/compute/#create-image-metadata
"""
post_body = json.dumps({'metadata': meta})
resp, body = self.post('images/%s/metadata' % image_id, post_body)
@@ -127,7 +127,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-or-update-image-metadata-item
+ https://docs.openstack.org/api-ref/compute/#create-or-update-image-metadata-item
"""
post_body = json.dumps({'meta': meta})
resp, body = self.put('images/%s/metadata/%s' % (image_id, key),
diff --git a/tempest/lib/services/compute/interfaces_client.py b/tempest/lib/services/compute/interfaces_client.py
index d7c3107..e1c02fa 100644
--- a/tempest/lib/services/compute/interfaces_client.py
+++ b/tempest/lib/services/compute/interfaces_client.py
@@ -33,7 +33,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-interface
+ https://docs.openstack.org/api-ref/compute/#create-interface
"""
post_body = {'interfaceAttachment': kwargs}
post_body = json.dumps(post_body)
diff --git a/tempest/lib/services/compute/keypairs_client.py b/tempest/lib/services/compute/keypairs_client.py
index 5215fca..47cf2d0 100644
--- a/tempest/lib/services/compute/keypairs_client.py
+++ b/tempest/lib/services/compute/keypairs_client.py
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-keypairs
+ https://docs.openstack.org/api-ref/compute/#list-keypairs
"""
url = 'os-keypairs'
if params:
@@ -48,7 +48,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-keypair-details
+ https://docs.openstack.org/api-ref/compute/#show-keypair-details
"""
url = "os-keypairs/%s" % keypair_name
if params:
@@ -64,7 +64,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-or-import-keypair
+ https://docs.openstack.org/api-ref/compute/#create-or-import-keypair
"""
post_body = json.dumps({'keypair': kwargs})
resp, body = self.post("os-keypairs", body=post_body)
@@ -78,7 +78,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-keypair
+ https://docs.openstack.org/api-ref/compute/#delete-keypair
"""
url = "os-keypairs/%s" % keypair_name
if params:
diff --git a/tempest/lib/services/compute/migrations_client.py b/tempest/lib/services/compute/migrations_client.py
index 68c8f3f..23de064 100644
--- a/tempest/lib/services/compute/migrations_client.py
+++ b/tempest/lib/services/compute/migrations_client.py
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-migrations
+ https://docs.openstack.org/api-ref/compute/#list-migrations
"""
url = 'os-migrations'
diff --git a/tempest/lib/services/compute/quota_classes_client.py b/tempest/lib/services/compute/quota_classes_client.py
index 64e06f4..9b64099 100644
--- a/tempest/lib/services/compute/quota_classes_client.py
+++ b/tempest/lib/services/compute/quota_classes_client.py
@@ -37,7 +37,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-or-update-quotas-for-quota-class
+ https://docs.openstack.org/api-ref/compute/#create-or-update-quotas-for-quota-class
"""
post_body = json.dumps({'quota_class_set': kwargs})
diff --git a/tempest/lib/services/compute/quotas_client.py b/tempest/lib/services/compute/quotas_client.py
index 99c8d0f..12e865e 100644
--- a/tempest/lib/services/compute/quotas_client.py
+++ b/tempest/lib/services/compute/quotas_client.py
@@ -35,8 +35,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-a-quota
- https://developer.openstack.org/api-ref/compute/#show-the-detail-of-quota
+ https://docs.openstack.org/api-ref/compute/#show-a-quota
+ https://docs.openstack.org/api-ref/compute/#show-the-detail-of-quota
"""
params = {}
@@ -59,7 +59,7 @@
def show_default_quota_set(self, tenant_id):
"""List the default quota set for a tenant.
- https://developer.openstack.org/api-ref/compute/#list-default-quotas-for-tenant
+ https://docs.openstack.org/api-ref/compute/#list-default-quotas-for-tenant
"""
url = 'os-quota-sets/%s/defaults' % tenant_id
@@ -74,7 +74,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-quotas
+ https://docs.openstack.org/api-ref/compute/#update-quotas
"""
post_body = json.dumps({'quota_set': kwargs})
@@ -94,7 +94,7 @@
def delete_quota_set(self, tenant_id):
"""Delete the tenant's quota set.
- https://developer.openstack.org/api-ref/compute/#revert-quotas-to-defaults
+ https://docs.openstack.org/api-ref/compute/#revert-quotas-to-defaults
"""
resp, body = self.delete('os-quota-sets/%s' % tenant_id)
schema = self.get_schema(self.schema_versions_info)
diff --git a/tempest/lib/services/compute/security_group_default_rules_client.py b/tempest/lib/services/compute/security_group_default_rules_client.py
index 70cab88..bed18e9 100644
--- a/tempest/lib/services/compute/security_group_default_rules_client.py
+++ b/tempest/lib/services/compute/security_group_default_rules_client.py
@@ -28,7 +28,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-default-security-group-rule
+ https://docs.openstack.org/api-ref/compute/#create-default-security-group-rule
"""
post_body = json.dumps({'security_group_default_rule': kwargs})
url = 'os-security-group-default-rules'
diff --git a/tempest/lib/services/compute/security_group_rules_client.py b/tempest/lib/services/compute/security_group_rules_client.py
index 710bfab..7c2bd66 100644
--- a/tempest/lib/services/compute/security_group_rules_client.py
+++ b/tempest/lib/services/compute/security_group_rules_client.py
@@ -28,7 +28,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-security-group-rule
+ https://docs.openstack.org/api-ref/compute/#create-security-group-rule
"""
post_body = json.dumps({'security_group_rule': kwargs})
url = 'os-security-group-rules'
diff --git a/tempest/lib/services/compute/security_groups_client.py b/tempest/lib/services/compute/security_groups_client.py
index b525f68..9493144 100644
--- a/tempest/lib/services/compute/security_groups_client.py
+++ b/tempest/lib/services/compute/security_groups_client.py
@@ -30,7 +30,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-security-groups
+ https://docs.openstack.org/api-ref/compute/#list-security-groups
"""
url = 'os-security-groups'
@@ -47,7 +47,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-security-group-details
+ https://docs.openstack.org/api-ref/compute/#show-security-group-details
"""
url = "os-security-groups/%s" % security_group_id
resp, body = self.get(url)
@@ -60,7 +60,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-security-group
+ https://docs.openstack.org/api-ref/compute/#create-security-group
"""
post_body = json.dumps({'security_group': kwargs})
resp, body = self.post('os-security-groups', post_body)
@@ -73,7 +73,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-security-group
+ https://docs.openstack.org/api-ref/compute/#update-security-group
"""
post_body = json.dumps({'security_group': kwargs})
resp, body = self.put('os-security-groups/%s' % security_group_id,
@@ -87,7 +87,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-security-group
+ https://docs.openstack.org/api-ref/compute/#delete-security-group
"""
resp, body = self.delete(
'os-security-groups/%s' % security_group_id)
diff --git a/tempest/lib/services/compute/server_groups_client.py b/tempest/lib/services/compute/server_groups_client.py
index 0d440d5..89ad2d9 100644
--- a/tempest/lib/services/compute/server_groups_client.py
+++ b/tempest/lib/services/compute/server_groups_client.py
@@ -35,7 +35,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-server-group
+ https://docs.openstack.org/api-ref/compute/#create-server-group
"""
post_body = json.dumps({'server_group': kwargs})
resp, body = self.post('os-server-groups', post_body)
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index 18e08cc..a687137 100644
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -33,6 +33,8 @@
from tempest.lib.api_schema.response.compute.v2_57 import servers as schemav257
from tempest.lib.api_schema.response.compute.v2_6 import servers as schemav26
from tempest.lib.api_schema.response.compute.v2_63 import servers as schemav263
+from tempest.lib.api_schema.response.compute.v2_70 import servers as schemav270
+from tempest.lib.api_schema.response.compute.v2_71 import servers as schemav271
from tempest.lib.api_schema.response.compute.v2_8 import servers as schemav28
from tempest.lib.api_schema.response.compute.v2_9 import servers as schemav29
from tempest.lib.common import rest_client
@@ -55,7 +57,9 @@
{'min': '2.48', 'max': '2.53', 'schema': schemav248},
{'min': '2.54', 'max': '2.56', 'schema': schemav254},
{'min': '2.57', 'max': '2.62', 'schema': schemav257},
- {'min': '2.63', 'max': None, 'schema': schemav263}]
+ {'min': '2.63', 'max': '2.69', 'schema': schemav263},
+ {'min': '2.70', 'max': '2.70', 'schema': schemav270},
+ {'min': '2.71', 'max': None, 'schema': schemav271}]
def __init__(self, auth_provider, service, region,
enable_instance_password=True, **kwargs):
@@ -68,7 +72,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/compute/#create-server
+ https://docs.openstack.org/api-ref/compute/#create-server
:param name: Server name
:param imageRef: Image reference (UUID)
@@ -113,7 +117,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-server
+ https://docs.openstack.org/api-ref/compute/#update-server
Most parameters except the following are passed to the API without
any changes.
@@ -134,7 +138,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-server-details
+ https://docs.openstack.org/api-ref/compute/#show-server-details
"""
resp, body = self.get("servers/%s" % server_id)
body = json.loads(body)
@@ -147,7 +151,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-server
+ https://docs.openstack.org/api-ref/compute/#delete-server
"""
resp, body = self.delete("servers/%s" % server_id)
self.validate_response(schema.delete_server, resp, body)
@@ -158,8 +162,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-servers
- https://developer.openstack.org/api-ref/compute/#list-servers-detailed
+ https://docs.openstack.org/api-ref/compute/#list-servers
+ https://docs.openstack.org/api-ref/compute/#list-servers-detailed
"""
url = 'servers'
@@ -182,7 +186,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-ips
+ https://docs.openstack.org/api-ref/compute/#list-ips
"""
resp, body = self.get("servers/%s/ips" % server_id)
body = json.loads(body)
@@ -213,7 +217,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-server-back-up-createbackup-action
+ https://docs.openstack.org/api-ref/compute/#create-server-back-up-createbackup-action
"""
return self.action(server_id, "createBackup", **kwargs)
@@ -222,7 +226,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#change-administrative-password-changepassword-action
+ https://docs.openstack.org/api-ref/compute/#change-administrative-password-changepassword-action
"""
return self.action(server_id, 'changePassword', **kwargs)
@@ -250,7 +254,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#reboot-server-reboot-action
+ https://docs.openstack.org/api-ref/compute/#reboot-server-reboot-action
"""
return self.action(server_id, 'reboot', **kwargs)
@@ -259,7 +263,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#rebuild-server-rebuild-action
+ https://docs.openstack.org/api-ref/compute/#rebuild-server-rebuild-action
Most parameters except the following are passed to the API without
any changes.
@@ -281,7 +285,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#resize-server-resize-action
+ https://docs.openstack.org/api-ref/compute/#resize-server-resize-action
Most parameters except the following are passed to the API without
any changes.
@@ -297,7 +301,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#confirm-resized-server-confirmresize-action
+ https://docs.openstack.org/api-ref/compute/#confirm-resized-server-confirmresize-action
"""
return self.action(server_id, 'confirmResize',
schema.server_actions_confirm_resize,
@@ -308,7 +312,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#revert-resized-server-revertresize-action
+ https://docs.openstack.org/api-ref/compute/#revert-resized-server-revertresize-action
"""
return self.action(server_id, 'revertResize', **kwargs)
@@ -317,7 +321,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-all-metadata
+ https://docs.openstack.org/api-ref/compute/#list-all-metadata
"""
resp, body = self.get("servers/%s/metadata" % server_id)
body = json.loads(body)
@@ -329,7 +333,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#replace-metadata-items
+ https://docs.openstack.org/api-ref/compute/#replace-metadata-items
"""
if no_metadata_field:
post_body = ""
@@ -346,7 +350,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-or-update-metadata-items
+ https://docs.openstack.org/api-ref/compute/#create-or-update-metadata-items
"""
post_body = json.dumps({'metadata': meta})
resp, body = self.post('servers/%s/metadata' % server_id,
@@ -361,7 +365,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-metadata-item-details
+ https://docs.openstack.org/api-ref/compute/#show-metadata-item-details
"""
resp, body = self.get("servers/%s/metadata/%s" % (server_id, key))
body = json.loads(body)
@@ -374,7 +378,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-or-update-metadata-item
+ https://docs.openstack.org/api-ref/compute/#create-or-update-metadata-item
"""
post_body = json.dumps({'meta': meta})
resp, body = self.put('servers/%s/metadata/%s' % (server_id, key),
@@ -389,7 +393,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-metadata-item
+ https://docs.openstack.org/api-ref/compute/#delete-metadata-item
"""
resp, body = self.delete("servers/%s/metadata/%s" %
(server_id, key))
@@ -402,7 +406,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#stop-server-os-stop-action
+ https://docs.openstack.org/api-ref/compute/#stop-server-os-stop-action
"""
return self.action(server_id, 'os-stop', **kwargs)
@@ -411,7 +415,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#start-server-os-start-action
+ https://docs.openstack.org/api-ref/compute/#start-server-os-start-action
"""
return self.action(server_id, 'os-start', **kwargs)
@@ -420,17 +424,23 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#attach-a-volume-to-an-instance
+ https://docs.openstack.org/api-ref/compute/#attach-a-volume-to-an-instance
"""
post_body = json.dumps({'volumeAttachment': kwargs})
resp, body = self.post('servers/%s/os-volume_attachments' % server_id,
post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.attach_volume, resp, body)
return rest_client.ResponseBody(resp, body)
def update_attached_volume(self, server_id, attachment_id, **kwargs):
- """Swaps a volume attached to an instance for another volume"""
+ """Swaps a volume attached to an instance for another volume
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/compute/#update-a-volume-attachment
+ """
post_body = json.dumps({'volumeAttachment': kwargs})
resp, body = self.put('servers/%s/os-volume_attachments/%s' %
(server_id, attachment_id),
@@ -443,7 +453,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#detach-a-volume-from-an-instance
+ https://docs.openstack.org/api-ref/compute/#detach-a-volume-from-an-instance
"""
resp, body = self.delete('servers/%s/os-volume_attachments/%s' %
(server_id, volume_id))
@@ -455,11 +465,12 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-a-detail-of-a-volume-attachment
+ https://docs.openstack.org/api-ref/compute/#show-a-detail-of-a-volume-attachment
"""
resp, body = self.get('servers/%s/os-volume_attachments/%s' % (
server_id, volume_id))
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.show_volume_attachment, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -468,11 +479,12 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-volume-attachments-for-an-instance
+ https://docs.openstack.org/api-ref/compute/#list-volume-attachments-for-an-instance
"""
resp, body = self.get('servers/%s/os-volume_attachments' % (
server_id))
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.list_volume_attachments, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -481,7 +493,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#add-security-group-to-a-server-addsecuritygroup-action
+ https://docs.openstack.org/api-ref/compute/#add-security-group-to-a-server-addsecuritygroup-action
"""
return self.action(server_id, 'addSecurityGroup', **kwargs)
@@ -490,7 +502,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#remove-security-group-from-a-server-removesecuritygroup-action
+ https://docs.openstack.org/api-ref/compute/#remove-security-group-from-a-server-removesecuritygroup-action
"""
return self.action(server_id, 'removeSecurityGroup', **kwargs)
@@ -499,7 +511,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#live-migrate-server-os-migratelive-action
+ https://docs.openstack.org/api-ref/compute/#live-migrate-server-os-migratelive-action
"""
return self.action(server_id, 'os-migrateLive', **kwargs)
@@ -508,7 +520,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#migrate-server-migrate-action
+ https://docs.openstack.org/api-ref/compute/#migrate-server-migrate-action
"""
return self.action(server_id, 'migrate', **kwargs)
@@ -517,7 +529,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#lock-server-lock-action
+ https://docs.openstack.org/api-ref/compute/#lock-server-lock-action
"""
return self.action(server_id, 'lock', **kwargs)
@@ -526,7 +538,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#unlock-server-unlock-action
+ https://docs.openstack.org/api-ref/compute/#unlock-server-unlock-action
"""
return self.action(server_id, 'unlock', **kwargs)
@@ -535,7 +547,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#suspend-server-suspend-action
+ https://docs.openstack.org/api-ref/compute/#suspend-server-suspend-action
"""
return self.action(server_id, 'suspend', **kwargs)
@@ -544,7 +556,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#resume-suspended-server-resume-action
+ https://docs.openstack.org/api-ref/compute/#resume-suspended-server-resume-action
"""
return self.action(server_id, 'resume', **kwargs)
@@ -553,7 +565,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#pause-server-pause-action
+ https://docs.openstack.org/api-ref/compute/#pause-server-pause-action
"""
return self.action(server_id, 'pause', **kwargs)
@@ -562,7 +574,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#unpause-server-unpause-action
+ https://docs.openstack.org/api-ref/compute/#unpause-server-unpause-action
"""
return self.action(server_id, 'unpause', **kwargs)
@@ -571,7 +583,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#reset-server-state-os-resetstate-action
+ https://docs.openstack.org/api-ref/compute/#reset-server-state-os-resetstate-action
"""
return self.action(server_id, 'os-resetState', **kwargs)
@@ -580,7 +592,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#shelve-server-shelve-action
+ https://docs.openstack.org/api-ref/compute/#shelve-server-shelve-action
"""
return self.action(server_id, 'shelve', **kwargs)
@@ -589,7 +601,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#unshelve-restore-shelved-server-unshelve-action
+ https://docs.openstack.org/api-ref/compute/#unshelve-restore-shelved-server-unshelve-action
"""
return self.action(server_id, 'unshelve', **kwargs)
@@ -598,7 +610,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#shelf-offload-remove-server-shelveoffload-action
+ https://docs.openstack.org/api-ref/compute/#shelf-offload-remove-server-shelveoffload-action
"""
return self.action(server_id, 'shelveOffload', **kwargs)
@@ -607,7 +619,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-console-output-os-getconsoleoutput-action
+ https://docs.openstack.org/api-ref/compute/#show-console-output-os-getconsoleoutput-action
"""
return self.action(server_id, 'os-getConsoleOutput',
schema.get_console_output, **kwargs)
@@ -617,7 +629,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-remote-console
+ https://docs.openstack.org/api-ref/compute/#create-remote-console
"""
param = {
'remote_console': {
@@ -646,7 +658,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#rescue-server-rescue-action
+ https://docs.openstack.org/api-ref/compute/#rescue-server-rescue-action
"""
if self.enable_instance_password:
rescue_schema = schema.rescue_server_with_admin_pass
@@ -659,7 +671,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#unrescue-server-unrescue-action
+ https://docs.openstack.org/api-ref/compute/#unrescue-server-unrescue-action
"""
return self.action(server_id, 'unrescue')
@@ -692,7 +704,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#force-delete-server-forcedelete-action
+ https://docs.openstack.org/api-ref/compute/#force-delete-server-forcedelete-action
"""
return self.action(server_id, 'forceDelete', **kwargs)
@@ -701,7 +713,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#restore-soft-deleted-instance-restore-action
+ https://docs.openstack.org/api-ref/compute/#restore-soft-deleted-instance-restore-action
"""
return self.action(server_id, 'restore', **kwargs)
@@ -710,7 +722,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#reset-networking-on-a-server-resetnetwork-action
+ https://docs.openstack.org/api-ref/compute/#reset-networking-on-a-server-resetnetwork-action
"""
return self.action(server_id, 'resetNetwork', **kwargs)
@@ -719,7 +731,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#inject-network-information-injectnetworkinfo-action
+ https://docs.openstack.org/api-ref/compute/#inject-network-information-injectnetworkinfo-action
"""
return self.action(server_id, 'injectNetworkInfo', **kwargs)
@@ -728,7 +740,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#get-vnc-console-os-getvncconsole-action-deprecated
+ https://docs.openstack.org/api-ref/compute/#get-vnc-console-os-getvncconsole-action-deprecated
"""
return self.action(server_id, "os-getVNCConsole",
schema.get_vnc_console, **kwargs)
@@ -738,7 +750,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#add-associate-fixed-ip-addfixedip-action-deprecated
+ https://docs.openstack.org/api-ref/compute/#add-associate-fixed-ip-addfixedip-action-deprecated
"""
return self.action(server_id, 'addFixedIp', **kwargs)
@@ -747,7 +759,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#remove-disassociate-fixed-ip-removefixedip-action-deprecated
+ https://docs.openstack.org/api-ref/compute/#remove-disassociate-fixed-ip-removefixedip-action-deprecated
"""
return self.action(server_id, 'removeFixedIp', **kwargs)
@@ -756,7 +768,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-security-groups-by-server
+ https://docs.openstack.org/api-ref/compute/#list-security-groups-by-server
"""
resp, body = self.get("servers/%s/os-security-groups" % server_id)
body = json.loads(body)
@@ -769,7 +781,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-tags
+ https://docs.openstack.org/api-ref/compute/#list-tags
"""
url = 'servers/%s/tags' % server_id
resp, body = self.get(url)
@@ -783,7 +795,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#replace-tags
+ https://docs.openstack.org/api-ref/compute/#replace-tags
:param tags: List of tags to replace current server tags with.
"""
@@ -800,7 +812,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-all-tags
+ https://docs.openstack.org/api-ref/compute/#delete-all-tags
"""
url = 'servers/%s/tags' % server_id
resp, body = self.delete(url)
@@ -813,7 +825,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#check-tag-existence
+ https://docs.openstack.org/api-ref/compute/#check-tag-existence
:param tag: Check for existence of tag on specified server.
"""
@@ -828,7 +840,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#add-a-single-tag
+ https://docs.openstack.org/api-ref/compute/#add-a-single-tag
:param tag: Tag to be added to the specified server.
"""
@@ -843,7 +855,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-a-single-tag
+ https://docs.openstack.org/api-ref/compute/#delete-a-single-tag
:param tag: Tag to be removed from the specified server.
"""
@@ -858,7 +870,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#evacuate-server-evacuate-action
+ https://docs.openstack.org/api-ref/compute/#evacuate-server-evacuate-action
"""
if self.enable_instance_password:
evacuate_schema = schema.evacuate_server_with_admin_pass
diff --git a/tempest/lib/services/compute/services_client.py b/tempest/lib/services/compute/services_client.py
index d52de3a..4e3383f 100644
--- a/tempest/lib/services/compute/services_client.py
+++ b/tempest/lib/services/compute/services_client.py
@@ -38,7 +38,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-compute-services
+ https://docs.openstack.org/api-ref/compute/#list-compute-services
"""
url = 'os-services'
if params:
@@ -60,7 +60,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-compute-service
+ https://docs.openstack.org/api-ref/compute/#update-compute-service
"""
put_body = json.dumps(kwargs)
resp, body = self.put('os-services/%s' % service_id, put_body)
@@ -76,7 +76,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#enable-scheduling-for-a-compute-service
+ https://docs.openstack.org/api-ref/compute/#enable-scheduling-for-a-compute-service
"""
post_body = json.dumps(kwargs)
resp, body = self.put('os-services/enable', post_body)
@@ -91,7 +91,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#disable-scheduling-for-a-compute-service
+ https://docs.openstack.org/api-ref/compute/#disable-scheduling-for-a-compute-service
"""
post_body = json.dumps(kwargs)
resp, body = self.put('os-services/disable', post_body)
@@ -106,7 +106,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#disable-scheduling-for-a-compute-service-and-log-disabled-reason
+ https://docs.openstack.org/api-ref/compute/#disable-scheduling-for-a-compute-service-and-log-disabled-reason
"""
post_body = json.dumps(kwargs)
resp, body = self.put('os-services/disable-log-reason', post_body)
@@ -121,7 +121,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#update-forced-down
+ https://docs.openstack.org/api-ref/compute/#update-forced-down
"""
post_body = json.dumps(kwargs)
resp, body = self.put('os-services/force-down', post_body)
diff --git a/tempest/lib/services/compute/snapshots_client.py b/tempest/lib/services/compute/snapshots_client.py
index df8d6fb..225eb8d 100644
--- a/tempest/lib/services/compute/snapshots_client.py
+++ b/tempest/lib/services/compute/snapshots_client.py
@@ -29,7 +29,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-snapshot
+ https://docs.openstack.org/api-ref/compute/#create-snapshot
"""
post_body = {
'volume_id': volume_id
@@ -53,7 +53,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-snapshots
+ https://docs.openstack.org/api-ref/compute/#list-snapshots
"""
url = 'os-snapshots'
diff --git a/tempest/lib/services/compute/tenant_usages_client.py b/tempest/lib/services/compute/tenant_usages_client.py
index ade60e5..a34730c 100644
--- a/tempest/lib/services/compute/tenant_usages_client.py
+++ b/tempest/lib/services/compute/tenant_usages_client.py
@@ -28,7 +28,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-tenant-usage-statistics-for-all-tenants
+ https://docs.openstack.org/api-ref/compute/#list-tenant-usage-statistics-for-all-tenants
"""
url = 'os-simple-tenant-usage'
if params:
@@ -44,7 +44,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-usage-statistics-for-tenant
+ https://docs.openstack.org/api-ref/compute/#show-usage-statistics-for-tenant
"""
url = 'os-simple-tenant-usage/%s' % tenant_id
if params:
diff --git a/tempest/lib/services/compute/volumes_client.py b/tempest/lib/services/compute/volumes_client.py
index 95cdd53..11282ee 100644
--- a/tempest/lib/services/compute/volumes_client.py
+++ b/tempest/lib/services/compute/volumes_client.py
@@ -29,8 +29,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#list-volumes
- https://developer.openstack.org/api-ref/compute/#list-volumes-with-details
+ https://docs.openstack.org/api-ref/compute/#list-volumes
+ https://docs.openstack.org/api-ref/compute/#list-volumes-with-details
"""
url = 'os-volumes'
@@ -49,7 +49,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#show-volume-details
+ https://docs.openstack.org/api-ref/compute/#show-volume-details
"""
url = "os-volumes/%s" % volume_id
resp, body = self.get(url)
@@ -62,7 +62,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#create-volume
+ https://docs.openstack.org/api-ref/compute/#create-volume
"""
post_body = json.dumps({'volume': kwargs})
resp, body = self.post('os-volumes', post_body)
@@ -75,7 +75,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/compute/#delete-volume
+ https://docs.openstack.org/api-ref/compute/#delete-volume
"""
resp, body = self.delete("os-volumes/%s" % volume_id)
self.validate_response(schema.delete_volume, resp, body)
diff --git a/tempest/lib/services/identity/v2/endpoints_client.py b/tempest/lib/services/identity/v2/endpoints_client.py
index db8d7cc..d587b83 100644
--- a/tempest/lib/services/identity/v2/endpoints_client.py
+++ b/tempest/lib/services/identity/v2/endpoints_client.py
@@ -25,7 +25,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-admin/index.html#create-endpoint-template
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#create-endpoint-template
"""
post_body = json.dumps({'endpoint': kwargs})
diff --git a/tempest/lib/services/identity/v2/identity_client.py b/tempest/lib/services/identity/v2/identity_client.py
index c610d65..d7526f3 100644
--- a/tempest/lib/services/identity/v2/identity_client.py
+++ b/tempest/lib/services/identity/v2/identity_client.py
@@ -59,7 +59,7 @@
For a full list of available parameters, please refer to the
official API reference:
- https://developer.openstack.org/api-ref/identity/v2-admin/#validate-token
+ https://docs.openstack.org/api-ref/identity/v2-admin/#validate-token
"""
url = "tokens/%s" % token_id
if params:
diff --git a/tempest/lib/services/identity/v2/roles_client.py b/tempest/lib/services/identity/v2/roles_client.py
index 9e841dd..a133fc3 100644
--- a/tempest/lib/services/identity/v2/roles_client.py
+++ b/tempest/lib/services/identity/v2/roles_client.py
@@ -24,7 +24,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#create-a-role
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#create-a-role
"""
post_body = json.dumps({'role': kwargs})
resp, body = self.post('OS-KSADM/roles', post_body)
@@ -37,9 +37,9 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#show-a-role
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#show-a-role
OR
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#show-role-information-by-name
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#show-role-information-by-name
"""
resp, body = self.get('OS-KSADM/roles/%s' % role_id_or_name)
self.expected_success(200, resp.status)
@@ -51,7 +51,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#list-all-roles
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#list-all-roles
"""
url = 'OS-KSADM/roles'
if params:
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#delete-a-role
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#delete-a-role
"""
resp, body = self.delete('OS-KSADM/roles/%s' % role_id)
self.expected_success(204, resp.status)
@@ -77,7 +77,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#grant-roles-to-user-on-tenant
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#grant-roles-to-user-on-tenant
"""
resp, body = self.put('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
(tenant_id, user_id, role_id), "")
@@ -101,7 +101,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#revoke-role-from-user-on-tenant
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#revoke-role-from-user-on-tenant
"""
resp, body = self.delete('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
(tenant_id, user_id, role_id))
diff --git a/tempest/lib/services/identity/v2/services_client.py b/tempest/lib/services/identity/v2/services_client.py
index 47398db..fc51cb4 100644
--- a/tempest/lib/services/identity/v2/services_client.py
+++ b/tempest/lib/services/identity/v2/services_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-ext/#create-service-admin-extension
+ https://docs.openstack.org/api-ref/identity/v2-ext/#create-service-admin-extension
"""
post_body = json.dumps({'OS-KSADM:service': kwargs})
resp, body = self.post('/OS-KSADM/services', post_body)
@@ -47,7 +47,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-ext/#list-services-admin-extension
+ https://docs.openstack.org/api-ref/identity/v2-ext/#list-services-admin-extension
"""
url = '/OS-KSADM/services'
if params:
diff --git a/tempest/lib/services/identity/v2/tenants_client.py b/tempest/lib/services/identity/v2/tenants_client.py
index 026db64..09618ad 100644
--- a/tempest/lib/services/identity/v2/tenants_client.py
+++ b/tempest/lib/services/identity/v2/tenants_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-admin/index.html#create-tenant
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#create-tenant
"""
post_body = json.dumps({'tenant': kwargs})
resp, body = self.post('tenants', post_body)
@@ -39,7 +39,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-admin/index.html#delete-tenant
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#delete-tenant
"""
resp, body = self.delete('tenants/%s' % str(tenant_id))
self.expected_success(204, resp.status)
@@ -50,7 +50,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-admin/index.html#show-tenant-details-by-id
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#show-tenant-details-by-id
"""
resp, body = self.get('tenants/%s' % str(tenant_id))
self.expected_success(200, resp.status)
@@ -62,7 +62,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-tenants-admin-endpoint
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#list-tenants-admin-endpoint
"""
url = 'tenants'
if params:
@@ -77,7 +77,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-admin/index.html#update-tenant
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#update-tenant
"""
if 'id' not in kwargs:
kwargs['id'] = tenant_id
@@ -92,7 +92,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-users-on-a-tenant
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#list-users-on-a-tenant
"""
url = '/tenants/%s/users' % tenant_id
if params:
diff --git a/tempest/lib/services/identity/v2/users_client.py b/tempest/lib/services/identity/v2/users_client.py
index 44bb5fd..72f29be 100644
--- a/tempest/lib/services/identity/v2/users_client.py
+++ b/tempest/lib/services/identity/v2/users_client.py
@@ -24,7 +24,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-admin/index.html#create-user-admin-endpoint
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#create-user-admin-endpoint
"""
post_body = json.dumps({'user': kwargs})
resp, body = self.post('users', post_body)
@@ -37,7 +37,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-admin/index.html#update-user-admin-endpoint
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#update-user-admin-endpoint
"""
put_body = json.dumps({'user': kwargs})
resp, body = self.put('users/%s' % user_id, put_body)
@@ -50,7 +50,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-admin/index.html#show-user-details-admin-endpoint
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#show-user-details-admin-endpoint
"""
resp, body = self.get("users/%s" % user_id)
self.expected_success(200, resp.status)
@@ -62,7 +62,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-admin/index.html#delete-user-admin-endpoint
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#delete-user-admin-endpoint
"""
resp, body = self.delete("users/%s" % user_id)
self.expected_success(204, resp.status)
@@ -73,7 +73,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v2-admin/index.html#list-users-admin-endpoint
+ https://docs.openstack.org/api-ref/identity/v2-admin/index.html#list-users-admin-endpoint
"""
url = "users"
if params:
@@ -88,7 +88,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v2-ext/index.html#enable-disable-user
+ https://docs.openstack.org/api-ref/identity/v2-ext/index.html#enable-disable-user
"""
# NOTE: The URL (users/<id>/enabled) is different from the api-site
# one (users/<id>/OS-KSADM/enabled) , but they are the same API
diff --git a/tempest/lib/services/identity/v3/application_credentials_client.py b/tempest/lib/services/identity/v3/application_credentials_client.py
index 557aa9e..be2e172 100644
--- a/tempest/lib/services/identity/v3/application_credentials_client.py
+++ b/tempest/lib/services/identity/v3/application_credentials_client.py
@@ -15,7 +15,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3/index.html#application-credentials
+https://docs.openstack.org/api-ref/identity/v3/index.html#application-credentials
"""
from oslo_serialization import jsonutils as json
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v3/index.html#create-application-credential
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-application-credential
"""
post_body = json.dumps({'application_credential': kwargs})
resp, body = self.post('users/%s/application_credentials' % user_id,
@@ -46,7 +46,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v3/index.html#show-application-credential-details
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-application-credential-details
"""
resp, body = self.get('users/%s/application_credentials/%s' %
(user_id, application_credential_id))
@@ -59,7 +59,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v3/index.html#list-application-credentials
+ https://docs.openstack.org/api-ref/identity/v3/index.html#list-application-credentials
"""
url = 'users/%s/application_credentials' % user_id
if params:
@@ -75,7 +75,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v3/index.html#delete-application-credential
+ https://docs.openstack.org/api-ref/identity/v3/index.html#delete-application-credential
"""
resp, body = self.delete('users/%s/application_credentials/%s' %
(user_id, application_credential_id))
diff --git a/tempest/lib/services/identity/v3/catalog_client.py b/tempest/lib/services/identity/v3/catalog_client.py
index 232b85a..cb9eed1 100644
--- a/tempest/lib/services/identity/v3/catalog_client.py
+++ b/tempest/lib/services/identity/v3/catalog_client.py
@@ -11,7 +11,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3/index.html#get-service-catalog
+https://docs.openstack.org/api-ref/identity/v3/index.html#get-service-catalog
"""
from oslo_serialization import jsonutils as json
diff --git a/tempest/lib/services/identity/v3/credentials_client.py b/tempest/lib/services/identity/v3/credentials_client.py
index 6e5fd31..3f4b40e 100644
--- a/tempest/lib/services/identity/v3/credentials_client.py
+++ b/tempest/lib/services/identity/v3/credentials_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-http://developer.openstack.org/api-ref/identity/v3/index.html#credentials
+https://docs.openstack.org/api-ref/identity/v3/index.html#credentials
"""
from oslo_serialization import jsonutils as json
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-credential
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-credential
"""
post_body = json.dumps({'credential': kwargs})
resp, body = self.post('credentials', post_body)
@@ -44,7 +44,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-credential
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-credential
"""
post_body = json.dumps({'credential': kwargs})
resp, body = self.patch('credentials/%s' % credential_id, post_body)
@@ -57,7 +57,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-credential-details
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-credential-details
"""
resp, body = self.get('credentials/%s' % credential_id)
self.expected_success(200, resp.status)
@@ -69,7 +69,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-credentials
+ https://docs.openstack.org/api-ref/identity/v3/#list-credentials
"""
url = 'credentials'
if params:
@@ -84,7 +84,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#delete-credential
+ https://docs.openstack.org/api-ref/identity/v3/#delete-credential
"""
resp, body = self.delete('credentials/%s' % credential_id)
self.expected_success(204, resp.status)
diff --git a/tempest/lib/services/identity/v3/domain_configuration_client.py b/tempest/lib/services/identity/v3/domain_configuration_client.py
index d57f2d4..9410b99 100644
--- a/tempest/lib/services/identity/v3/domain_configuration_client.py
+++ b/tempest/lib/services/identity/v3/domain_configuration_client.py
@@ -25,7 +25,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-default-configuration-settings
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-default-configuration-settings
"""
url = 'domains/config/default'
resp, body = self.get(url)
@@ -38,7 +38,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-default-configuration-for-a-group
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-default-configuration-for-a-group
"""
url = 'domains/config/%s/default' % group
resp, body = self.get(url)
@@ -51,7 +51,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-default-option-for-a-group
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-default-option-for-a-group
"""
url = 'domains/config/%s/%s/default' % (group, option)
resp, body = self.get(url)
@@ -64,7 +64,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-domain-group-option-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-domain-group-option-configuration
"""
url = 'domains/%s/config/%s/%s' % (domain_id, group, option)
resp, body = self.get(url)
@@ -78,7 +78,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-domain-group-option-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-domain-group-option-configuration
"""
url = 'domains/%s/config/%s/%s' % (domain_id, group, option)
resp, body = self.patch(url, json.dumps({'config': kwargs}))
@@ -91,7 +91,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#delete-domain-group-option-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#delete-domain-group-option-configuration
"""
url = 'domains/%s/config/%s/%s' % (domain_id, group, option)
resp, body = self.delete(url)
@@ -103,7 +103,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-domain-group-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-domain-group-configuration
"""
url = 'domains/%s/config/%s' % (domain_id, group)
resp, body = self.get(url)
@@ -116,7 +116,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-domain-group-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-domain-group-configuration
"""
url = 'domains/%s/config/%s' % (domain_id, group)
resp, body = self.patch(url, json.dumps({'config': kwargs}))
@@ -129,7 +129,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#delete-domain-group-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#delete-domain-group-configuration
"""
url = 'domains/%s/config/%s' % (domain_id, group)
resp, body = self.delete(url)
@@ -141,7 +141,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-domain-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-domain-configuration
"""
url = 'domains/%s/config' % domain_id
resp, body = self.put(url, json.dumps({'config': kwargs}))
@@ -154,7 +154,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-domain-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-domain-configuration
"""
url = 'domains/%s/config' % domain_id
resp, body = self.get(url)
@@ -167,7 +167,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-domain-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-domain-configuration
"""
url = 'domains/%s/config' % domain_id
resp, body = self.patch(url, json.dumps({'config': kwargs}))
@@ -180,7 +180,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#delete-domain-configuration
+ https://docs.openstack.org/api-ref/identity/v3/index.html#delete-domain-configuration
"""
url = 'domains/%s/config' % domain_id
resp, body = self.delete(url)
diff --git a/tempest/lib/services/identity/v3/domains_client.py b/tempest/lib/services/identity/v3/domains_client.py
index 43cb62c..bd32cfc 100644
--- a/tempest/lib/services/identity/v3/domains_client.py
+++ b/tempest/lib/services/identity/v3/domains_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-domain
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-domain
"""
post_body = json.dumps({'domain': kwargs})
resp, body = self.post('domains', post_body)
@@ -38,7 +38,7 @@
"""Deletes a domain.
For APi details, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#delete-domain
+ https://docs.openstack.org/api-ref/identity/v3/index.html#delete-domain
"""
resp, body = self.delete('domains/%s' % domain_id)
self.expected_success(204, resp.status)
@@ -49,7 +49,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#list-domains
+ https://docs.openstack.org/api-ref/identity/v3/index.html#list-domains
"""
url = 'domains'
if params:
@@ -64,7 +64,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-domain
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-domain
"""
post_body = json.dumps({'domain': kwargs})
resp, body = self.patch('domains/%s' % domain_id, post_body)
@@ -76,7 +76,7 @@
"""Get Domain details.
For API details, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#show-domain-details
+ https://docs.openstack.org/api-ref/identity/v3/index.html#show-domain-details
"""
resp, body = self.get('domains/%s' % domain_id)
self.expected_success(200, resp.status)
diff --git a/tempest/lib/services/identity/v3/endpoint_filter_client.py b/tempest/lib/services/identity/v3/endpoint_filter_client.py
index a8cd722..ce84869 100644
--- a/tempest/lib/services/identity/v3/endpoint_filter_client.py
+++ b/tempest/lib/services/identity/v3/endpoint_filter_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3-ext/#os-ep-filter-api
+https://docs.openstack.org/api-ref/identity/v3-ext/#os-ep-filter-api
"""
from oslo_serialization import jsonutils as json
diff --git a/tempest/lib/services/identity/v3/endpoint_groups_client.py b/tempest/lib/services/identity/v3/endpoint_groups_client.py
index ce99389..90d353d 100644
--- a/tempest/lib/services/identity/v3/endpoint_groups_client.py
+++ b/tempest/lib/services/identity/v3/endpoint_groups_client.py
@@ -26,7 +26,7 @@
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
+ https://docs.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)
@@ -39,7 +39,7 @@
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
+ https://docs.openstack.org/api-ref/identity/v3-ext/#update-endpoint-group
"""
post_body = json.dumps({'endpoint_group': kwargs})
resp, body = self.patch(
diff --git a/tempest/lib/services/identity/v3/endpoints_client.py b/tempest/lib/services/identity/v3/endpoints_client.py
index e24dca7..236b34c 100644
--- a/tempest/lib/services/identity/v3/endpoints_client.py
+++ b/tempest/lib/services/identity/v3/endpoints_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3/index.html#service-catalog-and-endpoints
+https://docs.openstack.org/api-ref/identity/v3/index.html#service-catalog-and-endpoints
"""
from oslo_serialization import jsonutils as json
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-endpoints
+ https://docs.openstack.org/api-ref/identity/v3/#list-endpoints
"""
url = 'endpoints'
if params:
@@ -46,7 +46,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-endpoint
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-endpoint
"""
post_body = json.dumps({'endpoint': kwargs})
resp, body = self.post('endpoints', post_body)
@@ -59,7 +59,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-endpoint
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-endpoint
"""
post_body = json.dumps({'endpoint': kwargs})
resp, body = self.patch('endpoints/%s' % endpoint_id, post_body)
diff --git a/tempest/lib/services/identity/v3/groups_client.py b/tempest/lib/services/identity/v3/groups_client.py
index bc6ead0..f823b21 100644
--- a/tempest/lib/services/identity/v3/groups_client.py
+++ b/tempest/lib/services/identity/v3/groups_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3/index.html#groups
+https://docs.openstack.org/api-ref/identity/v3/index.html#groups
"""
from oslo_serialization import jsonutils as json
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-group
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-group
"""
post_body = json.dumps({'group': kwargs})
resp, body = self.post('groups', post_body)
@@ -51,7 +51,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-groups
+ https://docs.openstack.org/api-ref/identity/v3/#list-groups
"""
url = 'groups'
if params:
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-group
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-group
"""
post_body = json.dumps({'group': kwargs})
resp, body = self.patch('groups/%s' % group_id, post_body)
@@ -92,7 +92,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-users-in-group
+ https://docs.openstack.org/api-ref/identity/v3/#list-users-in-group
"""
url = 'groups/%s/users' % group_id
if params:
diff --git a/tempest/lib/services/identity/v3/oauth_consumers_client.py b/tempest/lib/services/identity/v3/oauth_consumers_client.py
index 97fb141..7438936 100644
--- a/tempest/lib/services/identity/v3/oauth_consumers_client.py
+++ b/tempest/lib/services/identity/v3/oauth_consumers_client.py
@@ -28,7 +28,7 @@
For more information, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#create-consumer
+ https://docs.openstack.org/api-ref/identity/v3-ext/#create-consumer
"""
post_body = {"description": description}
post_body = json.dumps({'consumer': post_body})
@@ -44,7 +44,7 @@
For more information, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#delete-consumer
+ https://docs.openstack.org/api-ref/identity/v3-ext/#delete-consumer
"""
resp, body = self.delete('OS-OAUTH1/consumers/%s' % consumer_id)
self.expected_success(204, resp.status)
@@ -58,7 +58,7 @@
For more information, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/#update-consumer
+ https://docs.openstack.org/api-ref/identity/v3-ext/#update-consumer
"""
post_body = {"description": description}
post_body = json.dumps({'consumer': post_body})
@@ -75,7 +75,7 @@
For more information, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#show-consumer-details
+ https://docs.openstack.org/api-ref/identity/v3-ext/#show-consumer-details
"""
resp, body = self.get('OS-OAUTH1/consumers/%s' % consumer_id)
self.expected_success(200, resp.status)
@@ -87,7 +87,7 @@
For more information, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#list-consumers
+ https://docs.openstack.org/api-ref/identity/v3-ext/#list-consumers
"""
resp, body = self.get('OS-OAUTH1/consumers')
self.expected_success(200, resp.status)
diff --git a/tempest/lib/services/identity/v3/oauth_token_client.py b/tempest/lib/services/identity/v3/oauth_token_client.py
index 94da043..6ca401b 100644
--- a/tempest/lib/services/identity/v3/oauth_token_client.py
+++ b/tempest/lib/services/identity/v3/oauth_token_client.py
@@ -117,7 +117,7 @@
"""Create request token.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#create-request-token
+ https://docs.openstack.org/api-ref/identity/v3-ext/#create-request-token
"""
endpoint = 'OS-OAUTH1/request_token'
headers = {'Requested-Project-Id': project_id}
@@ -142,7 +142,7 @@
"""Authorize request token.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#authorize-request-token
+ https://docs.openstack.org/api-ref/identity/v3-ext/#authorize-request-token
"""
roles = [{'id': role_id} for role_id in role_ids]
body = {'roles': roles}
@@ -158,7 +158,7 @@
"""Create access token.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#create-access-token
+ https://docs.openstack.org/api-ref/identity/v3-ext/#create-access-token
"""
endpoint = 'OS-OAUTH1/access_token'
oauth_params = self._generate_params_with_signature(
@@ -181,7 +181,7 @@
"""Get access token.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#get-access-token
+ https://docs.openstack.org/api-ref/identity/v3-ext/#get-access-token
"""
resp, body = self.get("users/%s/OS-OAUTH1/access_tokens/%s"
% (user_id, access_token_id))
@@ -193,7 +193,7 @@
"""Revoke access token.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#revoke-access-token
+ https://docs.openstack.org/api-ref/identity/v3-ext/#revoke-access-token
"""
resp, body = self.delete("users/%s/OS-OAUTH1/access_tokens/%s"
% (user_id, access_token_id))
@@ -204,7 +204,7 @@
"""List access tokens.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#list-access-tokens
+ https://docs.openstack.org/api-ref/identity/v3-ext/#list-access-tokens
"""
resp, body = self.get("users/%s/OS-OAUTH1/access_tokens"
% (user_id))
@@ -216,7 +216,7 @@
"""List roles for an access token.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#list-roles-for-an-access-token
+ https://docs.openstack.org/api-ref/identity/v3-ext/#list-roles-for-an-access-token
"""
resp, body = self.get("users/%s/OS-OAUTH1/access_tokens/%s/roles"
% (user_id, access_token_id))
@@ -228,7 +228,7 @@
"""Show role details for an access token.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/#show-role-details-for-an-access-token
+ https://docs.openstack.org/api-ref/identity/v3-ext/#show-role-details-for-an-access-token
"""
resp, body = self.get("users/%s/OS-OAUTH1/access_tokens/%s/roles/%s"
% (user_id, access_token_id, role_id))
diff --git a/tempest/lib/services/identity/v3/policies_client.py b/tempest/lib/services/identity/v3/policies_client.py
index ca8dbbd..31c0d18 100644
--- a/tempest/lib/services/identity/v3/policies_client.py
+++ b/tempest/lib/services/identity/v3/policies_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3/index.html#policies
+https://docs.openstack.org/api-ref/identity/v3/index.html#policies
"""
from oslo_serialization import jsonutils as json
@@ -30,7 +30,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-policy
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-policy
"""
post_body = json.dumps({'policy': kwargs})
resp, body = self.post('policies', post_body)
@@ -58,7 +58,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-policy
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-policy
"""
post_body = json.dumps({'policy': kwargs})
url = 'policies/%s' % policy_id
@@ -79,7 +79,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#associate-policy-and-endpoint
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#associate-policy-and-endpoint
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/endpoints/{1}"\
.format(policy_id, endpoint_id)
@@ -91,7 +91,7 @@
"""Get policy association of endpoint.
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#verify-a-policy-and-endpoint-association
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#verify-a-policy-and-endpoint-association
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/endpoints/{1}"\
.format(policy_id, endpoint_id)
@@ -103,7 +103,7 @@
"""Delete policy association with endpoint.
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#delete-a-policy-and-endpoint-association
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#delete-a-policy-and-endpoint-association
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/endpoints/{1}"\
.format(policy_id, endpoint_id)
@@ -115,7 +115,7 @@
"""Create policy association with service.
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#associate-policy-and-service-type-endpoint
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#associate-policy-and-service-type-endpoint
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/services/{1}"\
.format(policy_id, service_id)
@@ -127,7 +127,7 @@
"""Get policy association of service.
API Reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#verify-a-policy-and-service-type-endpoint-association
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#verify-a-policy-and-service-type-endpoint-association
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/services/{1}"\
.format(policy_id, service_id)
@@ -139,7 +139,7 @@
"""Delete policy association with service.
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#delete-a-policy-and-service-type-endpoint-association
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#delete-a-policy-and-service-type-endpoint-association
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/services/{1}"\
.format(policy_id, service_id)
@@ -152,7 +152,7 @@
"""Create policy association with service and region.
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#associate-policy-and-service-type-endpoint-in-a-region
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#associate-policy-and-service-type-endpoint-in-a-region
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/services/{1}/regions/{2}"\
.format(policy_id, service_id, region_id)
@@ -165,7 +165,7 @@
"""Get policy association of service and region.
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#verify-a-policy-and-service-type-endpoint-in-a-region-association
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#verify-a-policy-and-service-type-endpoint-in-a-region-association
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/services/{1}/regions/{2}"\
.format(policy_id, service_id, region_id)
@@ -178,7 +178,7 @@
"""Delete policy association with service and region.
API reference:
- https://developer.openstack.org/api-ref/identity/v3-ext/index.html#delete-a-policy-and-service-type-endpoint-in-a-region-association
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#delete-a-policy-and-service-type-endpoint-in-a-region-association
"""
url = "policies/{0}/OS-ENDPOINT-POLICY/services/{1}/regions/{2}"\
.format(policy_id, service_id, region_id)
diff --git a/tempest/lib/services/identity/v3/project_tags_client.py b/tempest/lib/services/identity/v3/project_tags_client.py
index dd1a2a5..5562273 100644
--- a/tempest/lib/services/identity/v3/project_tags_client.py
+++ b/tempest/lib/services/identity/v3/project_tags_client.py
@@ -48,7 +48,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/identity/v3/#modify-tag-list-for-a-project
+ https://docs.openstack.org/api-ref/identity/v3/#modify-tag-list-for-a-project
"""
body = {'tags': tags}
if kwargs:
diff --git a/tempest/lib/services/identity/v3/projects_client.py b/tempest/lib/services/identity/v3/projects_client.py
index 20787da..b186fba 100644
--- a/tempest/lib/services/identity/v3/projects_client.py
+++ b/tempest/lib/services/identity/v3/projects_client.py
@@ -27,7 +27,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-project
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-project
"""
# Include the project name to the kwargs parameters
@@ -52,7 +52,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-project
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-project
"""
post_body = json.dumps({'project': kwargs})
diff --git a/tempest/lib/services/identity/v3/regions_client.py b/tempest/lib/services/identity/v3/regions_client.py
index d7507cf..a598c9c 100644
--- a/tempest/lib/services/identity/v3/regions_client.py
+++ b/tempest/lib/services/identity/v3/regions_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3/index.html#regions
+https://docs.openstack.org/api-ref/identity/v3/index.html#regions
"""
from oslo_serialization import jsonutils as json
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-region
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-region
"""
if region_id is not None:
method = self.put
@@ -50,7 +50,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-region
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-region
"""
post_body = json.dumps({'region': kwargs})
resp, body = self.patch('regions/%s' % region_id, post_body)
diff --git a/tempest/lib/services/identity/v3/role_assignments_client.py b/tempest/lib/services/identity/v3/role_assignments_client.py
index a426e69..51ee8f6 100644
--- a/tempest/lib/services/identity/v3/role_assignments_client.py
+++ b/tempest/lib/services/identity/v3/role_assignments_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-role-assignments
+ https://docs.openstack.org/api-ref/identity/v3/#list-role-assignments
:param effective: If True, returns the effective assignments, including
any assignments gained by virtue of group membership
diff --git a/tempest/lib/services/identity/v3/roles_client.py b/tempest/lib/services/identity/v3/roles_client.py
index 43e3c01..f9356be 100644
--- a/tempest/lib/services/identity/v3/roles_client.py
+++ b/tempest/lib/services/identity/v3/roles_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-role
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-role
"""
post_body = json.dumps({'role': kwargs})
resp, body = self.post('roles', post_body)
@@ -42,8 +42,12 @@
return rest_client.ResponseBody(resp, body)
def list_roles(self, **params):
- """Get the list of Roles."""
+ """Get the list of Roles.
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/identity/v3/index.html#list-roles
+ """
url = 'roles'
if params:
url += '?%s' % urllib.urlencode(params)
@@ -57,7 +61,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-role
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-role
"""
post_body = json.dumps({'role': kwargs})
resp, body = self.patch('roles/%s' % role_id, post_body)
@@ -219,7 +223,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#list-all-role-inference-rules
+ https://docs.openstack.org/api-ref/identity/v3/index.html#list-all-role-inference-rules
"""
resp, body = self.get('role_inferences')
self.expected_success(200, resp.status)
diff --git a/tempest/lib/services/identity/v3/services_client.py b/tempest/lib/services/identity/v3/services_client.py
index 7bbe850..eb961a5 100644
--- a/tempest/lib/services/identity/v3/services_client.py
+++ b/tempest/lib/services/identity/v3/services_client.py
@@ -14,7 +14,7 @@
# under the License.
"""
-https://developer.openstack.org/api-ref/identity/v3/index.html#service-catalog-and-endpoints
+https://docs.openstack.org/api-ref/identity/v3/index.html#service-catalog-and-endpoints
"""
from oslo_serialization import jsonutils as json
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#update-service
+ https://docs.openstack.org/api-ref/identity/v3/index.html#update-service
"""
patch_body = json.dumps({'service': kwargs})
resp, body = self.patch('services/%s' % service_id, patch_body)
@@ -52,7 +52,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#create-service
+ https://docs.openstack.org/api-ref/identity/v3/index.html#create-service
"""
body = json.dumps({'service': kwargs})
resp, body = self.post("services", body)
@@ -71,7 +71,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-services
+ https://docs.openstack.org/api-ref/identity/v3/#list-services
"""
url = 'services'
if params:
diff --git a/tempest/lib/services/identity/v3/trusts_client.py b/tempest/lib/services/identity/v3/trusts_client.py
index d113905..f1cc806 100644
--- a/tempest/lib/services/identity/v3/trusts_client.py
+++ b/tempest/lib/services/identity/v3/trusts_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/index.html#create-trust
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#create-trust
"""
post_body = json.dumps({'trust': kwargs})
resp, body = self.post('OS-TRUST/trusts', post_body)
@@ -45,7 +45,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3-ext/index.html#list-trusts
+ https://docs.openstack.org/api-ref/identity/v3-ext/index.html#list-trusts
"""
url = "OS-TRUST/trusts/"
if params:
diff --git a/tempest/lib/services/identity/v3/users_client.py b/tempest/lib/services/identity/v3/users_client.py
index e99a971..f47730f 100644
--- a/tempest/lib/services/identity/v3/users_client.py
+++ b/tempest/lib/services/identity/v3/users_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#create-user
+ https://docs.openstack.org/api-ref/identity/v3/#create-user
"""
post_body = json.dumps({'user': kwargs})
resp, body = self.post('users', post_body)
@@ -39,7 +39,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#update-user
+ https://docs.openstack.org/api-ref/identity/v3/#update-user
"""
if 'id' not in kwargs:
kwargs['id'] = user_id
@@ -54,7 +54,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/index.html#change-password-for-user
+ https://docs.openstack.org/api-ref/identity/v3/index.html#change-password-for-user
"""
update_user = json.dumps({'user': kwargs})
resp, _ = self.post('users/%s/password' % user_id, update_user)
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-projects-for-user
+ https://docs.openstack.org/api-ref/identity/v3/#list-projects-for-user
"""
url = 'users/%s/projects' % user_id
if params:
@@ -81,7 +81,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-users
+ https://docs.openstack.org/api-ref/identity/v3/#list-users
"""
url = 'users'
if params:
@@ -109,7 +109,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/identity/v3/#list-groups-to-which-a-user-belongs
+ https://docs.openstack.org/api-ref/identity/v3/#list-groups-to-which-a-user-belongs
"""
url = 'users/%s/groups' % user_id
if params:
diff --git a/tempest/lib/services/image/v1/image_members_client.py b/tempest/lib/services/image/v1/image_members_client.py
index 2318087..7499ec0 100644
--- a/tempest/lib/services/image/v1/image_members_client.py
+++ b/tempest/lib/services/image/v1/image_members_client.py
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v1/#list-shared-images
+ https://docs.openstack.org/api-ref/image/v1/#list-shared-images
"""
url = 'shared-images/%s' % tenant_id
@@ -45,7 +45,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v1/#add-member-to-image
+ https://docs.openstack.org/api-ref/image/v1/#add-member-to-image
"""
url = 'images/%s/members/%s' % (image_id, member_id)
body = json.dumps({'member': kwargs})
@@ -58,7 +58,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v1/#remove-member
+ https://docs.openstack.org/api-ref/image/v1/#remove-member
"""
url = 'images/%s/members/%s' % (image_id, member_id)
resp, __ = self.delete(url)
diff --git a/tempest/lib/services/image/v1/images_client.py b/tempest/lib/services/image/v1/images_client.py
index 42f8cf2..0e76a63 100644
--- a/tempest/lib/services/image/v1/images_client.py
+++ b/tempest/lib/services/image/v1/images_client.py
@@ -61,7 +61,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v1/index.html#create-image
+ https://docs.openstack.org/api-ref/image/v1/index.html#create-image
"""
if headers is None:
headers = {}
@@ -79,7 +79,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v1/index.html#update-image
+ https://docs.openstack.org/api-ref/image/v1/index.html#update-image
"""
if headers is None:
headers = {}
@@ -104,7 +104,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v1/#list-images
+ https://docs.openstack.org/api-ref/image/v1/#list-images
Most parameters except the following are passed to the API without
any changes.
diff --git a/tempest/lib/services/image/v2/image_members_client.py b/tempest/lib/services/image/v2/image_members_client.py
index e5118a8..65024c7 100644
--- a/tempest/lib/services/image/v2/image_members_client.py
+++ b/tempest/lib/services/image/v2/image_members_client.py
@@ -23,7 +23,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#list-image-members
+ https://docs.openstack.org/api-ref/image/v2/#list-image-members
"""
url = 'images/%s/members' % image_id
resp, body = self.get(url)
@@ -36,7 +36,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#create-image-member
+ https://docs.openstack.org/api-ref/image/v2/#create-image-member
"""
url = 'images/%s/members' % image_id
data = json.dumps(kwargs)
@@ -50,7 +50,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#update-image-member
+ https://docs.openstack.org/api-ref/image/v2/#update-image-member
"""
url = 'images/%s/members/%s' % (image_id, member_id)
data = json.dumps(kwargs)
@@ -64,7 +64,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#show-image-member-details
+ https://docs.openstack.org/api-ref/image/v2/#show-image-member-details
"""
url = 'images/%s/members/%s' % (image_id, member_id)
resp, body = self.get(url)
@@ -76,7 +76,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#delete-image-member
+ https://docs.openstack.org/api-ref/image/v2/#delete-image-member
"""
url = 'images/%s/members/%s' % (image_id, member_id)
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/images_client.py b/tempest/lib/services/image/v2/images_client.py
index 3c38dba..90778da 100644
--- a/tempest/lib/services/image/v2/images_client.py
+++ b/tempest/lib/services/image/v2/images_client.py
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v2/#update-image
+ https://docs.openstack.org/api-ref/image/v2/#update-image
"""
data = json.dumps(patch)
headers = {"Content-Type": "application/openstack-images-v2.0"
@@ -47,7 +47,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v2/#create-image
+ https://docs.openstack.org/api-ref/image/v2/#create-image
"""
data = json.dumps(kwargs)
resp, body = self.post('images', data)
@@ -60,7 +60,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#deactivate-image
+ https://docs.openstack.org/api-ref/image/v2/#deactivate-image
"""
url = 'images/%s/actions/deactivate' % image_id
resp, body = self.post(url, None)
@@ -72,7 +72,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#reactivate-image
+ https://docs.openstack.org/api-ref/image/v2/#reactivate-image
"""
url = 'images/%s/actions/reactivate' % image_id
resp, body = self.post(url, None)
@@ -84,7 +84,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v2/#delete-image
+ https://docs.openstack.org/api-ref/image/v2/#delete-image
"""
url = 'images/%s' % image_id
resp, _ = self.delete(url)
@@ -96,7 +96,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v2/#list-images
+ https://docs.openstack.org/api-ref/image/v2/#list-images
"""
url = 'images'
@@ -113,7 +113,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v2/#show-image
+ https://docs.openstack.org/api-ref/image/v2/#show-image
"""
url = 'images/%s' % image_id
resp, body = self.get(url)
@@ -138,7 +138,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#upload-binary-image-data
+ https://docs.openstack.org/api-ref/image/v2/#upload-binary-image-data
"""
url = 'images/%s/file' % image_id
@@ -157,7 +157,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#download-binary-image-data
+ https://docs.openstack.org/api-ref/image/v2/#download-binary-image-data
"""
url = 'images/%s/file' % image_id
resp, body = self.get(url)
@@ -169,7 +169,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#add-image-tag
+ https://docs.openstack.org/api-ref/image/v2/#add-image-tag
"""
url = 'images/%s/tags/%s' % (image_id, tag)
resp, body = self.put(url, body=None)
@@ -181,7 +181,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/#delete-image-tag
+ https://docs.openstack.org/api-ref/image/v2/#delete-image-tag
"""
url = 'images/%s/tags/%s' % (image_id, tag)
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/namespace_objects_client.py b/tempest/lib/services/image/v2/namespace_objects_client.py
index ac2e63e..0cae816 100644
--- a/tempest/lib/services/image/v2/namespace_objects_client.py
+++ b/tempest/lib/services/image/v2/namespace_objects_client.py
@@ -27,7 +27,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-objects
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#list-objects
"""
url = 'metadefs/namespaces/%s/objects' % namespace
if kwargs:
@@ -42,7 +42,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-object
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#create-object
"""
url = 'metadefs/namespaces/%s/objects' % namespace
data = json.dumps(kwargs)
@@ -56,7 +56,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-object
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#update-object
"""
url = 'metadefs/namespaces/%s/objects/%s' % (namespace, object_name)
data = json.dumps(kwargs)
@@ -70,7 +70,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#show-object
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#show-object
"""
url = 'metadefs/namespaces/%s/objects/%s' % (namespace, object_name)
resp, body = self.get(url)
@@ -83,7 +83,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-object
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#delete-object
"""
url = 'metadefs/namespaces/%s/objects/%s' % (namespace, object_name)
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/namespace_properties_client.py b/tempest/lib/services/image/v2/namespace_properties_client.py
index 1236b2b..5b245ca 100644
--- a/tempest/lib/services/image/v2/namespace_properties_client.py
+++ b/tempest/lib/services/image/v2/namespace_properties_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-properties
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#list-properties
"""
url = 'metadefs/namespaces/%s/properties' % namespace
resp, body = self.get(url)
@@ -39,7 +39,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-property
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#create-property
"""
url = 'metadefs/namespaces/%s/properties' % namespace
data = json.dumps(kwargs)
@@ -53,7 +53,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#show-property-definition
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#show-property-definition
"""
url = 'metadefs/namespaces/%s/properties/%s' % (namespace,
property_name)
@@ -67,7 +67,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-property-definition
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#update-property-definition
"""
url = 'metadefs/namespaces/%s/properties/%s' % (namespace,
property_name)
@@ -82,7 +82,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#remove-property-definition
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#remove-property-definition
"""
url = 'metadefs/namespaces/%s/properties/%s' % (namespace,
property_name)
diff --git a/tempest/lib/services/image/v2/namespace_tags_client.py b/tempest/lib/services/image/v2/namespace_tags_client.py
index 61cc33d..cf63e50 100644
--- a/tempest/lib/services/image/v2/namespace_tags_client.py
+++ b/tempest/lib/services/image/v2/namespace_tags_client.py
@@ -27,7 +27,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-tag-definition
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#create-tag-definition
"""
url = 'metadefs/namespaces/%s/tags/%s' % (namespace,
tag_name)
@@ -41,7 +41,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/image/v2/metadefs-index.html#get-tag-definition
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#get-tag-definition
"""
url = 'metadefs/namespaces/%s/tags/%s' % (namespace,
tag_name)
@@ -55,7 +55,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-tag-definition
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#update-tag-definition
"""
url = 'metadefs/namespaces/%s/tags/%s' % (namespace,
tag_name)
@@ -70,7 +70,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-tag-definition
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#delete-tag-definition
"""
url = 'metadefs/namespaces/%s/tags/%s' % (namespace, tag_name)
resp, _ = self.delete(url)
@@ -82,7 +82,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-tags
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#create-tags
"""
url = 'metadefs/namespaces/%s/tags' % namespace
data = json.dumps(kwargs)
@@ -96,7 +96,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-tags
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#list-tags
"""
url = 'metadefs/namespaces/%s/tags' % namespace
if params:
@@ -111,7 +111,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-all-tag-definitions
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#delete-all-tag-definitions
"""
url = 'metadefs/namespaces/%s/tags' % namespace
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/namespaces_client.py b/tempest/lib/services/image/v2/namespaces_client.py
index b00de89..c0fa74a 100644
--- a/tempest/lib/services/image/v2/namespaces_client.py
+++ b/tempest/lib/services/image/v2/namespaces_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-namespace
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#create-namespace
"""
data = json.dumps(kwargs)
resp, body = self.post('metadefs/namespaces', data)
@@ -39,7 +39,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-namespaces
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#list-namespaces
"""
url = 'metadefs/namespaces'
resp, body = self.get(url)
@@ -52,7 +52,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#get-namespace-details
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#get-namespace-details
"""
url = 'metadefs/namespaces/%s' % namespace
resp, body = self.get(url)
@@ -65,7 +65,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-namespace
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#update-namespace
"""
# NOTE: On Glance API, we need to pass namespace on both URI
# and a request body.
@@ -83,7 +83,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-namespace
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#delete-namespace
"""
url = 'metadefs/namespaces/%s' % namespace
resp, _ = self.delete(url)
diff --git a/tempest/lib/services/image/v2/resource_types_client.py b/tempest/lib/services/image/v2/resource_types_client.py
index 13259d1..ec02f1a 100644
--- a/tempest/lib/services/image/v2/resource_types_client.py
+++ b/tempest/lib/services/image/v2/resource_types_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-resource-types
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#list-resource-types
"""
url = 'metadefs/resource_types'
resp, body = self.get(url)
@@ -39,7 +39,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-resource-type-association
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#create-resource-type-association
"""
url = 'metadefs/namespaces/%s/resource_types' % namespace_id
data = json.dumps(kwargs)
@@ -53,7 +53,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-resource-type-associations
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#list-resource-type-associations
"""
url = 'metadefs/namespaces/%s/resource_types' % namespace_id
resp, body = self.get(url)
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#remove-resource-type-association
+ https://docs.openstack.org/api-ref/image/v2/metadefs-index.html#remove-resource-type-association
"""
url = 'metadefs/namespaces/%s/resource_types/%s' % (namespace_id,
resource_name)
diff --git a/tempest/lib/services/network/__init__.py b/tempest/lib/services/network/__init__.py
index 419e593..f7ac046 100644
--- a/tempest/lib/services/network/__init__.py
+++ b/tempest/lib/services/network/__init__.py
@@ -21,12 +21,16 @@
MeteringLabelsClient
from tempest.lib.services.network.networks_client import NetworksClient
from tempest.lib.services.network.ports_client import PortsClient
+from tempest.lib.services.network.qos_client import QosClient
+from tempest.lib.services.network.qos_minimum_bandwidth_rules_client import \
+ QosMinimumBandwidthRulesClient
from tempest.lib.services.network.quotas_client import QuotasClient
from tempest.lib.services.network.routers_client import RoutersClient
from tempest.lib.services.network.security_group_rules_client import \
SecurityGroupRulesClient
from tempest.lib.services.network.security_groups_client import \
SecurityGroupsClient
+from tempest.lib.services.network.segments_client import SegmentsClient
from tempest.lib.services.network.service_providers_client import \
ServiceProvidersClient
from tempest.lib.services.network.subnetpools_client import SubnetpoolsClient
@@ -37,6 +41,7 @@
__all__ = ['AgentsClient', 'ExtensionsClient', 'FloatingIPsClient',
'MeteringLabelRulesClient', 'MeteringLabelsClient',
'NetworksClient', 'NetworkVersionsClient', 'PortsClient',
- 'QuotasClient', 'RoutersClient', 'SecurityGroupRulesClient',
- 'SecurityGroupsClient', 'ServiceProvidersClient',
- 'SubnetpoolsClient', 'SubnetsClient', 'TagsClient']
+ 'QosClient', 'QosMinimumBandwidthRulesClient', 'QuotasClient',
+ 'RoutersClient', 'SecurityGroupRulesClient', 'SecurityGroupsClient',
+ 'SegmentsClient', 'ServiceProvidersClient', 'SubnetpoolsClient',
+ 'SubnetsClient', 'TagsClient']
diff --git a/tempest/lib/services/network/agents_client.py b/tempest/lib/services/network/agents_client.py
index 9fa4672..03f2543 100644
--- a/tempest/lib/services/network/agents_client.py
+++ b/tempest/lib/services/network/agents_client.py
@@ -22,7 +22,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/#update-agent
+ https://docs.openstack.org/api-ref/network/v2/#update-agent
"""
uri = '/agents/%s' % agent_id
return self.update_resource(uri, kwargs)
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/#show-agent-details
+ https://docs.openstack.org/api-ref/network/v2/#show-agent-details
"""
uri = '/agents/%s' % agent_id
return self.show_resource(uri, **fields)
@@ -42,7 +42,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/index.html#delete-agent
+ https://docs.openstack.org/api-ref/network/v2/index.html#delete-agent
"""
uri = '/agents/%s' % agent_id
return self.delete_resource(uri)
@@ -52,7 +52,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/#list-all-agents
+ https://docs.openstack.org/api-ref/network/v2/#list-all-agents
"""
uri = '/agents'
return self.list_resources(uri, **filters)
@@ -62,7 +62,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/#list-routers-hosted-by-an-l3-agent
+ https://docs.openstack.org/api-ref/network/v2/#list-routers-hosted-by-an-l3-agent
"""
uri = '/agents/%s/l3-routers' % agent_id
return self.list_resources(uri)
@@ -72,7 +72,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/#schedule-router-to-an-l3-agent
+ https://docs.openstack.org/api-ref/network/v2/#schedule-router-to-an-l3-agent
"""
uri = '/agents/%s/l3-routers' % agent_id
return self.create_resource(uri, kwargs, expect_empty_body=True)
@@ -82,7 +82,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/#remove-l3-router-from-an-l3-agent
+ https://docs.openstack.org/api-ref/network/v2/#remove-l3-router-from-an-l3-agent
"""
uri = '/agents/%s/l3-routers/%s' % (agent_id, router_id)
return self.delete_resource(uri)
@@ -101,7 +101,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/#schedule-a-network-to-a-dhcp-agent
+ https://docs.openstack.org/api-ref/network/v2/#schedule-a-network-to-a-dhcp-agent
"""
uri = '/agents/%s/dhcp-networks' % agent_id
return self.create_resource(uri, kwargs, expect_empty_body=True)
diff --git a/tempest/lib/services/network/extensions_client.py b/tempest/lib/services/network/extensions_client.py
index 3910c84..4701cb0 100644
--- a/tempest/lib/services/network/extensions_client.py
+++ b/tempest/lib/services/network/extensions_client.py
@@ -16,9 +16,21 @@
class ExtensionsClient(base.BaseNetworkClient):
def show_extension(self, ext_alias, **fields):
+ """Show extension details.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-extension-details
+ """
uri = '/extensions/%s' % ext_alias
return self.show_resource(uri, **fields)
def list_extensions(self, **filters):
+ """List extensions.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-extensions
+ """
uri = '/extensions'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/floating_ips_client.py b/tempest/lib/services/network/floating_ips_client.py
index 2bb18e0..a63150b 100644
--- a/tempest/lib/services/network/floating_ips_client.py
+++ b/tempest/lib/services/network/floating_ips_client.py
@@ -23,7 +23,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-floating-ip
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-floating-ip
"""
uri = '/floatingips'
post_data = {'floatingip': kwargs}
@@ -34,7 +34,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#update-floating-ip
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-floating-ip
"""
uri = '/floatingips/%s' % floatingip_id
post_data = {'floatingip': kwargs}
@@ -45,7 +45,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-floating-ip-details
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-floating-ip-details
"""
uri = '/floatingips/%s' % floatingip_id
return self.show_resource(uri, **fields)
@@ -59,7 +59,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-floating-ips
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-floating-ips
"""
uri = '/floatingips'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/metering_label_rules_client.py b/tempest/lib/services/network/metering_label_rules_client.py
index 9542e8f..dd5fd52 100644
--- a/tempest/lib/services/network/metering_label_rules_client.py
+++ b/tempest/lib/services/network/metering_label_rules_client.py
@@ -20,17 +20,24 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/index.html#create-metering-label-rule
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-metering-label-rule
"""
uri = '/metering/metering-label-rules'
post_data = {'metering_label_rule': kwargs}
return self.create_resource(uri, post_data)
def show_metering_label_rule(self, metering_label_rule_id, **fields):
+ """Show metering label rule.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-metering-label-rule-details
+ """
uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
return self.show_resource(uri, **fields)
def delete_metering_label_rule(self, metering_label_rule_id):
+ """Delete metering label rule."""
uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
return self.delete_resource(uri)
@@ -39,7 +46,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/index.html#list-metering-label-rules
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-metering-label-rules
"""
uri = '/metering/metering-label-rules'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/metering_labels_client.py b/tempest/lib/services/network/metering_labels_client.py
index 411da1f..80ed51f 100644
--- a/tempest/lib/services/network/metering_labels_client.py
+++ b/tempest/lib/services/network/metering_labels_client.py
@@ -20,7 +20,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-metering-label
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-metering-label
"""
uri = '/metering/metering-labels'
post_data = {'metering_label': kwargs}
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-metering-label-details
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-metering-label-details
"""
uri = '/metering/metering-labels/%s' % metering_label_id
return self.show_resource(uri, **fields)
@@ -41,7 +41,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#delete-metering-label
+ https://docs.openstack.org/api-ref/network/v2/index.html#delete-metering-label
"""
uri = '/metering/metering-labels/%s' % metering_label_id
return self.delete_resource(uri)
@@ -51,7 +51,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-metering-labels
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-metering-labels
"""
uri = '/metering/metering-labels'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/networks_client.py b/tempest/lib/services/network/networks_client.py
index 77d4823..f0e735e 100644
--- a/tempest/lib/services/network/networks_client.py
+++ b/tempest/lib/services/network/networks_client.py
@@ -20,7 +20,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-network
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-network
"""
uri = '/networks'
post_data = {'network': kwargs}
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#update-network
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-network
"""
uri = '/networks/%s' % network_id
post_data = {'network': kwargs}
@@ -42,7 +42,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-network-details
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-network-details
"""
uri = '/networks/%s' % network_id
return self.show_resource(uri, **fields)
@@ -56,7 +56,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-networks
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-networks
"""
uri = '/networks'
return self.list_resources(uri, **filters)
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#bulk-create-networks
+ https://docs.openstack.org/api-ref/network/v2/index.html#bulk-create-networks
"""
uri = '/networks'
return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/ports_client.py b/tempest/lib/services/network/ports_client.py
index daa15d7..d77b62f 100644
--- a/tempest/lib/services/network/ports_client.py
+++ b/tempest/lib/services/network/ports_client.py
@@ -21,7 +21,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-port
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-port
"""
uri = '/ports'
post_data = {'port': kwargs}
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#update-port
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-port
"""
uri = '/ports/%s' % port_id
post_data = {'port': kwargs}
@@ -43,7 +43,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-port-details
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-port-details
"""
uri = '/ports/%s' % port_id
return self.show_resource(uri, **fields)
@@ -53,7 +53,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#delete-port
+ https://docs.openstack.org/api-ref/network/v2/index.html#delete-port
"""
uri = '/ports/%s' % port_id
return self.delete_resource(uri)
@@ -63,7 +63,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-ports
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-ports
"""
uri = '/ports'
return self.list_resources(uri, **filters)
@@ -73,7 +73,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#bulk-create-ports
+ https://docs.openstack.org/api-ref/network/v2/index.html#bulk-create-ports
"""
uri = '/ports'
return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/qos_client.py b/tempest/lib/services/network/qos_client.py
new file mode 100644
index 0000000..47dc70a
--- /dev/null
+++ b/tempest/lib/services/network/qos_client.py
@@ -0,0 +1,70 @@
+# Copyright (c) 2019 Ericsson
+#
+# 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.network import base
+
+
+class QosClient(base.BaseNetworkClient):
+
+ def create_qos_policy(self, **kwargs):
+ """Creates a QoS policy.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-qos-policy
+ """
+ uri = '/qos/policies'
+ post_data = {'policy': kwargs}
+ return self.create_resource(uri, post_data)
+
+ def update_qos_policy(self, qos_policy_id, **kwargs):
+ """Updates a QoS policy.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-qos-policy
+ """
+ uri = '/qos/policies/%s' % qos_policy_id
+ post_data = {'policy': kwargs}
+ return self.update_resource(uri, post_data)
+
+ def show_qos_policy(self, qos_policy_id, **fields):
+ """Show details of a QoS policy.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-qos-policy-details
+ """
+ uri = '/qos/policies/%s' % qos_policy_id
+ return self.show_resource(uri, **fields)
+
+ def delete_qos_policy(self, qos_policy_id):
+ """Deletes a QoS policy.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#delete-qos-policy
+ """
+ uri = '/qos/policies/%s' % qos_policy_id
+ return self.delete_resource(uri)
+
+ def list_qos_policies(self, **filters):
+ """Lists QoS policies.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-qos-policies
+ """
+ uri = '/qos/policies'
+ return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/qos_minimum_bandwidth_rules_client.py b/tempest/lib/services/network/qos_minimum_bandwidth_rules_client.py
new file mode 100644
index 0000000..dd9f45f
--- /dev/null
+++ b/tempest/lib/services/network/qos_minimum_bandwidth_rules_client.py
@@ -0,0 +1,73 @@
+# Copyright (c) 2019 Ericsson
+#
+# 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.network import base
+
+
+class QosMinimumBandwidthRulesClient(base.BaseNetworkClient):
+
+ def create_minimum_bandwidth_rule(self, qos_policy_id, **kwargs):
+ """Creates a minimum bandwidth rule for a QoS policy.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-minimum-bandwidth-rule
+ """
+ uri = '/qos/policies/%s/minimum_bandwidth_rules' % qos_policy_id
+ post_data = {'minimum_bandwidth_rule': kwargs}
+ return self.create_resource(uri, post_data)
+
+ def update_minimum_bandwidth_rule(self, qos_policy_id, rule_id, **kwargs):
+ """Updates a minimum bandwidth rule.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-minimum-bandwidth-rule
+ """
+ uri = '/qos/policies/%s/minimum_bandwidth_rules/%s' % (
+ qos_policy_id, rule_id)
+ post_data = {'minimum_bandwidth_rule': kwargs}
+ return self.update_resource(uri, post_data)
+
+ def show_minimum_bandwidth_rule(self, qos_policy_id, rule_id, **fields):
+ """Show details of a minimum bandwidth rule.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-minimum-bandwidth-rule-details
+ """
+ uri = '/qos/policies/%s/minimum_bandwidth_rules/%s' % (
+ qos_policy_id, rule_id)
+ return self.show_resource(uri, **fields)
+
+ def delete_minimum_bandwidth_rule(self, qos_policy_id, rule_id):
+ """Deletes a minimum bandwidth rule for a QoS policy.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#delete-minimum-bandwidth-rule
+ """
+ uri = '/qos/policies/%s/minimum_bandwidth_rules/%s' % (
+ qos_policy_id, rule_id)
+ return self.delete_resource(uri)
+
+ def list_minimum_bandwidth_rules(self, qos_policy_id, **filters):
+ """Lists all minimum bandwidth rules for a QoS policy.
+
+ For full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-minimum-bandwidth-rules-for-qos-policy
+ """
+ uri = '/qos/policies/%s/minimum_bandwidth_rules' % qos_policy_id
+ return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/quotas_client.py b/tempest/lib/services/network/quotas_client.py
index e9666de..997d201 100644
--- a/tempest/lib/services/network/quotas_client.py
+++ b/tempest/lib/services/network/quotas_client.py
@@ -22,7 +22,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/index.html#update-quota-for-a-project
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-quota-for-a-project
"""
put_body = {'quota': kwargs}
uri = '/quotas/%s' % tenant_id
@@ -35,10 +35,22 @@
return self.delete_resource(uri)
def show_quotas(self, tenant_id, **fields):
+ """Show quota for a project.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-quotas-for-a-project
+ """
uri = '/quotas/%s' % tenant_id
return self.show_resource(uri, **fields)
def list_quotas(self, **filters):
+ """List quotas for projects with non default quota values.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-quotas-for-projects-with-non-default-quota-values
+ """
uri = '/quotas'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/routers_client.py b/tempest/lib/services/network/routers_client.py
index 19b7627..2af487f 100644
--- a/tempest/lib/services/network/routers_client.py
+++ b/tempest/lib/services/network/routers_client.py
@@ -20,7 +20,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-router
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-router
"""
post_body = {'router': kwargs}
uri = '/routers'
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#update-router
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-router
"""
uri = '/routers/%s' % router_id
update_body = {'router': kwargs}
@@ -42,7 +42,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-router-details
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-router-details
"""
uri = '/routers/%s' % router_id
return self.show_resource(uri, **fields)
@@ -56,7 +56,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-routers
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-routers
"""
uri = '/routers'
return self.list_resources(uri, **filters)
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#add-interface-to-router
+ https://docs.openstack.org/api-ref/network/v2/index.html#add-interface-to-router
"""
uri = '/routers/%s/add_router_interface' % router_id
return self.update_resource(uri, kwargs)
@@ -76,7 +76,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#remove-interface-from-router
+ https://docs.openstack.org/api-ref/network/v2/index.html#remove-interface-from-router
"""
uri = '/routers/%s/remove_router_interface' % router_id
return self.update_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/security_group_rules_client.py b/tempest/lib/services/network/security_group_rules_client.py
index d2bc4a9..d62b05f 100644
--- a/tempest/lib/services/network/security_group_rules_client.py
+++ b/tempest/lib/services/network/security_group_rules_client.py
@@ -20,7 +20,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-security-group-rule
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-security-group-rule
"""
uri = '/security-group-rules'
post_data = {'security_group_rule': kwargs}
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-security-group-rule
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-security-group-rule
"""
uri = '/security-group-rules/%s' % security_group_rule_id
return self.show_resource(uri, **fields)
@@ -45,7 +45,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-security-group-rules
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-security-group-rules
"""
uri = '/security-group-rules'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/security_groups_client.py b/tempest/lib/services/network/security_groups_client.py
index d3ebf20..b641839 100644
--- a/tempest/lib/services/network/security_groups_client.py
+++ b/tempest/lib/services/network/security_groups_client.py
@@ -21,7 +21,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-security-group
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-security-group
"""
uri = '/security-groups'
post_data = {'security_group': kwargs}
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#update-security-group
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-security-group
"""
uri = '/security-groups/%s' % security_group_id
post_data = {'security_group': kwargs}
@@ -43,7 +43,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-security-group
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-security-group
"""
uri = '/security-groups/%s' % security_group_id
return self.show_resource(uri, **fields)
@@ -53,7 +53,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#delete-security-group
+ https://docs.openstack.org/api-ref/network/v2/index.html#delete-security-group
"""
uri = '/security-groups/%s' % security_group_id
return self.delete_resource(uri)
@@ -63,7 +63,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-security-groups
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-security-groups
"""
uri = '/security-groups'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/segments_client.py b/tempest/lib/services/network/segments_client.py
new file mode 100644
index 0000000..30e6b23
--- /dev/null
+++ b/tempest/lib/services/network/segments_client.py
@@ -0,0 +1,63 @@
+# 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.network import base
+
+
+class SegmentsClient(base.BaseNetworkClient):
+
+ def create_segment(self, **kwargs):
+ """Creates a segment.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-segment
+ """
+ uri = '/segments'
+ post_data = {'segment': kwargs}
+ return self.create_resource(uri, post_data)
+
+ def update_segment(self, segment_id, **kwargs):
+ """Updates a segment.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-segment
+ """
+ uri = '/segments/%s' % segment_id
+ post_data = {'segment': kwargs}
+ return self.update_resource(uri, post_data)
+
+ def show_segment(self, segment_id, **fields):
+ """Shows details of a segment.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-segment-details
+ """
+ uri = '/segments/%s' % segment_id
+ return self.show_resource(uri, **fields)
+
+ def delete_segment(self, segment_id):
+ """Deletes a segment"""
+ uri = '/segments/%s' % segment_id
+ return self.delete_resource(uri)
+
+ def list_segments(self, **filters):
+ """Lists segments.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-segments
+ """
+ uri = '/segments'
+ return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/service_providers_client.py b/tempest/lib/services/network/service_providers_client.py
index 01313a0..4ce617f 100644
--- a/tempest/lib/services/network/service_providers_client.py
+++ b/tempest/lib/services/network/service_providers_client.py
@@ -20,7 +20,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/network/v2/index.html#list-service-providers
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-service-providers
"""
uri = '/service-providers'
return self.list_resources(uri, **filters)
diff --git a/tempest/lib/services/network/subnetpools_client.py b/tempest/lib/services/network/subnetpools_client.py
index 7e77e30..635c449 100644
--- a/tempest/lib/services/network/subnetpools_client.py
+++ b/tempest/lib/services/network/subnetpools_client.py
@@ -22,7 +22,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-subnet-pools
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-subnet-pools
"""
uri = '/subnetpools'
return self.list_resources(uri, **filters)
@@ -32,7 +32,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-subnet-pool
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-subnet-pool
"""
uri = '/subnetpools'
post_data = {'subnetpool': kwargs}
@@ -43,7 +43,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-subnet-pool
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-subnet-pool
"""
uri = '/subnetpools/%s' % subnetpool_id
return self.show_resource(uri, **fields)
@@ -53,7 +53,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#update-subnet-pool
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-subnet-pool
"""
uri = '/subnetpools/%s' % subnetpool_id
post_data = {'subnetpool': kwargs}
diff --git a/tempest/lib/services/network/subnets_client.py b/tempest/lib/services/network/subnets_client.py
index b843f84..00dd423 100644
--- a/tempest/lib/services/network/subnets_client.py
+++ b/tempest/lib/services/network/subnets_client.py
@@ -20,7 +20,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#create-subnet
+ https://docs.openstack.org/api-ref/network/v2/index.html#create-subnet
"""
uri = '/subnets'
post_data = {'subnet': kwargs}
@@ -31,7 +31,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#update-subnet
+ https://docs.openstack.org/api-ref/network/v2/index.html#update-subnet
"""
uri = '/subnets/%s' % subnet_id
post_data = {'subnet': kwargs}
@@ -42,7 +42,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#show-subnet-details
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-subnet-details
"""
uri = '/subnets/%s' % subnet_id
return self.show_resource(uri, **fields)
@@ -56,7 +56,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#list-subnets
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-subnets
"""
uri = '/subnets'
return self.list_resources(uri, **filters)
@@ -66,7 +66,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#bulk-create-subnet
+ https://docs.openstack.org/api-ref/network/v2/index.html#bulk-create-subnet
"""
uri = '/subnets'
return self.create_resource(uri, kwargs)
diff --git a/tempest/lib/services/network/tags_client.py b/tempest/lib/services/network/tags_client.py
index 5d49a79..71e17c7 100644
--- a/tempest/lib/services/network/tags_client.py
+++ b/tempest/lib/services/network/tags_client.py
@@ -25,7 +25,7 @@
"""Adds a tag on the resource.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#add-a-tag
+ https://docs.openstack.org/api-ref/network/v2/index.html#add-a-tag
"""
uri = '/%s/%s/tags/%s' % (resource_type, resource_id, tag)
return self.update_resource(
@@ -36,7 +36,7 @@
"""Confirm that a given tag is set on the resource.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#confirm-a-tag
+ https://docs.openstack.org/api-ref/network/v2/index.html#confirm-a-tag
"""
# TODO(felipemonteiro): Use the "check_resource" method in
# ``BaseNetworkClient`` once it has been implemented.
@@ -50,7 +50,7 @@
"""Replace all tags on the resource.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#replace-all-tags
+ https://docs.openstack.org/api-ref/network/v2/index.html#replace-all-tags
"""
uri = '/%s/%s/tags' % (resource_type, resource_id)
put_body = {"tags": tags}
@@ -60,7 +60,7 @@
"""Removes a tag on the resource.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#remove-a-tag
+ https://docs.openstack.org/api-ref/network/v2/index.html#remove-a-tag
"""
uri = '/%s/%s/tags/%s' % (resource_type, resource_id, tag)
return self.delete_resource(uri)
@@ -69,7 +69,7 @@
"""Removes all tags on the resource.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#remove-all-tags
+ https://docs.openstack.org/api-ref/network/v2/index.html#remove-all-tags
"""
uri = '/%s/%s/tags' % (resource_type, resource_id)
return self.delete_resource(uri)
@@ -78,7 +78,7 @@
"""Retrieves the tags for a resource.
For more information, please refer to the official API reference:
- http://developer.openstack.org/api-ref/networking/v2/index.html#obtain-tag-list
+ https://docs.openstack.org/api-ref/network/v2/index.html#obtain-tag-list
"""
uri = '/%s/%s/tags' % (resource_type, resource_id)
return self.list_resources(uri)
diff --git a/tempest/lib/services/network/versions_client.py b/tempest/lib/services/network/versions_client.py
index 807f416..5aa7964 100644
--- a/tempest/lib/services/network/versions_client.py
+++ b/tempest/lib/services/network/versions_client.py
@@ -24,7 +24,7 @@
"""Do a GET / to fetch available API version information.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/network/v2/index.html#list-api-versions
+ https://docs.openstack.org/api-ref/network/v2/index.html#list-api-versions
"""
# Note: we do a self.get('/') here because we want to use
@@ -38,7 +38,7 @@
"""Do a GET /<version> to fetch available resources.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/network/v2/index.html#show-api-v2-details
+ https://docs.openstack.org/api-ref/network/v2/index.html#show-api-v2-details
"""
resp, body = self.get(version + '/')
diff --git a/tempest/lib/services/object_storage/account_client.py b/tempest/lib/services/object_storage/account_client.py
index 6b097c1..8c15a88 100644
--- a/tempest/lib/services/object_storage/account_client.py
+++ b/tempest/lib/services/object_storage/account_client.py
@@ -34,7 +34,7 @@
Account Metadata can be created, updated or deleted based on
metadata header or value. For detailed info, please refer to the
official API reference:
- https://developer.openstack.org/api-ref/object-store/#create-update-or-delete-account-metadata
+ https://docs.openstack.org/api-ref/object-store/#create-update-or-delete-account-metadata
"""
headers = {}
if create_update_metadata:
@@ -63,7 +63,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/object-store/#show-account-details-and-list-containers
+ https://docs.openstack.org/api-ref/object-store/#show-account-details-and-list-containers
"""
url = '?%s' % urllib.urlencode(params) if params else ''
diff --git a/tempest/lib/services/object_storage/container_client.py b/tempest/lib/services/object_storage/container_client.py
index 430e0d4..027fb1f 100644
--- a/tempest/lib/services/object_storage/container_client.py
+++ b/tempest/lib/services/object_storage/container_client.py
@@ -30,7 +30,7 @@
with optional metadata passed in as a dictionary.
Full list of allowed headers or value, please refer to the
official API reference:
- https://developer.openstack.org/api-ref/object-store/#create-container
+ https://docs.openstack.org/api-ref/object-store/#create-container
"""
url = str(container_name)
@@ -61,7 +61,7 @@
Container Metadata can be created, updated or deleted based on
metadata header or value. For detailed info, please refer to the
official API reference:
- https://developer.openstack.org/api-ref/object-store/#create-update-or-delete-container-metadata
+ https://docs.openstack.org/api-ref/object-store/#create-update-or-delete-container-metadata
"""
url = str(container_name)
headers = {}
@@ -97,7 +97,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/object-store/#show-container-details-and-list-objects
+ https://docs.openstack.org/api-ref/object-store/#show-container-details-and-list-objects
"""
url = str(container_name)
diff --git a/tempest/lib/services/placement/placement_client.py b/tempest/lib/services/placement/placement_client.py
index 2c6d919..b8e91b8 100644
--- a/tempest/lib/services/placement/placement_client.py
+++ b/tempest/lib/services/placement/placement_client.py
@@ -26,7 +26,7 @@
For full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/placement/#list-allocation-candidates
+ https://docs.openstack.org/api-ref/placement/#list-allocation-candidates
"""
url = '/allocation_candidates'
if params:
@@ -41,7 +41,7 @@
For full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/placement/#list-allocations
+ https://docs.openstack.org/api-ref/placement/#list-allocations
"""
url = '/allocations/%s' % consumer_uuid
resp, body = self.get(url)
diff --git a/tempest/lib/services/volume/v1/backups_client.py b/tempest/lib/services/volume/v1/backups_client.py
index 77c40b3..edc5dda 100644
--- a/tempest/lib/services/volume/v1/backups_client.py
+++ b/tempest/lib/services/volume/v1/backups_client.py
@@ -28,7 +28,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/block-storage/v2/#create-backup
+ https://docs.openstack.org/api-ref/block-storage/v2/#create-backup
"""
post_body = json.dumps({'backup': kwargs})
resp, body = self.post('backups', post_body)
@@ -41,7 +41,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/block-storage/v2/#restore-backup
+ https://docs.openstack.org/api-ref/block-storage/v2/#restore-backup
"""
post_body = json.dumps({'restore': kwargs})
resp, body = self.post('backups/%s/restore' % (backup_id), post_body)
diff --git a/tempest/lib/services/volume/v1/encryption_types_client.py b/tempest/lib/services/volume/v1/encryption_types_client.py
index 1fde79f..8e75ff9 100644
--- a/tempest/lib/services/volume/v1/encryption_types_client.py
+++ b/tempest/lib/services/volume/v1/encryption_types_client.py
@@ -51,7 +51,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#create-an-encryption-type-for-v2
+ https://docs.openstack.org/api-ref/block-storage/v2/#create-an-encryption-type-for-v2
"""
url = "/types/%s/encryption" % volume_type_id
post_body = json.dumps({'encryption': kwargs})
diff --git a/tempest/lib/services/volume/v1/hosts_client.py b/tempest/lib/services/volume/v1/hosts_client.py
index 9b19b84..f344678 100644
--- a/tempest/lib/services/volume/v1/hosts_client.py
+++ b/tempest/lib/services/volume/v1/hosts_client.py
@@ -27,7 +27,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#list-all-hosts
+ https://docs.openstack.org/api-ref/block-storage/v2/#list-all-hosts
"""
url = 'os-hosts'
if params:
diff --git a/tempest/lib/services/volume/v1/qos_client.py b/tempest/lib/services/volume/v1/qos_client.py
index 593bddd..67f2ead 100644
--- a/tempest/lib/services/volume/v1/qos_client.py
+++ b/tempest/lib/services/volume/v1/qos_client.py
@@ -43,7 +43,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/block-storage/v2/#create-qos-specification
+ https://docs.openstack.org/api-ref/block-storage/v2/#create-qos-specification
"""
post_body = json.dumps({'qos_specs': kwargs})
resp, body = self.post('qos-specs', post_body)
@@ -79,7 +79,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/block-storage/v2/#set-keys-in-qos-specification
+ https://docs.openstack.org/api-ref/block-storage/v2/#set-keys-in-qos-specification
"""
put_body = json.dumps({"qos_specs": kwargs})
resp, body = self.put('qos-specs/%s' % qos_id, put_body)
@@ -94,7 +94,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#unset-keys-in-qos-specification
+ https://docs.openstack.org/api-ref/block-storage/v2/#unset-keys-in-qos-specification
"""
put_body = json.dumps({'keys': keys})
resp, body = self.put('qos-specs/%s/delete_keys' % qos_id, put_body)
diff --git a/tempest/lib/services/volume/v1/quotas_client.py b/tempest/lib/services/volume/v1/quotas_client.py
index 84f34f2..7f191ca 100644
--- a/tempest/lib/services/volume/v1/quotas_client.py
+++ b/tempest/lib/services/volume/v1/quotas_client.py
@@ -47,7 +47,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#update-quotas
+ https://docs.openstack.org/api-ref/block-storage/v2/#update-quotas
"""
put_body = jsonutils.dumps({'quota_set': kwargs})
resp, body = self.put('os-quota-sets/%s' % tenant_id, put_body)
diff --git a/tempest/lib/services/volume/v1/snapshots_client.py b/tempest/lib/services/volume/v1/snapshots_client.py
index 51f7b9b..7dfdcf2 100644
--- a/tempest/lib/services/volume/v1/snapshots_client.py
+++ b/tempest/lib/services/volume/v1/snapshots_client.py
@@ -27,8 +27,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#list-snapshots
- https://developer.openstack.org/api-ref/block-storage/v2/#list-snapshots-with-details
+ https://docs.openstack.org/api-ref/block-storage/v2/#list-snapshots
+ https://docs.openstack.org/api-ref/block-storage/v2/#list-snapshots-with-details
"""
url = 'snapshots'
if detail:
@@ -46,7 +46,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#show-snapshot-details
+ https://docs.openstack.org/api-ref/block-storage/v2/#show-snapshot-details
"""
url = "snapshots/%s" % snapshot_id
resp, body = self.get(url)
@@ -59,7 +59,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#create-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v2/#create-snapshot
"""
post_body = json.dumps({'snapshot': kwargs})
resp, body = self.post('snapshots', post_body)
@@ -72,7 +72,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#delete-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v2/#delete-snapshot
"""
resp, body = self.delete("snapshots/%s" % snapshot_id)
self.expected_success(202, resp.status)
@@ -124,7 +124,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#update-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v2/#update-snapshot
"""
put_body = json.dumps({'snapshot': kwargs})
resp, body = self.put('snapshots/%s' % snapshot_id, put_body)
@@ -137,7 +137,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#show-snapshot-metadata
+ https://docs.openstack.org/api-ref/block-storage/v2/#show-snapshot-metadata
"""
url = "snapshots/%s/metadata" % snapshot_id
resp, body = self.get(url)
@@ -150,7 +150,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#update-snapshot-metadata
+ https://docs.openstack.org/api-ref/block-storage/v2/#update-snapshot-metadata
"""
put_body = json.dumps(kwargs)
url = "snapshots/%s/metadata" % snapshot_id
diff --git a/tempest/lib/services/volume/v1/types_client.py b/tempest/lib/services/volume/v1/types_client.py
index da9eb8b..d434e65 100644
--- a/tempest/lib/services/volume/v1/types_client.py
+++ b/tempest/lib/services/volume/v1/types_client.py
@@ -40,7 +40,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#list-all-volume-types-for-v2
+ https://docs.openstack.org/api-ref/block-storage/v2/#list-all-volume-types-for-v2
"""
url = 'types'
if params:
@@ -56,7 +56,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#show-volume-type-details-for-v2
+ https://docs.openstack.org/api-ref/block-storage/v2/#show-volume-type-details-for-v2
"""
url = "types/%s" % volume_type_id
resp, body = self.get(url)
@@ -69,7 +69,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#create-volume-type-for-v2
+ https://docs.openstack.org/api-ref/block-storage/v2/#create-volume-type-for-v2
"""
post_body = json.dumps({'volume_type': kwargs})
resp, body = self.post('types', post_body)
@@ -82,7 +82,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#delete-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v2/#delete-volume-type
"""
resp, body = self.delete("types/%s" % volume_type_id)
self.expected_success(202, resp.status)
@@ -137,7 +137,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#update-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v2/#update-volume-type
"""
put_body = json.dumps({'volume_type': kwargs})
resp, body = self.put('types/%s' % volume_type_id, put_body)
@@ -156,7 +156,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#update-extra-specs-for-a-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v2/#update-extra-specs-for-a-volume-type
"""
url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
put_body = json.dumps(extra_specs)
diff --git a/tempest/lib/services/volume/v1/volumes_client.py b/tempest/lib/services/volume/v1/volumes_client.py
index 0e6ea9f..4ed5eb1 100644
--- a/tempest/lib/services/volume/v1/volumes_client.py
+++ b/tempest/lib/services/volume/v1/volumes_client.py
@@ -41,8 +41,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#list-volumes
- https://developer.openstack.org/api-ref/block-storage/v2/#list-volumes-with-details
+ https://docs.openstack.org/api-ref/block-storage/v2/#list-volumes
+ https://docs.openstack.org/api-ref/block-storage/v2/#list-volumes-with-details
"""
url = 'volumes'
if detail:
@@ -68,7 +68,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#create-volume
+ https://docs.openstack.org/api-ref/block-storage/v2/#create-volume
"""
post_body = json.dumps({'volume': kwargs})
resp, body = self.post('volumes', post_body)
@@ -81,7 +81,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#update-volume
+ https://docs.openstack.org/api-ref/block-storage/v2/#update-volume
"""
put_body = json.dumps({'volume': kwargs})
resp, body = self.put('volumes/%s' % volume_id, put_body)
@@ -109,7 +109,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#attach-volume-to-server
+ https://docs.openstack.org/api-ref/block-storage/v2/#attach-volume-to-server
"""
post_body = json.dumps({'os-attach': kwargs})
url = 'volumes/%s/action' % (volume_id)
@@ -166,7 +166,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#extend-volume-size
+ https://docs.openstack.org/api-ref/block-storage/v2/#extend-volume-size
"""
post_body = json.dumps({'os-extend': kwargs})
url = 'volumes/%s/action' % (volume_id)
@@ -179,7 +179,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#reset-volume-statuses
+ https://docs.openstack.org/api-ref/block-storage/v2/#reset-volume-statuses
"""
post_body = json.dumps({'os-reset_status': kwargs})
resp, body = self.post('volumes/%s/action' % volume_id, post_body)
@@ -191,7 +191,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#create-volume-transfer
+ https://docs.openstack.org/api-ref/block-storage/v2/#create-volume-transfer
"""
post_body = json.dumps({'transfer': kwargs})
resp, body = self.post('os-volume-transfer', post_body)
@@ -212,7 +212,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#list-volume-transfers
+ https://docs.openstack.org/api-ref/block-storage/v2/#list-volume-transfers
"""
url = 'os-volume-transfer'
if params:
@@ -233,7 +233,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/#accept-volume-transfer
+ https://docs.openstack.org/api-ref/block-storage/v2/#accept-volume-transfer
"""
url = 'os-volume-transfer/%s/accept' % transfer_id
post_body = json.dumps({'accept': kwargs})
diff --git a/tempest/lib/services/volume/v3/backups_client.py b/tempest/lib/services/volume/v3/backups_client.py
index fb64333..970471e 100644
--- a/tempest/lib/services/volume/v3/backups_client.py
+++ b/tempest/lib/services/volume/v3/backups_client.py
@@ -29,7 +29,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-a-backup
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-a-backup
"""
post_body = json.dumps({'backup': kwargs})
resp, body = self.post('backups', post_body)
@@ -42,7 +42,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#update-a-backup
+ https://docs.openstack.org/api-ref/block-storage/v3/#update-a-backup
"""
put_body = json.dumps({'backup': kwargs})
resp, body = self.put('backups/%s' % backup_id, put_body)
@@ -55,7 +55,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#restore-a-backup
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#restore-a-backup
"""
post_body = json.dumps({'restore': kwargs})
resp, body = self.post('backups/%s/restore' % (backup_id), post_body)
@@ -82,8 +82,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-backups-for-project
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-backups-with-detail
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-backups-for-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-backups-with-detail
"""
url = "backups"
if detail:
@@ -108,7 +108,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#import-a-backup
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#import-a-backup
"""
post_body = json.dumps({'backup-record': kwargs})
resp, body = self.post("backups/import_record", post_body)
diff --git a/tempest/lib/services/volume/v3/capabilities_client.py b/tempest/lib/services/volume/v3/capabilities_client.py
index 7ebcd69..dc850a8 100644
--- a/tempest/lib/services/volume/v3/capabilities_client.py
+++ b/tempest/lib/services/volume/v3/capabilities_client.py
@@ -15,6 +15,7 @@
from oslo_serialization import jsonutils as json
+from tempest.lib.api_schema.response.volume import capabilities as schema
from tempest.lib.common import rest_client
@@ -25,10 +26,10 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v2/index.html#show-back-end-capabilities
+ https://docs.openstack.org/api-ref/block-storage/v2/index.html#show-back-end-capabilities
"""
url = 'capabilities/%s' % host
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.show_backend_capabilities, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/encryption_types_client.py b/tempest/lib/services/volume/v3/encryption_types_client.py
index 03de187..bd809d6 100644
--- a/tempest/lib/services/volume/v3/encryption_types_client.py
+++ b/tempest/lib/services/volume/v3/encryption_types_client.py
@@ -59,7 +59,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-an-encryption-type
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-an-encryption-type
"""
url = "/types/%s/encryption" % volume_type_id
post_body = json.dumps({'encryption': kwargs})
@@ -80,7 +80,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-an-encryption-type
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-an-encryption-type
"""
url = "/types/%s/encryption/provider" % volume_type_id
put_body = json.dumps({'encryption': kwargs})
diff --git a/tempest/lib/services/volume/v3/extensions_client.py b/tempest/lib/services/volume/v3/extensions_client.py
index 45b7a56..f1fe5c9 100644
--- a/tempest/lib/services/volume/v3/extensions_client.py
+++ b/tempest/lib/services/volume/v3/extensions_client.py
@@ -15,6 +15,7 @@
from oslo_serialization import jsonutils as json
+from tempest.lib.api_schema.response.volume import extensions as schema
from tempest.lib.common import rest_client
@@ -25,5 +26,5 @@
url = 'extensions'
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.list_extensions, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/group_snapshots_client.py b/tempest/lib/services/volume/v3/group_snapshots_client.py
index 16412d3..e425a3f 100644
--- a/tempest/lib/services/volume/v3/group_snapshots_client.py
+++ b/tempest/lib/services/volume/v3/group_snapshots_client.py
@@ -29,7 +29,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#create-group-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v3/#create-group-snapshot
"""
post_body = json.dumps({'group_snapshot': kwargs})
resp, body = self.post('group_snapshots', post_body)
@@ -41,7 +41,7 @@
"""Deletes a group snapshot.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#delete-group-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v3/#delete-group-snapshot
"""
resp, body = self.delete('group_snapshots/%s' % group_snapshot_id)
self.expected_success(202, resp.status)
@@ -51,7 +51,7 @@
"""Returns the details of a single group snapshot.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#show-group-snapshot-details
+ https://docs.openstack.org/api-ref/block-storage/v3/#show-group-snapshot-details
"""
url = "group_snapshots/%s" % str(group_snapshot_id)
resp, body = self.get(url)
@@ -63,8 +63,8 @@
"""Information for all the tenant's group snapshots.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#list-group-snapshots
- https://developer.openstack.org/api-ref/block-storage/v3/#list-group-snapshots-with-details
+ https://docs.openstack.org/api-ref/block-storage/v3/#list-group-snapshots
+ https://docs.openstack.org/api-ref/block-storage/v3/#list-group-snapshots-with-details
"""
url = "group_snapshots"
if detail:
@@ -80,7 +80,7 @@
"""Resets group snapshot status.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#reset-group-snapshot-status
+ https://docs.openstack.org/api-ref/block-storage/v3/#reset-group-snapshot-status
"""
post_body = json.dumps({'reset_status': {'status': status_to_set}})
resp, body = self.post('group_snapshots/%s/action' % group_snapshot_id,
diff --git a/tempest/lib/services/volume/v3/group_types_client.py b/tempest/lib/services/volume/v3/group_types_client.py
index 1ccb9f8..99833ce 100644
--- a/tempest/lib/services/volume/v3/group_types_client.py
+++ b/tempest/lib/services/volume/v3/group_types_client.py
@@ -33,7 +33,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#create-group-type
+ https://docs.openstack.org/api-ref/block-storage/v3/#create-group-type
"""
post_body = json.dumps({'group_type': kwargs})
resp, body = self.post('group_types', post_body)
@@ -52,7 +52,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#list-group-types
+ https://docs.openstack.org/api-ref/block-storage/v3/#list-group-types
"""
url = 'group_types'
if params:
@@ -63,11 +63,23 @@
self.expected_success(200, resp.status)
return rest_client.ResponseBody(resp, body)
+ def show_default_group_type(self):
+ """Returns the details of default group_type.
+
+ For more information, please refer to the official API reference:
+ https://docs.openstack.org/api-ref/block-storage/v3/#show-default-group-type-details
+ """
+ url = 'group_types/default'
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp, body)
+
def show_group_type(self, group_type_id):
"""Returns the details of a single group_type.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#show-group-type-details
+ https://docs.openstack.org/api-ref/block-storage/v3/#show-group-type-details
"""
url = "group_types/%s" % group_type_id
resp, body = self.get(url)
@@ -80,7 +92,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#update-group-type
+ https://docs.openstack.org/api-ref/block-storage/v3/#update-group-type
"""
post_body = json.dumps({'group_type': kwargs})
resp, body = self.put('group_types/%s' % group_type_id, post_body)
@@ -93,7 +105,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#create-or-update-group-specs-for-a-group-type
+ https://docs.openstack.org/api-ref/block-storage/v3/#create-or-update-group-specs-for-a-group-type
"""
url = "group_types/%s/group_specs" % group_type_id
post_body = json.dumps({'group_specs': group_specs})
@@ -123,7 +135,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#update-one-specific-group-spec-for-a-group-type
+ https://docs.openstack.org/api-ref/block-storage/v3/#update-one-specific-group-spec-for-a-group-type
"""
url = "group_types/%s/group_specs/%s" % (group_type_id, spec_id)
put_body = json.dumps(spec)
diff --git a/tempest/lib/services/volume/v3/groups_client.py b/tempest/lib/services/volume/v3/groups_client.py
index 3cf1e6a..ffae232 100644
--- a/tempest/lib/services/volume/v3/groups_client.py
+++ b/tempest/lib/services/volume/v3/groups_client.py
@@ -30,7 +30,7 @@
group_type and volume_types are required parameters in kwargs.
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#create-group
+ https://docs.openstack.org/api-ref/block-storage/v3/#create-group
"""
post_body = json.dumps({'group': kwargs})
resp, body = self.post('groups', post_body)
@@ -43,7 +43,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#delete-group
+ https://docs.openstack.org/api-ref/block-storage/v3/#delete-group
"""
post_body = {'delete-volumes': delete_volumes}
post_body = json.dumps({'delete': post_body})
@@ -57,7 +57,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#show-group-details
+ https://docs.openstack.org/api-ref/block-storage/v3/#show-group-details
"""
url = "groups/%s" % str(group_id)
resp, body = self.get(url)
@@ -70,8 +70,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#list-groups
- https://developer.openstack.org/api-ref/block-storage/v3/#list-groups-with-details
+ https://docs.openstack.org/api-ref/block-storage/v3/#list-groups
+ https://docs.openstack.org/api-ref/block-storage/v3/#list-groups-with-details
"""
url = "groups"
if detail:
@@ -88,7 +88,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#create-group-from-source
+ https://docs.openstack.org/api-ref/block-storage/v3/#create-group-from-source
"""
post_body = json.dumps({'create-from-src': kwargs})
resp, body = self.post('groups/action', post_body)
@@ -101,7 +101,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#update-group
+ https://docs.openstack.org/api-ref/block-storage/v3/#update-group
"""
put_body = json.dumps({'group': kwargs})
resp, body = self.put('groups/%s' % group_id, put_body)
@@ -112,7 +112,7 @@
"""Resets group status.
For more information, please refer to the official API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#reset-group-status
+ https://docs.openstack.org/api-ref/block-storage/v3/#reset-group-status
"""
post_body = json.dumps({'reset_status': {'status': status_to_set}})
resp, body = self.post('groups/%s/action' % group_id, post_body)
diff --git a/tempest/lib/services/volume/v3/hosts_client.py b/tempest/lib/services/volume/v3/hosts_client.py
index 8b65805..019a852 100644
--- a/tempest/lib/services/volume/v3/hosts_client.py
+++ b/tempest/lib/services/volume/v3/hosts_client.py
@@ -16,6 +16,7 @@
from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
+from tempest.lib.api_schema.response.volume import hosts as schema
from tempest.lib.common import rest_client
@@ -27,7 +28,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-all-hosts-for-a-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-all-hosts-for-a-project
"""
url = 'os-hosts'
if params:
@@ -35,13 +36,13 @@
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.list_hosts, resp, body)
return rest_client.ResponseBody(resp, body)
def show_host(self, host_name):
"""Show host details."""
url = 'os-hosts/%s' % host_name
resp, body = self.get(url)
- self.expected_success(200, resp.status)
body = json.loads(body)
+ self.validate_response(schema.show_host, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/messages_client.py b/tempest/lib/services/volume/v3/messages_client.py
index 47538cd..b770fac 100644
--- a/tempest/lib/services/volume/v3/messages_client.py
+++ b/tempest/lib/services/volume/v3/messages_client.py
@@ -15,6 +15,7 @@
from oslo_serialization import jsonutils as json
+from tempest.lib.api_schema.response.volume import messages as schema
from tempest.lib.common import rest_client
from tempest.lib import exceptions as lib_exc
from tempest.lib.services.volume import base_client
@@ -28,7 +29,7 @@
url = 'messages/%s' % str(message_id)
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.show_message, resp, body)
return rest_client.ResponseBody(resp, body)
def list_messages(self):
@@ -36,14 +37,14 @@
url = 'messages'
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.list_messages, resp, body)
return rest_client.ResponseBody(resp, body)
def delete_message(self, message_id):
"""Delete a single message."""
url = 'messages/%s' % str(message_id)
resp, body = self.delete(url)
- self.expected_success(204, resp.status)
+ self.validate_response(schema.delete_message, resp, body)
return rest_client.ResponseBody(resp, body)
def is_resource_deleted(self, id):
diff --git a/tempest/lib/services/volume/v3/qos_client.py b/tempest/lib/services/volume/v3/qos_client.py
index 5205590..752e381 100644
--- a/tempest/lib/services/volume/v3/qos_client.py
+++ b/tempest/lib/services/volume/v3/qos_client.py
@@ -42,7 +42,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-a-qos-specification
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-a-qos-specification
"""
post_body = json.dumps({'qos_specs': kwargs})
resp, body = self.post('qos-specs', post_body)
@@ -78,7 +78,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#set-keys-in-a-qos-specification
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#set-keys-in-a-qos-specification
"""
put_body = json.dumps({"qos_specs": kwargs})
resp, body = self.put('qos-specs/%s' % qos_id, put_body)
@@ -93,7 +93,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#unset-keys-in-a-qos-specification
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#unset-keys-in-a-qos-specification
"""
put_body = json.dumps({'keys': keys})
resp, body = self.put('qos-specs/%s/delete_keys' % qos_id, put_body)
diff --git a/tempest/lib/services/volume/v3/quota_classes_client.py b/tempest/lib/services/volume/v3/quota_classes_client.py
index a8eb536..cf03918 100644
--- a/tempest/lib/services/volume/v3/quota_classes_client.py
+++ b/tempest/lib/services/volume/v3/quota_classes_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#show-quota-classes-for-a-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#show-quota-classes-for-a-project
"""
url = 'os-quota-class-sets/%s' % quota_class_id
resp, body = self.get(url)
@@ -39,7 +39,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-quota-classes-for-a-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-quota-classes-for-a-project
"""
url = 'os-quota-class-sets/%s' % quota_class_id
put_body = json.dumps({'quota_class_set': kwargs})
diff --git a/tempest/lib/services/volume/v3/quotas_client.py b/tempest/lib/services/volume/v3/quotas_client.py
index 538a915..5b1a52c 100644
--- a/tempest/lib/services/volume/v3/quotas_client.py
+++ b/tempest/lib/services/volume/v3/quotas_client.py
@@ -16,6 +16,7 @@
from oslo_serialization import jsonutils
from six.moves.urllib import parse as urllib
+from tempest.lib.api_schema.response.volume import quotas as schema
from tempest.lib.common import rest_client
@@ -27,8 +28,8 @@
url = 'os-quota-sets/%s/defaults' % tenant_id
resp, body = self.get(url)
- self.expected_success(200, resp.status)
body = jsonutils.loads(body)
+ self.validate_response(schema.show_quota_set, resp, body)
return rest_client.ResponseBody(resp, body)
def show_quota_set(self, tenant_id, params=None):
@@ -39,8 +40,11 @@
url += '?%s' % urllib.urlencode(params)
resp, body = self.get(url)
- self.expected_success(200, resp.status)
body = jsonutils.loads(body)
+ if params and params.get('usage', False):
+ self.validate_response(schema.show_quota_set_usage, resp, body)
+ else:
+ self.validate_response(schema.show_quota_set, resp, body)
return rest_client.ResponseBody(resp, body)
def update_quota_set(self, tenant_id, **kwargs):
@@ -48,16 +52,16 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-quotas-for-a-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-quotas-for-a-project
"""
put_body = jsonutils.dumps({'quota_set': kwargs})
resp, body = self.put('os-quota-sets/%s' % tenant_id, put_body)
- self.expected_success(200, resp.status)
body = jsonutils.loads(body)
+ self.validate_response(schema.update_quota_set, resp, body)
return rest_client.ResponseBody(resp, body)
def delete_quota_set(self, tenant_id):
"""Delete the tenant's quota set."""
resp, body = self.delete('os-quota-sets/%s' % tenant_id)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.delete_quota_set, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/scheduler_stats_client.py b/tempest/lib/services/volume/v3/scheduler_stats_client.py
index 9b80851..2ae8600 100644
--- a/tempest/lib/services/volume/v3/scheduler_stats_client.py
+++ b/tempest/lib/services/volume/v3/scheduler_stats_client.py
@@ -25,7 +25,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-all-back-end-storage-pools
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-all-back-end-storage-pools
"""
url = 'scheduler-stats/get_pools'
if detail:
diff --git a/tempest/lib/services/volume/v3/services_client.py b/tempest/lib/services/volume/v3/services_client.py
index 22155a9..8bc82c9 100644
--- a/tempest/lib/services/volume/v3/services_client.py
+++ b/tempest/lib/services/volume/v3/services_client.py
@@ -16,6 +16,7 @@
from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
+from tempest.lib.api_schema.response.volume import services as schema
from tempest.lib.common import rest_client
@@ -27,7 +28,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#list-all-cinder-services
+ https://docs.openstack.org/api-ref/block-storage/v3/#list-all-cinder-services
"""
url = 'os-services'
if params:
@@ -35,7 +36,7 @@
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.list_services, resp, body)
return rest_client.ResponseBody(resp, body)
def enable_service(self, **kwargs):
@@ -43,12 +44,12 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#enable-a-cinder-service
+ https://docs.openstack.org/api-ref/block-storage/v3/#enable-a-cinder-service
"""
put_body = json.dumps(kwargs)
resp, body = self.put('os-services/enable', put_body)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.enable_service, resp, body)
return rest_client.ResponseBody(resp, body)
def disable_service(self, **kwargs):
@@ -56,12 +57,12 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#disable-a-cinder-service
+ https://docs.openstack.org/api-ref/block-storage/v3/#disable-a-cinder-service
"""
put_body = json.dumps(kwargs)
resp, body = self.put('os-services/disable', put_body)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.disable_service, resp, body)
return rest_client.ResponseBody(resp, body)
def disable_log_reason(self, **kwargs):
@@ -69,12 +70,12 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#log-disabled-cinder-service-information
+ https://docs.openstack.org/api-ref/block-storage/v3/#log-disabled-cinder-service-information
"""
put_body = json.dumps(kwargs)
resp, body = self.put('os-services/disable-log-reason', put_body)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.disable_log_reason, resp, body)
return rest_client.ResponseBody(resp, body)
def freeze_host(self, **kwargs):
@@ -82,11 +83,11 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#freeze-a-cinder-backend-host
+ https://docs.openstack.org/api-ref/block-storage/v3/#freeze-a-cinder-backend-host
"""
put_body = json.dumps(kwargs)
- resp, _ = self.put('os-services/freeze', put_body)
- self.expected_success(200, resp.status)
+ resp, body = self.put('os-services/freeze', put_body)
+ self.validate_response(schema.freeze_host, resp, body)
return rest_client.ResponseBody(resp)
def thaw_host(self, **kwargs):
@@ -94,9 +95,9 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#thaw-a-cinder-backend-host
+ https://docs.openstack.org/api-ref/block-storage/v3/#thaw-a-cinder-backend-host
"""
put_body = json.dumps(kwargs)
- resp, _ = self.put('os-services/thaw', put_body)
- self.expected_success(200, resp.status)
+ resp, body = self.put('os-services/thaw', put_body)
+ self.validate_response(schema.thaw_host, resp, body)
return rest_client.ResponseBody(resp)
diff --git a/tempest/lib/services/volume/v3/snapshot_manage_client.py b/tempest/lib/services/volume/v3/snapshot_manage_client.py
index 43fd328..77920e4 100644
--- a/tempest/lib/services/volume/v3/snapshot_manage_client.py
+++ b/tempest/lib/services/volume/v3/snapshot_manage_client.py
@@ -15,6 +15,7 @@
from oslo_serialization import jsonutils as json
+from tempest.lib.api_schema.response.volume import manage_snapshot as schema
from tempest.lib.common import rest_client
@@ -22,10 +23,15 @@
"""Snapshot manage client."""
def manage_snapshot(self, **kwargs):
- """Manage a snapshot."""
+ """Manage a snapshot.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#manage-an-existing-snapshot
+ """
post_body = json.dumps({'snapshot': kwargs})
url = 'os-snapshot-manage'
resp, body = self.post(url, post_body)
- self.expected_success(202, resp.status)
body = json.loads(body)
+ self.validate_response(schema.manage_snapshot, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/snapshots_client.py b/tempest/lib/services/volume/v3/snapshots_client.py
index cae65b2..264381d 100644
--- a/tempest/lib/services/volume/v3/snapshots_client.py
+++ b/tempest/lib/services/volume/v3/snapshots_client.py
@@ -28,8 +28,8 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-accessible-snapshots
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-snapshots-and-details
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-accessible-snapshots
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-snapshots-and-details
"""
url = 'snapshots'
if detail:
@@ -47,7 +47,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#show-a-snapshot-s-details
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#show-a-snapshot-s-details
"""
url = "snapshots/%s" % snapshot_id
resp, body = self.get(url)
@@ -60,7 +60,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-a-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-a-snapshot
"""
post_body = json.dumps({'snapshot': kwargs})
resp, body = self.post('snapshots', post_body)
@@ -73,7 +73,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-a-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-a-snapshot
"""
put_body = json.dumps({'snapshot': kwargs})
resp, body = self.put('snapshots/%s' % snapshot_id, put_body)
@@ -86,7 +86,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#delete-a-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#delete-a-snapshot
"""
resp, body = self.delete("snapshots/%s" % snapshot_id)
self.expected_success(202, resp.status)
@@ -116,7 +116,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#update-status-of-a-snapshot
+ https://docs.openstack.org/api-ref/block-storage/v3/#update-status-of-a-snapshot
"""
post_body = json.dumps({'os-update_snapshot_status': kwargs})
url = 'snapshots/%s/action' % snapshot_id
@@ -129,7 +129,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-a-snapshot-s-metadata
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-a-snapshot-s-metadata
"""
put_body = json.dumps({'metadata': metadata})
url = "snapshots/%s/metadata" % snapshot_id
@@ -143,7 +143,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#show-a-snapshot-s-metadata
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#show-a-snapshot-s-metadata
"""
url = "snapshots/%s/metadata" % snapshot_id
resp, body = self.get(url)
@@ -156,7 +156,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-a-snapshot-s-metadata
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-a-snapshot-s-metadata
"""
put_body = json.dumps(kwargs)
url = "snapshots/%s/metadata" % snapshot_id
@@ -178,7 +178,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#update-a-snapshot-s-metadata-for-a-specific-key
+ https://docs.openstack.org/api-ref/block-storage/v3/#update-a-snapshot-s-metadata-for-a-specific-key
"""
put_body = json.dumps(kwargs)
url = "snapshots/%s/metadata/%s" % (snapshot_id, id)
diff --git a/tempest/lib/services/volume/v3/transfers_client.py b/tempest/lib/services/volume/v3/transfers_client.py
index 97c5597..f572f95 100644
--- a/tempest/lib/services/volume/v3/transfers_client.py
+++ b/tempest/lib/services/volume/v3/transfers_client.py
@@ -16,6 +16,7 @@
from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
+from tempest.lib.api_schema.response.volume import transfers as schema
from tempest.lib.common import rest_client
@@ -27,12 +28,12 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-a-volume-transfer
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-a-volume-transfer
"""
post_body = json.dumps({'transfer': kwargs})
resp, body = self.post('os-volume-transfer', post_body)
body = json.loads(body)
- self.expected_success(202, resp.status)
+ self.validate_response(schema.create_volume_transfer, resp, body)
return rest_client.ResponseBody(resp, body)
def show_volume_transfer(self, transfer_id):
@@ -40,7 +41,7 @@
url = "os-volume-transfer/%s" % transfer_id
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema.show_volume_transfer, resp, body)
return rest_client.ResponseBody(resp, body)
def list_volume_transfers(self, detail=False, **params):
@@ -48,23 +49,25 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-volume-transfers-for-a-project
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-volume-transfers-and-details
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-volume-transfers-for-a-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-volume-transfers-and-details
"""
url = 'os-volume-transfer'
+ schema_list_transfers = schema.list_volume_transfers_no_detail
if detail:
url += '/detail'
+ schema_list_transfers = schema.list_volume_transfers_with_detail
if params:
url += '?%s' % urllib.urlencode(params)
resp, body = self.get(url)
body = json.loads(body)
- self.expected_success(200, resp.status)
+ self.validate_response(schema_list_transfers, resp, body)
return rest_client.ResponseBody(resp, body)
def delete_volume_transfer(self, transfer_id):
"""Delete a volume transfer."""
resp, body = self.delete("os-volume-transfer/%s" % transfer_id)
- self.expected_success(202, resp.status)
+ self.validate_response(schema.delete_volume_transfer, resp, body)
return rest_client.ResponseBody(resp, body)
def accept_volume_transfer(self, transfer_id, **kwargs):
@@ -72,11 +75,11 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#accept-a-volume-transfer
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#accept-a-volume-transfer
"""
url = 'os-volume-transfer/%s/accept' % transfer_id
post_body = json.dumps({'accept': kwargs})
resp, body = self.post(url, post_body)
body = json.loads(body)
- self.expected_success(202, resp.status)
+ self.validate_response(schema.accept_volume_transfer, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/types_client.py b/tempest/lib/services/volume/v3/types_client.py
index 1405785..705d319 100644
--- a/tempest/lib/services/volume/v3/types_client.py
+++ b/tempest/lib/services/volume/v3/types_client.py
@@ -40,7 +40,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-all-volume-types
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-all-volume-types
"""
url = 'types'
if params:
@@ -56,7 +56,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#show-volume-type-detail
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#show-volume-type-detail
"""
url = "types/%s" % volume_type_id
resp, body = self.get(url)
@@ -69,7 +69,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-a-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-a-volume-type
"""
post_body = json.dumps({'volume_type': kwargs})
resp, body = self.post('types', post_body)
@@ -82,7 +82,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#delete-a-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#delete-a-volume-type
"""
resp, body = self.delete("types/%s" % volume_type_id)
self.expected_success(202, resp.status)
@@ -93,7 +93,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#show-all-extra-specifications-for-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v3/#show-all-extra-specifications-for-volume-type
"""
url = 'types/%s/extra_specs' % volume_type_id
if params:
@@ -137,7 +137,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume-type
"""
put_body = json.dumps({'volume_type': kwargs})
resp, body = self.put('types/%s' % volume_type_id, put_body)
@@ -156,7 +156,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-extra-specification-for-volume-type
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-extra-specification-for-volume-type
"""
url = "types/%s/extra_specs/%s" % (volume_type_id, extra_spec_name)
put_body = json.dumps(extra_specs)
@@ -170,7 +170,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#add-private-volume-type-access-to-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#add-private-volume-type-access-to-project
"""
post_body = json.dumps({'addProjectAccess': kwargs})
url = 'types/%s/action' % volume_type_id
@@ -183,7 +183,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#remove-private-volume-type-access-from-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#remove-private-volume-type-access-from-project
"""
post_body = json.dumps({'removeProjectAccess': kwargs})
url = 'types/%s/action' % volume_type_id
@@ -196,7 +196,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-private-volume-type-access-detail
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-private-volume-type-access-detail
"""
url = 'types/%s/os-volume-type-access' % volume_type_id
resp, body = self.get(url)
diff --git a/tempest/lib/services/volume/v3/versions_client.py b/tempest/lib/services/volume/v3/versions_client.py
index 57629bd..175f1f5 100644
--- a/tempest/lib/services/volume/v3/versions_client.py
+++ b/tempest/lib/services/volume/v3/versions_client.py
@@ -14,6 +14,8 @@
import time
+from six.moves.urllib.parse import urljoin
+
from oslo_serialization import jsonutils as json
from tempest.lib.api_schema.response.volume import versions as schema
@@ -28,7 +30,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#list-all-api-versions
+ https://docs.openstack.org/api-ref/block-storage/v3/#list-all-api-versions
"""
version_url = self._get_base_version_url()
@@ -45,3 +47,22 @@
body = json.loads(body)
self.validate_response(schema.list_versions, resp, body)
return rest_client.ResponseBody(resp, body)
+
+ def show_version(self, version):
+ """Show API version details
+
+ Use raw_request in order to have access to the endpoints minus
+ version and project in order to add version only back.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/block-storage/v3/#show-api-v3-details
+ """
+
+ version_url = urljoin(self._get_base_version_url(), version + '/')
+ resp, body = self.raw_request(version_url, 'GET',
+ {'X-Auth-Token': self.token})
+ self._error_checker(resp, body)
+ body = json.loads(body)
+ self.validate_response(schema.volume_api_version_details, resp, body)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v3/volume_manage_client.py b/tempest/lib/services/volume/v3/volume_manage_client.py
index 349e11d..85b1b82 100644
--- a/tempest/lib/services/volume/v3/volume_manage_client.py
+++ b/tempest/lib/services/volume/v3/volume_manage_client.py
@@ -26,7 +26,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#manage-an-existing-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#manage-an-existing-volume
"""
post_body = json.dumps({'volume': kwargs})
resp, body = self.post('os-volume-manage', post_body)
diff --git a/tempest/lib/services/volume/v3/volumes_client.py b/tempest/lib/services/volume/v3/volumes_client.py
index 2dbdd11..14a3c48 100644
--- a/tempest/lib/services/volume/v3/volumes_client.py
+++ b/tempest/lib/services/volume/v3/volumes_client.py
@@ -38,7 +38,7 @@
def list_hosts(self):
"""Lists all hosts summary info that is not disabled.
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-all-hosts-for-a-project
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-all-hosts-for-a-project
"""
resp, body = self.get('os-hosts')
body = json.loads(body)
@@ -51,8 +51,8 @@
Params can be a string (must be urlencoded) or a dictionary.
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-accessible-volumes-with-details
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#list-accessible-volumes
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-accessible-volumes-with-details
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#list-accessible-volumes
"""
url = 'volumes'
if detail:
@@ -71,7 +71,7 @@
For a full list of available parameters please refer to the offical
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#migrate-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#migrate-a-volume
"""
post_body = json.dumps({'os-migrate_volume': kwargs})
resp, body = self.post('volumes/%s/action' % volume_id, post_body)
@@ -91,7 +91,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-a-volume
"""
post_body = json.dumps({'volume': kwargs})
resp, body = self.post('volumes', post_body)
@@ -104,7 +104,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume
"""
put_body = json.dumps({'volume': kwargs})
resp, body = self.put('volumes/%s' % volume_id, put_body)
@@ -117,7 +117,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#delete-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#delete-a-volume
"""
url = 'volumes/%s' % volume_id
if params:
@@ -131,7 +131,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/#get-volumes-summary
+ https://docs.openstack.org/api-ref/block-storage/v3/#get-volumes-summary
"""
url = 'volumes/summary'
if params:
@@ -142,7 +142,12 @@
return rest_client.ResponseBody(resp, body)
def upload_volume(self, volume_id, **kwargs):
- """Uploads a volume in Glance."""
+ """Uploads a volume in Glance.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#upload-volume-to-image
+ """
post_body = json.dumps({'os-volume_upload_image': kwargs})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
@@ -155,7 +160,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#attach-volume-to-a-server
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#attach-volume-to-a-server
"""
post_body = json.dumps({'os-attach': kwargs})
url = 'volumes/%s/action' % (volume_id)
@@ -168,7 +173,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume-s-bootable-status
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume-s-bootable-status
"""
post_body = json.dumps({'os-set_bootable': kwargs})
url = 'volumes/%s/action' % (volume_id)
@@ -212,7 +217,9 @@
except lib_exc.NotFound:
return True
if volume["volume"]["status"] == "error_deleting":
- raise lib_exc.DeleteErrorException(resource_id=id)
+ raise lib_exc.DeleteErrorException(
+ "Volume %s failed to delete and is in error_deleting status" %
+ volume['id'])
return False
@property
@@ -225,7 +232,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#extend-a-volume-size
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#extend-a-volume-size
"""
post_body = json.dumps({'os-extend': kwargs})
url = 'volumes/%s/action' % (volume_id)
@@ -238,7 +245,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#reset-a-volume-s-statuses
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#reset-a-volume-s-statuses
"""
post_body = json.dumps({'os-reset_status': kwargs})
resp, body = self.post('volumes/%s/action' % volume_id, post_body)
@@ -246,7 +253,12 @@
return rest_client.ResponseBody(resp, body)
def update_volume_readonly(self, volume_id, **kwargs):
- """Update the Specified Volume readonly."""
+ """Update the Specified Volume readonly.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#updates-volume-read-only-access-mode-flag
+ """
post_body = json.dumps({'os-update_readonly_flag': kwargs})
url = 'volumes/%s/action' % (volume_id)
resp, body = self.post(url, post_body)
@@ -265,7 +277,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#create-metadata-for-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#create-metadata-for-volume
"""
put_body = json.dumps({'metadata': metadata})
url = "volumes/%s/metadata" % volume_id
@@ -287,7 +299,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume-s-metadata
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#update-a-volume-s-metadata
"""
put_body = json.dumps({'metadata': metadata})
url = "volumes/%s/metadata" % volume_id
@@ -325,7 +337,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#retype-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#retype-a-volume
"""
post_body = json.dumps({'os-retype': kwargs})
resp, body = self.post('volumes/%s/action' % volume_id, post_body)
@@ -337,7 +349,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#force-delete-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#force-delete-a-volume
"""
post_body = json.dumps({'os-force_detach': kwargs})
url = 'volumes/%s/action' % volume_id
@@ -350,7 +362,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#set-image-metadata-for-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#set-image-metadata-for-a-volume
"""
post_body = json.dumps({'os-set_image_metadata': {'metadata': kwargs}})
url = "volumes/%s/action" % (volume_id)
@@ -381,7 +393,7 @@
For a full list of available parameters, please refer to the official
API reference:
- https://developer.openstack.org/api-ref/block-storage/v3/index.html#unmanage-a-volume
+ https://docs.openstack.org/api-ref/block-storage/v3/index.html#unmanage-a-volume
"""
post_body = json.dumps({'os-unmanage': {}})
resp, body = self.post('volumes/%s/action' % volume_id, post_body)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index d09f20c..1252f09 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -28,6 +28,8 @@
from tempest.common import waiters
from tempest import config
from tempest import exceptions
+from tempest.lib.common import api_microversion_fixture
+from tempest.lib.common import api_version_utils
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions as lib_exc
@@ -37,12 +39,57 @@
LOG = log.getLogger(__name__)
+LATEST_MICROVERSION = 'latest'
+
class ScenarioTest(tempest.test.BaseTestCase):
"""Base class for scenario tests. Uses tempest own clients. """
credentials = ['primary']
+ compute_min_microversion = None
+ compute_max_microversion = LATEST_MICROVERSION
+ volume_min_microversion = None
+ volume_max_microversion = LATEST_MICROVERSION
+ placement_min_microversion = None
+ placement_max_microversion = LATEST_MICROVERSION
+
+ @classmethod
+ def skip_checks(cls):
+ super(ScenarioTest, cls).skip_checks()
+ api_version_utils.check_skip_with_microversion(
+ cls.compute_min_microversion, cls.compute_max_microversion,
+ CONF.compute.min_microversion, CONF.compute.max_microversion)
+ api_version_utils.check_skip_with_microversion(
+ cls.volume_min_microversion, cls.volume_max_microversion,
+ CONF.volume.min_microversion, CONF.volume.max_microversion)
+ api_version_utils.check_skip_with_microversion(
+ cls.placement_min_microversion, cls.placement_max_microversion,
+ CONF.placement.min_microversion, CONF.placement.max_microversion)
+
+ @classmethod
+ def resource_setup(cls):
+ super(ScenarioTest, cls).resource_setup()
+ cls.compute_request_microversion = (
+ api_version_utils.select_request_microversion(
+ cls.compute_min_microversion,
+ CONF.compute.min_microversion))
+ cls.volume_request_microversion = (
+ api_version_utils.select_request_microversion(
+ cls.volume_min_microversion,
+ CONF.volume.min_microversion))
+ cls.placement_request_microversion = (
+ api_version_utils.select_request_microversion(
+ cls.placement_min_microversion,
+ CONF.placement.min_microversion))
+
+ def setUp(self):
+ super(ScenarioTest, self).setUp()
+ self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+ compute_microversion=self.compute_request_microversion,
+ volume_microversion=self.volume_request_microversion,
+ placement_microversion=self.placement_request_microversion))
+
@classmethod
def setup_clients(cls):
super(ScenarioTest, cls).setup_clients()
@@ -227,6 +274,10 @@
tenant_network = self.get_tenant_network()
+ if CONF.compute.compute_volume_common_az:
+ kwargs.setdefault('availability_zone',
+ CONF.compute.compute_volume_common_az)
+
body, _ = compute.create_test_server(
clients,
tenant_network=tenant_network,
@@ -260,6 +311,11 @@
'imageRef': imageRef,
'volume_type': volume_type,
'size': size}
+
+ if CONF.compute.compute_volume_common_az:
+ kwargs.setdefault('availability_zone',
+ CONF.compute.compute_volume_common_az)
+
volume = self.volumes_client.create_volume(**kwargs)['volume']
self.addCleanup(self.volumes_client.wait_for_resource_deletion,
@@ -346,8 +402,10 @@
def create_volume_type(self, client=None, name=None, backend_name=None):
if not client:
client = self.os_admin.volume_types_client_latest
- randomized_name = name or data_utils.rand_name(
- 'volume-type-' + self.__class__.__name__)
+ if not name:
+ class_name = self.__class__.__name__
+ name = data_utils.rand_name(class_name + '-volume-type')
+ randomized_name = data_utils.rand_name('scenario-type-' + name)
LOG.debug("Creating a volume type: %s on backend %s",
randomized_name, backend_name)
@@ -777,13 +835,15 @@
def _create_network(self, networks_client=None,
tenant_id=None,
namestart='network-smoke-',
- port_security_enabled=True):
+ port_security_enabled=True, **net_dict):
if not networks_client:
networks_client = self.networks_client
if not tenant_id:
tenant_id = networks_client.tenant_id
name = data_utils.rand_name(namestart)
network_kwargs = dict(name=name, tenant_id=tenant_id)
+ if net_dict:
+ network_kwargs.update(net_dict)
# Neutron disables port security by default so we have to check the
# config before trying to create the network with port_security_enabled
if CONF.network_feature_enabled.port_security:
@@ -977,24 +1037,33 @@
raise
def check_remote_connectivity(self, source, dest, should_succeed=True,
- nic=None):
- """assert ping server via source ssh connection
+ nic=None, protocol='icmp'):
+ """check server connectivity via source ssh connection
- :param source: RemoteClient: an ssh connection from which to ping
- :param dest: an IP to ping against
- :param should_succeed: boolean: should ping succeed or not
- :param nic: specific network interface to ping from
+ :param source: RemoteClient: an ssh connection from which to execute
+ the check
+ :param dest: an IP to check connectivity against
+ :param should_succeed: boolean should connection succeed or not
+ :param nic: specific network interface to test connectivity from
+ :param protocol: the protocol used to test connectivity with.
+ :returns: True, if the connection succeeded and it was expected to
+ succeed. False otherwise.
"""
- def ping_remote():
+ method_name = '%s_check' % protocol
+ connectivity_checker = getattr(source, method_name)
+
+ def connect_remote():
try:
- source.ping_host(dest, nic=nic)
+ connectivity_checker(dest, nic=nic)
except lib_exc.SSHExecCommandFailed:
- LOG.warning('Failed to ping IP: %s via a ssh connection '
- 'from: %s.', dest, source.ssh_client.host)
+ LOG.warning('Failed to check %(protocol)s connectivity for '
+ 'IP %(dest)s via a ssh connection from: %(src)s.',
+ dict(protocol=protocol, dest=dest,
+ src=source.ssh_client.host))
return not should_succeed
return should_succeed
- result = test_utils.call_until_true(ping_remote,
+ result = test_utils.call_until_true(connect_remote,
CONF.validation.ping_timeout, 1)
if result:
return
@@ -1199,7 +1268,7 @@
def create_networks(self, networks_client=None,
routers_client=None, subnets_client=None,
tenant_id=None, dns_nameservers=None,
- port_security_enabled=True):
+ port_security_enabled=True, **net_dict):
"""Create a network with a subnet connected to a router.
The baremetal driver is a special case since all nodes are
@@ -1207,6 +1276,11 @@
:param tenant_id: id of tenant to create resources in.
:param dns_nameservers: list of dns servers to send to subnet.
+ :param port_security_enabled: whether or not port_security is enabled
+ :param net_dict: a dict containing experimental network information in
+ a form like this: {'provider:network_type': 'vlan',
+ 'provider:physical_network': 'foo',
+ 'provider:segmentation_id': '42'}
:returns: network, subnet, router
"""
if CONF.network.shared_physical_network:
@@ -1226,7 +1300,8 @@
network = self._create_network(
networks_client=networks_client,
tenant_id=tenant_id,
- port_security_enabled=port_security_enabled)
+ port_security_enabled=port_security_enabled,
+ **net_dict)
router = self._get_router(client=routers_client,
tenant_id=tenant_id)
subnet_kwargs = dict(network=network,
diff --git a/tempest/scenario/test_minbw_allocation_placement.py b/tempest/scenario/test_minbw_allocation_placement.py
new file mode 100644
index 0000000..e7085f6
--- /dev/null
+++ b/tempest/scenario/test_minbw_allocation_placement.py
@@ -0,0 +1,195 @@
+# Copyright (c) 2019 Ericsson
+#
+# 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_log import log as logging
+
+from tempest.common import utils
+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.scenario import manager
+
+
+LOG = logging.getLogger(__name__)
+CONF = config.CONF
+
+
+class MinBwAllocationPlacementTest(manager.NetworkScenarioTest):
+ credentials = ['primary', 'admin']
+ required_extensions = ['port-resource-request',
+ 'qos',
+ 'qos-bw-minimum-ingress']
+ # The feature QoS minimum bandwidth allocation in Placement API depends on
+ # Granular resource requests to GET /allocation_candidates and Support
+ # allocation candidates with nested resource providers features in
+ # Placement (see: https://specs.openstack.org/openstack/nova-specs/specs/
+ # stein/approved/bandwidth-resource-provider.html#rest-api-impact) and this
+ # means that the minimum placement microversion is 1.29
+ placement_min_microversion = '1.29'
+ placement_max_microversion = 'latest'
+
+ # Nova rejects to boot VM with port which has resource_request field, below
+ # microversion 2.72
+ compute_min_microversion = '2.72'
+ compute_max_microversion = 'latest'
+
+ INGRESS_RESOURCE_CLASS = "NET_BW_IGR_KILOBIT_PER_SEC"
+ INGRESS_DIRECTION = 'ingress'
+
+ SMALLEST_POSSIBLE_BW = 1
+ # For any realistic inventory value (that is inventory != MAX_INT) an
+ # allocation candidate request of MAX_INT is expected to be rejected, see:
+ # https://github.com/openstack/placement/blob/master/placement/
+ # db/constants.py#L16
+ PLACEMENT_MAX_INT = 0x7FFFFFFF
+
+ @classmethod
+ def setup_clients(cls):
+ super(MinBwAllocationPlacementTest, cls).setup_clients()
+ cls.placement_client = cls.os_admin.placement_client
+ cls.networks_client = cls.os_admin.networks_client
+ cls.subnets_client = cls.os_admin.subnets_client
+ cls.routers_client = cls.os_adm.routers_client
+ cls.qos_client = cls.os_admin.qos_client
+ cls.qos_min_bw_client = cls.os_admin.qos_min_bw_client
+
+ @classmethod
+ def skip_checks(cls):
+ super(MinBwAllocationPlacementTest, cls).skip_checks()
+ if not CONF.network_feature_enabled.qos_placement_physnet:
+ msg = "Skipped as no physnet is available in config for " \
+ "placement based QoS allocation."
+ raise cls.skipException(msg)
+
+ def _create_policy_and_min_bw_rule(self, name_prefix, min_kbps):
+ policy = self.qos_client.create_qos_policy(
+ name=data_utils.rand_name(name_prefix),
+ shared=True)['policy']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.qos_client.delete_qos_policy, policy['id'])
+ rule = self.qos_min_bw_client.create_minimum_bandwidth_rule(
+ policy['id'],
+ **{
+ 'min_kbps': min_kbps,
+ 'direction': self.INGRESS_DIRECTION
+ })['minimum_bandwidth_rule']
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.qos_min_bw_client.delete_minimum_bandwidth_rule, policy['id'],
+ rule['id'])
+
+ return policy
+
+ def _create_qos_policies(self):
+ self.qos_policy_valid = self._create_policy_and_min_bw_rule(
+ name_prefix='test_policy_valid',
+ min_kbps=self.SMALLEST_POSSIBLE_BW)
+ self.qos_policy_not_valid = self._create_policy_and_min_bw_rule(
+ name_prefix='test_policy_not_valid',
+ min_kbps=self.PLACEMENT_MAX_INT)
+
+ def _create_network_and_qos_policies(self):
+ physnet_name = CONF.network_feature_enabled.qos_placement_physnet
+ base_segm = \
+ CONF.network_feature_enabled.provider_net_base_segmentation_id
+
+ self.prov_network, _, _ = self.create_networks(
+ networks_client=self.networks_client,
+ routers_client=self.routers_client,
+ subnets_client=self.subnets_client,
+ **{
+ 'shared': True,
+ 'provider:network_type': 'vlan',
+ 'provider:physical_network': physnet_name,
+ 'provider:segmentation_id': base_segm
+ })
+
+ self._create_qos_policies()
+
+ def _check_if_allocation_is_possible(self):
+ alloc_candidates = self.placement_client.list_allocation_candidates(
+ resources1='%s:%s' % (self.INGRESS_RESOURCE_CLASS,
+ self.SMALLEST_POSSIBLE_BW))
+ if len(alloc_candidates['provider_summaries']) == 0:
+ self.fail('No allocation candidates are available for %s:%s' %
+ (self.INGRESS_RESOURCE_CLASS, self.SMALLEST_POSSIBLE_BW))
+
+ # Just to be sure check with impossible high (placement max_int),
+ # allocation
+ alloc_candidates = self.placement_client.list_allocation_candidates(
+ resources1='%s:%s' % (self.INGRESS_RESOURCE_CLASS,
+ self.PLACEMENT_MAX_INT))
+ if len(alloc_candidates['provider_summaries']) != 0:
+ self.fail('For %s:%s there should be no available candidate!' %
+ (self.INGRESS_RESOURCE_CLASS, self.PLACEMENT_MAX_INT))
+
+ @decorators.idempotent_id('78625d92-212c-400e-8695-dd51706858b8')
+ @decorators.attr(type='slow')
+ @utils.services('compute', 'network')
+ def test_qos_min_bw_allocation_basic(self):
+ """"Basic scenario with QoS min bw allocation in placement.
+
+ Steps:
+ * Create prerequisites:
+ ** VLAN type provider network with subnet.
+ ** valid QoS policy with minimum bandwidth rule with min_kbps=1
+ (This is a simplification to skip the checks in placement for
+ detecting the resource provider tree and inventories, as if
+ bandwidth resource is available 1 kbs will be available).
+ ** invalid QoS policy with minimum bandwidth rule with
+ min_kbs=max integer from placement (this is a simplification again
+ to avoid detection of RP tress and inventories, as placement will
+ reject such big allocation).
+ * Create port with valid QoS policy, and boot VM with that, it should
+ pass.
+ * Create port with invalid QoS policy, and try to boot VM with that,
+ it should fail.
+ """
+
+ self._check_if_allocation_is_possible()
+
+ self._create_network_and_qos_policies()
+
+ valid_port = self.create_port(
+ self.prov_network['id'], qos_policy_id=self.qos_policy_valid['id'])
+
+ server1 = self.create_server(
+ networks=[{'port': valid_port['id']}])
+ allocations = self.placement_client.list_allocations(server1['id'])
+
+ self.assertGreater(len(allocations['allocations']), 0)
+ bw_resource_in_alloc = False
+ for rp, resources in allocations['allocations'].items():
+ if self.INGRESS_RESOURCE_CLASS in resources['resources']:
+ bw_resource_in_alloc = True
+ self.assertTrue(bw_resource_in_alloc)
+
+ # boot another vm with max int bandwidth
+ not_valid_port = self.create_port(
+ self.prov_network['id'],
+ qos_policy_id=self.qos_policy_not_valid['id'])
+ server2 = self.create_server(
+ wait_until=None,
+ networks=[{'port': not_valid_port['id']}])
+ waiters.wait_for_server_status(
+ client=self.os_primary.servers_client, server_id=server2['id'],
+ status='ERROR', ready_wait=False, raise_on_error=False)
+ allocations = self.placement_client.list_allocations(server2['id'])
+
+ self.assertEqual(0, len(allocations['allocations']))
+ server2 = self.servers_client.show_server(server2['id'])
+ self.assertIn('fault', server2['server'])
+ self.assertIn('No valid host', server2['server']['fault']['message'])
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 37bcd04..f03e9de 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -200,7 +200,8 @@
self.assertEqual(resize_flavor, server['flavor']['id'])
else:
flavor = self.flavors_client.show_flavor(resize_flavor)['flavor']
- for key in ['original_name', 'ram', 'vcpus', 'disk']:
+ self.assertEqual(flavor['name'], server['original_name'])
+ for key in ['ram', 'vcpus', 'disk']:
self.assertEqual(flavor[key], server['flavor'][key])
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
@@ -257,7 +258,7 @@
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- @decorators.skip_because(bug='1788403')
+ @decorators.skip_because(bug='1836595')
@decorators.idempotent_id('25b188d7-0183-4b1e-a11d-15840c8e2fd6')
@testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
'Cold migration is not available.')
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 438ee01..8de6614 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -166,9 +166,10 @@
if self._sysconfig_network_scripts_dir_exists(ssh):
try:
ssh.exec_command(
- 'echo -e "DEVICE=%(nic)s\\nIPV6INIT=yes" | '
+ 'echo -e "DEVICE=%(nic)s\\nNAME=%(nic)s\\nIPV6INIT=yes" | '
'sudo tee /etc/sysconfig/network-scripts/ifcfg-%(nic)s; '
- 'sudo /sbin/service network restart' % {'nic': nic})
+ 'sudo nmcli connection reload' % {'nic': nic})
+ ssh.exec_command('sudo nmcli connection up %s' % nic)
except exceptions.SSHExecCommandFailed as e:
# NOTE(slaweq): Sometimes it can happen that this SSH command
# will fail because of some error from network manager in
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 2b7926a..9cbd831 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -395,24 +395,22 @@
self.check_remote_connectivity(source=access_point_ssh,
dest=self._get_server_ip(server))
- def _test_cross_tenant_block(self, source_tenant, dest_tenant):
+ def _test_cross_tenant_block(self, source_tenant, dest_tenant, ruleset):
# if public router isn't defined, then dest_tenant access is via
# floating-ip
+ protocol = ruleset['protocol']
access_point_ssh = self._connect_to_access_point(source_tenant)
ip = self._get_server_ip(dest_tenant.access_point,
floating=self.floating_ip_access)
self.check_remote_connectivity(source=access_point_ssh, dest=ip,
- should_succeed=False)
+ should_succeed=False, protocol=protocol)
- def _test_cross_tenant_allow(self, source_tenant, dest_tenant):
+ def _test_cross_tenant_allow(self, source_tenant, dest_tenant, ruleset):
"""check for each direction:
creating rule for tenant incoming traffic enables only 1way traffic
"""
- ruleset = dict(
- protocol='icmp',
- direction='ingress'
- )
+ protocol = ruleset['protocol']
sec_group_rules_client = (
dest_tenant.manager.security_group_rules_client)
self._create_security_group_rule(
@@ -423,10 +421,10 @@
access_point_ssh = self._connect_to_access_point(source_tenant)
ip = self._get_server_ip(dest_tenant.access_point,
floating=self.floating_ip_access)
- self.check_remote_connectivity(access_point_ssh, ip)
+ self.check_remote_connectivity(access_point_ssh, ip, protocol=protocol)
# test that reverse traffic is still blocked
- self._test_cross_tenant_block(dest_tenant, source_tenant)
+ self._test_cross_tenant_block(dest_tenant, source_tenant, ruleset)
# allow reverse traffic and check
sec_group_rules_client = (
@@ -440,7 +438,8 @@
access_point_ssh_2 = self._connect_to_access_point(dest_tenant)
ip = self._get_server_ip(source_tenant.access_point,
floating=self.floating_ip_access)
- self.check_remote_connectivity(access_point_ssh_2, ip)
+ self.check_remote_connectivity(access_point_ssh_2, ip,
+ protocol=protocol)
def _verify_mac_addr(self, tenant):
"""Verify that VM has the same ip, mac as listed in port"""
@@ -470,6 +469,17 @@
self._log_console_output(
servers=[tenant.access_point], client=client)
+ def _create_protocol_ruleset(self, protocol, port=80):
+ if protocol == 'icmp':
+ ruleset = dict(protocol='icmp',
+ direction='ingress')
+ else:
+ ruleset = dict(protocol=protocol,
+ port_range_min=port,
+ port_range_max=port,
+ direction='ingress')
+ return ruleset
+
@decorators.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
@utils.services('compute', 'network')
def test_cross_tenant_traffic(self):
@@ -484,8 +494,18 @@
# cross tenant check
source_tenant = self.primary_tenant
dest_tenant = self.alt_tenant
- self._test_cross_tenant_block(source_tenant, dest_tenant)
- self._test_cross_tenant_allow(source_tenant, dest_tenant)
+
+ protocol = CONF.scenario.protocol
+ LOG.debug("Testing cross tenant traffic for %s protocol",
+ protocol)
+ if protocol in ['udp', 'tcp']:
+ for tenant in [source_tenant, dest_tenant]:
+ access_point = self._connect_to_access_point(tenant)
+ access_point.nc_listen_host(protocol=protocol)
+
+ ruleset = self._create_protocol_ruleset(protocol)
+ self._test_cross_tenant_block(source_tenant, dest_tenant, ruleset)
+ self._test_cross_tenant_allow(source_tenant, dest_tenant, ruleset)
except Exception:
self._log_console_output_for_all_tenants()
raise
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 2782119..af79ea0 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -70,7 +70,6 @@
raise lib_exc.TimeoutException
@decorators.attr(type='slow')
- @decorators.skip_because(bug="1664793")
@decorators.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
@@ -91,6 +90,11 @@
# create and add floating IP to server1
ip_for_server = self.get_server_ip(server)
+ # Make sure the machine ssh-able before attaching the volume
+ self.get_remote_client(ip_for_server,
+ private_key=keypair['private_key'],
+ server=server)
+
self.nova_volume_attach(server, volume)
self._wait_for_volume_available_on_the_system(ip_for_server,
keypair['private_key'])
@@ -119,6 +123,13 @@
# create and add floating IP to server_from_snapshot
ip_for_snapshot = self.get_server_ip(server_from_snapshot)
+ # Make sure the machine ssh-able before attaching the volume
+ # Just a live machine is responding
+ # for device attache/detach as expected
+ self.get_remote_client(ip_for_snapshot,
+ private_key=keypair['private_key'],
+ server=server_from_snapshot)
+
# attach volume2 to instance2
self.nova_volume_attach(server_from_snapshot, volume_from_snapshot)
self._wait_for_volume_available_on_the_system(ip_for_snapshot,
diff --git a/tempest/test.py b/tempest/test.py
index 85000b6..438f4d9 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -20,6 +20,7 @@
import debtcollector.moves
import fixtures
from oslo_log import log as logging
+import pkg_resources
import six
import testtools
@@ -77,6 +78,10 @@
atexit.register(validate_tearDownClass)
+class DummyException(Exception):
+ pass
+
+
class BaseTestCase(testtools.testcase.WithAttributes,
testtools.TestCase):
"""The test base class defines Tempest framework for class level fixtures.
@@ -140,6 +145,26 @@
cls._teardowns = []
@classmethod
+ def handle_skip_exception(cls):
+ try:
+ stestr_version = pkg_resources.parse_version(
+ pkg_resources.get_distribution("stestr").version)
+ stestr_min = pkg_resources.parse_version('2.5.0')
+ new_stestr = (stestr_version >= stestr_min)
+ import unittest
+ import unittest2
+ if sys.version_info >= (3, 5) and new_stestr:
+ exc = unittest2.case.SkipTest
+ exc_to_raise = unittest.case.SkipTest
+ else:
+ exc = unittest.case.SkipTest
+ exc_to_raise = unittest2.case.SkipTest
+ except Exception:
+ exc = DummyException
+ exc_to_raise = DummyException
+ return exc, exc_to_raise
+
+ @classmethod
def setUpClass(cls):
cls.__setupclass_called = True
# Reset state
@@ -148,11 +173,24 @@
if hasattr(super(BaseTestCase, cls), 'setUpClass'):
super(BaseTestCase, cls).setUpClass()
# All the configuration checks that may generate a skip
- cls.skip_checks()
- if not cls.__skip_checks_called:
- raise RuntimeError("skip_checks for %s did not call the super's "
- "skip_checks" % cls.__name__)
+ # TODO(gmann): cls.handle_skip_exception is really workaround for
+ # testtools bug- https://github.com/testing-cabal/testtools/issues/272
+ # stestr which is used by Tempest internally to run the test switch
+ # the customize test runner(which use stdlib unittest) for >=py3.5
+ # else testtools.run.- https://github.com/mtreinish/stestr/pull/265
+ # These two test runner are not compatible due to skip exception
+ # handling(due to unittest2). testtools.run treat unittestt.SkipTest
+ # as error and stdlib unittest treat unittest2.case.SkipTest raised
+ # by testtools.TestCase.skipException.
+ # The below workaround can be removed once testtools fix issue# 272.
try:
+ exc, exc_to_raise = cls.handle_skip_exception()
+ cls.skip_checks()
+
+ if not cls.__skip_checks_called:
+ raise RuntimeError(
+ "skip_checks for %s did not call the super's "
+ "skip_checks" % cls.__name__)
# Allocation of all required credentials and client managers
cls._teardowns.append(('credentials', cls.clear_credentials))
cls.setup_credentials()
@@ -164,6 +202,8 @@
# Additional class-wide test resources
cls._teardowns.append(('resources', cls.resource_cleanup))
cls.resource_setup()
+ except exc as e:
+ raise exc_to_raise(e.args)
except Exception:
etype, value, trace = sys.exc_info()
LOG.info("%s raised in %s.setUpClass. Invoking tearDownClass.",
diff --git a/tempest/tests/cmd/test_cleanup.py b/tempest/tests/cmd/test_cleanup.py
index b47da0b..1618df9 100644
--- a/tempest/tests/cmd/test_cleanup.py
+++ b/tempest/tests/cmd/test_cleanup.py
@@ -12,6 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import mock
+
from tempest.cmd import cleanup
from tempest.tests import base
@@ -24,3 +26,17 @@
test_saved_json = 'tempest/tests/cmd/test_saved_state_json.json'
# test if the file is loaded without any issues/exceptions
c._load_json(test_saved_json)
+
+ @mock.patch('tempest.cmd.cleanup.TempestCleanup.init')
+ @mock.patch('tempest.cmd.cleanup.TempestCleanup._cleanup')
+ def test_take_action_got_exception(self, mock_cleanup, mock_init):
+ c = cleanup.TempestCleanup(None, None, 'test')
+ c.GOT_EXCEPTIONS.append('exception')
+ mock_cleanup.return_value = True
+ mock_init.return_value = True
+ try:
+ c.take_action(mock.Mock())
+ except Exception as exc:
+ self.assertEqual(str(exc), '[\'exception\']')
+ return
+ assert False
diff --git a/tempest/tests/cmd/test_cleanup_services.py b/tempest/tests/cmd/test_cleanup_services.py
index 3262b1c..de0dbec 100644
--- a/tempest/tests/cmd/test_cleanup_services.py
+++ b/tempest/tests/cmd/test_cleanup_services.py
@@ -19,6 +19,7 @@
from tempest import clients
from tempest.cmd import cleanup_service
from tempest import config
+from tempest.lib import exceptions
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests.lib import fake_credentials
@@ -27,13 +28,24 @@
class TestBaseService(base.TestCase):
+ class TestException(cleanup_service.BaseService):
+ def delete(self):
+ raise exceptions.NotImplemented
+
+ def dry_run(self):
+ raise exceptions.NotImplemented
+
+ def save_state(self):
+ raise exceptions.NotImplemented
+
def test_base_service_init(self):
kwargs = {'data': {'data': 'test'},
'is_dry_run': False,
'saved_state_json': {'saved': 'data'},
'is_preserve': False,
'is_save_state': True,
- 'tenant_id': 'project_id'}
+ 'tenant_id': 'project_id',
+ 'got_exceptions': []}
base = cleanup_service.BaseService(kwargs)
self.assertEqual(base.data, kwargs['data'])
self.assertFalse(base.is_dry_run)
@@ -41,6 +53,28 @@
self.assertFalse(base.is_preserve)
self.assertTrue(base.is_save_state)
self.assertEqual(base.tenant_filter['project_id'], kwargs['tenant_id'])
+ self.assertEqual(base.got_exceptions, kwargs['got_exceptions'])
+
+ def test_not_implemented_ex(self):
+ kwargs = {'data': {'data': 'test'},
+ 'is_dry_run': False,
+ 'saved_state_json': {'saved': 'data'},
+ 'is_preserve': False,
+ 'is_save_state': False,
+ 'tenant_id': 'project_id',
+ 'got_exceptions': []}
+ base = self.TestException(kwargs)
+ # delete
+ base.run()
+ self.assertEqual(len(base.got_exceptions), 1)
+ # save_state
+ base.save_state = True
+ base.run()
+ self.assertEqual(len(base.got_exceptions), 2)
+ # dry_run
+ base.is_dry_run = True
+ base.run()
+ self.assertEqual(len(base.got_exceptions), 3)
class MockFunctionsBase(base.TestCase):
diff --git a/tempest/tests/cmd/test_run.py b/tempest/tests/cmd/test_run.py
index 0e00d94..8997a4c 100644
--- a/tempest/tests/cmd/test_run.py
+++ b/tempest/tests/cmd/test_run.py
@@ -49,7 +49,7 @@
args = mock.Mock(spec=argparse.Namespace)
setattr(args, 'smoke', False)
setattr(args, 'regex', '')
- self.assertIsNone(None, self.run_cmd._build_regex(args))
+ self.assertIsNone(self.run_cmd._build_regex(args))
def test__build_regex_smoke(self):
args = mock.Mock(spec=argparse.Namespace)
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
old mode 100644
new mode 100755
index d56e8a4..02e1c99
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -73,6 +73,25 @@
mock.call(volume_id)])
mock_sleep.assert_called_once_with(1)
+ @mock.patch.object(time, 'sleep')
+ def test_wait_for_volume_status_error_extending(self, mock_sleep):
+ # Tests that the wait method raises VolumeExtendErrorException if
+ # the volume status is 'error_extending'.
+ client = mock.Mock(spec=volumes_client.VolumesClient,
+ resource_type="volume",
+ build_interval=1)
+ volume1 = {'volume': {'status': 'extending'}}
+ volume2 = {'volume': {'status': 'error_extending'}}
+ mock_show = mock.Mock(side_effect=(volume1, volume2))
+ client.show_volume = mock_show
+ volume_id = '7532b91e-aa0a-4e06-b3e5-20c0c5ee1caa'
+ self.assertRaises(exceptions.VolumeExtendErrorException,
+ waiters.wait_for_volume_resource_status,
+ client, volume_id, 'available')
+ mock_show.assert_has_calls([mock.call(volume_id),
+ mock.call(volume_id)])
+ mock_sleep.assert_called_once_with(1)
+
class TestInterfaceWaiters(base.TestCase):
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index 1f0080f..644a018 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -88,7 +88,7 @@
# the information using gnu/linux tools.
def _assert_exec_called_with(self, cmd):
- cmd = "set -eu -o pipefail; PATH=$PATH:/sbin; " + cmd
+ cmd = "set -eu -o pipefail; PATH=$PATH:/sbin:/usr/sbin; " + cmd
self.ssh_mock.mock.exec_command.assert_called_with(cmd)
def test_get_disks(self):
diff --git a/tempest/tests/lib/services/identity/v3/test_projects_client.py b/tempest/tests/lib/services/identity/v3/test_projects_client.py
index 6ffbcde..d26de06 100644
--- a/tempest/tests/lib/services/identity/v3/test_projects_client.py
+++ b/tempest/tests/lib/services/identity/v3/test_projects_client.py
@@ -62,7 +62,8 @@
"/0c4e939acacf4376bdcd1129f1a054ad"
},
"name": "admin",
- "parent_id": None
+ "parent_id": None,
+ "tags": []
},
{
"is_domain": False,
@@ -75,7 +76,8 @@
"/0cbd49cbf76d405d9c86562e1d579bd3"
},
"name": "demo",
- "parent_id": None
+ "parent_id": None,
+ "tags": []
},
{
"is_domain": False,
@@ -88,7 +90,8 @@
"/2db68fed84324f29bb73130c6c2094fb"
},
"name": "swifttenanttest2",
- "parent_id": None
+ "parent_id": None,
+ "tags": []
},
{
"is_domain": False,
@@ -101,7 +104,8 @@
"/3d594eb0f04741069dbbb521635b21c7"
},
"name": "service",
- "parent_id": None
+ "parent_id": None,
+ "tags": []
}
]
}
diff --git a/tempest/tests/lib/services/network/test_qos_client.py b/tempest/tests/lib/services/network/test_qos_client.py
new file mode 100644
index 0000000..b04b847
--- /dev/null
+++ b/tempest/tests/lib/services/network/test_qos_client.py
@@ -0,0 +1,139 @@
+# Copyright (c) 2019 Ericsson
+#
+# 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.services.network import qos_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestQosClient(base.BaseServiceTest):
+
+ FAKE_QOS_POLICY_ID = "f1011b08-1297-11e9-a1e7-c7e6825a2616"
+
+ FAKE_QOS_POLICY_REQUEST = {
+ 'name': 'foo',
+ 'shared': True
+ }
+
+ FAKE_QOS_POLICY_RESPONSE = {
+ 'policy': {
+ "name": "10Mbit",
+ "description": "This policy limits the ports to 10Mbit max.",
+ "rules": [],
+ "id": FAKE_QOS_POLICY_ID,
+ "is_default": False,
+ "project_id": "8d4c70a21fed4aeba121a1a429ba0d04",
+ "revision_number": 1,
+ "tenant_id": "8d4c70a21fed4aeba121a1a429ba0d04",
+ "created_at": "2018-04-03T21:26:39Z",
+ "updated_at": "2018-04-03T21:26:39Z",
+ "shared": False,
+ "tags": ["tag1,tag2"]
+ }
+ }
+
+ FAKE_QOS_POLICIES = {
+ 'policies': [
+ FAKE_QOS_POLICY_RESPONSE['policy']
+ ]
+ }
+
+ def setUp(self):
+ super(TestQosClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.qos_client = qos_client.QosClient(
+ fake_auth, "network", "regionOne")
+
+ def _test_create_qos_policy(self, bytes_body=False):
+ self.check_service_client_function(
+ self.qos_client.create_qos_policy,
+ "tempest.lib.common.rest_client.RestClient.post",
+ self.FAKE_QOS_POLICY_RESPONSE,
+ bytes_body,
+ 201,
+ **self.FAKE_QOS_POLICY_REQUEST)
+
+ def _test_list_qos_policies(self, bytes_body=False):
+ self.check_service_client_function(
+ self.qos_client.list_qos_policies,
+ "tempest.lib.common.rest_client.RestClient.get",
+ self.FAKE_QOS_POLICIES,
+ bytes_body,
+ 200)
+
+ def _test_show_qos_policy(self, bytes_body=False):
+ self.check_service_client_function(
+ self.qos_client.show_qos_policy,
+ "tempest.lib.common.rest_client.RestClient.get",
+ self.FAKE_QOS_POLICY_RESPONSE,
+ bytes_body,
+ 200,
+ qos_policy_id=self.FAKE_QOS_POLICY_ID)
+
+ def _test_update_qos_polcy(self, bytes_body=False):
+ update_kwargs = {
+ "name": "100Mbit",
+ "description": "This policy limits the ports to 100Mbit max.",
+ "shared": True
+ }
+
+ resp_body = {
+ "policy": copy.deepcopy(
+ self.FAKE_QOS_POLICY_RESPONSE['policy']
+ )
+ }
+ resp_body["policy"].update(update_kwargs)
+
+ self.check_service_client_function(
+ self.qos_client.update_qos_policy,
+ "tempest.lib.common.rest_client.RestClient.put",
+ resp_body,
+ bytes_body,
+ 200,
+ qos_policy_id=self.FAKE_QOS_POLICY_ID,
+ **update_kwargs)
+
+ def test_create_qos_policy_with_str_body(self):
+ self._test_create_qos_policy()
+
+ def test_create_qos_policy_with_bytes_body(self):
+ self._test_create_qos_policy(bytes_body=True)
+
+ def test_update_qos_policy_with_str_body(self):
+ self._test_update_qos_polcy()
+
+ def test_update_qos_policy_with_bytes_body(self):
+ self._test_update_qos_polcy(bytes_body=True)
+
+ def test_show_qos_policy_with_str_body(self):
+ self._test_show_qos_policy()
+
+ def test_show_qos_policy_with_bytes_body(self):
+ self._test_show_qos_policy(bytes_body=True)
+
+ def test_delete_qos_policy(self):
+ self.check_service_client_function(
+ self.qos_client.delete_qos_policy,
+ "tempest.lib.common.rest_client.RestClient.delete",
+ {},
+ status=204,
+ qos_policy_id=self.FAKE_QOS_POLICY_ID)
+
+ def test_list_qos_policies_with_str_body(self):
+ self._test_list_qos_policies()
+
+ def test_list_qos_policies_with_bytes_body(self):
+ self._test_list_qos_policies(bytes_body=True)
diff --git a/tempest/tests/lib/services/network/test_qos_minimum_bandwidth_rules_client.py b/tempest/tests/lib/services/network/test_qos_minimum_bandwidth_rules_client.py
new file mode 100644
index 0000000..8234dda
--- /dev/null
+++ b/tempest/tests/lib/services/network/test_qos_minimum_bandwidth_rules_client.py
@@ -0,0 +1,137 @@
+# Copyright (c) 2019 Ericsson
+#
+# 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.services.network import qos_minimum_bandwidth_rules_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestQosMinimumBandwidthRulesClient(base.BaseServiceTest):
+
+ FAKE_QOS_POLICY_ID = "f1011b08-1297-11e9-a1e7-c7e6825a2616"
+ FAKE_MIN_BW_RULE_ID = "e758c89e-1297-11e9-a6cf-cf46a71e6699"
+
+ FAKE_MIN_BW_RULE_REQUEST = {
+ 'qos_policy_id': FAKE_QOS_POLICY_ID,
+ 'min_kbps': 1000,
+ 'direction': 'ingress'
+ }
+
+ FAKE_MIN_BW_RULE_RESPONSE = {
+ 'minimum_bandwidth_rule': {
+ 'id': FAKE_MIN_BW_RULE_ID,
+ 'min_kbps': 10000,
+ 'direction': 'egress'
+ }
+ }
+
+ FAKE_MIN_BW_RULES = {
+ 'bandwidth_limit_rules': [
+ FAKE_MIN_BW_RULE_RESPONSE['minimum_bandwidth_rule']
+ ]
+ }
+
+ def setUp(self):
+ super(TestQosMinimumBandwidthRulesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.qos_min_bw_client = qos_minimum_bandwidth_rules_client.\
+ QosMinimumBandwidthRulesClient(fake_auth, "network", "regionOne")
+
+ def _test_create_minimum_bandwidth_rule(self, bytes_body=False):
+ self.check_service_client_function(
+ self.qos_min_bw_client.create_minimum_bandwidth_rule,
+ "tempest.lib.common.rest_client.RestClient.post",
+ self.FAKE_MIN_BW_RULE_RESPONSE,
+ bytes_body,
+ 201,
+ **self.FAKE_MIN_BW_RULE_REQUEST
+ )
+
+ def _test_list_minimum_bandwidth_rules(self, bytes_body=False):
+ self.check_service_client_function(
+ self.qos_min_bw_client.list_minimum_bandwidth_rules,
+ "tempest.lib.common.rest_client.RestClient.get",
+ self.FAKE_MIN_BW_RULES,
+ bytes_body,
+ 200,
+ qos_policy_id=self.FAKE_QOS_POLICY_ID
+ )
+
+ def _test_show_minimum_bandwidth_rule(self, bytes_body=False):
+ self.check_service_client_function(
+ self.qos_min_bw_client.show_minimum_bandwidth_rule,
+ "tempest.lib.common.rest_client.RestClient.get",
+ self.FAKE_MIN_BW_RULE_RESPONSE,
+ bytes_body,
+ 200,
+ qos_policy_id=self.FAKE_QOS_POLICY_ID,
+ rule_id=self.FAKE_MIN_BW_RULE_ID
+ )
+
+ def _test_update_qos_polcy(self, bytes_body=False):
+ update_kwargs = {
+ "min_kbps": "20000"
+ }
+
+ resp_body = {
+ "minimum_bandwidth_rule": copy.deepcopy(
+ self.FAKE_MIN_BW_RULE_RESPONSE['minimum_bandwidth_rule']
+ )
+ }
+ resp_body["minimum_bandwidth_rule"].update(update_kwargs)
+
+ self.check_service_client_function(
+ self.qos_min_bw_client.update_minimum_bandwidth_rule,
+ "tempest.lib.common.rest_client.RestClient.put",
+ resp_body,
+ bytes_body,
+ 200,
+ qos_policy_id=self.FAKE_QOS_POLICY_ID,
+ rule_id=self.FAKE_MIN_BW_RULE_ID,
+ **update_kwargs)
+
+ def test_create_minimum_bandwidth_rule_with_str_body(self):
+ self._test_create_minimum_bandwidth_rule()
+
+ def test_create_minimum_bandwidth_rule_with_bytes_body(self):
+ self._test_create_minimum_bandwidth_rule(bytes_body=True)
+
+ def test_update_minimum_bandwidth_rule_with_str_body(self):
+ self._test_update_qos_polcy()
+
+ def test_update_minimum_bandwidth_rule_with_bytes_body(self):
+ self._test_update_qos_polcy(bytes_body=True)
+
+ def test_show_minimum_bandwidth_rule_with_str_body(self):
+ self._test_show_minimum_bandwidth_rule()
+
+ def test_show_minimum_bandwidth_rule_with_bytes_body(self):
+ self._test_show_minimum_bandwidth_rule(bytes_body=True)
+
+ def test_delete_minimum_bandwidth_rule(self):
+ self.check_service_client_function(
+ self.qos_min_bw_client.delete_minimum_bandwidth_rule,
+ "tempest.lib.common.rest_client.RestClient.delete",
+ {},
+ status=204,
+ qos_policy_id=self.FAKE_QOS_POLICY_ID,
+ rule_id=self.FAKE_MIN_BW_RULE_ID)
+
+ def test_list_minimum_bandwidth_rule_with_str_body(self):
+ self._test_list_minimum_bandwidth_rules()
+
+ def test_list_minimum_bandwidth_rule_with_bytes_body(self):
+ self._test_list_minimum_bandwidth_rules(bytes_body=True)
diff --git a/tempest/tests/lib/services/network/test_segments_client.py b/tempest/tests/lib/services/network/test_segments_client.py
new file mode 100644
index 0000000..579c78f
--- /dev/null
+++ b/tempest/tests/lib/services/network/test_segments_client.py
@@ -0,0 +1,140 @@
+# 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.services.network import segments_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestSegmentsClient(base.BaseServiceTest):
+
+ FAKE_SEGMENT_ID = '83a59912-a473-11e9-a012-af494c35c9c2'
+ FAKE_NETWORK_ID = '913ab0e4-a473-11e9-84a3-af1c16fc05de'
+
+ FAKE_SEGMENT_REQUEST = {
+ 'segment': {
+ 'network_id': FAKE_NETWORK_ID,
+ 'segmentation_id': 2000,
+ 'network_type': 'vlan',
+ 'physical_network': 'segment-1'
+ }
+ }
+
+ FAKE_SEGMENT_RESPONSE = {
+ 'segment': {
+ 'name': 'foo',
+ 'network_id': FAKE_NETWORK_ID,
+ 'segmentation_id': 2000,
+ 'network_type': 'vlan',
+ 'physical_network': 'segment-1',
+ 'revision_number': 1,
+ 'id': FAKE_SEGMENT_ID,
+ 'created_at': '2019-07-12T09:13:56Z',
+ 'updated_at': '2019-07-12T09:13:56Z',
+ 'description': 'bar'
+ }
+ }
+
+ FAKE_SEGMENTS = {
+ 'segments': [
+ FAKE_SEGMENT_RESPONSE['segment']
+ ]
+ }
+
+ def setUp(self):
+ super(TestSegmentsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.segments_client = segments_client.SegmentsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_create_segment(self, bytes_body=False):
+ self.check_service_client_function(
+ self.segments_client.create_segment,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_SEGMENT_RESPONSE,
+ bytes_body,
+ 201,
+ **self.FAKE_SEGMENT_REQUEST['segment']
+ )
+
+ def _test_list_segments(self, bytes_body=False):
+ self.check_service_client_function(
+ self.segments_client.list_segments,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_SEGMENTS,
+ bytes_body,
+ 200
+ )
+
+ def _test_show_segment(self, bytes_body=False):
+ self.check_service_client_function(
+ self.segments_client.show_segment,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_SEGMENT_RESPONSE,
+ bytes_body,
+ 200,
+ segment_id=self.FAKE_SEGMENT_ID
+ )
+
+ def _test_update_segment(self, bytes_body=False):
+ update_kwargs = {
+ 'name': 'notfoo'
+ }
+
+ resp_body = {
+ 'segment': copy.deepcopy(self.FAKE_SEGMENT_RESPONSE['segment'])
+ }
+ resp_body['segment'].update(update_kwargs)
+
+ self.check_service_client_function(
+ self.segments_client.update_segment,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ resp_body,
+ bytes_body,
+ 200,
+ segment_id=self.FAKE_SEGMENT_ID,
+ **update_kwargs
+ )
+
+ def test_create_segment_with_str_body(self):
+ self._test_create_segment()
+
+ def test_create_segment_with_bytes_body(self):
+ self._test_create_segment(bytes_body=True)
+
+ def test_update_segment_with_str_body(self):
+ self._test_update_segment()
+
+ def test_update_segment_with_bytes_body(self):
+ self._test_update_segment(bytes_body=True)
+
+ def test_show_segment_with_str_body(self):
+ self._test_show_segment()
+
+ def test_show_segment_with_bytes_body(self):
+ self._test_show_segment(bytes_body=True)
+
+ def test_delete_segment(self):
+ self.check_service_client_function(
+ self.segments_client.delete_segment,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ status=204,
+ segment_id=self.FAKE_SEGMENT_ID)
+
+ def test_list_segment_with_str_body(self):
+ self._test_list_segments()
+
+ def test_list_segment_with_bytes_body(self):
+ self._test_list_segments(bytes_body=True)
diff --git a/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py b/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
index c788181..70a3ee5 100644
--- a/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_encryption_types_client.py
@@ -20,27 +20,35 @@
class TestEncryptionTypesClient(base.BaseServiceTest):
FAKE_CREATE_ENCRYPTION_TYPE = {
"encryption": {
- "id": "cbc36478b0bd8e67e89",
- "name": "FakeEncryptionType",
- "type": "fakeType",
+ "volume_type_id": "cbc36478b0bd8e67e89",
+ "control_location": "front-end",
+ "encryption_id": "81e069c6-7394-4856-8df7-3b237ca61f74",
+ "key_size": 128,
"provider": "LuksEncryptor",
- "cipher": "aes-xts-plain64",
- "key_size": "512",
- "control_location": "front-end"
+ "cipher": "aes-xts-plain64"
+ }
+ }
+
+ FAKE_UPDATE_ENCRYPTION_TYPE = {
+ "encryption": {
+ "key_size": 64,
+ "provider": "LuksEncryptor",
+ "control_location": "front-end",
+ "cipher": "aes-xts-plain64"
}
}
FAKE_INFO_ENCRYPTION_TYPE = {
- "encryption": {
- "name": "FakeEncryptionType",
- "type": "fakeType",
- "description": "test_description",
- "volume_type": "fakeType",
- "provider": "LuksEncryptor",
- "cipher": "aes-xts-plain64",
- "key_size": "512",
- "control_location": "front-end"
- }
+ "volume_type_id": "cbc36478b0bd8e67e89",
+ "control_location": "front-end",
+ "deleted": False,
+ "created_at": "2015-08-27T09:49:58-05:00",
+ "updated_at": "2015-08-29T09:49:58-05:00",
+ "encryption_id": "81e069c6-7394-4856-8df7-3b237ca61f74",
+ "key_size": 128,
+ "provider": "LuksEncryptor",
+ "deleted_at": "2015-08-30T09:49:58-05:00",
+ "cipher": "aes-xts-plain64"
}
FAKE_ENCRYPTION_SPECS_ITEM = {
@@ -50,10 +58,8 @@
def setUp(self):
super(TestEncryptionTypesClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = encryption_types_client.EncryptionTypesClient(fake_auth,
- 'volume',
- 'regionOne'
- )
+ self.client = encryption_types_client.EncryptionTypesClient(
+ fake_auth, 'volume', 'regionOne')
def _test_create_encryption(self, bytes_body=False):
self.check_service_client_function(
@@ -101,3 +107,16 @@
{},
volume_type_id="cbc36478b0bd8e67e89",
status=202)
+
+ def test_update_encryption_type_with_str_body(self):
+ self._test_update_encryption_type()
+
+ def test_update_encryption_type_with_bytes_body(self):
+ self._test_update_encryption_type(bytes_body=True)
+
+ def _test_update_encryption_type(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.update_encryption_type,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ self.FAKE_UPDATE_ENCRYPTION_TYPE,
+ bytes_body, volume_type_id="cbc36478b0bd8e67e89")
diff --git a/tempest/tests/lib/services/volume/v3/test_group_snapshots_client.py b/tempest/tests/lib/services/volume/v3/test_group_snapshots_client.py
index c2784b2..889fd42 100644
--- a/tempest/tests/lib/services/volume/v3/test_group_snapshots_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_group_snapshots_client.py
@@ -20,9 +20,9 @@
class TestGroupSnapshotsClient(base.BaseServiceTest):
FAKE_CREATE_GROUP_SNAPSHOT = {
"group_snapshot": {
- "group_id": "49c8c114-0d68-4e89-b8bc-3f5a674d54be",
- "name": "group-snapshot-001",
- "description": "Test group snapshot 1"
+ "id": "6f519a48-3183-46cf-a32f-41815f816666",
+ "name": "first_group_snapshot",
+ "group_type_id": "58737af7-786b-48b7-ab7c-2447e74b0ef4"
}
}
@@ -34,7 +34,7 @@
"description": "Test group snapshot 1",
"group_type_id": "0e58433f-d108-4bf3-a22c-34e6b71ef86b",
"status": "available",
- "created_at": "20127-06-20T03:50:07Z"
+ "created_at": "2017-06-20T03:50:07Z"
}
}
@@ -102,8 +102,7 @@
resp_body = {
'group_snapshots': [{
'id': group_snapshot['id'],
- 'name': group_snapshot['name'],
- 'group_type_id': group_snapshot['group_type_id']}
+ 'name': group_snapshot['name']}
for group_snapshot in
self.FAKE_LIST_GROUP_SNAPSHOTS['group_snapshots']
]
diff --git a/tempest/tests/lib/services/volume/v3/test_group_types_client.py b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
index c60cc36..8b853d7 100644
--- a/tempest/tests/lib/services/volume/v3/test_group_types_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_group_types_client.py
@@ -22,10 +22,13 @@
class TestGroupTypesClient(base.BaseServiceTest):
FAKE_CREATE_GROUP_TYPE = {
"group_type": {
- "name": "group-type-001",
- "description": "Test group type 1",
- "group_specs": {},
+ "id": "6685584b-1eac-4da6-b5c3-555430cf68ff",
+ "name": "grp-type-001",
+ "description": "group type 001",
"is_public": True,
+ "group_specs": {
+ "consistent_group_snapshot_enabled": "<is> False"
+ }
}
}
@@ -35,7 +38,16 @@
"name": "group-type-001",
"description": "Test group type 1",
"is_public": True,
- "created_at": "20127-06-20T03:50:07Z",
+ "group_specs": {},
+ }
+ }
+
+ FAKE_INFO_DEFAULT_GROUP_TYPE = {
+ "group_type": {
+ "id": "7270c56e-6354-4528-8e8b-f54dee2232c8",
+ "name": "group-type-default",
+ "description": "default group type",
+ "is_public": True,
"group_specs": {},
}
}
@@ -47,24 +59,27 @@
"name": "group-type-001",
"description": "Test group type 1",
"is_public": True,
- "created_at": "2017-06-20T03:50:07Z",
- "group_specs": {},
+ "group_specs": {
+ "consistent_group_snapshot_enabled": "<is> False"
+ }
},
{
"id": "e479997c-650b-40a4-9dfe-77655818b0d2",
"name": "group-type-002",
"description": "Test group type 2",
"is_public": True,
- "created_at": "2017-06-19T01:52:47Z",
- "group_specs": {},
+ "group_specs": {
+ "consistent_group_snapshot_enabled": "<is> False"
+ }
},
{
"id": "c5c4769e-213c-40a6-a568-8e797bb691d4",
"name": "group-type-003",
"description": "Test group type 3",
"is_public": True,
- "created_at": "2017-06-18T06:34:32Z",
- "group_specs": {},
+ "group_specs": {
+ "consistent_group_snapshot_enabled": "<is> False"
+ }
}
]
}
@@ -114,6 +129,13 @@
bytes_body,
group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5")
+ def _test_show_default_group_type(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_default_group_type,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_INFO_DEFAULT_GROUP_TYPE,
+ bytes_body)
+
def _test_list_group_types(self, bytes_body=False):
self.check_service_client_function(
self.client.list_group_types,
@@ -123,15 +145,12 @@
def _test_update_group_types(self, bytes_body=False):
resp_body = copy.deepcopy(self.FAKE_INFO_GROUP_TYPE)
- resp_body['group_type'].pop('created_at')
-
self.check_service_client_function(
self.client.update_group_type,
'tempest.lib.common.rest_client.RestClient.put',
resp_body,
bytes_body,
- group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5",
- name='updated-group-type-name')
+ group_type_id="3fbbcccf-d058-4502-8844-6feeffdf4cb5")
def _test_create_or_update_group_type_specs(self, bytes_body=False):
group_specs = self.FAKE_CREATE_GROUP_TYPE_SPECS['group_specs']
@@ -192,6 +211,12 @@
def test_show_group_type_with_bytes_body(self):
self._test_show_group_type(bytes_body=True)
+ def test_show_default_group_type_with_str_body(self):
+ self._test_show_default_group_type()
+
+ def test_show_default_group_type_with_bytes_body(self):
+ self._test_show_default_group_type(bytes_body=True)
+
def test_list_group_types_with_str_body(self):
self._test_list_group_types()
diff --git a/tempest/tests/lib/services/volume/v3/test_groups_client.py b/tempest/tests/lib/services/volume/v3/test_groups_client.py
index 918e958..5a5ae88 100644
--- a/tempest/tests/lib/services/volume/v3/test_groups_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_groups_client.py
@@ -20,27 +20,22 @@
class TestGroupsClient(base.BaseServiceTest):
FAKE_CREATE_GROUP = {
"group": {
- "name": "group-001",
- "description": "Test group 1",
- "group_type": "0e58433f-d108-4bf3-a22c-34e6b71ef86b",
- "volume_types": ["2103099d-7cc3-4e52-a2f1-23a5284416f3"],
- "availability_zone": "az1",
+ "id": "6f519a48-3183-46cf-a32f-41815f816666",
+ "name": "first_group"
}
}
FAKE_CREATE_GROUP_FROM_GROUP_SNAPSHOT = {
- "create-from-src": {
- "name": "group-002",
- "description": "Test group 2",
- "group_snapshot_id": "79c9afdb-7e46-4d71-9249-1f022886963c",
+ "group": {
+ "id": "6f519a48-3183-46cf-a32f-41815f816668",
+ "name": "first_group"
}
}
FAKE_CREATE_GROUP_FROM_GROUP = {
- "create-from-src": {
- "name": "group-003",
- "description": "Test group 3",
- "source_group_id": "e92f9dc7-0b20-492d-8ab2-3ad8fdac270e",
+ "group": {
+ "id": "6f519a48-3183-46cf-a32f-41815f816667",
+ "name": "other_group"
}
}
diff --git a/tempest/tests/lib/services/volume/v3/test_hosts_client.py b/tempest/tests/lib/services/volume/v3/test_hosts_client.py
index 09bc0b1..8033e38 100644
--- a/tempest/tests/lib/services/volume/v3/test_hosts_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_hosts_client.py
@@ -48,7 +48,7 @@
"total_volume_gb": "2",
"total_snapshot_gb": "0",
"project": "(total)",
- "host": "fake-host",
+ "host": "fake-host@rbd",
"snapshot_count": "0"
}
},
@@ -58,7 +58,7 @@
"total_volume_gb": "2",
"total_snapshot_gb": "0",
"project": "f21a9c86d7114bf99c711f4874d80474",
- "host": "fake-host",
+ "host": "fake-host@lvm",
"snapshot_count": "0"
}
}
diff --git a/tempest/tests/lib/services/volume/v3/test_quotas_client.py b/tempest/tests/lib/services/volume/v3/test_quotas_client.py
index aa5d251..f09784c 100644
--- a/tempest/tests/lib/services/volume/v3/test_quotas_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_quotas_client.py
@@ -20,15 +20,26 @@
class TestQuotasClient(base.BaseServiceTest):
FAKE_QUOTAS = {
"quota_set": {
+ "id": '730a1cbd-68ca-4d68-8e09-d603f2dfa72b',
"gigabytes": 5,
"snapshots": 10,
- "volumes": 20
+ "volumes": 20,
+ 'backups': 10,
+ 'groups': 10,
+ 'per_volume_gigabytes': 1000,
+ 'backup_gigabytes': 2000
}
}
- FAKE_UPDATE_QUOTAS_REQUEST = {
+ FAKE_UPDATE_QUOTAS_RESPONSE = {
"quota_set": {
- "security_groups": 45
+ "gigabytes": 6,
+ "snapshots": 11,
+ "volumes": 21,
+ 'backups': 11,
+ 'groups': 11,
+ 'per_volume_gigabytes': 1001,
+ 'backup_gigabytes': 2001
}
}
@@ -57,7 +68,7 @@
self.check_service_client_function(
self.client.update_quota_set,
'tempest.lib.common.rest_client.RestClient.put',
- self.FAKE_UPDATE_QUOTAS_REQUEST,
+ self.FAKE_UPDATE_QUOTAS_RESPONSE,
bytes_body, tenant_id="fake_tenant")
def test_show_default_quota_set_with_str_body(self):
diff --git a/tempest/tests/lib/services/volume/v3/test_versions_client.py b/tempest/tests/lib/services/volume/v3/test_versions_client.py
index 9627b9a..575cae3 100644
--- a/tempest/tests/lib/services/volume/v3/test_versions_client.py
+++ b/tempest/tests/lib/services/volume/v3/test_versions_client.py
@@ -69,6 +69,27 @@
]
}
+ FAKE_VERSION_DETAILS = {
+ "versions": [
+ {
+ "id": "v3.0",
+ "links": [
+ {"href": "https://docs.openstack.org/",
+ "type": "text/html", "rel": "describedby"},
+ {"href": "http://127.0.0.1:44895/v3/", "rel": "self"}
+ ],
+ "media-types": [
+ {"base": "application/json",
+ "type": "application/vnd.openstack.volume+json;version=3"}
+ ],
+ "min_version": "3.0",
+ "status": "CURRENT",
+ "updated": "2018-07-17T00:00:00Z",
+ "version": "3.59"
+ }
+ ]
+ }
+
def setUp(self):
super(TestVersionsClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
@@ -76,6 +97,14 @@
'volume',
'regionOne')
+ def _test_get_base_version_url(self, url, expected_base_url):
+ fake_auth = fake_auth_provider.FakeAuthProvider(fake_base_url=url)
+ client = versions_client.VersionsClient(fake_auth,
+ 'volume',
+ 'regionOne')
+ self.assertEqual(expected_base_url,
+ client._get_base_version_url())
+
def _test_list_versions(self, bytes_body=False):
self.check_service_client_function(
self.client.list_versions,
@@ -84,8 +113,30 @@
bytes_body,
300)
+ def _test_show_version(self, version, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_version,
+ 'tempest.lib.common.rest_client.RestClient.raw_request',
+ self.FAKE_VERSION_DETAILS,
+ bytes_body,
+ 200, version=version)
+
def test_list_versions_with_str_body(self):
self._test_list_versions()
def test_list_versions_with_bytes_body(self):
self._test_list_versions(bytes_body=True)
+
+ def test_show_version_details_with_str_body(self):
+ self._test_show_version('v3')
+
+ def test_show_version_details_with_bytes_body(self):
+ self._test_show_version('v3', bytes_body=True)
+
+ def test_get_base_version_url_app_name(self):
+ self._test_get_base_version_url('https://bar.org/volume/v1/123',
+ 'https://bar.org/volume/')
+ self._test_get_base_version_url('https://bar.org/volume/v2/123',
+ 'https://bar.org/volume/')
+ self._test_get_base_version_url('https://bar.org/volume/v3/123',
+ 'https://bar.org/volume/')
diff --git a/tempest/tests/lib/test_api_microversion_fixture.py b/tempest/tests/lib/test_api_microversion_fixture.py
new file mode 100644
index 0000000..ad98ed0
--- /dev/null
+++ b/tempest/tests/lib/test_api_microversion_fixture.py
@@ -0,0 +1,58 @@
+# Copyright 2019 NEC Corporation.
+#
+# 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.common import api_microversion_fixture
+from tempest.lib.services.compute import base_compute_client
+from tempest.lib.services.placement import base_placement_client
+from tempest.lib.services.volume import base_client
+from tempest.tests import base
+
+
+class TestAPIMicroversionFixture(base.TestCase):
+ def setUp(self):
+ super(TestAPIMicroversionFixture, self).setUp()
+ # Verify that all the microversion are reset back to None
+ # by Fixture.
+ self.assertIsNone(base_compute_client.COMPUTE_MICROVERSION)
+ self.assertIsNone(base_client.VOLUME_MICROVERSION)
+ self.assertIsNone(base_placement_client.PLACEMENT_MICROVERSION)
+
+ def test_compute_microversion(self):
+ self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+ compute_microversion='2.10'))
+ self.assertEqual('2.10', base_compute_client.COMPUTE_MICROVERSION)
+ self.assertIsNone(base_client.VOLUME_MICROVERSION)
+ self.assertIsNone(base_placement_client.PLACEMENT_MICROVERSION)
+
+ def test_volume_microversion(self):
+ self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+ volume_microversion='3.10'))
+ self.assertIsNone(base_compute_client.COMPUTE_MICROVERSION)
+ self.assertEqual('3.10', base_client.VOLUME_MICROVERSION)
+ self.assertIsNone(base_placement_client.PLACEMENT_MICROVERSION)
+
+ def test_placement_microversion(self):
+ self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+ placement_microversion='1.10'))
+ self.assertIsNone(base_compute_client.COMPUTE_MICROVERSION)
+ self.assertIsNone(base_client.VOLUME_MICROVERSION)
+ self.assertEqual('1.10', base_placement_client.PLACEMENT_MICROVERSION)
+
+ def test_multiple_service_microversion(self):
+ self.useFixture(api_microversion_fixture.APIMicroversionFixture(
+ compute_microversion='2.10', volume_microversion='3.10',
+ placement_microversion='1.10'))
+ self.assertEqual('2.10', base_compute_client.COMPUTE_MICROVERSION)
+ self.assertEqual('3.10', base_client.VOLUME_MICROVERSION)
+ self.assertEqual('1.10', base_placement_client.PLACEMENT_MICROVERSION)
diff --git a/tempest/tests/test_test.py b/tempest/tests/test_test.py
index fc50736..ad0793c 100644
--- a/tempest/tests/test_test.py
+++ b/tempest/tests/test_test.py
@@ -531,8 +531,8 @@
def test_skip_only(self):
# If a skip condition is hit in the test, no credentials or resource
# is provisioned / cleaned-up
- self.mocks['skip_checks'].side_effect = (
- testtools.testcase.TestSkipped())
+ exc, _ = test.BaseTestCase.handle_skip_exception()
+ self.mocks['skip_checks'].side_effect = (exc)
suite = unittest.TestSuite((self.test,))
log = []
result = LoggingTestResult(log)
diff --git a/tools/format.sh b/tools/format.sh
index dec8f1c..ef5cc92 100755
--- a/tools/format.sh
+++ b/tools/format.sh
@@ -15,7 +15,8 @@
# isort is not compatible with the default flake8 (H306), maybe flake8-isort
# isort -rc -sl -fss ../tempest ../setup.py
-$AUTOPEP8 --exit-code --max-line-length=79 --experimental --in-place -r ../tempest ../setup.py
+$AUTOPEP8 --exit-code --max-line-length=79 --experimental --in-place \
+ -r ../tempest ../setup.py
ERROR=$?
if [[ $ERROR -eq 0 ]]; then
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index 3772774..255487e 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -19,24 +19,41 @@
#
# In order to function correctly, the environment in which the
# script runs must have
-# * network access to the review.openstack.org Gerrit API
+# * network access to the review.opendev.org Gerrit API
# working directory
-# * network access to https://git.openstack.org/cgit
+# * network access to https://opendev.org/openstack
import json
import re
+import sys
-try:
- # For Python 3.0 and later
- from urllib.error import HTTPError
- import urllib.request as urllib
-except ImportError:
- # Fall back to Python 2's urllib2
- import urllib2 as urllib
- from urllib2 import HTTPError
+import urllib3
+from urllib3.util import retry
+# List of projects having tempest plugin stale or unmaintained for a long time
+# (6 months or more)
+# TODO(masayukig): Some of these can be removed from BLACKLIST in the future
+# when the patches are merged.
+BLACKLIST = [
+ 'openstack/barbican-tempest-plugin',
+ # https://review.opendev.org/#/c/634631/
+ 'x/gce-api', # It looks gce-api doesn't support python3 yet.
+ 'x/group-based-policy', # It looks this doesn't support python3 yet.
+ 'x/intel-nfv-ci-tests', # https://review.opendev.org/#/c/634640/
+ 'openstack/networking-generic-switch',
+ # https://review.opendev.org/#/c/634846/
+ 'openstack/networking-l2gw-tempest-plugin',
+ # https://review.opendev.org/#/c/635093/
+ 'openstack/networking-midonet', # https://review.opendev.org/#/c/635096/
+ 'x/networking-plumgrid', # https://review.opendev.org/#/c/635096/
+ 'x/networking-spp', # https://review.opendev.org/#/c/635098/
+ 'openstack/neutron-dynamic-routing',
+ # https://review.opendev.org/#/c/637718/
+ 'openstack/neutron-vpnaas', # https://review.opendev.org/#/c/637719/
+ 'x/valet', # https://review.opendev.org/#/c/638339/
+]
-url = 'https://review.openstack.org/projects/'
+url = 'https://review.opendev.org/projects/'
# This is what a project looks like
'''
@@ -46,48 +63,65 @@
},
'''
-
-def is_in_openstack_namespace(proj):
- return proj.startswith('openstack/')
-
-# Rather than returning a 404 for a nonexistent file, cgit delivers a
-# 0-byte response to a GET request. It also does not provide a
-# Content-Length in a HEAD response, so the way we tell if a file exists
-# is to check the length of the entire GET response body.
+http = urllib3.PoolManager(cert_reqs='CERT_REQUIRED')
+retries = retry.Retry(status_forcelist=[500], backoff_factor=1.0)
def has_tempest_plugin(proj):
try:
- r = urllib.urlopen(
- "https://git.openstack.org/cgit/%s/plain/setup.cfg" % proj)
- except HTTPError as err:
- if err.code == 404:
+ r = http.request('GET', "https://opendev.org/%s/raw/branch/"
+ "master/setup.cfg" % proj, retries=retries)
+ if r.status == 404:
return False
+ except urllib3.exceptions.MaxRetryError as err:
+ # We should not ignore non 404 errors.
+ raise err
p = re.compile(r'^tempest\.test_plugins', re.M)
- if p.findall(r.read().decode('utf-8')):
+ if p.findall(r.data.decode('utf-8')):
return True
else:
False
-r = urllib.urlopen(url)
+if len(sys.argv) > 1 and sys.argv[1] == 'blacklist':
+ for black_plugin in BLACKLIST:
+ print(black_plugin)
+ # We just need BLACKLIST when we use this `blacklist` option.
+ # So, this exits here.
+ sys.exit()
+
+r = http.request('GET', url, retries=retries)
# Gerrit prepends 4 garbage octets to the JSON, in order to counter
# cross-site scripting attacks. Therefore we must discard it so the
# json library won't choke.
-content = r.read().decode('utf-8')[4:]
-projects = sorted(filter(is_in_openstack_namespace, json.loads(content)))
+content = r.data.decode('utf-8')[4:]
+projects = sorted(json.loads(content))
-# Retrieve projects having no deb, puppet, ui or spec namespace as those
+# Retrieve projects having no deployment tool repo (such as deb,
+# puppet, ansible, etc.), infra repos, ui or spec namespace as those
# namespaces do not contains tempest plugins.
projects_list = [i for i in projects if not (
+ i.startswith('openstack-dev/') or
+ i.startswith('openstack-infra/') or
+ i.startswith('openstack/ansible-') or
+ i.startswith('openstack/charm-') or
+ i.startswith('openstack/cookbook-openstack-') or
+ i.startswith('openstack/devstack-') or
+ i.startswith('openstack/fuel-') or
i.startswith('openstack/deb-') or
i.startswith('openstack/puppet-') or
+ i.startswith('openstack/openstack-ansible-') or
+ i.startswith('x/deb-') or
+ i.startswith('x/fuel-') or
+ i.startswith('x/python-') or
+ i.startswith('zuul/') or
i.endswith('-ui') or
i.endswith('-specs'))]
found_plugins = list(filter(has_tempest_plugin, projects_list))
-# Every element of the found_plugins list begins with "openstack/".
-# We drop those initial 10 octets when printing the list.
+# We have tempest plugins not only in 'openstack/' namespace but also the
+# other name spaces such as 'airship/', 'x/', etc.
+# So, we print all of them here.
for project in found_plugins:
- print(project[10:])
+ print(project)
diff --git a/tools/generate-tempest-plugins-list.sh b/tools/generate-tempest-plugins-list.sh
index 17a4059..961cd09 100755
--- a/tools/generate-tempest-plugins-list.sh
+++ b/tools/generate-tempest-plugins-list.sh
@@ -28,9 +28,9 @@
# * the environment variable git_dir pointing to the location
# * of said git repositories
# ) OR (
-# * network access to the review.openstack.org Gerrit API
+# * network access to the review.opendev.org Gerrit API
# working directory
-# * network access to https://git.openstack.org/cgit
+# * network access to https://opendev.org/openstack
# ))
#
# If a file named doc/source/data/tempest-plugins-registry.header or
@@ -61,20 +61,37 @@
printf " ===\n"
}
+function print_plugin_table {
+ title_underline ${name_col_len}
+ printf "%-3s %-${name_col_len}s %s\n" "SR" "Plugin Name" "URL"
+ title_underline ${name_col_len}
+
+ i=0
+ for plugin in $1; do
+ i=$((i+1))
+ giturl="https://opendev.org/${plugin}"
+ printf "%-3s %-${name_col_len}s %s\n" "$i" "${plugin}" "${giturl}"
+ done
+
+ title_underline ${name_col_len}
+}
+
printf "\n\n"
-title_underline ${name_col_len}
-printf "%-3s %-${name_col_len}s %s\n" "SR" "Plugin Name" "URL"
-title_underline ${name_col_len}
+print_plugin_table "${sorted_plugins}"
-i=0
-for plugin in ${sorted_plugins}; do
- i=$((i+1))
- giturl="https://git.openstack.org/openstack/${plugin}"
- gitlink="https://git.openstack.org/cgit/openstack/${plugin}"
- printf "%-3s %-${name_col_len}s %s\n" "$i" "${plugin}" "\`${giturl} <${gitlink}>\`__"
-done
+printf "\n\n"
-title_underline ${name_col_len}
+# Print BLACKLIST
+if [[ -r doc/source/data/tempest-blacklisted-plugins-registry.header ]]; then
+ cat doc/source/data/tempest-blacklisted-plugins-registry.header
+fi
+
+blacklist=$(python tools/generate-tempest-plugins-list.py blacklist)
+name_col_len=$(echo "${blacklist}" | wc -L)
+name_col_len=$(( name_col_len + 20 ))
+
+printf "\n\n"
+print_plugin_table "${blacklist}"
printf "\n\n"
diff --git a/tools/tempest-integrated-gate-compute-blacklist.txt b/tools/tempest-integrated-gate-compute-blacklist.txt
new file mode 100644
index 0000000..8805262
--- /dev/null
+++ b/tools/tempest-integrated-gate-compute-blacklist.txt
@@ -0,0 +1,13 @@
+# This file includes the backlist of tests which need to be
+# skipped for Integrated-gate-compute template. Integrated-gate-compute template
+# needs to run only Nova, Neutron, Cinder and Glance related tests and rest all
+# tests will be skipped by below list.
+
+# Skip keystone and Swift API tests.
+tempest.api.identity
+tempest.api.object_storage
+
+# Skip Swift only scenario tests.
+tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_basic_ops
+tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_acl_anonymous_download
+tempest.scenario.test_volume_backup_restore.TestVolumeBackupRestore.test_volume_backup_restore
diff --git a/tools/tempest-integrated-gate-networking-blacklist.txt b/tools/tempest-integrated-gate-networking-blacklist.txt
new file mode 100644
index 0000000..9566f69
--- /dev/null
+++ b/tools/tempest-integrated-gate-networking-blacklist.txt
@@ -0,0 +1,17 @@
+# This file includes the backlist of tests which need to be
+# skipped for Integrated-gate-networking template.
+
+# Skip Cinder, Glance, keystone and Swift API tests.
+tempest.api.volume
+tempest.api.image
+tempest.api.object_storage
+tempest.api.identity
+
+# Skip Cinder, Glance and Swift only scenario tests.
+tempest.scenario.test_encrypted_cinder_volumes.TestEncryptedCinderVolumes.test_encrypted_cinder_volumes_luks
+tempest.scenario.test_encrypted_cinder_volumes.TestEncryptedCinderVolumes.test_encrypted_cinder_volumes_cryptsetup
+tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_basic_ops
+tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_acl_anonymous_download
+tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_boot_server_from_encrypted_volume_luks
+tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_image_defined_boot_from_volume
+tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_create_server_from_volume_snapshot
diff --git a/tools/tempest-integrated-gate-object-storage-blacklist.txt b/tools/tempest-integrated-gate-object-storage-blacklist.txt
new file mode 100644
index 0000000..064cf46
--- /dev/null
+++ b/tools/tempest-integrated-gate-object-storage-blacklist.txt
@@ -0,0 +1,17 @@
+# This file includes the backlist of tests which need to be
+# skipped for Integrated-gate-object-storage template. Integrated-gate-object-storage template
+# needs to run only Swift, Cinder and Glance related tests and rest all
+# tests will be skipped by below list.
+
+# Skip network, compute, keystone API tests.
+tempest.api.network
+tempest.api.compute
+tempest.api.identity
+
+# Skip network, compute, keystone only scenario tests
+tempest.scenario.test_network_advanced_server_ops.TestNetworkAdvancedServerOps.test_network_advanced_server_ops
+tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops
+tempest.scenario.test_network_v6.TestGettingAddress.test_security_groups_basic_ops
+tempest.scenario.test_server_advanced_ops.TestServerAdvancedOps.test_server_sequence_suspend_resume
+tempest.scenario.test_server_basic_ops.TestServerBasicOps.test_server_basic_ops
+tempest.scenario.test_server_multinode.TestServerMultinode.test_schedule_to_all_nodes
diff --git a/tools/tempest-integrated-gate-placement-blacklist.txt b/tools/tempest-integrated-gate-placement-blacklist.txt
new file mode 100644
index 0000000..efba796
--- /dev/null
+++ b/tools/tempest-integrated-gate-placement-blacklist.txt
@@ -0,0 +1,19 @@
+# This file includes the backlist of tests which need to be
+# skipped for Integrated-gate-placement template. Integrated-gate-placement template
+# needs to run only Nova and Neutron related tests and rest all
+# tests will be skipped by below list.
+
+# Skip Cinder, Glance, keystone and Swift API tests.
+tempest.api.volume
+tempest.api.image
+tempest.api.identity
+tempest.api.object_storage
+
+# Skip Cinder, Glance and Swift only scenario tests.
+tempest.scenario.test_encrypted_cinder_volumes.TestEncryptedCinderVolumes.test_encrypted_cinder_volumes_luks
+tempest.scenario.test_encrypted_cinder_volumes.TestEncryptedCinderVolumes.test_encrypted_cinder_volumes_cryptsetup
+tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_basic_ops
+tempest.scenario.test_object_storage_basic_ops.TestObjectStorageBasicOps.test_swift_acl_anonymous_download
+tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_boot_server_from_encrypted_volume_luks
+tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_image_defined_boot_from_volume
+tempest.scenario.test_volume_boot_pattern.TestVolumeBootPattern.test_create_server_from_volume_snapshot
diff --git a/tools/tempest-integrated-gate-storage-blacklist.txt b/tools/tempest-integrated-gate-storage-blacklist.txt
new file mode 100644
index 0000000..3900f96
--- /dev/null
+++ b/tools/tempest-integrated-gate-storage-blacklist.txt
@@ -0,0 +1,13 @@
+# This file includes the backlist of tests which need to be
+# skipped for Integrated-gate-storage template. Integrated-gate-storage template
+# needs to run only Cinder, Glance, Swift and Nova related tests and rest all
+# tests will be skipped by below list.
+
+# Skip network, keystone API tests.
+tempest.api.network
+tempest.api.identity
+
+# Skip network only scenario tests.
+tempest.scenario.test_network_advanced_server_ops.TestNetworkAdvancedServerOps.test_network_advanced_server_ops
+tempest.scenario.test_network_basic_ops.TestNetworkBasicOps.test_network_basic_ops
+tempest.scenario.test_network_v6.TestGettingAddress.test_security_groups_basic_ops
diff --git a/tools/tempest-plugin-sanity.sh b/tools/tempest-plugin-sanity.sh
index 6bb87c5..a087a4c 100644
--- a/tools/tempest-plugin-sanity.sh
+++ b/tools/tempest-plugin-sanity.sh
@@ -43,56 +43,25 @@
# 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 for a long time
-# (6 months or more)
-# TODO(masayukig): Some of these can be removed from BLACKLIST in the future.
-# barbican-tempest-plugin: https://review.openstack.org/#/c/634631/
-# cyborg-tempest-plugin: https://review.opendev.org/659687
-# intel-nfv-ci-tests: https://review.openstack.org/#/c/634640/
-# networking-ansible: https://review.openstack.org/#/c/634647/
-# networking-generic-switch: https://review.openstack.org/#/c/634846/
-# networking-l2gw-tempest-plugin: https://review.openstack.org/#/c/635093/
-# networking-midonet: https://review.openstack.org/#/c/635096/
-# networking-plumgrid: https://review.openstack.org/#/c/635096/
-# networking-spp: https://review.openstack.org/#/c/635098/
-# neutron-dynamic-routing: https://review.openstack.org/#/c/637718/
-# neutron-vpnaas: https://review.openstack.org/#/c/637719/
-# nova-lxd: https://review.openstack.org/#/c/638334/
-# valet: https://review.openstack.org/#/c/638339/
-# vitrage-tempest-plugin: https://review.openstack.org/#/c/639003/
-BLACKLIST="
-barbican-tempest-plugin
-cyborg-tempest-plugin
-intel-nfv-ci-tests
-networking-ansible
-networking-generic-switch
-networking-l2gw-tempest-plugin
-networking-midonet
-networking-plumgrid
-networking-spp
-neutron-dynamic-routing
-neutron-vpnaas
-nova-lxd
-valet
-vitrage-tempest-plugin
-"
+
+BLACKLIST="$(python tools/generate-tempest-plugins-list.py blacklist)"
# Function to clone project using zuul-cloner or from git
-function clone_project() {
+function clone_project {
if [ -e /usr/zuul-env/bin/zuul-cloner ]; then
/usr/zuul-env/bin/zuul-cloner --cache-dir /opt/git \
- https://git.openstack.org \
- openstack/"$1"
+ https://opendev.org \
+ "$1"
elif [ -e /usr/bin/git ]; then
- /usr/bin/git clone https://git.openstack.org/openstack/"$1" \
- openstack/"$1"
+ /usr/bin/git clone https://opendev.org/"$1" \
+ "$1"
fi
}
# function to create virtualenv to perform sanity operation
-function prepare_workspace() {
+function prepare_workspace {
SANITY_DIR=$(pwd)
virtualenv -p python3 --clear "$SANITY_DIR"/.venv
export TVENV="$SANITY_DIR/tools/with_venv.sh"
@@ -103,16 +72,16 @@
}
# Function to install project
-function install_project() {
- "$TVENV" pip install "$SANITY_DIR"/openstack/"$1"
+function install_project {
+ "$TVENV" pip install "$SANITY_DIR"/"$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
+ if [ -e "$SANITY_DIR"/"$1"/test-requirements.txt ]; then
+ "$TVENV" pip install -r "$SANITY_DIR"/"$1"/test-requirements.txt
fi
}
# Function to perform sanity checking on Tempest plugin
-function tempest_sanity() {
+function tempest_sanity {
"$TVENV" tempest init "$SANITY_DIR"/tempest_sanity && \
cd "$SANITY_DIR"/tempest_sanity && \
"$TVENV" tempest list-plugins && \
@@ -125,13 +94,13 @@
# Remove the sanity workspace in case of remaining
rm -fr "$SANITY_DIR"/tempest_sanity
# Remove the project directory after sanity run
- rm -fr "$SANITY_DIR"/openstack/"$1"
+ rm -fr "$SANITY_DIR"/"$1"
return $retval
}
# Function to run sanity check on each project
-function plugin_sanity_check() {
+function plugin_sanity_check {
prepare_workspace && \
clone_project "$1" && \
install_project "$1" && \
@@ -152,8 +121,10 @@
fi
done
+echo "Passed Plugins: $passed_plugin"
+echo "Failed Plugins: $failed_plugin"
+
# Check for failed status
if [[ -n $failed_plugin ]]; then
- echo "Failed Plugins: $failed_plugin"
exit 1
fi
diff --git a/tools/verify-ipv6-only-deployments.sh b/tools/verify-ipv6-only-deployments.sh
new file mode 100755
index 0000000..2596395
--- /dev/null
+++ b/tools/verify-ipv6-only-deployments.sh
@@ -0,0 +1,92 @@
+#!/bin/bash
+#
+#
+# NOTE(gmann): This script is used in 'devstack-tempest-ipv6' zuul job to verify that
+# services are deployed on IPv6 properly or not. This will capture if any devstck or devstack
+# plugins are missing the required setting to listen on IPv6 address. This is run as part of
+# run phase of zuul job and before test run. Child job of 'devstack-tempest-ipv6'
+# can expand the IPv6 verification specific to project by defining the new post-run script which
+# will run along with this base script.
+# If there are more common verification for IPv6 then we can always extent this script.
+
+# Keep track of the DevStack directory
+TOP_DIR=$(cd $(dirname "$0")/../../devstack && pwd)
+source $TOP_DIR/stackrc
+source $TOP_DIR/openrc admin admin
+
+function verify_devstack_ipv6_setting {
+ local _service_host=''
+ _service_host=$(echo $SERVICE_HOST | tr -d [])
+ local _host_ipv6=''
+ _host_ipv6=$(echo $HOST_IPV6 | tr -d [])
+ local _service_listen_address=''
+ _service_listen_address=$(echo $SERVICE_LISTEN_ADDRESS | tr -d [])
+ local _service_local_host=''
+ _service_local_host=$(echo $SERVICE_LOCAL_HOST | tr -d [])
+ if [[ "$SERVICE_IP_VERSION" != 6 ]]; then
+ echo $SERVICE_IP_VERSION "SERVICE_IP_VERSION is not set to 6 which is must for devstack to deploy services with IPv6 address."
+ exit 1
+ fi
+ is_service_host_ipv6=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_service_host'"))')
+ if [[ "$is_service_host_ipv6" != "True" ]]; then
+ echo $SERVICE_HOST "SERVICE_HOST is not ipv6 which means devstack cannot deploy services on IPv6 address."
+ exit 1
+ fi
+ is_host_ipv6=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_host_ipv6'"))')
+ if [[ "$is_host_ipv6" != "True" ]]; then
+ echo $HOST_IPV6 "HOST_IPV6 is not ipv6 which means devstack cannot deploy services on IPv6 address."
+ exit 1
+ fi
+ is_service_listen_address=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_service_listen_address'"))')
+ if [[ "$is_service_listen_address" != "True" ]]; then
+ echo $SERVICE_LISTEN_ADDRESS "SERVICE_LISTEN_ADDRESS is not ipv6 which means devstack cannot deploy services on IPv6 address."
+ exit 1
+ fi
+ is_service_local_host=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$_service_local_host'"))')
+ if [[ "$is_service_local_host" != "True" ]]; then
+ echo $SERVICE_LOCAL_HOST "SERVICE_LOCAL_HOST is not ipv6 which means devstack cannot deploy services on IPv6 address."
+ exit 1
+ fi
+ echo "Devstack is properly configured with IPv6"
+ echo "SERVICE_IP_VERSION: " $SERVICE_IP_VERSION "HOST_IPV6: " $HOST_IPV6 "SERVICE_HOST: " $SERVICE_HOST "SERVICE_LISTEN_ADDRESS: " $SERVICE_LISTEN_ADDRESS "SERVICE_LOCAL_HOST: " $SERVICE_LOCAL_HOST
+}
+
+function sanity_check_system_ipv6_enabled {
+ system_ipv6_enabled=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_ipv6_enabled())')
+ if [[ $system_ipv6_enabled != "True" ]]; then
+ echo "IPv6 is disabled in system"
+ exit 1
+ fi
+ echo "IPv6 is enabled in system"
+}
+
+function verify_service_listen_address_is_ipv6 {
+ local endpoints_verified=False
+ local all_ipv6=True
+ endpoints=$(openstack endpoint list -f value -c URL)
+ for endpoint in ${endpoints}; do
+ local endpoint_address=''
+ endpoint_address=$(echo "$endpoint" | awk -F/ '{print $3}' | awk -F] '{print $1}')
+ endpoint_address=$(echo $endpoint_address | tr -d [])
+ local is_endpoint_ipv6=''
+ is_endpoint_ipv6=$(python3 -c 'import oslo_utils.netutils as nutils; print(nutils.is_valid_ipv6("'$endpoint_address'"))')
+ if [[ "$is_endpoint_ipv6" != "True" ]]; then
+ all_ipv6=False
+ echo $endpoint ": This is not ipv6 endpoint which means corresponding service is not listening on IPv6 address."
+ continue
+ fi
+ endpoints_verified=True
+ done
+ if [[ "$all_ipv6" == "False" ]] || [[ "$endpoints_verified" == "False" ]]; then
+ exit 1
+ fi
+ echo "All services deployed by devstack is on IPv6 endpoints"
+ echo $endpoints
+}
+
+#First thing to verify if system has IPv6 enabled or not
+sanity_check_system_ipv6_enabled
+#Verify whether devstack is configured properly with IPv6 setting
+verify_devstack_ipv6_setting
+#Get all registrfed endpoints by devstack in keystone and verify that each endpoints address is IPv6.
+verify_service_listen_address_is_ipv6
diff --git a/tox.ini b/tox.ini
index 9bee3dd..effd400 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = pep8,py36,py37,py27,pip-check-reqs
+envlist = pep8,py36,py37,py27,bashate,pip-check-reqs
minversion = 2.3.1
skipsdist = True
@@ -9,7 +9,7 @@
VIRTUAL_ENV={envdir}
OS_TEST_PATH=./tempest/test_discover
deps =
- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/requirements.txt
[testenv]
@@ -25,7 +25,7 @@
install_command = pip install {opts} {packages}
whitelist_externals = *
deps =
- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/requirements.txt
-r{toxinidir}/test-requirements.txt
commands =
@@ -62,7 +62,7 @@
deps = {[tempestenv]deps}
commands =
find . -type f -name "*.pyc" -delete
- tempest run --regex {posargs}
+ tempest run --regex {posargs:''}
[testenv:all-plugin]
# DEPRECATED
@@ -82,7 +82,7 @@
echo "WARNING: The all-plugin env is deprecated and will be removed"
echo "WARNING Please use the 'all' environment for Tempest plugins."
find . -type f -name "*.pyc" -delete
- tempest run --regex {posargs}
+ tempest run --regex {posargs:''}
[testenv:all-site-packages]
sitepackages = True
@@ -93,7 +93,7 @@
deps = {[tempestenv]deps}
commands =
find . -type f -name "*.pyc" -delete
- tempest run --regex {posargs}
+ tempest run --regex {posargs:''}
[testenv:full]
envdir = .tox/tempest
@@ -118,6 +118,66 @@
find . -type f -name "*.pyc" -delete
tempest run --regex '(^tempest\.scenario.*)|(?!.*\[.*\bslow\b.*\])(^tempest\.api)' {posargs}
+[testenv:integrated-network]
+envdir = .tox/tempest
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
+# The regex below is used to select which tests to run and exclude the slow tag and
+# tests listed in blacklist file:
+commands =
+ find . -type f -name "*.pyc" -delete
+ tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' --blacklist_file ./tools/tempest-integrated-gate-networking-blacklist.txt {posargs}
+ tempest run --combine --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)' --blacklist_file ./tools/tempest-integrated-gate-networking-blacklist.txt {posargs}
+
+[testenv:integrated-compute]
+envdir = .tox/tempest
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
+# The regex below is used to select which tests to run and exclude the slow tag and
+# tests listed in blacklist file:
+commands =
+ find . -type f -name "*.pyc" -delete
+ tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' --blacklist_file ./tools/tempest-integrated-gate-compute-blacklist.txt {posargs}
+ tempest run --combine --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)' --blacklist_file ./tools/tempest-integrated-gate-compute-blacklist.txt {posargs}
+
+[testenv:integrated-placement]
+envdir = .tox/tempest
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
+# The regex below is used to select which tests to run and exclude the slow tag and
+# tests listed in blacklist file:
+commands =
+ find . -type f -name "*.pyc" -delete
+ tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' --blacklist_file ./tools/tempest-integrated-gate-placement-blacklist.txt {posargs}
+ tempest run --combine --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)' --blacklist_file ./tools/tempest-integrated-gate-placement-blacklist.txt {posargs}
+
+[testenv:integrated-storage]
+envdir = .tox/tempest
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
+# The regex below is used to select which tests to run and exclude the slow tag and
+# tests listed in blacklist file:
+commands =
+ find . -type f -name "*.pyc" -delete
+ tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' --blacklist_file ./tools/tempest-integrated-gate-storage-blacklist.txt {posargs}
+ tempest run --combine --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)' --blacklist_file ./tools/tempest-integrated-gate-storage-blacklist.txt {posargs}
+
+[testenv:integrated-object-storage]
+envdir = .tox/tempest
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
+# The regex below is used to select which tests to run and exclude the slow tag and
+# tests listed in blacklist file:
+commands =
+ find . -type f -name "*.pyc" -delete
+ tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' --blacklist_file ./tools/tempest-integrated-gate-object-storage-blacklist.txt {posargs}
+ tempest run --combine --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.scenario)' --blacklist_file ./tools/tempest-integrated-gate-object-storage-blacklist.txt {posargs}
+
[testenv:full-serial]
envdir = .tox/tempest
sitepackages = {[tempestenv]sitepackages}
@@ -171,9 +231,21 @@
find . -type f -name "*.pyc" -delete
tempest run --serial --regex '\[.*\bslow\b.*\]' {posargs}
+[testenv:ipv6-only]
+envdir = .tox/tempest
+sitepackages = {[tempestenv]sitepackages}
+setenv = {[tempestenv]setenv}
+deps = {[tempestenv]deps}
+# Run only smoke and ipv6 tests. This env is used to tests
+# the ipv6 deployments and basic tests run fine so that we can
+# verify that services listen on IPv6 address.
+commands =
+ find . -type f -name "*.pyc" -delete
+ tempest run --regex '\[.*\bsmoke|ipv6|test_network_v6\b.*\]' {posargs}
+
[testenv:venv]
deps =
- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/requirements.txt
-r{toxinidir}/doc/requirements.txt
commands = {posargs}
@@ -188,7 +260,7 @@
[testenv:docs]
basepython = python3
deps =
- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/requirements.txt
-r{toxinidir}/doc/requirements.txt
commands =
@@ -196,6 +268,15 @@
sphinx-build -W -b html doc/source doc/build/html
whitelist_externals = rm
+[testenv:pdf-docs]
+basepython = python3
+deps = {[testenv:docs]deps}
+whitelist_externals =
+ make
+commands =
+ sphinx-build -W -b latex doc/source doc/build/pdf
+ make -C doc/build/pdf
+
[testenv:pep8]
deps =
-r{toxinidir}/test-requirements.txt
@@ -221,7 +302,7 @@
import_exceptions = tempest.services
[flake8]
-# E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved. For further detail see https://review.openstack.org/#/c/36788/
+# E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved. For further detail see https://review.opendev.org/#/c/36788/
# E123 skipped because it is ignored by default in the default pep8
# E129 skipped because it is too limiting when combined with other rules
# W504 skipped because it is overeager and unnecessary
@@ -234,7 +315,7 @@
[testenv:releasenotes]
basepython = python3
deps =
- -c{env:UPPER_CONSTRAINTS_FILE:https://git.openstack.org/cgit/openstack/requirements/plain/upper-constraints.txt}
+ -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
-r{toxinidir}/requirements.txt
-r{toxinidir}/doc/requirements.txt
commands =
@@ -243,6 +324,20 @@
-b html releasenotes/source releasenotes/build/html
whitelist_externals = rm
+[testenv:bashate]
+basepython = python3
+# if you want to test out some changes you have made to bashate
+# against tempest, just set BASHATE_INSTALL_PATH=/path/... to your
+# modified bashate tree
+deps =
+ {env:BASHATE_INSTALL_PATH:bashate}
+whitelist_externals = bash
+commands = bash -c "find {toxinidir}/tools \
+ -not \( -type d -name .?\* -prune \) \
+ -type f \
+ -name \*.sh \
+ -print0 | xargs -0 bashate -v -eE005,E042 -i E006"
+
[testenv:pip-check-reqs]
# Do not install test-requirements as that will pollute the virtualenv for
# determining missing packages.