Merge "Added CONF.validation entry security_method"
diff --git a/.gitignore b/.gitignore
index f584532..efba45e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,4 +19,4 @@
.coverage*
!.coveragerc
cover/
-doc/source/_static/tempest.conf
+doc/source/_static/tempest.conf.sample
diff --git a/HACKING.rst b/HACKING.rst
index 6ddb8ac..e15e213 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -15,6 +15,8 @@
- [T106] vim configuration should not be kept in source files.
- [T107] Check that a service tag isn't in the module path
- [T108] Check no hyphen at the end of rand_name() argument
+- [T109] Cannot use testtools.skip decorator; instead use
+ decorators.skip_because from tempest-lib
- [N322] Method's default argument shouldn't be mutable
Test Data/Configuration
@@ -72,11 +74,10 @@
Most other assert method can include more information by default.
For example ``self.assertIn`` can include the whole set.
-It is recommended to use testtools matcher for the more tricky assertions.
-`[doc] <http://testtools.readthedocs.org/en/latest/for-test-authors.html#matchers>`_
+It is recommended to use testtools `matcher`_ for the more tricky assertions.
+You can implement your own specific `matcher`_ as well.
-You can implement your own specific matcher as well.
-`[doc] <http://testtools.readthedocs.org/en/latest/for-test-authors.html#writing-your-own-matchers>`_
+.. _matcher: http://testtools.readthedocs.org/en/latest/for-test-authors.html#matchers
If the test case fails you can see the related logs and the information
carried by the exception (exception class, backtrack and exception info).
@@ -158,8 +159,8 @@
sections for the test (one of those is mandatory):
- A resource (part of the URL of the request): Resources needed for a test
- must be created in `setUpClass` and registered with `set_resource` e.g.:
- `cls.set_resource("server", server['id'])`
+ must be created in `setUpClass` and registered with `set_resource` e.g.:
+ `cls.set_resource("server", server['id'])`
- A json schema: defines properties for a request.
@@ -319,7 +320,7 @@
Every function that provides a test must have an ``idempotent_id`` decorator
that is a unique ``uuid-4`` instance. This ID is used to complement the fully
-qualified test name and track test funcionality through refactoring. The
+qualified test name and track test functionality through refactoring. The
format of the metadata looks like::
@test.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
diff --git a/README.rst b/README.rst
index 7a7dfa6..7108eaf 100644
--- a/README.rst
+++ b/README.rst
@@ -37,57 +37,61 @@
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.
+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.
-The easiest way to create a configuration file is to generate a sample
-in the ``etc/`` directory ::
+#. You first need to install Tempest this is done with pip, after you check out
+ the Tempest repo you simply run something like::
- $> cd $TEMPEST_ROOT_DIR
- $> oslo-config-generator --config-file \
- tools/config/config-generator.tempest.conf \
- --output-file etc/tempest.conf
+ $ pip install tempest
-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.
+ 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.
-.. note::
+#. Installing Tempest will create a /etc/tempest dir which will contain the
+ sample config file packaged with Tempest. The contents of /etc/tempest will
+ be copied to all local working dirs, so if there is any common configuration
+ you'd like to be shared between anyone setting up local Tempest working dirs
+ it's recommended that you copy or rename tempest.conf.sample to tempest.conf
+ and make those changes to that file in /etc/tempest
- 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.
+#. Setup a local working Tempest dir. This is done using the tempest init
+ command::
-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.
+ tempest init cloud-01
-After setting up your configuration file, you can execute the set of Tempest
-tests by using ``testr`` ::
+ works the same as::
- $> testr run --parallel
+ mkdir cloud-01 && cd cloud-01 && tempest init
-.. _testr: http://testrepository.readthedocs.org/en/latest/MANUAL.html
+ 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.
-To run one single test serially ::
+#. 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.
- $> testr run tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server
+#. Once the configuration is done you're now ready to run Tempest. This can
+ be done with testr directly or any `testr`_ based test runner, like
+ `ostestr`_. For example, from the working dir running::
-Alternatively, you can use the run_tempest.sh script which will create a venv
-and run the tests or use tox to do the same. Tox also contains several existing
-job configurations. For example::
+ $ ostestr --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty))'
- $> tox -efull
+ will run the same set of tests as the default gate jobs.
-which will run the same set of tests as the OpenStack gate. (it's exactly how
-the gate invokes Tempest) Or::
-
- $> tox -esmoke
-
-to run the tests tagged as smoke.
-
+.. _testr: https://testrepository.readthedocs.org/en/latest/MANUAL.html
+.. _ostestr: http://docs.openstack.org/developer/os-testr/
Configuration
-------------
@@ -146,3 +150,60 @@
there might be uncaught issues running on Python 3.4. So until there is a gating
job which does a full Tempest run using Python 3.4 there isn't any guarantee
that running Tempest under Python 3.4 is bug free.
+
+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 \
+ tools/config/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
+
+Alternatively, you can use the run_tempest.sh script which will create a venv
+and run the tests or use tox to do the same. Tox also contains several existing
+job configurations. For example::
+
+ $> tox -efull
+
+which will run the same set of tests as the OpenStack gate. (it's exactly how
+the gate invokes Tempest) Or::
+
+ $> tox -esmoke
+
+to run the tests tagged as smoke.
diff --git a/REVIEWING.rst b/REVIEWING.rst
index 74bd2ad..f7334ad 100644
--- a/REVIEWING.rst
+++ b/REVIEWING.rst
@@ -34,7 +34,7 @@
Reject Copy and Paste Test Code
-------------------------
+-------------------------------
When creating new tests that are similar to existing tests it is tempting to
simply copy the code and make a few modifications. This increases code size and
the maintenance burden. Such changes should not be approved if it is easy to
@@ -51,6 +51,19 @@
whether to skip or not.
+Configuration Options
+---------------------
+With the introduction of the tempest external test plugin interface we needed
+to provide a stable contract for tempest's configuration options. This means
+we can no longer simply remove a configuration option when it's no longer used.
+Patches proposed that remove options without a deprecation cycle should not
+be approved. Similarly when changing default values with configuration we need
+to similarly be careful that we don't break existing functionality. Also, when
+adding options, just as before, we need to weigh the benefit of adding an
+additional option against the complexity and maintenance overhead having it
+costs.
+
+
Test Documentation
------------------
When a new test is being added refer to the :ref:`TestDocumentation` section in
diff --git a/doc/source/account_generator.rst b/doc/source/account_generator.rst
index 1c30473..032a20d 100644
--- a/doc/source/account_generator.rst
+++ b/doc/source/account_generator.rst
@@ -1,5 +1,5 @@
---------------------------------
+--------------------------------------
Tempest Test-Account Generator Utility
---------------------------------
+--------------------------------------
-.. automodule:: tempest.cmd.account_generator
\ No newline at end of file
+.. automodule:: tempest.cmd.account_generator
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 3ec25ea..f85899b 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -15,18 +15,6 @@
import os
import subprocess
-# Build a tempest sample config file:
-def build_sample_config(app):
- root_dir = os.path.dirname(
- os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- subprocess.call(["oslo-config-generator", "--config-file",
- "tools/config/config-generator.tempest.conf",
- "--output-file", "doc/source/_static/tempest.conf"],
- cwd=root_dir)
-
-def setup(app):
- app.connect('builder-inited', build_sample_config)
-
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
@@ -42,9 +30,13 @@
extensions = ['sphinx.ext.autodoc',
'sphinx.ext.todo',
'sphinx.ext.viewcode',
- 'oslosphinx'
+ 'oslosphinx',
+ 'oslo_config.sphinxconfiggen',
]
+config_generator_config_file = '../../tools/config/config-generator.tempest.conf'
+sample_config_basename = '_static/tempest'
+
todo_include_todos = True
# Add any paths that contain templates here, relative to this directory.
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 3c109b5..ec430b7 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -6,7 +6,8 @@
This guide is a starting point for configuring tempest. It aims to elaborate
on and explain some of the mandatory and common configuration settings and how
they are used in conjunction. The source of truth on each option is the sample
-config file which explains the purpose of each individual option.
+config file which explains the purpose of each individual option. You can see
+the sample config file here: :ref:`tempest-sampleconf`
Lock Path
---------
diff --git a/doc/source/index.rst b/doc/source/index.rst
index e9f2161..fe6074f 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -24,7 +24,6 @@
field_guide/index
field_guide/api
- field_guide/cli
field_guide/scenario
field_guide/stress
field_guide/thirdparty
diff --git a/doc/source/sampleconf.rst b/doc/source/sampleconf.rst
index 2a72971..c290140 100644
--- a/doc/source/sampleconf.rst
+++ b/doc/source/sampleconf.rst
@@ -8,7 +8,6 @@
if you are having issues with an option, please compare your version of
Tempest with the version of this documentation.
-The sample configuration can also be viewed in `file form <_static/tempest.conf>`_.
+The sample configuration can also be viewed in `file form <_static/tempest.conf.sample>`_.
-.. include:: _static/tempest.conf
- :code:
+.. literalinclude:: _static/tempest.conf.sample
diff --git a/requirements.txt b/requirements.txt
index cc2a187..b25b9d3 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
# 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.
-pbr<2.0,>=1.4
+pbr<2.0,>=1.6
cliff>=1.14.0 # Apache-2.0
anyjson>=0.3.3
httplib2>=0.7.5
@@ -9,11 +9,11 @@
testtools>=1.4.0
boto>=2.32.1
paramiko>=1.13.0
-netaddr>=0.7.12
+netaddr!=0.7.16,>=0.7.12
testrepository>=0.0.18
pyOpenSSL>=0.14
oslo.concurrency>=2.3.0 # Apache-2.0
-oslo.config>=2.1.0 # Apache-2.0
+oslo.config>=2.3.0 # Apache-2.0
oslo.i18n>=1.5.0 # Apache-2.0
oslo.log>=1.8.0 # Apache-2.0
oslo.serialization>=1.4.0 # Apache-2.0
diff --git a/setup.cfg b/setup.cfg
index ab40f12..46e21f1 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -42,5 +42,8 @@
build-dir = doc/build
source-dir = doc/source
+[pbr]
+warnerrors = True
+
[wheel]
universal = 1
diff --git a/tempest/README.rst b/tempest/README.rst
index fec2874..f93a173 100644
--- a/tempest/README.rst
+++ b/tempest/README.rst
@@ -57,7 +57,7 @@
stress job.
:ref:`third_party_field_guide`
------------------------------
+------------------------------
Many openstack components include 3rdparty API support. It is
completely legitimate for Tempest to include tests of 3rdparty APIs,
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 7a3e8db..0a11d52 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -43,8 +43,6 @@
# Non admin tenant ID
cls.tenant_id = cls.flavors_client.tenant_id
- # Compute admin tenant ID
- cls.adm_tenant_id = cls.client.tenant_id
cls.flavor_name_prefix = 'test_flavor_access_'
cls.ram = 512
cls.vcpus = 1
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index c8ca938..e979616 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -80,5 +80,6 @@
self.assertNotEqual(0, len(ips_list))
for ip in netaddr.IPNetwork(self.ip_range).iter_hosts():
self.assertIn(str(ip), map(lambda x: x['address'], ips_list))
- body = self.client.delete_floating_ips_bulk(self.ip_range)
- self.assertEqual(self.ip_range, body.data)
+ body = (self.client.delete_floating_ips_bulk(self.ip_range)
+ ['floating_ips_bulk_delete'])
+ self.assertEqual(self.ip_range, body)
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index d6bc6f5..410f7b7 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -81,7 +81,7 @@
return server_id
def _volume_clean_up(self, server_id, volume_id):
- body = self.volumes_client.show_volume(volume_id)
+ body = self.volumes_client.show_volume(volume_id)['volume']
if body['status'] == 'in-use':
self.servers_client.detach_volume(server_id, volume_id)
self.volumes_client.wait_for_volume_status(volume_id, 'available')
@@ -111,7 +111,8 @@
self._migrate_server_to(server_id, target_host)
waiters.wait_for_server_status(self.servers_client, server_id, state)
- migration_list = self.admin_migration_client.list_migrations()
+ migration_list = (self.admin_migration_client.list_migrations()
+ ['migrations'])
msg = ("Live Migration failed. Migrations list for Instance "
"%s: [" % server_id)
@@ -157,7 +158,8 @@
actual_host = self._get_host_for_server(server_id)
target_host = self._get_host_other_than(actual_host)
- volume = self.volumes_client.create_volume(display_name='test')
+ volume = self.volumes_client.create_volume(
+ display_name='test')['volume']
self.volumes_client.wait_for_volume_status(volume['id'],
'available')
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index 7d69e13..f81d665 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -45,11 +45,11 @@
self.servers_client.resize_server(server_id, self.flavor_ref_alt)
waiters.wait_for_server_status(self.servers_client,
server_id, 'VERIFY_RESIZE')
- self.servers_client.confirm_resize(server_id)
+ self.servers_client.confirm_resize_server(server_id)
waiters.wait_for_server_status(self.servers_client,
server_id, 'ACTIVE')
- body = self.client.list_migrations()
+ body = self.client.list_migrations()['migrations']
instance_uuids = [x['instance_uuid'] for x in body]
self.assertIn(server_id, instance_uuids)
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 3416eae..ef96f9b 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -59,7 +59,7 @@
# Admin can get the default resource quota set for a tenant
expected_quota_set = self.default_quota_set | set(['id'])
quota_set = self.adm_client.show_default_quota_set(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
self.assertEqual(quota_set['id'], self.demo_tenant_id)
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
@@ -68,7 +68,7 @@
def test_update_all_quota_resources_for_tenant(self):
# Admin can update all the resource quota limits for a tenant
default_quota_set = self.adm_client.show_default_quota_set(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
new_quota_set = {'injected_file_content_bytes': 20480,
'metadata_items': 256, 'injected_files': 10,
'ram': 10240, 'floating_ips': 20, 'fixed_ips': 10,
@@ -79,7 +79,7 @@
quota_set = self.adm_client.update_quota_set(
self.demo_tenant_id,
force=True,
- **new_quota_set)
+ **new_quota_set)['quota_set']
default_quota_set.pop('id')
# NOTE(PhilDay) The following is safe as we're not updating these
@@ -107,7 +107,7 @@
self.addCleanup(identity_client.delete_tenant, tenant_id)
self.adm_client.update_quota_set(tenant_id, ram='5120')
- quota_set = self.adm_client.show_quota_set(tenant_id)
+ quota_set = self.adm_client.show_quota_set(tenant_id)['quota_set']
self.assertEqual(5120, quota_set['ram'])
# Verify that GET shows the updated quota set of user
@@ -126,8 +126,8 @@
self.adm_client.update_quota_set(tenant_id,
user_id=user_id,
ram='2048')
- quota_set = self.adm_client.show_quota_set(tenant_id,
- user_id=user_id)
+ quota_set = self.adm_client.show_quota_set(
+ tenant_id, user_id=user_id)['quota_set']
self.assertEqual(2048, quota_set['ram'])
@test.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
@@ -140,14 +140,15 @@
description=tenant_desc)
tenant_id = tenant['id']
self.addCleanup(identity_client.delete_tenant, tenant_id)
- quota_set_default = self.adm_client.show_quota_set(tenant_id)
+ quota_set_default = (self.adm_client.show_quota_set(tenant_id)
+ ['quota_set'])
ram_default = quota_set_default['ram']
self.adm_client.update_quota_set(tenant_id, ram='5120')
self.adm_client.delete_quota_set(tenant_id)
- quota_set_new = self.adm_client.show_quota_set(tenant_id)
+ quota_set_new = self.adm_client.show_quota_set(tenant_id)['quota_set']
self.assertEqual(ram_default, quota_set_new['ram'])
@@ -169,7 +170,7 @@
def _restore_default_quotas(self, original_defaults):
LOG.debug("restoring quota class defaults")
self.adm_client.update_quota_class_set(
- 'default', **original_defaults)
+ 'default', **original_defaults)['quota_class_set']
# NOTE(sdague): this test is problematic as it changes
# global state, and possibly needs to be part of a set of
@@ -178,7 +179,8 @@
@test.idempotent_id('7932ab0f-5136-4075-b201-c0e2338df51a')
def test_update_default_quotas(self):
LOG.debug("get the current 'default' quota class values")
- body = self.adm_client.show_quota_class_set('default')
+ body = (self.adm_client.show_quota_class_set('default')
+ ['quota_class_set'])
self.assertIn('id', body)
self.assertEqual('default', body.pop('id'))
# restore the defaults when the test is done
@@ -190,8 +192,8 @@
# to a very small number which causes issues.
body[quota] = default + 100
LOG.debug("update limits for the default quota class set")
- update_body = self.adm_client.update_quota_class_set('default',
- **body)
+ update_body = self.adm_client.update_quota_class_set(
+ 'default', **body)['quota_class_set']
LOG.debug("assert that the response has all of the changed values")
self.assertThat(update_body.items(),
matchers.ContainsAll(body.items()))
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index b4fc749..758cd43 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -55,13 +55,14 @@
@test.idempotent_id('91058876-9947-4807-9f22-f6eb17140d9b')
def test_create_server_when_cpu_quota_is_full(self):
# Disallow server creation when tenant's vcpu quota is full
- quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
+ quota_set = (self.adm_client.show_quota_set(self.demo_tenant_id)
+ ['quota_set'])
default_vcpu_quota = quota_set['cores']
vcpu_quota = 0 # Set the quota to zero to conserve resources
- quota_set = self.adm_client.update_quota_set(self.demo_tenant_id,
- force=True,
- cores=vcpu_quota)
+ self.adm_client.update_quota_set(self.demo_tenant_id,
+ force=True,
+ cores=vcpu_quota)
self.addCleanup(self.adm_client.update_quota_set, self.demo_tenant_id,
cores=default_vcpu_quota)
@@ -72,7 +73,8 @@
@test.idempotent_id('6fdd7012-584d-4327-a61c-49122e0d5864')
def test_create_server_when_memory_quota_is_full(self):
# Disallow server creation when tenant's memory quota is full
- quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
+ quota_set = (self.adm_client.show_quota_set(self.demo_tenant_id)
+ ['quota_set'])
default_mem_quota = quota_set['ram']
mem_quota = 0 # Set the quota to zero to conserve resources
@@ -89,7 +91,8 @@
@test.idempotent_id('7c6be468-0274-449a-81c3-ac1c32ee0161')
def test_create_server_when_instances_quota_is_full(self):
# Once instances quota limit is reached, disallow server creation
- quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
+ quota_set = (self.adm_client.show_quota_set(self.demo_tenant_id)
+ ['quota_set'])
default_instances_quota = quota_set['instances']
instances_quota = 0 # Set quota to zero to disallow server creation
@@ -108,17 +111,17 @@
def test_security_groups_exceed_limit(self):
# Negative test: Creation Security Groups over limit should FAIL
- quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
+ quota_set = (self.adm_client.show_quota_set(self.demo_tenant_id)
+ ['quota_set'])
default_sg_quota = quota_set['security_groups']
# Set the quota to number of used security groups
- sg_quota = self.limits_client.show_limits()['absolute'][
+ sg_quota = self.limits_client.show_limits()['limits']['absolute'][
'totalSecurityGroupsUsed']
- quota_set =\
- self.adm_client.update_quota_set(self.demo_tenant_id,
- force=True,
- security_groups=sg_quota)
+ self.adm_client.update_quota_set(self.demo_tenant_id,
+ force=True,
+ security_groups=sg_quota)
self.addCleanup(self.adm_client.update_quota_set,
self.demo_tenant_id,
@@ -140,15 +143,14 @@
# Negative test: Creation of Security Group Rules should FAIL
# when we reach limit maxSecurityGroupRules
- quota_set = self.adm_client.show_quota_set(self.demo_tenant_id)
+ quota_set = (self.adm_client.show_quota_set(self.demo_tenant_id)
+ ['quota_set'])
default_sg_rules_quota = quota_set['security_group_rules']
sg_rules_quota = 0 # Set the quota to zero to conserve resources
- quota_set =\
- self.adm_client.update_quota_set(
- self.demo_tenant_id,
- force=True,
- security_group_rules=sg_rules_quota)
+ self.adm_client.update_quota_set(self.demo_tenant_id,
+ force=True,
+ security_group_rules=sg_rules_quota)
self.addCleanup(self.adm_client.update_quota_set,
self.demo_tenant_id,
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index d65f335..c2dc94c 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -69,7 +69,8 @@
self.useFixture(fixtures.LockFixture('compute_quotas'))
flavor_name = data_utils.rand_name("flavor")
flavor_id = self._get_unused_flavor_id()
- quota_set = self.quotas_client.show_default_quota_set(self.tenant_id)
+ quota_set = (self.quotas_client.show_default_quota_set(self.tenant_id)
+ ['quota_set'])
ram = int(quota_set['ram']) + 1
vcpus = 8
disk = 10
@@ -93,7 +94,8 @@
flavor_name = data_utils.rand_name("flavor")
flavor_id = self._get_unused_flavor_id()
ram = 512
- quota_set = self.quotas_client.show_default_quota_set(self.tenant_id)
+ quota_set = (self.quotas_client.show_default_quota_set(self.tenant_id)
+ ['quota_set'])
vcpus = int(quota_set['cores']) + 1
disk = 10
flavor_ref = self.flavors_client.create_flavor(name=flavor_name,
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index bf2e0c1..1f53f9a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -75,7 +75,6 @@
cls.networks_client = cls.os.networks_client
cls.limits_client = cls.os.limits_client
cls.volumes_extensions_client = cls.os.volumes_extensions_client
- cls.volumes_client = cls.os.volumes_client
cls.interfaces_client = cls.os.interfaces_client
cls.fixed_ips_client = cls.os.fixed_ips_client
cls.availability_zone_client = cls.os.availability_zone_client
@@ -89,6 +88,12 @@
cls.migrations_client = cls.os.migrations_client
cls.security_group_default_rules_client = (
cls.os.security_group_default_rules_client)
+ cls.versions_client = cls.os.compute_versions_client
+
+ if CONF.volume_feature_enabled.api_v1:
+ cls.volumes_client = cls.os.volumes_client
+ else:
+ cls.volumes_client = cls.os.volumes_v2_client
@classmethod
def resource_setup(cls):
@@ -290,7 +295,7 @@
if 'wait_until' in kwargs:
waiters.wait_for_image_status(cls.images_client,
image_id, kwargs['wait_until'])
- image = cls.images_client.show_image(image_id)
+ image = cls.images_client.show_image(image_id)['image']
if kwargs['wait_until'] == 'ACTIVE':
if kwargs.get('wait_for_server', True):
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index d16c020..975b850 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -64,7 +64,8 @@
def test_list_image_metadata(self):
# All metadata key/value pairs for an image should be returned
resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'os_version': 'value1', 'os_distro': 'value2'}
+ expected = {'metadata': {
+ 'os_version': 'value1', 'os_distro': 'value2'}}
self.assertEqual(expected, resp_metadata)
@test.idempotent_id('ece7befc-d3ce-42a4-b4be-c3067a418c29')
@@ -74,7 +75,8 @@
self.client.set_image_metadata(self.image_id,
req_metadata)
- resp_metadata = self.client.list_image_metadata(self.image_id)
+ resp_metadata = (self.client.list_image_metadata(self.image_id)
+ ['metadata'])
self.assertEqual(req_metadata, resp_metadata)
@test.idempotent_id('7b491c11-a9d5-40fe-a696-7f7e03d3fea2')
@@ -85,16 +87,17 @@
req_metadata)
resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'os_version': 'alt1',
- 'os_distro': 'value2',
- 'architecture': 'value3'}
+ expected = {'metadata': {
+ 'os_version': 'alt1',
+ 'os_distro': 'value2',
+ 'architecture': 'value3'}}
self.assertEqual(expected, resp_metadata)
@test.idempotent_id('4f5db52f-6685-4c75-b848-f4bb363f9aa6')
def test_get_image_metadata_item(self):
# The value for a specific metadata key should be returned
meta = self.client.show_image_metadata_item(self.image_id,
- 'os_distro')
+ 'os_distro')['meta']
self.assertEqual('value2', meta['os_distro'])
@test.idempotent_id('f2de776a-4778-4d90-a5da-aae63aee64ae')
@@ -105,7 +108,7 @@
self.client.set_image_metadata_item(self.image_id,
'os_version', meta)
resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'os_version': 'alt', 'os_distro': 'value2'}
+ expected = {'metadata': {'os_version': 'alt', 'os_distro': 'value2'}}
self.assertEqual(expected, resp_metadata)
@test.idempotent_id('a013796c-ba37-4bb5-8602-d944511def14')
@@ -114,5 +117,5 @@
self.client.delete_image_metadata_item(self.image_id,
'os_version')
resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'os_distro': 'value2'}
+ expected = {'metadata': {'os_distro': 'value2'}}
self.assertEqual(expected, resp_metadata)
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 7f23730..126d092 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -74,7 +74,7 @@
@test.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
def test_create_image_from_stopped_server(self):
server = self.create_test_server(wait_until='ACTIVE')
- self.servers_client.stop(server['id'])
+ self.servers_client.stop_server(server['id'])
waiters.wait_for_server_status(self.servers_client,
server['id'], 'SHUTOFF')
self.addCleanup(self.servers_client.delete_server, server['id'])
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 4f15ce1..37c2bb6 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -86,11 +86,11 @@
waiters.wait_for_image_status(self.client, image_id, 'ACTIVE')
# Verify the image was created correctly
- image = self.client.show_image(image_id)
+ image = self.client.show_image(image_id)['image']
self.assertEqual(name, image['name'])
self.assertEqual('test', image['metadata']['image_type'])
- original_image = self.client.show_image(self.image_ref)
+ original_image = self.client.show_image(self.image_ref)['image']
# Verify minRAM is the same as the original image
self.assertEqual(image['minRam'], original_image['minRam'])
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 247a57b..9f3ba71 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -63,7 +63,7 @@
image_file = six.StringIO(('*' * 1024))
cls.glance_client.update_image(image_id, data=image_file)
waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE')
- body = cls.client.show_image(image_id)
+ body = cls.client.show_image(image_id)['image']
return body
# Create non-snapshot images via glance
@@ -106,7 +106,7 @@
# The list of images should contain only images with the
# provided status
params = {'status': 'ACTIVE'}
- images = self.client.list_images(**params)
+ images = self.client.list_images(**params)['images']
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
@@ -117,7 +117,7 @@
# List of all images should contain the expected images filtered
# by name
params = {'name': self.image1['name']}
- images = self.client.list_images(**params)
+ images = self.client.list_images(**params)['images']
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
@@ -129,7 +129,7 @@
def test_list_images_filter_by_server_id(self):
# The images should contain images filtered by server id
params = {'server': self.server1['id']}
- images = self.client.list_images(**params)
+ images = self.client.list_images(**params)['images']
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot1_id]),
@@ -150,7 +150,7 @@
# Try all server link types
for link in server_links:
params = {'server': link['href']}
- images = self.client.list_images(**params)
+ images = self.client.list_images(**params)['images']
self.assertFalse(any([i for i in images
if i['id'] == self.snapshot1_id]))
@@ -165,7 +165,7 @@
def test_list_images_filter_by_type(self):
# The list of servers should be filtered by image type
params = {'type': 'snapshot'}
- images = self.client.list_images(**params)
+ images = self.client.list_images(**params)['images']
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot1_id]))
@@ -180,7 +180,7 @@
def test_list_images_limit_results(self):
# Verify only the expected number of results are returned
params = {'limit': '1'}
- images = self.client.list_images(**params)
+ images = self.client.list_images(**params)['images']
self.assertEqual(1, len([x for x in images if 'id' in x]))
@test.idempotent_id('18bac3ae-da27-436c-92a9-b22474d13aab')
@@ -190,7 +190,7 @@
# Becoming ACTIVE will modify the updated time
# Filter by the image's created time
params = {'changes-since': self.image3['created']}
- images = self.client.list_images(**params)
+ images = self.client.list_images(**params)['images']
found = any([i for i in images if i['id'] == self.image3_id])
self.assertTrue(found)
@@ -199,7 +199,7 @@
# Detailed list of all images should only contain images
# with the provided status
params = {'status': 'ACTIVE'}
- images = self.client.list_images(detail=True, **params)
+ images = self.client.list_images(detail=True, **params)['images']
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
@@ -210,7 +210,7 @@
# Detailed list of all images should contain the expected
# images filtered by name
params = {'name': self.image1['name']}
- images = self.client.list_images(detail=True, **params)
+ images = self.client.list_images(detail=True, **params)['images']
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
@@ -221,7 +221,7 @@
# Verify only the expected number of results (with full details)
# are returned
params = {'limit': '1'}
- images = self.client.list_images(detail=True, **params)
+ images = self.client.list_images(detail=True, **params)['images']
self.assertEqual(1, len(images))
@test.idempotent_id('8c78f822-203b-4bf6-8bba-56ebd551cf84')
@@ -234,7 +234,7 @@
# Try all server link types
for link in server_links:
params = {'server': link['href']}
- images = self.client.list_images(detail=True, **params)
+ images = self.client.list_images(detail=True, **params)['images']
self.assertFalse(any([i for i in images
if i['id'] == self.snapshot1_id]))
@@ -249,7 +249,7 @@
def test_list_images_with_detail_filter_by_type(self):
# The detailed list of servers should be filtered by image type
params = {'type': 'snapshot'}
- images = self.client.list_images(detail=True, **params)
+ images = self.client.list_images(detail=True, **params)['images']
self.client.show_image(self.image_ref)
self.assertTrue(any([i for i in images
@@ -268,5 +268,5 @@
# Becoming ACTIVE will modify the updated time
# Filter by the image's created time
params = {'changes-since': self.image1['created']}
- images = self.client.list_images(detail=True, **params)
+ images = self.client.list_images(detail=True, **params)['images']
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index b67378c..6ca15d6 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -37,19 +37,19 @@
@test.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
def test_get_image(self):
# Returns the correct details for a single image
- image = self.client.show_image(self.image_ref)
+ image = self.client.show_image(self.image_ref)['image']
self.assertEqual(self.image_ref, image['id'])
@test.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
def test_list_images(self):
# The list of all images should contain the image
- images = self.client.list_images()
+ images = self.client.list_images()['images']
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
@test.idempotent_id('9f94cb6b-7f10-48c5-b911-a0b84d7d4cd6')
def test_list_images_with_detail(self):
# Detailed list of all images should contain the expected images
- images = self.client.list_images(detail=True)
+ images = self.client.list_images(detail=True)['images']
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 0029bb9..69811f4 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -27,7 +27,7 @@
@test.idempotent_id('b54c66af-6ab6-4cf0-a9e5-a0cb58d75e0b')
def test_absLimits_get(self):
# To check if all limits are present in the response
- limits = self.client.show_limits()
+ limits = self.client.show_limits()['limits']
absolute_limits = limits['absolute']
expected_elements = ['maxImageMeta', 'maxPersonality',
'maxPersonalitySize',
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index cbd2004..5755f5b 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -38,7 +38,7 @@
def test_max_image_meta_exceed_limit(self):
# We should not create vm with image meta over maxImageMeta limit
# Get max limit value
- limits = self.client.show_limits()
+ limits = self.client.show_limits()['limits']
max_meta = limits['absolute']['maxImageMeta']
# No point in running this test if there is no limit.
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 35f2b2c..529b596 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -307,11 +307,11 @@
admin_pass = self.image_ssh_password
- server_no_eph_disk = (self.create_test_server(
- validatable=True,
- wait_until='ACTIVE',
- adminPass=admin_pass,
- flavor=flavor_no_eph_disk_id))
+ server_no_eph_disk = self.create_test_server(
+ validatable=True,
+ wait_until='ACTIVE',
+ adminPass=admin_pass,
+ flavor=flavor_no_eph_disk_id)
# Get partition number of server without extra specs.
server_no_eph_disk = self.client.show_server(
@@ -326,11 +326,11 @@
# Explicit server deletion necessary for Juno compatibility
self.client.delete_server(server_no_eph_disk['id'])
- server_with_eph_disk = (self.create_test_server(
- validatable=True,
- wait_until='ACTIVE',
- adminPass=admin_pass,
- flavor=flavor_with_eph_disk_id))
+ server_with_eph_disk = self.create_test_server(
+ validatable=True,
+ wait_until='ACTIVE',
+ adminPass=admin_pass,
+ flavor=flavor_with_eph_disk_id)
server_with_eph_disk = self.client.show_server(
server_with_eph_disk['id'])
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index 81639da..5d461ab 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -51,7 +51,7 @@
def test_delete_server_while_in_shutoff_state(self):
# Delete a server while it's VM state is Shutoff
server = self.create_test_server(wait_until='ACTIVE')
- self.client.stop(server['id'])
+ self.client.stop_server(server['id'])
waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
@@ -117,7 +117,8 @@
device = '/dev/%s' % CONF.compute.volume_device_name
server = self.create_test_server(wait_until='ACTIVE')
- volume = volumes_client.create_volume()
+ volume = (volumes_client.create_volume(size=CONF.volume.volume_size)
+ ['volume'])
self.addCleanup(volumes_client.delete_volume, volume['id'])
waiters.wait_for_volume_status(volumes_client,
volume['id'], 'available')
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 5b9338a..929b300 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -105,7 +105,7 @@
disk_config='AUTO')
waiters.wait_for_server_status(self.client, self.server_id,
'VERIFY_RESIZE')
- self.client.confirm_resize(self.server_id)
+ self.client.confirm_resize_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
server = self.client.show_server(self.server_id)
@@ -124,7 +124,7 @@
disk_config='MANUAL')
waiters.wait_for_server_status(self.client, self.server_id,
'VERIFY_RESIZE')
- self.client.confirm_resize(self.server_id)
+ self.client.confirm_resize_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
server = self.client.show_server(self.server_id)
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 6160844..16e4392 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -44,7 +44,7 @@
# Check to see if the alternate image ref actually exists...
images_client = cls.images_client
- images = images_client.list_images()
+ images = images_client.list_images()['images']
if cls.image_ref != cls.image_ref_alt and \
any([image for image in images
@@ -137,11 +137,11 @@
def test_list_servers_filter_by_shutoff_status(self):
# Filter the list of servers by server shutoff status
params = {'status': 'shutoff'}
- self.client.stop(self.s1['id'])
+ self.client.stop_server(self.s1['id'])
waiters.wait_for_server_status(self.client, self.s1['id'],
'SHUTOFF')
body = self.client.list_servers(**params)
- self.client.start(self.s1['id'])
+ self.client.start_server(self.s1['id'])
waiters.wait_for_server_status(self.client, self.s1['id'],
'ACTIVE')
servers = body['servers']
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 96a4502..47629c0 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -191,7 +191,7 @@
old_image = server['image']['id']
new_image = (self.image_ref_alt
if old_image == self.image_ref else self.image_ref)
- self.client.stop(self.server_id)
+ self.client.stop_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
rebuilt_server = self.client.rebuild_server(self.server_id, new_image)
# If the server was rebuilt on a different image, restore it to the
@@ -212,14 +212,14 @@
rebuilt_image_id = server['image']['id']
self.assertEqual(new_image, rebuilt_image_id)
- self.client.start(self.server_id)
+ self.client.start_server(self.server_id)
def _test_resize_server_confirm(self, stop=False):
# The server's RAM and disk space should be modified to that of
# the provided flavor
if stop:
- self.client.stop(self.server_id)
+ self.client.stop_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id,
'SHUTOFF')
@@ -227,7 +227,7 @@
waiters.wait_for_server_status(self.client, self.server_id,
'VERIFY_RESIZE')
- self.client.confirm_resize(self.server_id)
+ self.client.confirm_resize_server(self.server_id)
expected_status = 'SHUTOFF' if stop else 'ACTIVE'
waiters.wait_for_server_status(self.client, self.server_id,
expected_status)
@@ -237,7 +237,7 @@
if stop:
# NOTE(mriedem): tearDown requires the server to be started.
- self.client.start(self.server_id)
+ self.client.start_server(self.server_id)
# NOTE(jlk): Explicitly delete the server to get a new one for later
# tests. Avoids resize down race issues.
@@ -266,7 +266,7 @@
waiters.wait_for_server_status(self.client, self.server_id,
'VERIFY_RESIZE')
- self.client.revert_resize(self.server_id)
+ self.client.revert_resize_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
server = self.client.show_server(self.server_id)
@@ -411,7 +411,7 @@
server = self.create_test_server(wait_until='ACTIVE')
temp_server_id = server['id']
- self.client.stop(temp_server_id)
+ self.client.stop_server(temp_server_id)
waiters.wait_for_server_status(self.client, temp_server_id, 'SHUTOFF')
self.wait_for(self._get_output)
@@ -456,7 +456,7 @@
server = self.client.show_server(self.server_id)
image_name = server['name'] + '-shelved'
params = {'name': image_name}
- images = self.images_client.list_images(**params)
+ images = self.images_client.list_images(**params)['images']
self.assertEqual(1, len(images))
self.assertEqual(image_name, images[0]['name'])
@@ -465,9 +465,9 @@
@test.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
def test_stop_start_server(self):
- self.client.stop(self.server_id)
+ self.client.stop_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
- self.client.start(self.server_id)
+ self.client.start_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
@test.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
@@ -479,11 +479,11 @@
self.assertEqual(server['status'], 'ACTIVE')
# Locked server is not allowed to be stopped by non-admin user
self.assertRaises(lib_exc.Conflict,
- self.client.stop, self.server_id)
+ self.client.stop_server, self.server_id)
self.client.unlock_server(self.server_id)
- self.client.stop(self.server_id)
+ self.client.stop_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
- self.client.start(self.server_id)
+ self.client.start_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
def _validate_url(self, url):
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index c42ec3d..5804dbe 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -137,7 +137,7 @@
# A 403 Forbidden or 413 Overlimit (old behaviour) exception
# will be raised while exceeding metadata items limit for
# tenant.
- quota_set = self.quotas.show_quota_set(self.tenant_id)
+ quota_set = self.quotas.show_quota_set(self.tenant_id)['quota_set']
quota_metadata = quota_set['metadata_items']
if quota_metadata == -1:
raise self.skipException("No limit for metadata_items")
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index b3cc072..a7fc235 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -34,7 +34,7 @@
# number of files are injected into the server.
file_contents = 'This is a test file.'
personality = []
- limits = self.user_client.show_limits()
+ limits = self.user_client.show_limits()['limits']
max_file_limit = limits['absolute']['maxPersonality']
if max_file_limit == -1:
raise self.skipException("No limit for personality files")
@@ -52,7 +52,7 @@
# Server should be created successfully if maximum allowed number of
# files is injected into the server during creation.
file_contents = 'This is a test file.'
- limits = self.user_client.show_limits()
+ limits = self.user_client.show_limits()['limits']
max_file_limit = limits['absolute']['maxPersonality']
if max_file_limit == -1:
raise self.skipException("No limit for personality files")
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 81417d24..f8567cf 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -61,8 +61,8 @@
def _create_volume(self):
volume = self.volumes_extensions_client.create_volume(
- CONF.volume.volume_size, display_name=data_utils.rand_name(
- self.__class__.__name__ + '_volume'))
+ size=CONF.volume.volume_size, display_name=data_utils.rand_name(
+ self.__class__.__name__ + '_volume'))['volume']
self.addCleanup(self.delete_volume, volume['id'])
waiters.wait_for_volume_status(self.volumes_extensions_client,
volume['id'], 'available')
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index c243adf..8cfb670 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -95,7 +95,7 @@
def test_update_server_name_in_stop_state(self):
# The server name should be changed to the the provided value
server = self.create_test_server(wait_until='ACTIVE')
- self.client.stop(server['id'])
+ self.client.stop_server(server['id'])
waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
updated_server = self._update_server_name(server['id'], 'SHUTOFF')
self.assertNotIn('progress', updated_server)
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index 5a14418..d5b60da 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -243,22 +243,21 @@
def test_update_name_of_non_existent_server(self):
# Update name of a non-existent server
- server_name = data_utils.rand_name('server')
+ nonexistent_server = data_utils.rand_uuid()
new_name = data_utils.rand_name('server') + '_updated'
self.assertRaises(lib_exc.NotFound, self.client.update_server,
- server_name, name=new_name)
+ nonexistent_server, name=new_name)
@test.attr(type=['negative'])
@test.idempotent_id('38204696-17c6-44da-9590-40f87fb5a899')
def test_update_server_set_empty_name(self):
# Update name of the server to an empty string
- server_name = data_utils.rand_name('server')
new_name = ''
self.assertRaises(lib_exc.BadRequest, self.client.update_server,
- server_name, name=new_name)
+ self.server_id, name=new_name)
@test.attr(type=['negative'])
@test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
@@ -336,7 +335,7 @@
def test_stop_non_existent_server(self):
# Stop a non existent server
nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound, self.servers_client.stop,
+ self.assertRaises(lib_exc.NotFound, self.servers_client.stop_server,
nonexistent_server)
@test.idempotent_id('6a8dc0c6-6cd4-4c0a-9f32-413881828091')
@@ -480,7 +479,7 @@
server = self.client.show_server(self.server_id)
image_name = server['name'] + '-shelved'
params = {'name': image_name}
- images = self.images_client.list_images(**params)
+ images = self.images_client.list_images(**params)['images']
self.assertEqual(1, len(images))
self.assertEqual(image_name, images[0]['name'])
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 85f0041..7aa6d34 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -57,4 +57,5 @@
for virt_iface in virt_ifaces['virtual_interfaces']:
mac_address = virt_iface['mac_address']
self.assertTrue(netaddr.valid_mac(mac_address),
- "Invalid mac address detected.")
+ "Invalid mac address detected. mac address: %s"
+ % mac_address)
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 7751c9a..b5a24c7 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -76,7 +76,7 @@
body = cls.glance_client.update_image(image_id,
data=image_file)['image']
cls.glance_client.wait_for_image_status(image_id, 'active')
- cls.image = cls.images_client.show_image(image_id)
+ cls.image = cls.images_client.show_image(image_id)['image']
cls.keypairname = data_utils.rand_name('keypair')
cls.keypairs_client.create_keypair(name=cls.keypairname)
diff --git a/tempest/api/compute/test_networks.py b/tempest/api/compute/test_networks.py
index bf2a78d..b53db3d 100644
--- a/tempest/api/compute/test_networks.py
+++ b/tempest/api/compute/test_networks.py
@@ -19,16 +19,16 @@
CONF = config.CONF
-class NetworksTestJSON(base.BaseV2ComputeTest):
+class ComputeNetworksTest(base.BaseV2ComputeTest):
@classmethod
def skip_checks(cls):
- super(NetworksTestJSON, cls).skip_checks()
+ super(ComputeNetworksTest, cls).skip_checks()
if CONF.service_available.neutron:
raise cls.skipException('nova-network is not available.')
@classmethod
def setup_clients(cls):
- super(NetworksTestJSON, cls).setup_clients()
+ super(ComputeNetworksTest, cls).setup_clients()
cls.client = cls.os.networks_client
@test.idempotent_id('3fe07175-312e-49a5-a623-5f52eeada4c2')
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index 9f37143..43f4c97 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -54,14 +54,14 @@
def test_get_quotas(self):
# User can get the quota set for it's tenant
expected_quota_set = self.default_quota_set | set(['id'])
- quota_set = self.client.show_quota_set(self.tenant_id)
+ quota_set = self.client.show_quota_set(self.tenant_id)['quota_set']
self.assertEqual(quota_set['id'], self.tenant_id)
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
# get the quota set using user id
quota_set = self.client.show_quota_set(self.tenant_id,
- self.user_id)
+ self.user_id)['quota_set']
self.assertEqual(quota_set['id'], self.tenant_id)
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
@@ -70,7 +70,8 @@
def test_get_default_quotas(self):
# User can get the default quota set for it's tenant
expected_quota_set = self.default_quota_set | set(['id'])
- quota_set = self.client.show_default_quota_set(self.tenant_id)
+ quota_set = (self.client.show_default_quota_set(self.tenant_id)
+ ['quota_set'])
self.assertEqual(quota_set['id'], self.tenant_id)
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
@@ -79,6 +80,7 @@
def test_compare_tenant_quotas_with_default_quotas(self):
# Tenants are created with the default quota values
defualt_quota_set = \
- self.client.show_default_quota_set(self.tenant_id)
- tenant_quota_set = self.client.show_quota_set(self.tenant_id)
+ self.client.show_default_quota_set(self.tenant_id)['quota_set']
+ tenant_quota_set = (self.client.show_quota_set(self.tenant_id)
+ ['quota_set'])
self.assertEqual(defualt_quota_set, tenant_quota_set)
diff --git a/tempest/api/compute/test_tenant_networks.py b/tempest/api/compute/test_tenant_networks.py
index ad5adaa..96b7ef6 100644
--- a/tempest/api/compute/test_tenant_networks.py
+++ b/tempest/api/compute/test_tenant_networks.py
@@ -16,18 +16,29 @@
from tempest import test
-class NetworksTestJSON(base.BaseV2ComputeTest):
+class ComputeTenantNetworksTest(base.BaseV2ComputeTest):
@classmethod
def resource_setup(cls):
- super(NetworksTestJSON, cls).resource_setup()
+ super(ComputeTenantNetworksTest, cls).resource_setup()
cls.client = cls.os.tenant_networks_client
+ cls.network = cls.get_tenant_network()
+
+ @classmethod
+ def setup_credentials(cls):
+ cls.set_network_resources(network=True)
+ super(ComputeTenantNetworksTest, cls).setup_credentials()
@test.idempotent_id('edfea98e-bbe3-4c7a-9739-87b986baff26')
+ @test.services('network')
def test_list_show_tenant_networks(self):
- tenant_networks = self.client.list_tenant_networks()
- self.assertNotEmpty(tenant_networks, "No tenant networks found.")
+ # Fetch all networks that are visible to the tenant: this may include
+ # shared and external networks
+ tenant_networks = [
+ n['id'] for n in self.client.list_tenant_networks()['networks']
+ ]
+ self.assertIn(self.network['id'], tenant_networks,
+ "No tenant networks found.")
- for net in tenant_networks:
- tenant_network = self.client.show_tenant_network(net['id'])
- self.assertEqual(net['id'], tenant_network['id'])
+ net = self.client.show_tenant_network(self.network['id'])
+ self.assertEqual(self.network['id'], net['network']['id'])
diff --git a/tempest/api/compute/test_versions.py b/tempest/api/compute/test_versions.py
new file mode 100644
index 0000000..369cf31
--- /dev/null
+++ b/tempest/api/compute/test_versions.py
@@ -0,0 +1,24 @@
+# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.compute import base
+from tempest import test
+
+
+class TestVersions(base.BaseComputeTest):
+
+ @test.idempotent_id('6c0a0990-43b6-4529-9b61-5fd8daf7c55c')
+ def test_list_api_versions(self):
+ result = self.versions_client.list_versions()
+ self.assertIsNotNone(result)
diff --git a/tempest/api/compute/v2/__init__.py b/tempest/api/compute/v2/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/compute/v2/__init__.py
+++ /dev/null
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 6496854..ba34039 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -75,7 +75,7 @@
# Create a volume and wait for it to become ready
self.volume = self.volumes_client.create_volume(
- CONF.volume.volume_size, display_name='test')
+ CONF.volume.volume_size, display_name='test')['volume']
self.addCleanup(self._delete_volume)
self.volumes_client.wait_for_volume_status(self.volume['id'],
'available')
@@ -97,11 +97,11 @@
# the volume remains attached.
self._create_and_attach()
- self.servers_client.stop(self.server['id'])
+ self.servers_client.stop_server(self.server['id'])
waiters.wait_for_server_status(self.servers_client, self.server['id'],
'SHUTOFF')
- self.servers_client.start(self.server['id'])
+ self.servers_client.start_server(self.server['id'])
waiters.wait_for_server_status(self.servers_client, self.server['id'],
'ACTIVE')
@@ -116,11 +116,11 @@
self._detach(self.server['id'], self.volume['id'])
self.attachment = None
- self.servers_client.stop(self.server['id'])
+ self.servers_client.stop_server(self.server['id'])
waiters.wait_for_server_status(self.servers_client, self.server['id'],
'SHUTOFF')
- self.servers_client.start(self.server['id'])
+ self.servers_client.start_server(self.server['id'])
waiters.wait_for_server_status(self.servers_client, self.server['id'],
'ACTIVE')
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 44339a3..6074054 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -46,8 +46,9 @@
v_name = data_utils.rand_name('Volume')
metadata = {'Type': 'work'}
# Create volume
- volume = self.client.create_volume(display_name=v_name,
- metadata=metadata)
+ volume = self.client.create_volume(size=CONF.volume.volume_size,
+ display_name=v_name,
+ metadata=metadata)['volume']
self.addCleanup(self.delete_volume, volume['id'])
self.assertIn('id', volume)
self.assertIn('displayName', volume)
@@ -59,7 +60,7 @@
# Wait for Volume status to become ACTIVE
waiters.wait_for_volume_status(self.client, volume['id'], 'available')
# GET Volume
- fetched_volume = self.client.show_volume(volume['id'])
+ fetched_volume = self.client.show_volume(volume['id'])['volume']
# Verification of details of fetched Volume
self.assertEqual(v_name,
fetched_volume['displayName'],
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 22b3d13..f0ed141 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -54,11 +54,12 @@
v_name = data_utils.rand_name('volume')
metadata = {'Type': 'work'}
try:
- volume = cls.client.create_volume(display_name=v_name,
- metadata=metadata)
+ volume = cls.client.create_volume(size=CONF.volume.volume_size,
+ display_name=v_name,
+ metadata=metadata)['volume']
waiters.wait_for_volume_status(cls.client,
volume['id'], 'available')
- volume = cls.client.show_volume(volume['id'])
+ volume = cls.client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
cls.volume_id_list.append(volume['id'])
except Exception:
@@ -88,7 +89,7 @@
def test_volume_list(self):
# Should return the list of Volumes
# Fetch all Volumes
- fetched_list = self.client.list_volumes()
+ fetched_list = self.client.list_volumes()['volumes']
# Now check if all the Volumes created in setup are in fetched list
missing_volumes = [
v for v in self.volume_list if v not in fetched_list
@@ -103,7 +104,7 @@
def test_volume_list_with_details(self):
# Should return the list of Volumes with details
# Fetch all Volumes
- fetched_list = self.client.list_volumes(detail=True)
+ fetched_list = self.client.list_volumes(detail=True)['volumes']
# Now check if all the Volumes created in setup are in fetched list
missing_volumes = [
v for v in self.volume_list if v not in fetched_list
@@ -118,7 +119,7 @@
def test_volume_list_param_limit(self):
# Return the list of volumes based on limit set
params = {'limit': 2}
- fetched_vol_list = self.client.list_volumes(**params)
+ fetched_vol_list = self.client.list_volumes(**params)['volumes']
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volumes by limit set")
@@ -127,7 +128,8 @@
def test_volume_list_with_detail_param_limit(self):
# Return the list of volumes with details based on limit set.
params = {'limit': 2}
- fetched_vol_list = self.client.list_volumes(detail=True, **params)
+ fetched_vol_list = self.client.list_volumes(detail=True,
+ **params)['volumes']
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volume details by limit set")
@@ -136,9 +138,9 @@
def test_volume_list_param_offset_and_limit(self):
# Return the list of volumes based on offset and limit set.
# get all volumes list
- all_vol_list = self.client.list_volumes()
+ all_vol_list = self.client.list_volumes()['volumes']
params = {'offset': 1, 'limit': 1}
- fetched_vol_list = self.client.list_volumes(**params)
+ fetched_vol_list = self.client.list_volumes(**params)['volumes']
# Validating length of the fetched volumes
self.assertEqual(len(fetched_vol_list), params['limit'],
@@ -153,9 +155,10 @@
def test_volume_list_with_detail_param_offset_and_limit(self):
# Return the list of volumes details based on offset and limit set.
# get all volumes list
- all_vol_list = self.client.list_volumes(detail=True)
+ all_vol_list = self.client.list_volumes(detail=True)['volumes']
params = {'offset': 1, 'limit': 1}
- fetched_vol_list = self.client.list_volumes(detail=True, **params)
+ fetched_vol_list = self.client.list_volumes(detail=True,
+ **params)['volumes']
# Validating length of the fetched volumes
self.assertEqual(len(fetched_vol_list), params['limit'],
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 5681ac6..b5f86da 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -92,7 +92,6 @@
token_id = token_auth.response['x-subject-token']
orig_expires_at = token_auth['token']['expires_at']
- orig_issued_at = token_auth['token']['issued_at']
orig_user = token_auth['token']['user']
self.assertIsInstance(token_auth['token']['expires_at'], unicode)
@@ -117,7 +116,6 @@
self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
'Expiration time should match original token')
self.assertIsInstance(token_auth['token']['issued_at'], unicode)
- self.assertNotEqual(orig_issued_at, token_auth['token']['issued_at'])
self.assertEqual(set(['password', 'token']),
set(token_auth['token']['methods']))
self.assertEqual(orig_user, token_auth['token']['user'],
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index b8700a6..fac8826 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -34,7 +34,6 @@
if not CONF.identity_feature_enabled.trust:
raise self.skipException("Trusts aren't enabled")
- self.trustee_username = CONF.identity.alt_username
self.trust_id = None
def tearDown(self):
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 7b23e66..ada292f 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -77,7 +77,7 @@
@classmethod
def setup_clients(cls):
super(BaseIdentityV2Test, cls).setup_clients()
- cls.non_admin_client = cls.os.identity_client
+ cls.non_admin_client = cls.os.identity_public_client
cls.non_admin_token_client = cls.os.token_client
@classmethod
@@ -97,6 +97,7 @@
def setup_clients(cls):
super(BaseIdentityV2AdminTest, cls).setup_clients()
cls.client = cls.os_adm.identity_client
+ cls.non_admin_client = cls.os.identity_client
cls.token_client = cls.os_adm.token_client
@classmethod
diff --git a/tempest/api/identity/v2/test_tenants.py b/tempest/api/identity/v2/test_tenants.py
new file mode 100644
index 0000000..1fcff8d
--- /dev/null
+++ b/tempest/api/identity/v2/test_tenants.py
@@ -0,0 +1,50 @@
+# Copyright 2015 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest_lib import exceptions as lib_exc
+
+from tempest.api.identity import base
+from tempest import test
+
+
+class IdentityTenantsTest(base.BaseIdentityV2Test):
+
+ credentials = ['primary', 'alt']
+
+ @test.idempotent_id('ecae2459-243d-4ba1-ad02-65f15dc82b78')
+ def test_list_tenants_returns_only_authorized_tenants(self):
+ alt_tenant_name = self.alt_manager.credentials.credentials.tenant_name
+ resp = self.non_admin_client.list_tenants()
+
+ # check that user can see only that tenants that he presents in so user
+ # can successfully authenticate using his credentials and tenant name
+ # from received tenants list
+ for tenant in resp['tenants']:
+ body = self.non_admin_token_client.auth(
+ self.os.credentials.username,
+ self.os.credentials.password,
+ tenant['name'])
+ self.assertNotEmpty(body['token']['id'])
+ self.assertEqual(body['token']['tenant']['id'], tenant['id'])
+ self.assertEqual(body['token']['tenant']['name'], tenant['name'])
+ self.assertEqual(body['user']['id'], self.os.credentials.user_id)
+
+ # check that user cannot log in to alt user's tenant
+ self.assertRaises(
+ lib_exc.Unauthorized,
+ self.non_admin_token_client.auth,
+ self.os.credentials.username,
+ self.os.credentials.password,
+ alt_tenant_name)
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
new file mode 100644
index 0000000..4e5b41d
--- /dev/null
+++ b/tempest/api/identity/v2/test_users.py
@@ -0,0 +1,78 @@
+# Copyright 2015 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import copy
+
+from tempest_lib.common.utils import data_utils
+from tempest_lib import exceptions
+
+from tempest.api.identity import base
+from tempest import manager
+from tempest import test
+
+
+class IdentityUsersTest(base.BaseIdentityV2Test):
+
+ @classmethod
+ def resource_setup(cls):
+ super(IdentityUsersTest, cls).resource_setup()
+ cls.creds = cls.os.credentials
+ cls.username = cls.creds.username
+ cls.password = cls.creds.password
+ cls.tenant_name = cls.creds.tenant_name
+
+ @test.idempotent_id('165859c9-277f-4124-9479-a7d1627b0ca7')
+ def test_user_update_own_password(self):
+ self.new_creds = copy.copy(self.creds.credentials)
+ self.new_creds.password = data_utils.rand_password()
+ # we need new non-admin Identity Client with new credentials, since
+ # current non_admin_client token will be revoked after updating
+ # password
+ self.non_admin_client_for_cleanup = copy.copy(self.non_admin_client)
+ self.non_admin_client_for_cleanup.auth_provider = (
+ manager.get_auth_provider(self.new_creds))
+ user_id = self.creds.credentials.user_id
+ old_pass = self.creds.credentials.password
+ new_pass = self.new_creds.password
+
+ # to change password back. important for allow_tenant_isolation = false
+ self.addCleanup(
+ self.non_admin_client_for_cleanup.update_user_own_password,
+ user_id=user_id,
+ new_pass=old_pass,
+ old_pass=new_pass)
+
+ # user updates own password
+ resp = self.non_admin_client.update_user_own_password(
+ user_id=user_id, new_pass=new_pass, old_pass=old_pass)
+
+ # check authorization with new token
+ self.non_admin_token_client.auth_token(resp['token']['id'])
+ # check authorization with new password
+ self.non_admin_token_client.auth(self.username,
+ new_pass,
+ self.tenant_name)
+
+ # authorize with old token should lead to Unauthorized
+ self.assertRaises(exceptions.Unauthorized,
+ self.non_admin_token_client.auth_token,
+ self.non_admin_client.token)
+
+ # authorize with old password should lead to Unauthorized
+ self.assertRaises(exceptions.Unauthorized,
+ self.non_admin_token_client.auth,
+ self.username,
+ old_pass,
+ self.tenant_name)
diff --git a/tempest/api/identity/v3/test_api_discovery.py b/tempest/api/identity/v3/test_api_discovery.py
index 2ec8ad8..e0207a9 100644
--- a/tempest/api/identity/v3/test_api_discovery.py
+++ b/tempest/api/identity/v3/test_api_discovery.py
@@ -23,7 +23,7 @@
@test.attr(type='smoke')
@test.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
def test_api_version_resources(self):
- descr = self.non_admin_client.get_api_description()
+ descr = self.non_admin_client.get_api_description()['version']
expected_resources = ('id', 'links', 'media-types', 'status',
'updated')
@@ -34,7 +34,7 @@
@test.attr(type='smoke')
@test.idempotent_id('657c1970-4722-4189-8831-7325f3bc4265')
def test_api_media_types(self):
- descr = self.non_admin_client.get_api_description()
+ descr = self.non_admin_client.get_api_description()['version']
# Get MIME type bases and descriptions
media_types = [(media_type['base'], media_type['type']) for
media_type in descr['media-types']]
@@ -49,7 +49,7 @@
@test.attr(type='smoke')
@test.idempotent_id('8879a470-abfb-47bb-bb8d-5a7fd279ad1e')
def test_api_version_statuses(self):
- descr = self.non_admin_client.get_api_description()
+ descr = self.non_admin_client.get_api_description()['version']
status = descr['status'].lower()
supported_statuses = ['current', 'stable', 'experimental',
'supported', 'deprecated']
diff --git a/tempest/api/identity/v3/test_projects.py b/tempest/api/identity/v3/test_projects.py
new file mode 100644
index 0000000..a547b06
--- /dev/null
+++ b/tempest/api/identity/v3/test_projects.py
@@ -0,0 +1,53 @@
+# Copyright 2015 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest_lib import exceptions as lib_exc
+
+from tempest.api.identity import base
+from tempest import test
+
+
+class IdentityV3ProjectsTest(base.BaseIdentityV3Test):
+
+ credentials = ['primary', 'alt']
+
+ @test.idempotent_id('86128d46-e170-4644-866a-cc487f699e1d')
+ def test_list_projects_returns_only_authorized_projects(self):
+ alt_project_name =\
+ self.alt_manager.credentials.credentials.project_name
+ resp = self.non_admin_client.list_user_projects(
+ self.os.credentials.user_id)
+
+ # check that user can see only that projects that he presents in so
+ # user can successfully authenticate using his credentials and
+ # project name from received projects list
+ for project in resp['projects']:
+ token_id, body = self.non_admin_token.get_token(
+ username=self.os.credentials.username,
+ password=self.os.credentials.password,
+ project_name=project['name'],
+ auth_data=True)
+ self.assertNotEmpty(token_id)
+ self.assertEqual(body['project']['id'], project['id'])
+ self.assertEqual(body['project']['name'], project['name'])
+ self.assertEqual(body['user']['id'], self.os.credentials.user_id)
+
+ # check that user cannot log in to alt user's project
+ self.assertRaises(
+ lib_exc.Unauthorized,
+ self.non_admin_token.get_token,
+ username=self.os.credentials.username,
+ password=self.os.credentials.password,
+ project_name=alt_project_name)
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
new file mode 100644
index 0000000..a1f664f
--- /dev/null
+++ b/tempest/api/identity/v3/test_users.py
@@ -0,0 +1,72 @@
+# Copyright 2015 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import copy
+
+from tempest_lib.common.utils import data_utils
+from tempest_lib import exceptions
+
+from tempest.api.identity import base
+from tempest import manager
+from tempest import test
+
+
+class IdentityV3UsersTest(base.BaseIdentityV3Test):
+
+ @classmethod
+ def resource_setup(cls):
+ super(IdentityV3UsersTest, cls).resource_setup()
+ cls.creds = cls.os.credentials
+ cls.user_id = cls.creds.user_id
+ cls.username = cls.creds.username
+ cls.password = cls.creds.password
+
+ @test.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
+ def test_user_update_own_password(self):
+ self.new_creds = copy.copy(self.creds.credentials)
+ self.new_creds.password = data_utils.rand_password()
+ # we need new non-admin Identity V3 Client with new credentials, since
+ # current non_admin_client token will be revoked after updating
+ # password
+ self.non_admin_client_for_cleanup = copy.copy(self.non_admin_client)
+ self.non_admin_client_for_cleanup.auth_provider = (
+ manager.get_auth_provider(self.new_creds))
+ user_id = self.creds.credentials.user_id
+ old_pass = self.creds.credentials.password
+ new_pass = self.new_creds.password
+ # to change password back. important for allow_tenant_isolation = false
+ self.addCleanup(
+ self.non_admin_client_for_cleanup.update_user_password,
+ user_id=user_id,
+ password=old_pass,
+ original_password=new_pass)
+
+ # user updates own password
+ self.non_admin_client.update_user_password(
+ user_id=user_id, password=new_pass, original_password=old_pass)
+
+ # check authorization with new password
+ self.non_admin_token.auth(user_id=self.user_id, password=new_pass)
+
+ # authorize with old token should lead to IdentityError (404 code)
+ self.assertRaises(exceptions.IdentityError,
+ self.non_admin_token.auth,
+ token=self.non_admin_client.token)
+
+ # authorize with old password should lead to Unauthorized
+ self.assertRaises(exceptions.Unauthorized,
+ self.non_admin_token.auth,
+ user_id=self.user_id,
+ password=old_pass)
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 7739d16..d4dbfcd 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -119,9 +119,6 @@
img7 = cls._create_standard_image('33', 'bare', 'raw', 142)
img8 = cls._create_standard_image('33', 'bare', 'raw', 142)
cls.created_set = set(cls.created_images)
- # 4x-4x remote image
- cls.remote_set = set((img1, img2, img3, img4))
- cls.standard_set = set((img5, img6, img7, img8))
# 5x bare, 3x ami
cls.bare_set = set((img1, img3, img4, img7, img8))
cls.ami_set = set((img2, img5, img6))
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 4a86aca..86b4973 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -32,7 +32,6 @@
# dhcp agent: this is done by creating a regular port
cls.network = cls.create_network()
cls.subnet = cls.create_subnet(cls.network)
- cls.cidr = cls.subnet['cidr']
cls.port = cls.create_port(cls.network)
@test.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index fda8fc3..fa6fa33 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -77,7 +77,6 @@
@classmethod
def resource_setup(cls):
super(BaseNetworkTest, cls).resource_setup()
- cls.network_cfg = CONF.network
cls.networks = []
cls.subnets = []
cls.ports = []
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index f56688f..d6b03eb 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -40,7 +40,7 @@
'agent', 'dhcp_agent_scheduler', 'provider',
'router', 'extraroute', 'external-net',
'allowed-address-pairs', 'extra_dhcp_opt',
- 'metering', 'dvr', 'service-type']
+ 'metering', 'dvr']
expected_alias = [ext for ext in expected_alias if
test.is_extension_enabled(ext, 'network')]
actual_alias = list()
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 842a56d..1116573 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -27,7 +27,7 @@
CONF = config.CONF
-class NetworksTestJSON(base.BaseNetworkTest):
+class NetworksTest(base.BaseNetworkTest):
"""
Tests the following operations in the Neutron API using the REST client for
Neutron:
@@ -61,12 +61,11 @@
@classmethod
def resource_setup(cls):
- super(NetworksTestJSON, cls).resource_setup()
+ super(NetworksTest, cls).resource_setup()
cls.network = cls.create_network()
cls.name = cls.network['name']
cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
cls._ip_version)
- cls.cidr = cls.subnet['cidr']
cls._subnet_data = {6: {'gateway':
str(cls._get_gateway_from_tempest_conf(6)),
'allocation_pools':
@@ -534,7 +533,7 @@
_ip_version = 6
-class NetworksIpV6TestJSON(NetworksTestJSON):
+class NetworksIpV6TestJSON(NetworksTest):
_ip_version = 6
@test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index 5dc1c21..94c3f9a 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -26,35 +26,35 @@
@test.attr(type=['negative'])
@test.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
def test_show_non_existent_network(self):
- non_exist_id = data_utils.rand_name('network')
+ non_exist_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.client.show_network,
non_exist_id)
@test.attr(type=['negative'])
@test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
def test_show_non_existent_subnet(self):
- non_exist_id = data_utils.rand_name('subnet')
+ non_exist_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
non_exist_id)
@test.attr(type=['negative'])
@test.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
def test_show_non_existent_port(self):
- non_exist_id = data_utils.rand_name('port')
+ non_exist_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.client.show_port,
non_exist_id)
@test.attr(type=['negative'])
@test.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
def test_update_non_existent_network(self):
- non_exist_id = data_utils.rand_name('network')
+ non_exist_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.client.update_network,
non_exist_id, name="new_name")
@test.attr(type=['negative'])
@test.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
def test_delete_non_existent_network(self):
- non_exist_id = data_utils.rand_name('network')
+ non_exist_id = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.client.delete_network,
non_exist_id)
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 1308414..aa3d274 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -275,7 +275,7 @@
next_cidr = netaddr.IPNetwork(self.tenant_cidr)
# Prepare to build several routes
test_routes = []
- routes_num = 5
+ routes_num = 4
# Create a router
router = self._create_router(
data_utils.rand_name('router-'), True)
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index 0f107f5..1cc9437 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -321,7 +321,7 @@
self.assertNotIn('x-container-meta-', str(resp))
@test.idempotent_id('cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef')
- def test_update_container_metadata_with_create_and_delete_matadata(self):
+ def test_update_container_metadata_with_create_and_delete_metadata(self):
# Send one request of adding and deleting metadata
container_name = data_utils.rand_name(name='TestContainer')
metadata_1 = {'test-container-meta1': 'Meta1'}
@@ -379,8 +379,8 @@
self.assertNotIn('x-container-meta-test-container-meta1', resp)
@test.idempotent_id('31f40a5f-6a52-4314-8794-cd89baed3040')
- def test_update_container_metadata_with_create_matadata_key(self):
- # update container metadata with a blenk value of metadata
+ def test_update_container_metadata_with_create_metadata_key(self):
+ # update container metadata with a blank value of metadata
container_name = self._create_container()
metadata = {'test-container-meta1': ''}
@@ -395,7 +395,7 @@
@test.idempotent_id('a2e36378-6f1f-43f4-840a-ffd9cfd61914')
def test_update_container_metadata_with_delete_metadata_key(self):
- # update container metadata with a blank value of matadata
+ # update container metadata with a blank value of metadata
container_name = data_utils.rand_name(name='TestContainer')
metadata = {'test-container-meta1': 'Meta1'}
self.container_client.create_container(container_name,
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 2198753..d64efee 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -811,7 +811,7 @@
@test.idempotent_id('aa467252-44f3-472a-b5ae-5b57c3c9c147')
def test_copy_object_across_containers(self):
- # create a container to use as asource container
+ # create a container to use as a source container
src_container_name = data_utils.rand_name(name='TestSourceContainer')
self.container_client.create_container(src_container_name)
self.containers.append(src_container_name)
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index d8f117e..4ba38ad 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -34,7 +34,7 @@
def _cinder_verify(self, volume_id, template):
self.assertIsNotNone(volume_id)
- volume = self.volumes_client.show_volume(volume_id)
+ volume = self.volumes_client.show_volume(volume_id)['volume']
self.assertEqual('available', volume.get('status'))
self.assertEqual(template['resources']['volume']['properties'][
'size'], volume.get('size'))
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index 5d1784f..8f07614 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -15,6 +15,7 @@
from oslo_utils import timeutils
from tempest_lib import exceptions as lib_exc
+from tempest.common import compute
from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
@@ -73,9 +74,11 @@
@classmethod
def create_server(cls):
- body = cls.servers_client.create_server(
- data_utils.rand_name('ceilometer-instance'),
- CONF.compute.image_ref, CONF.compute.flavor_ref,
+ tenant_network = cls.get_tenant_network()
+ body, server = compute.create_test_server(
+ cls.os,
+ tenant_network=tenant_network,
+ name=data_utils.rand_name('ceilometer-instance'),
wait_until='ACTIVE')
cls.server_ids.append(body['id'])
return body
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index 71a00c9..31eff9d 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -22,13 +22,6 @@
class TelemetryNotificationAPITestJSON(base.BaseTelemetryTest):
- @classmethod
- def skip_checks(cls):
- super(TelemetryNotificationAPITestJSON, cls).skip_checks()
- if CONF.telemetry.too_slow_to_test:
- raise cls.skipException("Ceilometer feature for fast work mysql "
- "is disabled")
-
@test.idempotent_id('d7f8c1c8-d470-4731-8604-315d3956caad')
@test.services('compute')
def test_check_nova_notification(self):
@@ -75,13 +68,6 @@
class TelemetryNotificationAdminAPITestJSON(base.BaseTelemetryAdminTest):
- @classmethod
- def skip_checks(cls):
- super(TelemetryNotificationAdminAPITestJSON, cls).skip_checks()
- if CONF.telemetry.too_slow_to_test:
- raise cls.skipException("Ceilometer feature for fast work mysql "
- "is disabled")
-
@test.idempotent_id('29604198-8b45-4fc0-8af8-1cae4f94ebe9')
@test.services('compute')
@decorators.skip_because(bug='1480490')
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index bbdf4a8..4337922 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -71,7 +71,8 @@
params = {self.name_field: vol_name, 'volume_type': type_name}
- self.volume = self.admin_volume_client.create_volume(**params)
+ self.volume = self.admin_volume_client.create_volume(
+ **params)['volume']
if with_prefix:
self.volume_id_list_with_prefix.append(self.volume['id'])
else:
@@ -135,7 +136,7 @@
# the multi backend feature has been enabled
# if multi-backend is enabled: os-vol-attr:host should be like:
# host@backend_name
- volume = self.admin_volume_client.show_volume(volume_id)
+ volume = self.admin_volume_client.show_volume(volume_id)['volume']
volume1_host = volume['os-vol-host-attr:host']
msg = ("multi-backend reporting incorrect values for volume %s" %
@@ -146,10 +147,10 @@
# this test checks that the two volumes created at setUp don't
# belong to the same backend (if they are, than the
# volume backend distinction is not working properly)
- volume = self.admin_volume_client.show_volume(volume1_id)
+ volume = self.admin_volume_client.show_volume(volume1_id)['volume']
volume1_host = volume['os-vol-host-attr:host']
- volume = self.admin_volume_client.show_volume(volume2_id)
+ volume = self.admin_volume_client.show_volume(volume2_id)['volume']
volume2_host = volume['os-vol-host-attr:host']
msg = ("volumes %s and %s were created in the same backend" %
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 66973a7..784f1b6 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -34,7 +34,7 @@
cls.name_field = cls.special_fields['name_field']
params = {cls.name_field: vol_name}
cls.volume = \
- cls.volumes_client.create_volume(**params)
+ cls.volumes_client.create_volume(**params)['volume']
cls.volumes_client.wait_for_volume_status(cls.volume['id'],
'available')
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 1a48204..f9117ed 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -32,14 +32,15 @@
@test.idempotent_id('59eada70-403c-4cef-a2a3-a8ce2f1b07a0')
def test_list_quotas(self):
- quotas = self.quotas_client.show_quota_set(self.demo_tenant_id)
+ quotas = (self.quotas_client.show_quota_set(self.demo_tenant_id)
+ ['quota_set'])
for key in QUOTA_KEYS:
self.assertIn(key, quotas)
@test.idempotent_id('2be020a2-5fdd-423d-8d35-a7ffbc36e9f7')
def test_list_default_quotas(self):
quotas = self.quotas_client.show_default_quota_set(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
for key in QUOTA_KEYS:
self.assertIn(key, quotas)
@@ -47,7 +48,7 @@
def test_update_all_quota_resources_for_tenant(self):
# Admin can update all the resource quota limits for a tenant
default_quota_set = self.quotas_client.show_default_quota_set(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
new_quota_set = {'gigabytes': 1009,
'volumes': 11,
'snapshots': 11}
@@ -55,7 +56,7 @@
# Update limits for all quota resources
quota_set = self.quotas_client.update_quota_set(
self.demo_tenant_id,
- **new_quota_set)
+ **new_quota_set)['quota_set']
cleanup_quota_set = dict(
(k, v) for k, v in six.iteritems(default_quota_set)
@@ -70,7 +71,7 @@
@test.idempotent_id('18c51ae9-cb03-48fc-b234-14a19374dbed')
def test_show_quota_usage(self):
quota_usage = self.quotas_client.show_quota_usage(
- self.os_adm.credentials.tenant_id)
+ self.os_adm.credentials.tenant_id)['quota_set']
for key in QUOTA_KEYS:
self.assertIn(key, quota_usage)
for usage_key in QUOTA_USAGE_KEYS:
@@ -79,14 +80,14 @@
@test.idempotent_id('ae8b6091-48ad-4bfa-a188-bbf5cc02115f')
def test_quota_usage(self):
quota_usage = self.quotas_client.show_quota_usage(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
volume = self.create_volume()
self.addCleanup(self.admin_volume_client.delete_volume,
volume['id'])
new_quota_usage = self.quotas_client.show_quota_usage(
- self.demo_tenant_id)
+ self.demo_tenant_id)['quota_set']
self.assertEqual(quota_usage['volumes']['in_use'] + 1,
new_quota_usage['volumes']['in_use'])
@@ -104,14 +105,15 @@
tenant_id = tenant['id']
self.addCleanup(identity_client.delete_tenant, tenant_id)
quota_set_default = self.quotas_client.show_default_quota_set(
- tenant_id)
+ tenant_id)['quota_set']
volume_default = quota_set_default['volumes']
self.quotas_client.update_quota_set(tenant_id,
volumes=(int(volume_default) + 5))
self.quotas_client.delete_quota_set(tenant_id)
- quota_set_new = self.quotas_client.show_quota_set(tenant_id)
+ quota_set_new = (self.quotas_client.show_quota_set(tenant_id)
+ ['quota_set'])
self.assertEqual(volume_default, quota_set_new['volumes'])
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index dd69b7f..2d9019a 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -58,7 +58,7 @@
'volume_type': volume_types[0]['id']}
# Create volume
- volume = self.volumes_client.create_volume(**params)
+ volume = self.volumes_client.create_volume(**params)['volume']
self.addCleanup(self._delete_volume, volume['id'])
self.assertEqual(volume_types[0]['name'], volume["volume_type"])
self.assertEqual(volume[self.name_field], vol_name,
@@ -74,7 +74,8 @@
self.volumes_client.wait_for_volume_status(volume['id'], 'available')
# Get volume details and Verify
- fetched_volume = self.volumes_client.show_volume(volume['id'])
+ fetched_volume = self.volumes_client.show_volume(
+ volume['id'])['volume']
self.assertEqual(volume_types[1]['name'],
fetched_volume['volume_type'],
'The fetched Volume type is different '
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 4288d58..6c32321 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -34,7 +34,7 @@
cls.name_field = cls.special_fields['name_field']
params = {cls.name_field: vol_name}
- cls.volume = cls.client.create_volume(**params)
+ cls.volume = cls.client.create_volume(**params)['volume']
cls.client.wait_for_volume_status(cls.volume['id'], 'available')
@classmethod
@@ -60,7 +60,7 @@
# Create a temp volume for force delete tests
vol_name = utils.rand_name('Volume')
params = {self.name_field: vol_name}
- temp_volume = self.client.create_volume(**params)
+ temp_volume = self.client.create_volume(**params)['volume']
self.client.wait_for_volume_status(temp_volume['id'], 'available')
return temp_volume
@@ -78,7 +78,7 @@
# test volume reset status : available->error->available
self._reset_volume_status(self.volume['id'], 'error')
volume_get = self.admin_volume_client.show_volume(
- self.volume['id'])
+ self.volume['id'])['volume']
self.assertEqual('error', volume_get['status'])
@test.idempotent_id('21737d5a-92f2-46d7-b009-a0cc0ee7a570')
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index 86fa668..0399413 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -14,6 +14,7 @@
# under the License.
from oslo_log import log as logging
+from tempest_lib import decorators
from tempest.api.volume import base
from tempest.common.utils import data_utils
@@ -79,6 +80,7 @@
self.admin_volume_client.wait_for_volume_status(
restore['volume_id'], 'available')
+ @decorators.skip_because(bug='1455043')
@test.idempotent_id('a99c54a1-dd80-4724-8a13-13bf58d4068d')
def test_volume_backup_export_import(self):
# Create backup
@@ -123,7 +125,7 @@
'available')
# Verify if restored volume is there in volume list
- volumes = self.admin_volume_client.list_volumes()
+ volumes = self.admin_volume_client.list_volumes()['volumes']
self.assertIn(restore['volume_id'], [v['id'] for v in volumes])
self.backups_adm_client.wait_for_backup_status(import_backup['id'],
'available')
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index c987100..cc020e3 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -16,7 +16,7 @@
from oslo_log import log as logging
from tempest_lib import exceptions as lib_exc
-from tempest.common import fixed_network
+from tempest.common import compute
from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
@@ -113,7 +113,7 @@
name_field = cls.special_fields['name_field']
kwargs[name_field] = name
- volume = cls.volumes_client.create_volume(size, **kwargs)
+ volume = cls.volumes_client.create_volume(size, **kwargs)['volume']
cls.volumes.append(volume)
cls.volumes_client.wait_for_volume_status(volume['id'], 'available')
@@ -162,12 +162,13 @@
@classmethod
def create_server(cls, name, **kwargs):
- network = cls.get_tenant_network()
- network_kwargs = fixed_network.set_networks_kwarg(network, kwargs)
- return cls.servers_client.create_server(name,
- cls.image_ref,
- cls.flavor_ref,
- **network_kwargs)
+ tenant_network = cls.get_tenant_network()
+ body, _ = compute.create_test_server(
+ cls.os,
+ tenant_network=tenant_network,
+ name=name,
+ **kwargs)
+ return body
class BaseVolumeAdminTest(BaseVolumeTest):
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 8529cfc..e529538 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -42,14 +42,16 @@
"key4": "<value&special_chars>"}
body = self.volumes_client.create_volume_metadata(self.volume_id,
- metadata)
+ metadata)['metadata']
# Get the metadata of the volume
- body = self.volumes_client.show_volume_metadata(self.volume_id)
+ body = self.volumes_client.show_volume_metadata(
+ self.volume_id)['metadata']
self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
# Delete one item metadata of the volume
self.volumes_client.delete_volume_metadata_item(
self.volume_id, "key1")
- body = self.volumes_client.show_volume_metadata(self.volume_id)
+ body = self.volumes_client.show_volume_metadata(
+ self.volume_id)['metadata']
self.assertNotIn("key1", body)
del metadata["key1"]
self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
@@ -66,15 +68,17 @@
# Create metadata for the volume
body = self.volumes_client.create_volume_metadata(
- self.volume_id, metadata)
+ self.volume_id, metadata)['metadata']
# Get the metadata of the volume
- body = self.volumes_client.show_volume_metadata(self.volume_id)
+ body = self.volumes_client.show_volume_metadata(
+ self.volume_id)['metadata']
self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
# Update metadata
body = self.volumes_client.update_volume_metadata(
- self.volume_id, update)
+ self.volume_id, update)['metadata']
# Get the metadata of the volume
- body = self.volumes_client.show_volume_metadata(self.volume_id)
+ body = self.volumes_client.show_volume_metadata(
+ self.volume_id)['metadata']
self.assertEqual(update, body)
@test.idempotent_id('862261c5-8df4-475a-8c21-946e50e36a20')
@@ -89,13 +93,14 @@
"key3": "value3_update"}
# Create metadata for the volume
body = self.volumes_client.create_volume_metadata(
- self.volume_id, metadata)
+ self.volume_id, metadata)['metadata']
self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
# Update metadata item
body = self.volumes_client.update_volume_metadata_item(
- self.volume_id, "key3", update_item)
+ self.volume_id, "key3", update_item)['meta']
# Get the metadata of the volume
- body = self.volumes_client.show_volume_metadata(self.volume_id)
+ body = self.volumes_client.show_volume_metadata(
+ self.volume_id)['metadata']
self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 27f8112..c0b6b7e 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -47,24 +47,24 @@
self.addCleanup(self._delete_volume, volume['id'])
# Create a volume transfer
- transfer = self.client.create_volume_transfer(volume['id'])
+ transfer = self.client.create_volume_transfer(volume['id'])['transfer']
transfer_id = transfer['id']
auth_key = transfer['auth_key']
self.client.wait_for_volume_status(volume['id'],
'awaiting-transfer')
# Get a volume transfer
- body = self.client.show_volume_transfer(transfer_id)
+ body = self.client.show_volume_transfer(transfer_id)['transfer']
self.assertEqual(volume['id'], body['volume_id'])
# List volume transfers, the result should be greater than
# or equal to 1
- body = self.client.list_volume_transfers()
+ body = self.client.list_volume_transfers()['transfers']
self.assertThat(len(body), matchers.GreaterThan(0))
# Accept a volume transfer by alt_tenant
body = self.alt_client.accept_volume_transfer(transfer_id,
- auth_key)
+ auth_key)['transfer']
self.alt_client.wait_for_volume_status(volume['id'], 'available')
@test.idempotent_id('ab526943-b725-4c07-b875-8e8ef87a2c30')
@@ -74,13 +74,13 @@
self.addCleanup(self._delete_volume, volume['id'])
# Create a volume transfer
- body = self.client.create_volume_transfer(volume['id'])
+ body = self.client.create_volume_transfer(volume['id'])['transfer']
transfer_id = body['id']
self.client.wait_for_volume_status(volume['id'],
'awaiting-transfer')
# List all volume transfers (looking for the one we created)
- body = self.client.list_volume_transfers()
+ body = self.client.list_volume_transfers()['transfers']
for transfer in body:
if volume['id'] == transfer['volume_id']:
break
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 58c5ba9..d4636ee 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -37,18 +37,14 @@
# Create a test shared instance
srv_name = data_utils.rand_name(cls.__name__ + '-Instance')
- cls.server = cls.create_server(srv_name)
- waiters.wait_for_server_status(cls.servers_client, cls.server['id'],
- 'ACTIVE')
+ cls.server = cls.create_server(
+ name=srv_name,
+ wait_until='ACTIVE')
# Create a test shared volume for attach/detach tests
cls.volume = cls.create_volume()
cls.client.wait_for_volume_status(cls.volume['id'], 'available')
- def _delete_image_with_wait(self, image_id):
- self.image_client.delete_image(image_id)
- self.image_client.wait_for_resource_deletion(image_id)
-
@classmethod
def resource_cleanup(cls):
# Delete the test instance
@@ -79,7 +75,8 @@
# Verify that a volume bootable flag is retrieved
for bool_bootable in [True, False]:
self.client.set_bootable_volume(self.volume['id'], bool_bootable)
- fetched_volume = self.client.show_volume(self.volume['id'])
+ fetched_volume = self.client.show_volume(
+ self.volume['id'])['volume']
# Get Volume information
bool_flag = self._is_true(fetched_volume['bootable'])
self.assertEqual(bool_bootable, bool_flag)
@@ -100,7 +97,7 @@
self.volume['id'],
'available')
self.addCleanup(self.client.detach_volume, self.volume['id'])
- volume = self.client.show_volume(self.volume['id'])
+ volume = self.client.show_volume(self.volume['id'])['volume']
self.assertIn('attachments', volume)
attachment = self.client.get_attachment_from_volume(volume)
self.assertEqual(mountpoint, attachment['device'])
@@ -116,9 +113,9 @@
# there is no way to delete it from Cinder, so we delete it from Glance
# using the Glance image_client and from Cinder via tearDownClass.
image_name = data_utils.rand_name('Image')
- body = self.client.upload_volume(self.volume['id'],
- image_name,
- CONF.volume.disk_format)
+ body = self.client.upload_volume(
+ self.volume['id'], image_name,
+ CONF.volume.disk_format)['os-volume_upload_image']
image_id = body["image_id"]
self.addCleanup(self.image_client.delete_image, image_id)
self.image_client.wait_for_image_status(image_id, 'active')
@@ -129,12 +126,12 @@
# Mark volume as reserved.
body = self.client.reserve_volume(self.volume['id'])
# To get the volume info
- body = self.client.show_volume(self.volume['id'])
+ body = self.client.show_volume(self.volume['id'])['volume']
self.assertIn('attaching', body['status'])
# Unmark volume as reserved.
body = self.client.unreserve_volume(self.volume['id'])
# To get the volume info
- body = self.client.show_volume(self.volume['id'])
+ body = self.client.show_volume(self.volume['id'])['volume']
self.assertIn('available', body['status'])
def _is_true(self, val):
@@ -147,7 +144,7 @@
self.client.update_volume_readonly(self.volume['id'],
readonly)
# Get Volume information
- fetched_volume = self.client.show_volume(self.volume['id'])
+ fetched_volume = self.client.show_volume(self.volume['id'])['volume']
bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
self.assertEqual(True, bool_flag)
@@ -156,7 +153,7 @@
self.client.update_volume_readonly(self.volume['id'], readonly)
# Get Volume information
- fetched_volume = self.client.show_volume(self.volume['id'])
+ fetched_volume = self.client.show_volume(self.volume['id'])['volume']
bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
self.assertEqual(False, bool_flag)
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index 179f8d3..78f5571 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -34,7 +34,7 @@
extend_size = int(self.volume['size']) + 1
self.client.extend_volume(self.volume['id'], extend_size)
self.client.wait_for_volume_status(self.volume['id'], 'available')
- volume = self.client.show_volume(self.volume['id'])
+ volume = self.client.show_volume(self.volume['id'])['volume']
self.assertEqual(int(volume['size']), extend_size)
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index a90f9ca..35c8898 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
from testtools import matchers
from tempest.api.volume import base
@@ -49,7 +50,7 @@
# Create a volume
kwargs[self.name_field] = v_name
kwargs['metadata'] = metadata
- volume = self.client.create_volume(**kwargs)
+ volume = self.client.create_volume(**kwargs)['volume']
self.assertIn('id', volume)
self.addCleanup(self._delete_volume, volume['id'])
self.client.wait_for_volume_status(volume['id'], 'available')
@@ -60,7 +61,7 @@
self.assertTrue(volume['id'] is not None,
"Field volume id is empty or not found.")
# Get Volume information
- fetched_volume = self.client.show_volume(volume['id'])
+ fetched_volume = self.client.show_volume(volume['id'])['volume']
self.assertEqual(v_name,
fetched_volume[self.name_field],
'The fetched Volume name is different '
@@ -88,12 +89,13 @@
new_desc = 'This is the new description of volume'
params = {self.name_field: new_v_name,
self.descrip_field: new_desc}
- update_volume = self.client.update_volume(volume['id'], **params)
+ update_volume = self.client.update_volume(
+ volume['id'], **params)['volume']
# Assert response body for update_volume method
self.assertEqual(new_v_name, update_volume[self.name_field])
self.assertEqual(new_desc, update_volume[self.descrip_field])
# Assert response body for show_volume method
- updated_volume = self.client.show_volume(volume['id'])
+ updated_volume = self.client.show_volume(volume['id'])['volume']
self.assertEqual(volume['id'], updated_volume['id'])
self.assertEqual(new_v_name, updated_volume[self.name_field])
self.assertEqual(new_desc, updated_volume[self.descrip_field])
@@ -108,7 +110,7 @@
new_v_desc = data_utils.rand_name('@#$%^* description')
params = {self.descrip_field: new_v_desc,
'availability_zone': volume['availability_zone']}
- new_volume = self.client.create_volume(**params)
+ new_volume = self.client.create_volume(**params)['volume']
self.assertIn('id', new_volume)
self.addCleanup(self._delete_volume, new_volume['id'])
self.client.wait_for_volume_status(new_volume['id'], 'available')
@@ -131,13 +133,15 @@
@test.idempotent_id('54a01030-c7fc-447c-86ee-c1182beae638')
@test.services('image')
def test_volume_create_get_update_delete_from_image(self):
- image = self.images_client.show_image(CONF.compute.image_ref)
+ image = self.images_client.show_image(CONF.compute.image_ref)['image']
min_disk = image.get('minDisk')
disk_size = max(min_disk, CONF.volume.volume_size)
self._volume_create_get_update_delete(
imageRef=CONF.compute.image_ref, size=disk_size)
@test.idempotent_id('3f591b4a-7dc6-444c-bd51-77469506b3a1')
+ @testtools.skipUnless(CONF.volume_feature_enabled.clone,
+ 'Cinder volume clones are disabled')
def test_volume_create_get_update_delete_as_clone(self):
origin = self.create_volume()
self._volume_create_get_update_delete(source_volid=origin['id'])
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 3847877..620366a 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -70,7 +70,7 @@
cls.metadata = {'Type': 'work'}
for i in range(3):
volume = cls.create_volume(metadata=cls.metadata)
- volume = cls.client.show_volume(volume['id'])
+ volume = cls.client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
cls.volume_id_list.append(volume['id'])
@@ -89,9 +89,10 @@
"""
if with_detail:
fetched_vol_list = \
- self.client.list_volumes(detail=True, params=params)
+ self.client.list_volumes(detail=True, params=params)['volumes']
else:
- fetched_vol_list = self.client.list_volumes(params=params)
+ fetched_vol_list = self.client.list_volumes(
+ params=params)['volumes']
# Validating params of fetched volumes
# In v2, only list detail view includes items in params.
@@ -116,7 +117,7 @@
def test_volume_list(self):
# Get a list of Volumes
# Fetch all volumes
- fetched_list = self.client.list_volumes()
+ fetched_list = self.client.list_volumes()['volumes']
self.assertVolumesIn(fetched_list, self.volume_list,
fields=self.VOLUME_FIELDS)
@@ -124,14 +125,14 @@
def test_volume_list_with_details(self):
# Get a list of Volumes with details
# Fetch all Volumes
- fetched_list = self.client.list_volumes(detail=True)
+ fetched_list = self.client.list_volumes(detail=True)['volumes']
self.assertVolumesIn(fetched_list, self.volume_list)
@test.idempotent_id('a28e8da4-0b56-472f-87a8-0f4d3f819c02')
def test_volume_list_by_name(self):
volume = self.volume_list[data_utils.rand_int_id(0, 2)]
params = {self.name: volume[self.name]}
- fetched_vol = self.client.list_volumes(params=params)
+ fetched_vol = self.client.list_volumes(params=params)['volumes']
self.assertEqual(1, len(fetched_vol), str(fetched_vol))
self.assertEqual(fetched_vol[0][self.name],
volume[self.name])
@@ -140,7 +141,8 @@
def test_volume_list_details_by_name(self):
volume = self.volume_list[data_utils.rand_int_id(0, 2)]
params = {self.name: volume[self.name]}
- fetched_vol = self.client.list_volumes(detail=True, params=params)
+ fetched_vol = self.client.list_volumes(
+ detail=True, params=params)['volumes']
self.assertEqual(1, len(fetched_vol), str(fetched_vol))
self.assertEqual(fetched_vol[0][self.name],
volume[self.name])
@@ -148,7 +150,7 @@
@test.idempotent_id('39654e13-734c-4dab-95ce-7613bf8407ce')
def test_volumes_list_by_status(self):
params = {'status': 'available'}
- fetched_list = self.client.list_volumes(params=params)
+ fetched_list = self.client.list_volumes(params=params)['volumes']
self._list_by_param_value_and_assert(params)
self.assertVolumesIn(fetched_list, self.volume_list,
fields=self.VOLUME_FIELDS)
@@ -156,7 +158,8 @@
@test.idempotent_id('2943f712-71ec-482a-bf49-d5ca06216b9f')
def test_volumes_list_details_by_status(self):
params = {'status': 'available'}
- fetched_list = self.client.list_volumes(detail=True, params=params)
+ fetched_list = self.client.list_volumes(
+ detail=True, params=params)['volumes']
for volume in fetched_list:
self.assertEqual('available', volume['status'])
self.assertVolumesIn(fetched_list, self.volume_list)
@@ -166,7 +169,7 @@
volume = self.volume_list[data_utils.rand_int_id(0, 2)]
zone = volume['availability_zone']
params = {'availability_zone': zone}
- fetched_list = self.client.list_volumes(params=params)
+ fetched_list = self.client.list_volumes(params=params)['volumes']
self._list_by_param_value_and_assert(params)
self.assertVolumesIn(fetched_list, self.volume_list,
fields=self.VOLUME_FIELDS)
@@ -176,7 +179,8 @@
volume = self.volume_list[data_utils.rand_int_id(0, 2)]
zone = volume['availability_zone']
params = {'availability_zone': zone}
- fetched_list = self.client.list_volumes(detail=True, params=params)
+ fetched_list = self.client.list_volumes(
+ detail=True, params=params)['volumes']
for volume in fetched_list:
self.assertEqual(zone, volume['availability_zone'])
self.assertVolumesIn(fetched_list, self.volume_list)
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 48f40f0..0af40ea 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -180,12 +180,13 @@
@test.services('compute')
def test_attach_volumes_with_nonexistent_volume_id(self):
srv_name = data_utils.rand_name('Instance')
- server = self.create_server(srv_name)
+ server = self.create_server(
+ name=srv_name,
+ wait_until='ACTIVE')
self.addCleanup(waiters.wait_for_server_termination,
self.servers_client, server['id'])
self.addCleanup(self.servers_client.delete_server, server['id'])
- waiters.wait_for_server_status(self.servers_client, server['id'],
- 'ACTIVE')
+
self.assertRaises(lib_exc.NotFound,
self.client.attach_volume,
str(uuid.uuid4()),
@@ -270,7 +271,7 @@
def test_list_volumes_with_nonexistent_name(self):
v_name = data_utils.rand_name('Volume')
params = {self.name_field: v_name}
- fetched_volume = self.client.list_volumes(params=params)
+ fetched_volume = self.client.list_volumes(params=params)['volumes']
self.assertEqual(0, len(fetched_volume))
@test.attr(type=['negative'])
@@ -279,14 +280,14 @@
v_name = data_utils.rand_name('Volume')
params = {self.name_field: v_name}
fetched_volume = \
- self.client.list_volumes(detail=True, params=params)
+ self.client.list_volumes(detail=True, params=params)['volumes']
self.assertEqual(0, len(fetched_volume))
@test.attr(type=['negative'])
@test.idempotent_id('143b279b-7522-466b-81be-34a87d564a7c')
def test_list_volumes_with_invalid_status(self):
params = {'status': 'null'}
- fetched_volume = self.client.list_volumes(params=params)
+ fetched_volume = self.client.list_volumes(params=params)['volumes']
self.assertEqual(0, len(fetched_volume))
@test.attr(type=['negative'])
@@ -294,7 +295,7 @@
def test_list_volumes_detail_with_invalid_status(self):
params = {'status': 'null'}
fetched_volume = \
- self.client.list_volumes(detail=True, params=params)
+ self.client.list_volumes(detail=True, params=params)['volumes']
self.assertEqual(0, len(fetched_volume))
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 058e220..7eaa9cc 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -14,7 +14,6 @@
from tempest.api.volume import base
from tempest.common.utils import data_utils
-from tempest.common import waiters
from tempest import config
from tempest import test
@@ -68,10 +67,10 @@
# Create a snapshot when volume status is in-use
# Create a test instance
server_name = data_utils.rand_name('instance')
- server = self.create_server(server_name)
+ server = self.create_server(
+ name=server_name,
+ wait_until='ACTIVE')
self.addCleanup(self.servers_client.delete_server, server['id'])
- waiters.wait_for_server_status(self.servers_client, server['id'],
- 'ACTIVE')
mountpoint = '/dev/%s' % CONF.compute.volume_device_name
self.servers_client.attach_volume(
server['id'], volumeId=self.volume_origin['id'],
@@ -178,7 +177,7 @@
snapshot = self.create_snapshot(self.volume_origin['id'])
# NOTE(gfidente): size is required also when passing snapshot_id
volume = self.volumes_client.create_volume(
- snapshot_id=snapshot['id'])
+ snapshot_id=snapshot['id'])['volume']
self.volumes_client.wait_for_volume_status(volume['id'], 'available')
self.volumes_client.delete_volume(volume['id'])
self.volumes_client.wait_for_resource_deletion(volume['id'])
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index ddc6822..94a9d16 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -47,7 +47,7 @@
cls.metadata = {'Type': 'work'}
for i in range(3):
volume = cls.create_volume(metadata=cls.metadata)
- volume = cls.client.show_volume(volume['id'])
+ volume = cls.client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
cls.volume_id_list.append(volume['id'])
@@ -71,8 +71,8 @@
'sort_dir': sort_dir,
'sort_key': sort_key
}
- fetched_volume = self.client.list_volumes(detail=True,
- params=params)
+ fetched_volume = self.client.list_volumes(
+ detail=True, params=params)['volumes']
self.assertEqual(limit, len(fetched_volume),
"The count of volumes is %s, expected:%s " %
(len(fetched_volume), limit))
@@ -123,7 +123,7 @@
while True:
# Get a list page
- response = method(return_body=True, params=params, **kwargs)
+ response = method(params=params, **kwargs)
# If we have to check ids
if remaining is not None:
diff --git a/tempest/api_schema/response/compute/v2_1/version.py b/tempest/api_schema/response/compute/v2_1/version.py
deleted file mode 100644
index 6579c63..0000000
--- a/tempest/api_schema/response/compute/v2_1/version.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2014 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.
-
-version = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'version': {
- 'type': 'object',
- 'properties': {
- 'id': {'type': 'string'},
- 'links': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'href': {'type': 'string', 'format': 'uri'},
- 'rel': {'type': 'string'},
- 'type': {'type': 'string'}
- },
- 'required': ['href', 'rel']
- }
- },
- 'media-types': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'base': {'type': 'string'},
- 'type': {'type': 'string'}
- },
- 'required': ['base', 'type']
- }
- },
- 'status': {'type': 'string'},
- 'updated': {'type': 'string', 'format': 'date-time'},
- 'version': {'type': 'string'},
- 'min_version': {'type': 'string'}
- },
- # NOTE: version and min_version have been added since Kilo,
- # so they should not be required.
- 'required': ['id', 'links', 'media-types', 'status', 'updated']
- }
- },
- 'required': ['version']
- }
-}
diff --git a/tempest/api_schema/response/compute/v2_1/versions.py b/tempest/api_schema/response/compute/v2_1/versions.py
new file mode 100644
index 0000000..f08695c
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_1/versions.py
@@ -0,0 +1,55 @@
+# 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.
+
+_version = {
+ 'type': 'object',
+ 'properties': {
+ 'id': {'type': 'string'},
+ 'links': {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'href': {'type': 'string', 'format': 'uri'},
+ 'rel': {'type': 'string'},
+ },
+ 'required': ['href', 'rel'],
+ 'additionalProperties': False
+ }
+ },
+ 'status': {'type': 'string'},
+ 'updated': {'type': 'string', 'format': 'date-time'},
+ 'version': {'type': 'string'},
+ 'min_version': {'type': 'string'}
+ },
+ # NOTE: version and min_version have been added since Kilo,
+ # so they should not be required.
+ 'required': ['id', 'links', 'status', 'updated'],
+ 'additionalProperties': False
+}
+
+list_versions = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'versions': {
+ 'type': 'array',
+ 'items': _version
+ }
+ },
+ 'required': ['versions'],
+ 'additionalProperties': False
+ }
+}
diff --git a/tempest/clients.py b/tempest/clients.py
index 7cb4347..c0d4585 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -77,6 +77,7 @@
TenantNetworksClient
from tempest.services.compute.json.tenant_usages_client import \
TenantUsagesClient
+from tempest.services.compute.json.versions_client import VersionsClient
from tempest.services.compute.json.volumes_extensions_client import \
VolumesExtensionsClient
from tempest.services.data_processing.v1_1.data_processing_client import \
@@ -321,8 +322,9 @@
'build_timeout': CONF.volume.build_timeout
})
self.volumes_extensions_client = VolumesExtensionsClient(
- self.auth_provider, default_volume_size=CONF.volume.volume_size,
- **params_volume)
+ self.auth_provider, **params_volume)
+ self.compute_versions_client = VersionsClient(self.auth_provider,
+ **params_volume)
def _set_database_clients(self):
self.database_flavors_client = DatabaseFlavorsClient(
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index e05cab3..49d5f8c 100755
--- a/tempest/cmd/account_generator.py
+++ b/tempest/cmd/account_generator.py
@@ -25,7 +25,7 @@
**Usage:** ``tempest-account-generator [-h] [OPTIONS] accounts_file.yaml``.
Positional Arguments
------------------
+--------------------
**accounts_file.yaml** (Required) Provide an output accounts yaml file. Utility
creates a .yaml file in the directory where the command is ran. The appropriate
name for the file is *accounts.yaml* and it should be placed in *tempest/etc*
@@ -49,7 +49,7 @@
+----------+------------------+----------------------+
Optional Arguments
------------------
+------------------
**-h**, **--help** (Optional) Shows help message with the description of
utility and its arguments, and exits.
@@ -90,7 +90,7 @@
import yaml
from tempest import config
-from tempest import exceptions
+from tempest import exceptions as exc
from tempest.services.identity.v2.json import identity_client
from tempest.services.network.json import network_client
import tempest_lib.auth
@@ -155,11 +155,10 @@
for r in u.get('roles', ()):
try:
role = filter(lambda r_: r_['name'] == r, roles)[0]
- u['role_ids'] += [role['id']]
except IndexError:
- raise exceptions.TempestException(
- "Role: %s - doesn't exist" % r
- )
+ msg = "Role: %s doesn't exist" % r
+ raise exc.InvalidConfiguration(msg)
+ u['role_ids'] += [role['id']]
existing = [x['name'] for x in identity_admin.list_tenants()['tenants']]
for tenant in resources['tenants']:
if tenant not in existing:
@@ -285,17 +284,18 @@
{'number': 1,
'prefix': 'alt',
'roles': (CONF.auth.tempest_roles +
- [CONF.object_storage.operator_role])},
- {'number': 1,
- 'prefix': 'swift_admin',
- 'roles': (CONF.auth.tempest_roles +
- [CONF.object_storage.operator_role,
- CONF.object_storage.reseller_admin_role])},
- {'number': 1,
- 'prefix': 'stack_owner',
- 'roles': (CONF.auth.tempest_roles +
- [CONF.orchestration.stack_owner_role])},
- ]
+ [CONF.object_storage.operator_role])}]
+ if CONF.service_available.swift:
+ spec.append({'number': 1,
+ 'prefix': 'swift_admin',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.operator_role,
+ CONF.object_storage.reseller_admin_role])})
+ if CONF.service_available.heat:
+ spec.append({'number': 1,
+ 'prefix': 'stack_owner',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.orchestration.stack_owner_role])})
if opts.admin:
spec.append({
'number': 1,
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index d101dc1..6d4e3a9 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -322,7 +322,7 @@
def list(self):
client = self.client
- vols = client.list_volumes()
+ vols = client.list_volumes()['volumes']
LOG.debug("List count, %s Volumes" % len(vols))
return vols
@@ -353,7 +353,7 @@
LOG.exception("Delete Volume Quotas exception.")
def dry_run(self):
- quotas = self.client.show_quota_usage(self.tenant_id)
+ quotas = self.client.show_quota_usage(self.tenant_id)['quota_set']
self.data['volume_quotas'] = quotas
@@ -372,7 +372,7 @@
def dry_run(self):
client = self.limits_client
- quotas = client.show_limits()
+ quotas = client.show_limits()['limits']
self.data['compute_quotas'] = quotas['absolute']
@@ -770,7 +770,7 @@
def list(self):
client = self.client
- images = client.list_images({"all_tenants": True})
+ images = client.list_images({"all_tenants": True})['images']
if not self.is_save_state:
images = [image for image in images if image['id']
not in self.saved_state_json['images'].keys()]
@@ -930,7 +930,7 @@
def list(self):
client = self.client
- domains = client.list_domains()
+ domains = client.list_domains()['domains']
if not self.is_save_state:
domains = [domain for domain in domains if domain['id']
not in self.saved_state_json['domains'].keys()]
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 7f896d1..6973c87 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -945,7 +945,7 @@
#######################
def _get_volume_by_name(client, name):
- body = client.volumes.list_volumes()
+ body = client.volumes.list_volumes()['volumes']
for volume in body:
if name == volume['display_name']:
return volume
@@ -967,7 +967,7 @@
size = volume['gb']
v_name = volume['name']
body = client.volumes.create_volume(size=size,
- display_name=v_name)
+ display_name=v_name)['volume']
client.volumes.wait_for_volume_status(body['id'], 'available')
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 9e7d894..6d53b59 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -144,6 +144,12 @@
'neutron': os.network_client,
'swift': os.account_client,
}
+ # NOTE (e0ne): Use Cinder API v2 by default because v1 is deprecated
+ if CONF.volume_feature_enabled.api_v2:
+ extensions_client['cinder'] = os.volumes_v2_extension_client
+ else:
+ extensions_client['cinder'] = os.volumes_extension_client
+
if service not in extensions_client:
print('No tempest extensions client for %s' % service)
exit(1)
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 05ea393..5c4d8af 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -27,7 +27,7 @@
def create_test_server(clients, validatable=False, validation_resources=None,
- tenant_network=None, **kwargs):
+ tenant_network=None, wait_until=None, **kwargs):
"""Common wrapper utility returning a test server.
This method is a common wrapper returning a test server that can be
@@ -37,6 +37,9 @@
:param validatable: Whether the server will be pingable or sshable.
:param validation_resources: Resources created for the connection to the
server. Include a keypair, a security group and an IP.
+ :param tenant_network: Tenant network to be used for creating a server.
+ :param wait_until: Server status to wait for the server to reach after
+ its creation.
:returns a tuple
"""
@@ -78,8 +81,8 @@
LOG.debug("No key provided.")
if CONF.validation.connect_method == 'floating':
- if 'wait_until' not in kwargs:
- kwargs['wait_until'] = 'ACTIVE'
+ if wait_until is None:
+ wait_until = 'ACTIVE'
body = clients.servers_client.create_server(name, image_id, flavor,
**kwargs)
@@ -96,11 +99,11 @@
# long for PEP8 compliance so:
assoc = clients.floating_ips_client.associate_floating_ip_to_server
- if 'wait_until' in kwargs:
+ if wait_until:
for server in servers:
try:
waiters.wait_for_server_status(
- clients.servers_client, server['id'], kwargs['wait_until'])
+ clients.servers_client, server['id'], wait_until)
# Multiple validatable servers are not supported for now. Their
# creation will fail with the condition above (l.58).
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 72ef255..248513e 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -123,11 +123,19 @@
The client should also have build_interval and build_timeout attributes.
"""
image = client.show_image(image_id)
+ # Compute image client return response wrapped in 'image' element
+ # which is not case with glance image client.
+ if 'image' in image:
+ image = image['image']
start = int(time.time())
while image['status'] != status:
time.sleep(client.build_interval)
image = client.show_image(image_id)
+ # Compute image client return response wrapped in 'image' element
+ # which is not case with glance image client.
+ if 'image' in image:
+ image = image['image']
status_curr = image['status']
if status_curr == 'ERROR':
raise exceptions.AddImageException(image_id=image_id)
@@ -154,13 +162,13 @@
def wait_for_volume_status(client, volume_id, status):
"""Waits for a Volume to reach a given status."""
- body = client.show_volume(volume_id)
+ body = client.show_volume(volume_id)['volume']
volume_status = body['status']
start = int(time.time())
while volume_status != status:
time.sleep(client.build_interval)
- body = client.show_volume(volume_id)
+ body = client.show_volume(volume_id)['volume']
volume_status = body['status']
if volume_status == 'error':
raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
diff --git a/tempest/config.py b/tempest/config.py
index 663a9f9..295b74d 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -77,7 +77,7 @@
cfg.BoolOpt('create_isolated_networks',
default=True,
help="If allow_tenant_isolation is set to True and Neutron is "
- "enabled Tempest will try to create a useable network, "
+ "enabled Tempest will try to create a usable network, "
"subnet, and router when needed for each tenant it "
"creates. However in some neutron configurations, like "
"with VLAN provider networks, this doesn't work. So if "
@@ -117,9 +117,7 @@
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The admin endpoint type to use for OpenStack Identity "
- "(Keystone) API v2",
- deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
- group='identity')]),
+ "(Keystone) API v2"),
cfg.StrOpt('v2_public_endpoint_type',
default='publicURL',
choices=['public', 'admin', 'internal',
@@ -133,9 +131,7 @@
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The endpoint type to use for OpenStack Identity "
- "(Keystone) API v3",
- deprecated_opts=[cfg.DeprecatedOpt('endpoint_type',
- group='identity')]),
+ "(Keystone) API v3"),
cfg.StrOpt('username',
help="Username to use for Nova API requests."),
cfg.StrOpt('tenant_name',
@@ -708,6 +704,9 @@
cfg.BoolOpt('snapshot',
default=True,
help='Runs Cinder volume snapshot test'),
+ cfg.BoolOpt('clone',
+ default=True,
+ help='Runs Cinder volume clone test'),
cfg.ListOpt('api_extensions',
default=['all'],
help='A list of enabled volume extensions with a special '
@@ -863,6 +862,7 @@
help="The endpoint type to use for the telemetry service."),
cfg.BoolOpt('too_slow_to_test',
default=True,
+ deprecated_for_removal=True,
help="This variable is used as flag to enable "
"notification tests")
]
@@ -887,7 +887,8 @@
help="Where the dashboard can be found"),
cfg.StrOpt('login_url',
default='http://localhost/auth/login/',
- help="Login page for the dashboard"),
+ help="Login page for the dashboard",
+ deprecated_for_removal=True),
]
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index db6375f..06ca09b 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -29,6 +29,7 @@
VI_HEADER_RE = re.compile(r"^#\s+vim?:.+")
RAND_NAME_HYPHEN_RE = re.compile(r".*rand_name\(.+[\-\_][\"\']\)")
mutable_default_args = re.compile(r"^\s*def .+\((.+=\{\}|.+=\[\])")
+TESTTOOLS_SKIP_DECORATOR = re.compile(r'\s*@testtools\.skip\((.*)\)')
def import_no_clients_in_api_and_scenario_tests(physical_line, filename):
@@ -132,6 +133,16 @@
yield (0, msg)
+def no_testtools_skip_decorator(logical_line):
+ """Check that methods do not have the testtools.skip decorator
+
+ T109
+ """
+ if TESTTOOLS_SKIP_DECORATOR.match(logical_line):
+ yield (0, "T109: Cannot use testtools.skip decorator; instead use "
+ "decorators.skip_because from tempest-lib")
+
+
def factory(register):
register(import_no_clients_in_api_and_scenario_tests)
register(scenario_tests_need_service_tags)
@@ -140,3 +151,4 @@
register(service_tags_not_in_module_path)
register(no_hyphen_at_end_of_rand_name)
register(no_mutable_default_args)
+ register(no_testtools_skip_decorator)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 40b6d83..4f113d3 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -18,6 +18,7 @@
import netaddr
from oslo_log import log
+from oslo_serialization import jsonutils as json
import six
from tempest_lib.common.utils import misc as misc_utils
from tempest_lib import exceptions as lib_exc
@@ -57,14 +58,19 @@
cls.security_group_rules_client = (
cls.manager.security_group_rules_client)
cls.servers_client = cls.manager.servers_client
- cls.volumes_client = cls.manager.volumes_client
- cls.snapshots_client = cls.manager.snapshots_client
cls.interface_client = cls.manager.interfaces_client
# Neutron network client
cls.network_client = cls.manager.network_client
# Heat client
cls.orchestration_client = cls.manager.orchestration_client
+ if CONF.volume_feature_enabled.api_v1:
+ cls.volumes_client = cls.manager.volumes_client
+ cls.snapshots_client = cls.manager.snapshots_client
+ else:
+ cls.volumes_client = cls.manager.volumes_v2_client
+ cls.snapshots_client = cls.manager.snapshots_v2_client
+
# ## Methods to handle sync and async deletes
def setUp(self):
@@ -201,7 +207,7 @@
name = data_utils.rand_name(self.__class__.__name__)
volume = self.volumes_client.create_volume(
size=size, display_name=name, snapshot_id=snapshot_id,
- imageRef=imageRef, volume_type=volume_type)
+ imageRef=imageRef, volume_type=volume_type)['volume']
if wait_on_delete:
self.addCleanup(self.volumes_client.wait_for_resource_deletion,
@@ -215,11 +221,15 @@
cleanup_callable=self.delete_wrapper,
cleanup_args=[self.volumes_client.delete_volume, volume['id']])
- self.assertEqual(name, volume['display_name'])
+ # NOTE(e0ne): Cinder API v2 uses name instead of display_name
+ if 'display_name' in volume:
+ self.assertEqual(name, volume['display_name'])
+ else:
+ self.assertEqual(name, volume['name'])
self.volumes_client.wait_for_volume_status(volume['id'], 'available')
# The volume retrieved on creation has a non-up-to-date status.
# Retrieval after it becomes active ensures correct details.
- volume = self.volumes_client.show_volume(volume['id'])
+ volume = self.volumes_client.show_volume(volume['id'])['volume']
return volume
def _create_loginable_secgroup_rule(self, secgroup_id=None):
@@ -416,6 +426,21 @@
cleanup_callable=self.delete_wrapper,
cleanup_args=[_image_client.delete_image, image_id])
snapshot_image = _image_client.get_image_meta(image_id)
+
+ bdm = snapshot_image.get('properties', {}).get('block_device_mapping')
+ if bdm:
+ bdm = json.loads(bdm)
+ if bdm and 'snapshot_id' in bdm[0]:
+ snapshot_id = bdm[0]['snapshot_id']
+ self.addCleanup(
+ self.snapshots_client.wait_for_resource_deletion,
+ snapshot_id)
+ self.addCleanup(
+ self.delete_wrapper, self.snapshots_client.delete_snapshot,
+ snapshot_id)
+ self.snapshots_client.wait_for_snapshot_status(snapshot_id,
+ 'available')
+
image_name = snapshot_image['name']
self.assertEqual(name, image_name)
LOG.debug("Created snapshot image %s for server %s",
@@ -429,14 +454,14 @@
self.assertEqual(self.volume['id'], volume['id'])
self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
# Refresh the volume after the attachment
- self.volume = self.volumes_client.show_volume(volume['id'])
+ self.volume = self.volumes_client.show_volume(volume['id'])['volume']
def nova_volume_detach(self):
self.servers_client.detach_volume(self.server['id'], self.volume['id'])
self.volumes_client.wait_for_volume_status(self.volume['id'],
'available')
- volume = self.volumes_client.show_volume(self.volume['id'])
+ volume = self.volumes_client.show_volume(self.volume['id'])['volume']
self.assertEqual('available', volume['status'])
def rebuild_server(self, server_id, image=None,
@@ -594,6 +619,12 @@
*args, **kwargs)
return ports_list['ports']
+ def _list_agents(self, *args, **kwargs):
+ """List agents using admin creds """
+ agents_list = self.admin_manager.network_client.list_agents(
+ *args, **kwargs)
+ return agents_list['agents']
+
def _create_subnet(self, network, client=None, namestart='subnet-smoke',
**kwargs):
"""
@@ -1094,6 +1125,7 @@
ports.append({'port': port.id})
if ports:
create_kwargs['networks'] = ports
+ self.ports = ports
return super(NetworkScenarioTest, self).create_server(
name=name, image=image, flavor=flavor,
@@ -1268,7 +1300,10 @@
@classmethod
def setup_clients(cls):
super(EncryptionScenarioTest, cls).setup_clients()
- cls.admin_volume_types_client = cls.os_adm.volume_types_client
+ if CONF.volume_feature_enabled.api_v1:
+ cls.admin_volume_types_client = cls.os_adm.volume_types_client
+ else:
+ cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
def _wait_for_volume_status(self, status):
self.status_timeout(
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 8e91a6d..d5bad64 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -88,7 +88,7 @@
parser = HorizonHTMLParser()
parser.feed(response)
- # construct login url for dashboard, discovery accomodates non-/ web
+ # construct login url for dashboard, discovery accommodates non-/ web
# root for dashboard
login_url = CONF.dashboard.dashboard_url + parser.login[1:]
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index c38ce2d..402bc68 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -63,19 +63,22 @@
def nova_show(self):
got_server = self.servers_client.show_server(self.server['id'])
+ excluded_keys = ['OS-EXT-AZ:availability_zone']
+ # Exclude these keys because of LP:#1486475
+ excluded_keys.extend(['OS-EXT-STS:power_state', 'updated'])
self.assertThat(
self.server, custom_matchers.MatchesDictExceptForKeys(
- got_server, excluded_keys=['OS-EXT-AZ:availability_zone']))
+ got_server, excluded_keys=excluded_keys))
def cinder_create(self):
self.volume = self.create_volume()
def cinder_list(self):
- volumes = self.volumes_client.list_volumes()
+ volumes = self.volumes_client.list_volumes()['volumes']
self.assertIn(self.volume['id'], [x['id'] for x in volumes])
def cinder_show(self):
- volume = self.volumes_client.show_volume(self.volume['id'])
+ volume = self.volumes_client.show_volume(self.volume['id'])['volume']
self.assertEqual(self.volume, volume)
def nova_reboot(self):
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 71c48fe..62b2976 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -100,11 +100,11 @@
@test.services('compute', 'network')
def test_server_connectivity_stop_start(self):
self._setup_network_and_servers()
- self.servers_client.stop(self.server['id'])
+ self.servers_client.stop_server(self.server['id'])
waiters.wait_for_server_status(self.servers_client,
self.server['id'], 'SHUTOFF')
self._check_network_connectivity(should_connect=False)
- self.servers_client.start(self.server['id'])
+ self.servers_client.start_server(self.server['id'])
self._wait_server_status_and_check_network_connectivity()
@test.idempotent_id('7b6860c2-afa3-4846-9522-adeb38dfbe08')
@@ -164,5 +164,5 @@
flavor_ref=resize_flavor)
waiters.wait_for_server_status(self.servers_client, self.server['id'],
'VERIFY_RESIZE')
- self.servers_client.confirm_resize(self.server['id'])
+ self.servers_client.confirm_resize_server(self.server['id'])
self._wait_server_status_and_check_network_connectivity()
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 0662938..8ca5e72 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -108,10 +108,12 @@
self.network, self.subnet, self.router = self.create_networks(**kwargs)
self.check_networks()
+ self.ports = []
self.port_id = None
if boot_with_port:
# create a port on the network and boot with that
self.port_id = self._create_port(self.network['id']).id
+ self.ports.append({'port': self.port_id})
name = data_utils.rand_name('server-smoke')
server = self._create_server(name, self.network, self.port_id)
@@ -632,7 +634,11 @@
# Setup the network, create a port and boot the server from that port.
self._setup_network_and_servers(boot_with_port=True)
_, server = self.floating_ip_tuple
- self.assertIsNotNone(self.port_id,
+ self.assertEqual(1, len(self.ports),
+ 'There should only be one port created for '
+ 'server %s.' % server['id'])
+ port_id = self.ports[0]['port']
+ self.assertIsNotNone(port_id,
'Server should have been created from a '
'pre-existing port.')
# Assert the port is bound to the server.
@@ -641,13 +647,86 @@
self.assertEqual(1, len(port_list),
'There should only be one port created for '
'server %s.' % server['id'])
- self.assertEqual(self.port_id, port_list[0]['id'])
+ self.assertEqual(port_id, port_list[0]['id'])
# Delete the server.
self.servers_client.delete_server(server['id'])
waiters.wait_for_server_termination(self.servers_client, server['id'])
# Assert the port still exists on the network but is unbound from
# the deleted server.
- port = self.network_client.show_port(self.port_id)['port']
+ port = self.network_client.show_port(port_id)['port']
self.assertEqual(self.network['id'], port['network_id'])
self.assertEqual('', port['device_id'])
self.assertEqual('', port['device_owner'])
+
+ @test.idempotent_id('2e788c46-fb3f-4ac9-8f82-0561555bea73')
+ @test.services('compute', 'network')
+ def test_router_rescheduling(self):
+ """Tests that router can be removed from agent and add to a new agent.
+
+ 1. Verify connectivity
+ 2. Remove router from all l3-agents
+ 3. Verify connectivity is down
+ 4. Assign router to new l3-agent (or old one if no new agent is
+ available)
+ 5. Verify connectivity
+ """
+
+ # TODO(yfried): refactor this test to be used for other agents (dhcp)
+ # as well
+
+ list_hosts = (self.admin_manager.network_client.
+ list_l3_agents_hosting_router)
+ schedule_router = (self.admin_manager.network_client.
+ add_router_to_l3_agent)
+ unschedule_router = (self.admin_manager.network_client.
+ remove_router_from_l3_agent)
+
+ agent_list = set(a["id"] for a in
+ self._list_agents(agent_type="L3 agent"))
+ self._setup_network_and_servers()
+
+ # NOTE(kevinbenton): we have to use the admin credentials to check
+ # for the distributed flag because self.router only has a tenant view.
+ admin = self.admin_manager.network_client.show_router(self.router.id)
+ if admin['router'].get('distributed', False):
+ msg = "Rescheduling test does not apply to distributed routers."
+ raise self.skipException(msg)
+
+ self.check_public_network_connectivity(should_connect=True)
+
+ # remove resource from agents
+ hosting_agents = set(a["id"] for a in
+ list_hosts(self.router.id)['agents'])
+ no_migration = agent_list == hosting_agents
+ LOG.info("Router will be assigned to {mig} hosting agent".
+ format(mig="the same" if no_migration else "a new"))
+
+ for hosting_agent in hosting_agents:
+ unschedule_router(hosting_agent, self.router.id)
+ self.assertNotIn(hosting_agent,
+ [a["id"] for a in
+ list_hosts(self.router.id)['agents']],
+ 'unscheduling router failed')
+
+ # verify resource is un-functional
+ self.check_public_network_connectivity(
+ should_connect=False,
+ msg='after router unscheduling',
+ should_check_floating_ip_status=False
+ )
+
+ # schedule resource to new agent
+ target_agent = list(hosting_agents if no_migration else
+ agent_list - hosting_agents)[0]
+ schedule_router(target_agent,
+ self.router['id'])
+ self.assertEqual(
+ target_agent,
+ list_hosts(self.router.id)['agents'][0]['id'],
+ "Router failed to reschedule. Hosting agent doesn't match "
+ "target agent")
+
+ # verify resource is functional
+ self.check_public_network_connectivity(
+ should_connect=True,
+ msg='After router rescheduling')
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 18fd09d..1db1ac2 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -161,9 +161,6 @@
cls.floating_ip_access = not CONF.network.public_router_id
- def cleanup_wrapper(self, resource):
- self.cleanup_resource(resource, self.__class__.__name__)
-
def setUp(self):
super(TestSecurityGroupsBasicOps, self).setUp()
self._deploy_tenant(self.primary_tenant)
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 8693fb3..99eecae 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -63,7 +63,7 @@
'VERIFY_RESIZE')
LOG.debug("Confirming resize of instance %s", instance_id)
- self.servers_client.confirm_resize(instance_id)
+ self.servers_client.confirm_resize_server(instance_id)
waiters.wait_for_server_status(self.servers_client, instance_id,
'ACTIVE')
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_swift_telemetry_middleware.py
index 29ce1a0..c5a0e7c 100644
--- a/tempest/scenario/test_swift_telemetry_middleware.py
+++ b/tempest/scenario/test_swift_telemetry_middleware.py
@@ -50,9 +50,6 @@
skip_msg = ("%s skipped as ceilometer is not available" %
cls.__name__)
raise cls.skipException(skip_msg)
- elif CONF.telemetry.too_slow_to_test:
- skip_msg = "Ceilometer feature for fast work mysql is disabled"
- raise cls.skipException(skip_msg)
@classmethod
def setup_clients(cls):
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 39dc6e4..ba419a6 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -11,6 +11,7 @@
# under the License.
from oslo_log import log
+from tempest_lib import decorators
from tempest.common.utils import data_utils
from tempest.common import waiters
@@ -48,7 +49,7 @@
vol_name = data_utils.rand_name('volume-origin')
return self.create_volume(name=vol_name, imageRef=img_uuid)
- def _boot_instance_from_volume(self, vol_id, keypair, security_group):
+ def _get_bdm(self, vol_id, delete_on_termination=False):
# NOTE(gfidente): the syntax for block_device_mapping is
# dev_name=id:type:size:delete_on_terminate
# where type needs to be "snap" if the server is booted
@@ -56,12 +57,20 @@
bd_map = [{
'device_name': 'vda',
'volume_id': vol_id,
- 'delete_on_termination': '0'}]
- create_kwargs = {
- 'block_device_mapping': bd_map,
- 'key_name': keypair['name'],
- 'security_groups': [{'name': security_group['name']}]
- }
+ 'delete_on_termination': str(int(delete_on_termination))}]
+ return {'block_device_mapping': bd_map}
+
+ def _boot_instance_from_volume(self, vol_id, keypair=None,
+ security_group=None,
+ delete_on_termination=False):
+ create_kwargs = dict()
+ if keypair:
+ create_kwargs['key_name'] = keypair['name']
+ if security_group:
+ create_kwargs['security_groups'] = [
+ {'name': security_group['name']}]
+ create_kwargs.update(self._get_bdm(
+ vol_id, delete_on_termination=delete_on_termination))
return self.create_server(image='', create_kwargs=create_kwargs)
def _create_snapshot_from_volume(self, vol_id):
@@ -74,7 +83,13 @@
self.snapshots_client.wait_for_resource_deletion, snap['id'])
self.addCleanup(self.snapshots_client.delete_snapshot, snap['id'])
self.snapshots_client.wait_for_snapshot_status(snap['id'], 'available')
- self.assertEqual(snap_name, snap['display_name'])
+
+ # NOTE(e0ne): Cinder API v2 uses name instead of display_name
+ if 'display_name' in snap:
+ self.assertEqual(snap_name, snap['display_name'])
+ else:
+ self.assertEqual(snap_name, snap['name'])
+
return snap
def _create_volume_from_snapshot(self, snap_id):
@@ -84,28 +99,14 @@
def _stop_instances(self, instances):
# NOTE(gfidente): two loops so we do not wait for the status twice
for i in instances:
- self.servers_client.stop(i['id'])
+ self.servers_client.stop_server(i['id'])
for i in instances:
waiters.wait_for_server_status(self.servers_client,
i['id'], 'SHUTOFF')
- def _detach_volumes(self, volumes):
- # NOTE(gfidente): two loops so we do not wait for the status twice
- for v in volumes:
- self.volumes_client.detach_volume(v['id'])
- for v in volumes:
- self.volumes_client.wait_for_volume_status(v['id'], 'available')
-
def _ssh_to_server(self, server, keypair):
if CONF.compute.use_floatingip_for_ssh:
- floating_ip = (self.floating_ips_client.create_floating_ip()
- ['floating_ip'])
- self.addCleanup(self.delete_wrapper,
- self.floating_ips_client.delete_floating_ip,
- floating_ip['id'])
- self.floating_ips_client.associate_floating_ip_to_server(
- floating_ip['ip'], server['id'])
- ip = floating_ip['ip']
+ ip = self.create_floating_ip(server)['ip']
else:
ip = server
@@ -175,18 +176,35 @@
# deletion operations to succeed
self._stop_instances([instance_2nd, instance_from_snapshot])
+ @decorators.skip_because(bug='1489581')
+ @test.idempotent_id('36c34c67-7b54-4b59-b188-02a2f458a63b')
+ @test.services('compute', 'volume', 'image')
+ def test_create_ebs_image_and_check_boot(self):
+ # create an instance from volume
+ volume_origin = self._create_volume_from_image()
+ instance = self._boot_instance_from_volume(volume_origin['id'],
+ delete_on_termination=True)
+ # create EBS image
+ name = data_utils.rand_name('image')
+ image = self.create_server_snapshot(instance, name=name)
+
+ # delete instance
+ self._delete_server(instance)
+
+ # boot instance from EBS image
+ instance = self.create_server(image=image['id'])
+ # just ensure that instance booted
+
+ # delete instance
+ self._delete_server(instance)
+
class TestVolumeBootPatternV2(TestVolumeBootPattern):
- def _boot_instance_from_volume(self, vol_id, keypair, security_group):
+ def _get_bdm(self, vol_id, delete_on_termination=False):
bd_map_v2 = [{
'uuid': vol_id,
'source_type': 'volume',
'destination_type': 'volume',
'boot_index': 0,
- 'delete_on_termination': False}]
- create_kwargs = {
- 'block_device_mapping_v2': bd_map_v2,
- 'key_name': keypair['name'],
- 'security_groups': [{'name': security_group['name']}]
- }
- return self.create_server(image='', create_kwargs=create_kwargs)
+ 'delete_on_termination': delete_on_termination}]
+ return {'block_device_mapping_v2': bd_map_v2}
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index 41b3470..0a7d492 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -44,7 +44,7 @@
self.flavors_client = os.flavors_client
def ssh_user(self, image_id):
- _image = self.images_client.show_image(image_id)
+ _image = self.images_client.show_image(image_id)['image']
for regex, user in self.ssh_users:
# First match wins
if re.match(regex, _image['name']) is not None:
@@ -57,14 +57,14 @@
string=str(image['name']))
def is_sshable_image(self, image_id):
- _image = self.images_client.show_image(image_id)
+ _image = self.images_client.show_image(image_id)['image']
return self._is_sshable_image(_image)
def _is_flavor_enough(self, flavor, image):
return image['minDisk'] <= flavor['disk']
def is_flavor_enough(self, flavor_id, image_id):
- _image = self.images_client.show_image(image_id)
+ _image = self.images_client.show_image(image_id)['image']
_flavor = self.flavors_client.show_flavor(flavor_id)['flavor']
return self._is_flavor_enough(_flavor, _image)
@@ -131,7 +131,7 @@
return []
if not hasattr(self, '_scenario_images'):
try:
- images = self.images_client.list_images()
+ images = self.images_client.list_images()['images']
self._scenario_images = [
(self._normalize_name(i['name']), dict(image_ref=i['id']))
for i in images if re.search(self.image_pattern,
diff --git a/tempest/services/compute/json/floating_ip_pools_client.py b/tempest/services/compute/json/floating_ip_pools_client.py
index 7a4434f..c83537a 100644
--- a/tempest/services/compute/json/floating_ip_pools_client.py
+++ b/tempest/services/compute/json/floating_ip_pools_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
diff --git a/tempest/services/compute/json/floating_ips_bulk_client.py b/tempest/services/compute/json/floating_ips_bulk_client.py
index c51f77e..dfe69f0 100644
--- a/tempest/services/compute/json/floating_ips_bulk_client.py
+++ b/tempest/services/compute/json/floating_ips_bulk_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
from tempest.common import service_client
@@ -47,5 +47,4 @@
resp, body = self.put('os-floating-ips-bulk/delete', post_body)
body = json.loads(body)
self.validate_response(schema.delete_floating_ips_bulk, resp, body)
- data = body['floating_ips_bulk_delete']
- return service_client.ResponseBodyData(resp, data)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 4e7e93f..99fdfe6 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -47,7 +47,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(_schema, resp, body)
- return service_client.ResponseBodyList(resp, body['images'])
+ return service_client.ResponseBody(resp, body)
def show_image(self, image_id):
"""Returns the details of a single image."""
@@ -55,7 +55,7 @@
self.expected_success(200, resp.status)
body = json.loads(body)
self.validate_response(schema.get_image, resp, body)
- return service_client.ResponseBody(resp, body['image'])
+ return service_client.ResponseBody(resp, body)
def delete_image(self, image_id):
"""Deletes the provided image."""
@@ -68,7 +68,7 @@
resp, body = self.get("images/%s/metadata" % image_id)
body = json.loads(body)
self.validate_response(schema.image_metadata, resp, body)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def set_image_metadata(self, image_id, meta):
"""Sets the metadata for an image."""
@@ -76,7 +76,7 @@
resp, body = self.put('images/%s/metadata' % image_id, post_body)
body = json.loads(body)
self.validate_response(schema.image_metadata, resp, body)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def update_image_metadata(self, image_id, meta):
"""Updates the metadata for an image."""
@@ -84,14 +84,14 @@
resp, body = self.post('images/%s/metadata' % image_id, post_body)
body = json.loads(body)
self.validate_response(schema.image_metadata, resp, body)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def show_image_metadata_item(self, image_id, key):
"""Returns the value for a specific image metadata key."""
resp, body = self.get("images/%s/metadata/%s" % (image_id, key))
body = json.loads(body)
self.validate_response(schema.image_meta_item, resp, body)
- return service_client.ResponseBody(resp, body['meta'])
+ return service_client.ResponseBody(resp, body)
def set_image_metadata_item(self, image_id, key, meta):
"""Sets the value for a specific image metadata key."""
@@ -100,7 +100,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.image_meta_item, resp, body)
- return service_client.ResponseBody(resp, body['meta'])
+ return service_client.ResponseBody(resp, body)
def delete_image_metadata_item(self, image_id, key):
"""Deletes a single image metadata key/value pair."""
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 4287619..b64b4a5 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -25,4 +25,4 @@
resp, body = self.get("limits")
body = json.loads(body)
self.validate_response(schema.get_limit, resp, body)
- return service_client.ResponseBody(resp, body['limits'])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index 06c8f13..b302539 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -31,4 +31,4 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_migrations, resp, body)
- return service_client.ResponseBodyList(resp, body['migrations'])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/quota_classes_client.py b/tempest/services/compute/json/quota_classes_client.py
index 30d3501..d55c3f1 100644
--- a/tempest/services/compute/json/quota_classes_client.py
+++ b/tempest/services/compute/json/quota_classes_client.py
@@ -29,7 +29,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(classes_schema.get_quota_class_set, resp, body)
- return service_client.ResponseBody(resp, body['quota_class_set'])
+ return service_client.ResponseBody(resp, body)
def update_quota_class_set(self, quota_class_id, **kwargs):
"""
@@ -43,4 +43,4 @@
body = json.loads(body)
self.validate_response(classes_schema.update_quota_class_set,
resp, body)
- return service_client.ResponseBody(resp, body['quota_class_set'])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 88d0567..4a1b909 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -30,7 +30,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.get_quota_set, resp, body)
- return service_client.ResponseBody(resp, body['quota_set'])
+ return service_client.ResponseBody(resp, body)
def show_default_quota_set(self, tenant_id):
"""List the default quota set for a tenant."""
@@ -39,7 +39,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.get_quota_set, resp, body)
- return service_client.ResponseBody(resp, body['quota_set'])
+ return service_client.ResponseBody(resp, body)
def update_quota_set(self, tenant_id, user_id=None, **kwargs):
"""
@@ -56,7 +56,7 @@
body = json.loads(body)
self.validate_response(schema.update_quota_set, resp, body)
- return service_client.ResponseBody(resp, body['quota_set'])
+ return service_client.ResponseBody(resp, body)
def delete_quota_set(self, tenant_id):
"""Delete the tenant's quota set."""
diff --git a/tempest/services/compute/json/security_group_rules_client.py b/tempest/services/compute/json/security_group_rules_client.py
index c9096d0..c1c6b1a 100644
--- a/tempest/services/compute/json/security_group_rules_client.py
+++ b/tempest/services/compute/json/security_group_rules_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import security_groups as schema
diff --git a/tempest/services/compute/json/server_groups_client.py b/tempest/services/compute/json/server_groups_client.py
index 30e9e5b..33501fb 100644
--- a/tempest/services/compute/json/server_groups_client.py
+++ b/tempest/services/compute/json/server_groups_client.py
@@ -14,7 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import servers as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 671450a..5603fed 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -97,35 +97,16 @@
self.validate_response(create_schema, resp, body)
return service_client.ResponseBody(resp, body['server'])
- def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
- accessIPv6=None, disk_config=None):
+ def update_server(self, server_id, **kwargs):
+ """Updates the properties of an existing server.
+ Most parameters except the following are passed to the API without
+ any changes.
+ :param disk_config: The name is changed to OS-DCF:diskConfig
"""
- Updates the properties of an existing server.
- server_id: The id of an existing server.
- name: The name of the server.
- personality: A list of files to be injected into the server.
- accessIPv4: The IPv4 access address for the server.
- accessIPv6: The IPv6 access address for the server.
- """
+ if kwargs.get('disk_config'):
+ kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config')
- post_body = {}
-
- if meta is not None:
- post_body['metadata'] = meta
-
- if name is not None:
- post_body['name'] = name
-
- if accessIPv4 is not None:
- post_body['accessIPv4'] = accessIPv4
-
- if accessIPv6 is not None:
- post_body['accessIPv6'] = accessIPv6
-
- if disk_config is not None:
- post_body['OS-DCF:diskConfig'] = disk_config
-
- post_body = json.dumps({'server': post_body})
+ post_body = json.dumps({'server': kwargs})
resp, body = self.put("servers/%s" % server_id, post_body)
body = json.loads(body)
self.validate_response(schema.update_server, resp, body)
@@ -252,13 +233,13 @@
kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config')
return self.action(server_id, 'resize', None, **kwargs)
- def confirm_resize(self, server_id, **kwargs):
+ def confirm_resize_server(self, server_id, **kwargs):
"""Confirms the flavor change for a server."""
return self.action(server_id, 'confirmResize',
None, schema.server_actions_confirm_resize,
**kwargs)
- def revert_resize(self, server_id, **kwargs):
+ def revert_resize_server(self, server_id, **kwargs):
"""Reverts a server back to its original flavor."""
return self.action(server_id, 'revertResize', None, **kwargs)
@@ -311,10 +292,10 @@
resp, body)
return service_client.ResponseBody(resp, body)
- def stop(self, server_id, **kwargs):
+ def stop_server(self, server_id, **kwargs):
return self.action(server_id, 'os-stop', None, **kwargs)
- def start(self, server_id, **kwargs):
+ def start_server(self, server_id, **kwargs):
return self.action(server_id, 'os-start', None, **kwargs)
def attach_volume(self, server_id, **kwargs):
diff --git a/tempest/services/compute/json/tenant_networks_client.py b/tempest/services/compute/json/tenant_networks_client.py
index d31c5f5..33166c0 100644
--- a/tempest/services/compute/json/tenant_networks_client.py
+++ b/tempest/services/compute/json/tenant_networks_client.py
@@ -24,10 +24,10 @@
resp, body = self.get("os-tenant-networks")
body = json.loads(body)
self.validate_response(schema.list_tenant_networks, resp, body)
- return service_client.ResponseBodyList(resp, body['networks'])
+ return service_client.ResponseBody(resp, body)
def show_tenant_network(self, network_id):
resp, body = self.get("os-tenant-networks/%s" % network_id)
body = json.loads(body)
self.validate_response(schema.get_tenant_network, resp, body)
- return service_client.ResponseBody(resp, body['network'])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/versions_client.py b/tempest/services/compute/json/versions_client.py
new file mode 100644
index 0000000..cbad02c
--- /dev/null
+++ b/tempest/services/compute/json/versions_client.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_serialization import jsonutils as json
+from six.moves import urllib
+
+from tempest.api_schema.response.compute.v2_1 import versions as schema
+from tempest.common import service_client
+
+
+class VersionsClient(service_client.ServiceClient):
+
+ def list_versions(self):
+ # NOTE: The URL which is gotten from keystone's catalog contains
+ # API version and project-id like "v2/{project-id}", but we need
+ # to access the URL which doesn't contain them for getting API
+ # versions. For that, here should use raw_request() instead of
+ # get().
+ endpoint = self.base_url
+ url = urllib.parse.urlparse(endpoint)
+ version_url = '%s://%s/' % (url.scheme, url.netloc)
+
+ resp, body = self.raw_request(version_url, 'GET')
+ body = json.loads(body)
+ self.validate_response(schema.list_versions, resp, body)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index ac55049..db92351 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -23,12 +23,6 @@
class VolumesExtensionsClient(service_client.ServiceClient):
- def __init__(self, auth_provider, service, region,
- default_volume_size=1, **kwargs):
- super(VolumesExtensionsClient, self).__init__(
- auth_provider, service, region, **kwargs)
- self.default_volume_size = default_volume_size
-
def list_volumes(self, detail=False, **params):
"""List all the volumes created."""
url = 'os-volumes'
@@ -41,7 +35,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_volumes, resp, body)
- return service_client.ResponseBodyList(resp, body['volumes'])
+ return service_client.ResponseBody(resp, body)
def show_volume(self, volume_id):
"""Returns the details of a single volume."""
@@ -49,9 +43,9 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.create_get_volume, resp, body)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
- def create_volume(self, size=None, **kwargs):
+ def create_volume(self, **kwargs):
"""
Creates a new Volume.
size(Required): Size of volume in GB.
@@ -59,18 +53,11 @@
display_name: Optional Volume Name.
metadata: A dictionary of values to be used as metadata.
"""
- if size is None:
- size = self.default_volume_size
- post_body = {
- 'size': size
- }
- post_body.update(kwargs)
-
- post_body = json.dumps({'volume': post_body})
+ post_body = json.dumps({'volume': kwargs})
resp, body = self.post('os-volumes', post_body)
body = json.loads(body)
self.validate_response(schema.create_get_volume, resp, body)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def delete_volume(self, volume_id):
"""Deletes the Specified Volume."""
diff --git a/tempest/services/database/json/limits_client.py b/tempest/services/database/json/limits_client.py
index 9358a33..da495d7 100644
--- a/tempest/services/database/json/limits_client.py
+++ b/tempest/services/database/json/limits_client.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
@@ -27,4 +28,5 @@
url += '?%s' % urllib.urlencode(params)
resp, body = self.get(url)
self.expected_success(200, resp.status)
+ body = json.loads(body)
return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index 43d253b..7a560d9 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
@@ -43,4 +44,5 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
+ body = json.loads(body)
return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index e6416d6..8eeefe7 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -297,6 +297,17 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, self._parse_resp(body))
+ def update_user_own_password(self, user_id, new_pass, old_pass):
+ """User updates own password"""
+ patch_body = {
+ "password": new_pass,
+ "original_password": old_pass
+ }
+ patch_body = json.dumps({'user': patch_body})
+ resp, body = self.patch('OS-KSCRUD/users/%s' % user_id, patch_body)
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBody(resp, self._parse_resp(body))
+
def list_extensions(self):
"""List all the extensions."""
resp, body = self.get('/extensions')
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 9a60a24..3f27624 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -27,7 +27,8 @@
url = ''
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def create_user(self, user_name, password=None, project_id=None,
email=None, domain_id='default', **kwargs):
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index c5aa41a..6cad746 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -71,7 +71,8 @@
"-json-patch"}
resp, body = self.patch('v2/images/%s' % image_id, data, headers)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def create_image(self, name, container_format, disk_format, **kwargs):
params = {
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index a979523..207554d 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -31,7 +31,8 @@
url = 'os-quota-sets/%s/defaults' % tenant_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = jsonutils.loads(body)
+ return service_client.ResponseBody(resp, body)
def show_quota_set(self, tenant_id, params=None):
"""List the quota set for a tenant."""
@@ -42,7 +43,8 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = jsonutils.loads(body)
+ return service_client.ResponseBody(resp, body)
def show_quota_usage(self, tenant_id):
"""List the quota set for a tenant."""
@@ -66,7 +68,8 @@
post_body = jsonutils.dumps({'quota_set': post_body})
resp, body = self.put('os-quota-sets/%s' % tenant_id, post_body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = jsonutils.loads(body)
+ return service_client.ResponseBody(resp, body)
def delete_quota_set(self, tenant_id):
"""Delete the tenant's quota set."""
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 26f186e..9304f63 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -39,30 +39,6 @@
"""Return the element 'attachment' from input volumes."""
return volume['attachments'][0]
- def _ext_get(self, url, key=None, status=200):
- """Extended get method.
-
- Retrieves requested url, checks that status is expected status and
- return a ResponseBody, ResponseBodyList or ResponseBodyData depending
- on received data's key entry.
-
- If key is not specified or is None we will return the whole body in a
- ResponseBody class.
- """
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.expected_success(status, resp.status)
-
- if not key:
- return service_client.ResponseBody(resp, body)
- elif isinstance(body[key], dict):
- return service_client.ResponseBody(resp, body[key])
- elif isinstance(body[key], list):
- return service_client.ResponseBodyList(resp, body[key])
-
- return service_client.ResponseBodyData(resp, body[key])
-
def _prepare_params(self, params):
"""Prepares params for use in get or _ext_get methods.
@@ -73,14 +49,10 @@
return params
return urllib.urlencode(params)
- def list_volumes(self, detail=False, params=None, return_body=False):
+ def list_volumes(self, detail=False, params=None):
"""List all the volumes created.
Params can be a string (must be urlencoded) or a dictionary.
- If return_body is True then we will return the whole response body in
- a ResponseBody class, it it's False or has not been specified we will
- return only the list of volumes in a ResponseBodyList (inherits from
- list).
"""
url = 'volumes'
if detail:
@@ -88,8 +60,10 @@
if params:
url += '?%s' % self._prepare_params(params)
- key = None if return_body else 'volumes'
- return self._ext_get(url, key)
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBody(resp, body)
def show_volume(self, volume_id):
"""Returns the details of a single volume."""
@@ -97,7 +71,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def create_volume(self, size=None, **kwargs):
"""
@@ -119,7 +93,7 @@
resp, body = self.post('volumes', post_body)
body = json.loads(body)
self.expected_success(self.create_resp, resp.status)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def update_volume(self, volume_id, **kwargs):
"""Updates the Specified Volume."""
@@ -127,7 +101,7 @@
resp, body = self.put('volumes/%s' % volume_id, put_body)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['volume'])
+ return service_client.ResponseBody(resp, body)
def delete_volume(self, volume_id):
"""Deletes the Specified Volume."""
@@ -146,8 +120,7 @@
resp, body = self.post(url, post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
- return service_client.ResponseBody(resp,
- body['os-volume_upload_image'])
+ return service_client.ResponseBody(resp, body)
def attach_volume(self, volume_id, instance_uuid, mountpoint):
"""Attaches a volume to a given instance on a given mountpoint."""
@@ -258,7 +231,7 @@
resp, body = self.post('os-volume-transfer', post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
- return service_client.ResponseBody(resp, body['transfer'])
+ return service_client.ResponseBody(resp, body)
def show_volume_transfer(self, transfer_id):
"""Returns the details of a volume transfer."""
@@ -266,7 +239,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['transfer'])
+ return service_client.ResponseBody(resp, body)
def list_volume_transfers(self, params=None):
"""List all the volume transfers created."""
@@ -276,7 +249,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, body['transfers'])
+ return service_client.ResponseBody(resp, body)
def delete_volume_transfer(self, transfer_id):
"""Delete a volume transfer."""
@@ -294,7 +267,7 @@
resp, body = self.post(url, post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
- return service_client.ResponseBody(resp, body['transfer'])
+ return service_client.ResponseBody(resp, body)
def update_volume_readonly(self, volume_id, readonly):
"""Update the Specified Volume readonly."""
@@ -321,7 +294,7 @@
resp, body = self.post(url, put_body)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def show_volume_metadata(self, volume_id):
"""Get metadata of the volume."""
@@ -329,7 +302,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def update_volume_metadata(self, volume_id, metadata):
"""Update metadata for the volume."""
@@ -338,7 +311,7 @@
resp, body = self.put(url, put_body)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def update_volume_metadata_item(self, volume_id, id, meta_item):
"""Update metadata item for the volume."""
@@ -347,7 +320,7 @@
resp, body = self.put(url, put_body)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['meta'])
+ return service_client.ResponseBody(resp, body)
def delete_volume_metadata_item(self, volume_id, id):
"""Delete metadata item for the volume."""
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index 68e2989..b35f587 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -30,7 +30,7 @@
name = data_utils.rand_name("volume")
self.logger.info("creating volume: %s" % name)
volume = self.manager.volumes_client.create_volume(
- display_name=name)
+ display_name=name)['volume']
self.manager.volumes_client.wait_for_volume_status(volume['id'],
'available')
self.logger.info("created volume: %s" % volume['id'])
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index dc7d217..fe481c4 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -85,7 +85,7 @@
self.logger.info("creating volume: %s" % name)
volumes_client = self.manager.volumes_client
self.volume = volumes_client.create_volume(
- display_name=name)
+ display_name=name)['volume']
volumes_client.wait_for_volume_status(self.volume['id'],
'available')
self.logger.info("created volume: %s" % self.volume['id'])
diff --git a/tempest/stress/actions/volume_create_delete.py b/tempest/stress/actions/volume_create_delete.py
index 4870055..3986748 100644
--- a/tempest/stress/actions/volume_create_delete.py
+++ b/tempest/stress/actions/volume_create_delete.py
@@ -20,7 +20,7 @@
name = data_utils.rand_name("volume")
self.logger.info("creating %s" % name)
volumes_client = self.manager.volumes_client
- volume = volumes_client.create_volume(display_name=name)
+ volume = volumes_client.create_volume(display_name=name)['volume']
vol_id = volume['id']
volumes_client.wait_for_volume_status(vol_id, 'available')
self.logger.info("created %s" % volume['id'])
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index a95d400..4a8f729 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -227,7 +227,7 @@
display_name=self.fake_object['name'])
mocked_function = self.fake_client.volumes.wait_for_volume_status
mocked_function.assert_called_once_with(
- self.fake_object.body['id'],
+ self.fake_object.body['volume']['id'],
'available')
def test_create_volume_existing(self):
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 6bc96f2..2de5802 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -240,7 +240,10 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
+ # NOTE (e0ne): mock both v1 and v2 APIs
fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+ fake_os.volumes_v2_extension_client.list_extensions = (
+ fake_list_extensions)
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['fake1', 'fake2', 'fake3'])))
@@ -262,7 +265,10 @@
{'alias': 'fake2'},
{'alias': 'not_fake'}]}
fake_os = mock.MagicMock()
+ # NOTE (e0ne): mock both v1 and v2 APIs
fake_os.volumes_extension_client.list_extensions = fake_list_extensions
+ fake_os.volumes_v2_extension_client.list_extensions = (
+ fake_list_extensions)
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, 'get_enabled_extensions',
return_value=(['all'])))
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index 1acef8a..9bf8059 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -41,7 +41,7 @@
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
self.fake_http = fake_http.fake_httplib2(return_type=200)
- self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(token_client.TokenClient, 'raw_request',
fake_identity._fake_v2_response)
self.useFixture(lockutils_fixtures.ExternalLockFixture())
self.test_accounts = [
@@ -86,7 +86,7 @@
return hash_list
def test_get_hash(self):
- self.stubs.Set(token_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(token_client.TokenClient, 'raw_request',
fake_identity._fake_v2_response)
test_account_class = accounts.Accounts('v2', 'test_name')
hash_list = self._get_hash_list(self.test_accounts)
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
index ed3f931..1bc7147 100644
--- a/tempest/tests/common/test_cred_provider.py
+++ b/tempest/tests/common/test_cred_provider.py
@@ -36,7 +36,7 @@
identity_response = fake_identity._fake_v2_response
credentials_class = auth.KeystoneV2Credentials
- tokenclient_class = v2_client.TokenClientJSON
+ tokenclient_class = v2_client.TokenClient
identity_version = 'v2'
def setUp(self):
@@ -114,7 +114,7 @@
credentials_class = auth.KeystoneV3Credentials
identity_response = fake_identity._fake_v3_response
- tokenclient_class = v3_client.V3TokenClientJSON
+ tokenclient_class = v3_client.V3TokenClient
identity_version = 'v3'
def setUp(self):
diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py
index 7aa6595..68a8295 100644
--- a/tempest/tests/common/test_waiters.py
+++ b/tempest/tests/common/test_waiters.py
@@ -55,8 +55,8 @@
# the volume status is 'error_restoring'.
client = mock.Mock(spec=volumes_client.BaseVolumesClient,
build_interval=1)
- volume1 = {'status': 'restoring-backup'}
- volume2 = {'status': 'error_restoring'}
+ volume1 = {'volume': {'status': 'restoring-backup'}}
+ volume2 = {'volume': {'status': 'error_restoring'}}
mock_show = mock.Mock(side_effect=(volume1, volume2))
client.show_volume = mock_show
volume_id = '7532b91e-aa0a-4e06-b3e5-20c0c5ee1caa'
diff --git a/tempest/tests/fake_tempest_plugin.py b/tempest/tests/fake_tempest_plugin.py
new file mode 100644
index 0000000..f718d0b
--- /dev/null
+++ b/tempest/tests/fake_tempest_plugin.py
@@ -0,0 +1,40 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# 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.test_discover import plugins
+
+
+class FakePlugin(plugins.TempestPlugin):
+ expected_load_test = ["my/test/path", "/home/dir"]
+
+ def load_tests(self):
+ return self.expected_load_test
+
+ def register_opts(self, conf):
+ return
+
+ def get_opt_lists(self):
+ return []
+
+
+class FakeStevedoreObj(object):
+ obj = FakePlugin()
+
+ @property
+ def name(self):
+ return self._name
+
+ def __init__(self, name='Test1'):
+ self._name = name
diff --git a/tempest/tests/services/compute/base.py b/tempest/tests/services/compute/base.py
new file mode 100644
index 0000000..a35a87c
--- /dev/null
+++ b/tempest/tests/services/compute/base.py
@@ -0,0 +1,43 @@
+# Copyright 2015 Deutsche Telekom AG. 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 httplib2
+
+from oslo_serialization import jsonutils as json
+from oslotest import mockpatch
+
+from tempest.tests import base
+
+
+class BaseComputeServiceTest(base.TestCase):
+ def create_response(self, body, to_utf=False, status=200):
+ json_body = {}
+ if body:
+ json_body = json.dumps(body)
+ if to_utf:
+ json_body = json_body.encode('utf-8')
+ response = (httplib2.Response({'status': status}), json_body)
+ return response
+
+ def check_service_client_function(self, function, function2mock,
+ body, to_utf=False, status=200,
+ **kwargs):
+ mocked_response = self.create_response(body, to_utf, status)
+ self.useFixture(mockpatch.Patch(
+ function2mock, return_value=mocked_response))
+ if kwargs:
+ resp = function(**kwargs)
+ else:
+ resp = function()
+ self.assertEqual(body, resp)
diff --git a/tempest/tests/services/compute/test_agents_client.py b/tempest/tests/services/compute/test_agents_client.py
index d14d8bf..9493a32 100644
--- a/tempest/tests/services/compute/test_agents_client.py
+++ b/tempest/tests/services/compute/test_agents_client.py
@@ -12,17 +12,37 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
from tempest.services.compute.json import agents_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestAgentsClient(base.TestCase):
+class TestAgentsClient(base.BaseComputeServiceTest):
+ FAKE_CREATE_AGENT = {
+ "agent":
+ {
+ "url": "http://foo.com",
+ "hypervisor": "kvm",
+ "md5hash": "md5",
+ "version": "2",
+ "architecture": "x86_64",
+ "os": "linux",
+ "agent_id": 1
+ }
+ }
+
+ FAKE_UPDATE_AGENT = {
+ "agent":
+ {
+ "url": "http://foo.com",
+ "hypervisor": "kvm",
+ "md5hash": "md5",
+ "version": "2",
+ "architecture": "x86_64",
+ "os": "linux",
+ "agent_id": 1
+ }
+ }
def setUp(self):
super(TestAgentsClient, self).setUp()
@@ -31,57 +51,34 @@
'compute', 'regionOne')
def _test_list_agents(self, bytes_body=False):
- body = '{"agents": []}'
- if bytes_body:
- body = body.encode('utf-8')
- expected = {"agents": []}
- response = (httplib2.Response({'status': 200}), body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.list_agents,
'tempest.common.service_client.ServiceClient.get',
- return_value=response))
- self.assertEqual(expected, self.client.list_agents())
+ {"agents": []},
+ bytes_body)
def _test_create_agent(self, bytes_body=False):
- expected = {"agent": {"url": "http://foo.com", "hypervisor": "kvm",
- "md5hash": "md5", "version": "2",
- "architecture": "x86_64",
- "os": "linux", "agent_id": 1}}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.create_agent,
'tempest.common.service_client.ServiceClient.post',
- return_value=mocked_resp))
- resp = self.client.create_agent(
+ self.FAKE_CREATE_AGENT,
+ bytes_body,
url="http://foo.com", hypervisor="kvm", md5hash="md5",
- version="2", architecture="x86_64", os="linux"
- )
- self.assertEqual(expected, resp)
+ version="2", architecture="x86_64", os="linux")
def _test_delete_agent(self):
- mocked_resp = (httplib2.Response({'status': 200}), None)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.delete_agent,
'tempest.common.service_client.ServiceClient.delete',
- return_value=mocked_resp))
- self.client.delete_agent("1")
+ {}, agent_id="1")
def _test_update_agent(self, bytes_body=False):
- expected = {"agent": {"url": "http://foo.com", "md5hash": "md5",
- "version": "2", "agent_id": 1}}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.update_agent,
'tempest.common.service_client.ServiceClient.put',
- return_value=mocked_resp))
- resp = self.client.update_agent(
- "1", url="http://foo.com", md5hash="md5", version="2"
- )
- self.assertEqual(expected, resp)
+ self.FAKE_UPDATE_AGENT,
+ bytes_body,
+ agent_id="1", url="http://foo.com", md5hash="md5", version="2")
def test_list_agents_with_str_body(self):
self._test_list_agents()
diff --git a/tempest/tests/services/compute/test_aggregates_client.py b/tempest/tests/services/compute/test_aggregates_client.py
index 14930a7..8184a46 100644
--- a/tempest/tests/services/compute/test_aggregates_client.py
+++ b/tempest/tests/services/compute/test_aggregates_client.py
@@ -12,17 +12,55 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
from tempest.services.compute.json import aggregates_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestAggregatesClient(base.TestCase):
+class TestAggregatesClient(base.BaseComputeServiceTest):
+ FAKE_SHOW_AGGREGATE = {
+ "aggregate":
+ {
+ "name": "hoge",
+ "availability_zone": None,
+ "deleted": False,
+ "created_at":
+ "2015-07-16T03:07:32.000000",
+ "updated_at": None,
+ "hosts": [],
+ "deleted_at": None,
+ "id": 1,
+ "metadata": {}
+ }
+ }
+
+ FAKE_CREATE_AGGREGATE = {
+ "aggregate":
+ {
+ "name": u'\xf4',
+ "availability_zone": None,
+ "deleted": False,
+ "created_at": "2015-07-21T04:11:18.000000",
+ "updated_at": None,
+ "deleted_at": None,
+ "id": 1
+ }
+ }
+
+ FAKE_UPDATE_AGGREGATE = {
+ "aggregate":
+ {
+ "name": u'\xe9',
+ "availability_zone": None,
+ "deleted": False,
+ "created_at": "2015-07-16T03:07:32.000000",
+ "updated_at": "2015-07-23T05:16:29.000000",
+ "hosts": [],
+ "deleted_at": None,
+ "id": 1,
+ "metadata": {}
+ }
+ }
def setUp(self):
super(TestAggregatesClient, self).setUp()
@@ -31,15 +69,11 @@
fake_auth, 'compute', 'regionOne')
def _test_list_aggregates(self, bytes_body=False):
- body = '{"aggregates": []}'
- if bytes_body:
- body = body.encode('utf-8')
- expected = {"aggregates": []}
- response = (httplib2.Response({'status': 200}), body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.list_aggregates,
'tempest.common.service_client.ServiceClient.get',
- return_value=response))
- self.assertEqual(expected, self.client.list_aggregates())
+ {"aggregates": []},
+ bytes_body)
def test_list_aggregates_with_str_body(self):
self._test_list_aggregates()
@@ -48,26 +82,12 @@
self._test_list_aggregates(bytes_body=True)
def _test_show_aggregate(self, bytes_body=False):
- expected = {"aggregate": {"name": "hoge",
- "availability_zone": None,
- "deleted": False,
- "created_at":
- "2015-07-16T03:07:32.000000",
- "updated_at": None,
- "hosts": [],
- "deleted_at": None,
- "id": 1,
- "metadata": {}}}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_aggregate,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_aggregate(1)
- self.assertEqual(expected, resp)
+ self.FAKE_SHOW_AGGREGATE,
+ bytes_body,
+ aggregate_id=1)
def test_show_aggregate_with_str_body(self):
self._test_show_aggregate()
@@ -76,23 +96,12 @@
self._test_show_aggregate(bytes_body=True)
def _test_create_aggregate(self, bytes_body=False):
- expected = {"aggregate": {"name": u'\xf4',
- "availability_zone": None,
- "deleted": False,
- "created_at": "2015-07-21T04:11:18.000000",
- "updated_at": None,
- "deleted_at": None,
- "id": 1}}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.create_aggregate,
'tempest.common.service_client.ServiceClient.post',
- return_value=mocked_resp))
- resp = self.client.create_aggregate(name='hoge')
- self.assertEqual(expected, resp)
+ self.FAKE_CREATE_AGGREGATE,
+ bytes_body,
+ name='hoge')
def test_create_aggregate_with_str_body(self):
self._test_create_aggregate()
@@ -101,34 +110,18 @@
self._test_create_aggregate(bytes_body=True)
def test_delete_aggregate(self):
- expected = {}
- mocked_resp = (httplib2.Response({'status': 200}), None)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.delete_aggregate,
'tempest.common.service_client.ServiceClient.delete',
- return_value=mocked_resp))
- resp = self.client.delete_aggregate("1")
- self.assertEqual(expected, resp)
+ {}, aggregate_id="1")
def _test_update_aggregate(self, bytes_body=False):
- expected = {"aggregate": {"name": u'\xe9',
- "availability_zone": None,
- "deleted": False,
- "created_at": "2015-07-16T03:07:32.000000",
- "updated_at": "2015-07-23T05:16:29.000000",
- "hosts": [],
- "deleted_at": None,
- "id": 1,
- "metadata": {}}}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.update_aggregate,
'tempest.common.service_client.ServiceClient.put',
- return_value=mocked_resp))
- resp = self.client.update_aggregate(1)
- self.assertEqual(expected, resp)
+ self.FAKE_UPDATE_AGGREGATE,
+ bytes_body,
+ aggregate_id=1)
def test_update_aggregate_with_str_body(self):
self._test_update_aggregate()
diff --git a/tempest/tests/services/compute/test_availability_zone_client.py b/tempest/tests/services/compute/test_availability_zone_client.py
new file mode 100644
index 0000000..715cfd7
--- /dev/null
+++ b/tempest/tests/services/compute/test_availability_zone_client.py
@@ -0,0 +1,51 @@
+# 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.services.compute.json import availability_zone_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestAvailabilityZoneClient(base.BaseComputeServiceTest):
+
+ FAKE_AVAILABIRITY_ZONE_INFO = {
+ "availabilityZoneInfo":
+ [
+ {
+ "zoneState": {
+ "available": True
+ },
+ "hosts": None,
+ "zoneName": u'\xf4'
+ }
+ ]
+ }
+
+ def setUp(self):
+ super(TestAvailabilityZoneClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = availability_zone_client.AvailabilityZoneClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def test_list_availability_zones_with_str_body(self):
+ self.check_service_client_function(
+ self.client.list_availability_zones,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_AVAILABIRITY_ZONE_INFO)
+
+ def test_list_availability_zones_with_bytes_body(self):
+ self.check_service_client_function(
+ self.client.list_availability_zones,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_AVAILABIRITY_ZONE_INFO, to_utf=True)
diff --git a/tempest/tests/services/compute/test_baremetal_nodes_client.py b/tempest/tests/services/compute/test_baremetal_nodes_client.py
new file mode 100644
index 0000000..edf9014
--- /dev/null
+++ b/tempest/tests/services/compute/test_baremetal_nodes_client.py
@@ -0,0 +1,74 @@
+# 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.
+
+import copy
+
+from tempest.services.compute.json import baremetal_nodes_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestBareMetalNodesClient(base.BaseComputeServiceTest):
+
+ FAKE_NODE_INFO = {'cpus': '8',
+ 'disk_gb': '64',
+ 'host': '10.0.2.15',
+ 'id': 'Identifier',
+ 'instance_uuid': "null",
+ 'interfaces': [
+ {
+ "address": "20::01",
+ "datapath_id": "null",
+ "id": 1,
+ "port_no": None
+ }
+ ],
+ 'memory_mb': '8192',
+ 'task_state': None}
+
+ def setUp(self):
+ super(TestBareMetalNodesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.baremetal_nodes_client = (baremetal_nodes_client.
+ BaremetalNodesClient
+ (fake_auth, 'compute',
+ 'regionOne'))
+
+ def _test_bareMetal_nodes(self, operation='list', bytes_body=False):
+ if operation != 'list':
+ expected = {"node": self.FAKE_NODE_INFO}
+ function = self.baremetal_nodes_client.show_baremetal_node
+ else:
+ node_info = copy.deepcopy(self.FAKE_NODE_INFO)
+ del node_info['instance_uuid']
+ expected = {"nodes": [node_info]}
+ function = self.baremetal_nodes_client.list_baremetal_nodes
+
+ self.check_service_client_function(
+ function,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body, 200,
+ baremetal_node_id='Identifier')
+
+ def test_list_bareMetal_nodes_with_str_body(self):
+ self._test_bareMetal_nodes()
+
+ def test_list_bareMetal_nodes_with_bytes_body(self):
+ self._test_bareMetal_nodes(bytes_body=True)
+
+ def test_show_bareMetal_node_with_str_body(self):
+ self._test_bareMetal_nodes('show')
+
+ def test_show_bareMetal_node_with_bytes_body(self):
+ self._test_bareMetal_nodes('show', True)
diff --git a/tempest/tests/services/compute/test_certificates_client.py b/tempest/tests/services/compute/test_certificates_client.py
new file mode 100644
index 0000000..c926fce
--- /dev/null
+++ b/tempest/tests/services/compute/test_certificates_client.py
@@ -0,0 +1,64 @@
+# 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.
+
+import copy
+
+from tempest.services.compute.json import certificates_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestCertificatesClient(base.BaseComputeServiceTest):
+
+ FAKE_CERTIFICATE = {
+ "certificate": {
+ "data": "-----BEGIN----MIICyzCCAjSgAwI----END CERTIFICATE-----\n",
+ "private_key": None
+ }
+ }
+
+ def setUp(self):
+ super(TestCertificatesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = certificates_client.CertificatesClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_show_certificate(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_certificate,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_CERTIFICATE,
+ bytes_body,
+ certificate_id="fake-id")
+
+ def test_show_certificate_with_str_body(self):
+ self._test_show_certificate()
+
+ def test_show_certificate_with_bytes_body(self):
+ self._test_show_certificate(bytes_body=True)
+
+ def _test_create_certificate(self, bytes_body=False):
+ cert = copy.deepcopy(self.FAKE_CERTIFICATE)
+ cert['certificate']['private_key'] = "my_private_key"
+ self.check_service_client_function(
+ self.client.create_certificate,
+ 'tempest.common.service_client.ServiceClient.post',
+ cert,
+ bytes_body)
+
+ def test_create_certificate_with_str_body(self):
+ self._test_create_certificate()
+
+ def test_create_certificate_with_bytes_body(self):
+ self._test_create_certificate(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_extensions_client.py b/tempest/tests/services/compute/test_extensions_client.py
index 20a5b7b..86f81f3 100644
--- a/tempest/tests/services/compute/test_extensions_client.py
+++ b/tempest/tests/services/compute/test_extensions_client.py
@@ -12,17 +12,24 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
from tempest.services.compute.json import extensions_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestExtensionsClient(base.TestCase):
+class TestExtensionsClient(base.BaseComputeServiceTest):
+
+ FAKE_SHOW_EXTENSION = {
+ "extension": {
+ "updated": "2011-06-09T00:00:00Z",
+ "name": "Multinic",
+ "links": [],
+ "namespace":
+ "http://docs.openstack.org/compute/ext/multinic/api/v1.1",
+ "alias": "NMN",
+ "description": u'\u2740(*\xb4\u25e1`*)\u2740'
+ }
+ }
def setUp(self):
super(TestExtensionsClient, self).setUp()
@@ -31,15 +38,11 @@
fake_auth, 'compute', 'regionOne')
def _test_list_extensions(self, bytes_body=False):
- body = '{"extensions": []}'
- if bytes_body:
- body = body.encode('utf-8')
- expected = {"extensions": []}
- response = (httplib2.Response({'status': 200}), body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.list_extensions,
'tempest.common.service_client.ServiceClient.get',
- return_value=response))
- self.assertEqual(expected, self.client.list_extensions())
+ {"extensions": []},
+ bytes_body)
def test_list_extensions_with_str_body(self):
self._test_list_extensions()
@@ -48,25 +51,12 @@
self._test_list_extensions(bytes_body=True)
def _test_show_extension(self, bytes_body=False):
- expected = {"extension": {
- "updated": "2011-06-09T00:00:00Z",
- "name": "Multinic",
- "links": [],
- "namespace":
- "http://docs.openstack.org/compute/ext/multinic/api/v1.1",
- "alias": "NMN",
- "description": u'\u2740(*\xb4\u25e1`*)\u2740'
- }}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_extension,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_extension("NMN")
- self.assertEqual(expected, resp)
+ self.FAKE_SHOW_EXTENSION,
+ bytes_body,
+ extension_alias="NMN")
def test_show_extension_with_str_body(self):
self._test_show_extension()
diff --git a/tempest/tests/services/compute/test_fixedIPs_client.py b/tempest/tests/services/compute/test_fixedIPs_client.py
new file mode 100644
index 0000000..d7a9694
--- /dev/null
+++ b/tempest/tests/services/compute/test_fixedIPs_client.py
@@ -0,0 +1,45 @@
+# 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.services.compute.json import fixed_ips_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFixedIPsClient(base.BaseComputeServiceTest):
+ FIXED_IP_INFO = {"fixed_ip": {"address": "10.0.0.1",
+ "cidr": "10.11.12.0/24",
+ "host": "localhost",
+ "hostname": "OpenStack"}}
+
+ def setUp(self):
+ super(TestFixedIPsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.fixedIPsClient = (fixed_ips_client.
+ FixedIPsClient
+ (fake_auth, 'compute',
+ 'regionOne'))
+
+ def _test_show_fixed_ip(self, bytes_body=False):
+ self.check_service_client_function(
+ self.fixedIPsClient.show_fixed_ip,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FIXED_IP_INFO, bytes_body,
+ status=200, fixed_ip='Identifier')
+
+ def test_show_fixed_ip_with_str_body(self):
+ self._test_show_fixed_ip()
+
+ def test_show_fixed_ip_with_bytes_body(self):
+ self._test_show_fixed_ip(True)
diff --git a/tempest/tests/services/compute/test_floating_ip_pools_client.py b/tempest/tests/services/compute/test_floating_ip_pools_client.py
new file mode 100644
index 0000000..0d19b7b
--- /dev/null
+++ b/tempest/tests/services/compute/test_floating_ip_pools_client.py
@@ -0,0 +1,47 @@
+# 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.services.compute.json import floating_ip_pools_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFloatingIPPoolsClient(base.BaseComputeServiceTest):
+
+ FAKE_FLOATING_IP_POOLS = {
+ "floating_ip_pools":
+ [
+ {"name": u'\u3042'},
+ {"name": u'\u3044'}
+ ]
+ }
+
+ def setUp(self):
+ super(TestFloatingIPPoolsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = floating_ip_pools_client.FloatingIPPoolsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def test_list_floating_ip_pools_with_str_body(self):
+ self.check_service_client_function(
+ self.client.list_floating_ip_pools,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_FLOATING_IP_POOLS)
+
+ def test_list_floating_ip_pools_with_bytes_body(self):
+ self.check_service_client_function(
+ self.client.list_floating_ip_pools,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_FLOATING_IP_POOLS, to_utf=True)
diff --git a/tempest/tests/services/compute/test_floating_ips_bulk_client.py b/tempest/tests/services/compute/test_floating_ips_bulk_client.py
new file mode 100644
index 0000000..6cf1b17
--- /dev/null
+++ b/tempest/tests/services/compute/test_floating_ips_bulk_client.py
@@ -0,0 +1,87 @@
+# 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.services.compute.json import floating_ips_bulk_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFloatingIPsBulkClient(base.BaseComputeServiceTest):
+
+ FAKE_FIP_BULK_LIST = {"floating_ip_info": [{
+ "address": "10.10.10.1",
+ "instance_uuid": None,
+ "fixed_ip": None,
+ "interface": "eth0",
+ "pool": "nova",
+ "project_id": None
+ },
+ {
+ "address": "10.10.10.2",
+ "instance_uuid": None,
+ "fixed_ip": None,
+ "interface": "eth0",
+ "pool": "nova",
+ "project_id": None
+ }]}
+
+ def setUp(self):
+ super(TestFloatingIPsBulkClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = floating_ips_bulk_client.FloatingIPsBulkClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_floating_ips_bulk(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_FIP_BULK_LIST,
+ to_utf=bytes_body)
+
+ def _test_create_floating_ips_bulk(self, bytes_body=False):
+ fake_fip_create_data = {"floating_ips_bulk_create": {
+ "ip_range": "192.168.1.0/24", "pool": "nova", "interface": "eth0"}}
+ self.check_service_client_function(
+ self.client.create_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.post',
+ fake_fip_create_data,
+ to_utf=bytes_body,
+ ip_range="192.168.1.0/24", pool="nova", interface="eth0")
+
+ def _test_delete_floating_ips_bulk(self, bytes_body=False):
+ fake_fip_delete_data = {"floating_ips_bulk_delete": "192.168.1.0/24"}
+ self.check_service_client_function(
+ self.client.delete_floating_ips_bulk,
+ 'tempest.common.service_client.ServiceClient.put',
+ fake_fip_delete_data,
+ to_utf=bytes_body,
+ ip_range="192.168.1.0/24")
+
+ def test_list_floating_ips_bulk_with_str_body(self):
+ self._test_list_floating_ips_bulk()
+
+ def test_list_floating_ips_bulk_with_bytes_body(self):
+ self._test_list_floating_ips_bulk(True)
+
+ def test_create_floating_ips_bulk_with_str_body(self):
+ self._test_create_floating_ips_bulk()
+
+ def test_create_floating_ips_bulk_with_bytes_body(self):
+ self._test_create_floating_ips_bulk(True)
+
+ def test_delete_floating_ips_bulk_with_str_body(self):
+ self._test_delete_floating_ips_bulk()
+
+ def test_delete_floating_ips_bulk_with_bytes_body(self):
+ self._test_delete_floating_ips_bulk(True)
diff --git a/tempest/tests/services/compute/test_instance_usage_audit_log_client.py b/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
new file mode 100644
index 0000000..d4bc889
--- /dev/null
+++ b/tempest/tests/services/compute/test_instance_usage_audit_log_client.py
@@ -0,0 +1,73 @@
+# 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.
+
+import datetime
+
+from tempest.services.compute.json import instance_usage_audit_log_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestInstanceUsagesAuditLogClient(base.BaseComputeServiceTest):
+
+ FAKE_AUDIT_LOG = {
+ "hosts_not_run": [
+ "f4eb7cfd155f4574967f8b55a7faed75"
+ ],
+ "log": {},
+ "num_hosts": 1,
+ "num_hosts_done": 0,
+ "num_hosts_not_run": 1,
+ "num_hosts_running": 0,
+ "overall_status": "0 of 1 hosts done. 0 errors.",
+ "period_beginning": "2012-12-01 00:00:00",
+ "period_ending": "2013-01-01 00:00:00",
+ "total_errors": 0,
+ "total_instances": 0
+ }
+
+ def setUp(self):
+ super(TestInstanceUsagesAuditLogClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = (instance_usage_audit_log_client.
+ InstanceUsagesAuditLogClient(fake_auth, 'compute',
+ 'regionOne'))
+
+ def _test_list_instance_usage_audit_logs(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_instance_usage_audit_logs,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"instance_usage_audit_logs": self.FAKE_AUDIT_LOG},
+ bytes_body)
+
+ def test_list_instance_usage_audit_logs_with_str_body(self):
+ self._test_list_instance_usage_audit_logs()
+
+ def test_list_instance_usage_audit_logs_with_bytes_body(self):
+ self._test_list_instance_usage_audit_logs(bytes_body=True)
+
+ def _test_show_instance_usage_audit_log(self, bytes_body=False):
+ before_time = datetime.datetime(2012, 12, 1, 0, 0)
+ self.check_service_client_function(
+ self.client.show_instance_usage_audit_log,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"instance_usage_audit_log": self.FAKE_AUDIT_LOG},
+ bytes_body,
+ time_before=before_time)
+
+ def test_show_instance_usage_audit_log_with_str_body(self):
+ self._test_show_instance_usage_audit_log()
+
+ def test_show_network_with_bytes_body_with_bytes_body(self):
+ self._test_show_instance_usage_audit_log(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_keypairs_client.py b/tempest/tests/services/compute/test_keypairs_client.py
index 8a0edd0..6ad187b 100644
--- a/tempest/tests/services/compute/test_keypairs_client.py
+++ b/tempest/tests/services/compute/test_keypairs_client.py
@@ -13,17 +13,13 @@
# under the License.
import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
from tempest.services.compute.json import keypairs_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestKeyPairsClient(base.TestCase):
+class TestKeyPairsClient(base.BaseComputeServiceTest):
FAKE_KEYPAIR = {"keypair": {
"public_key": "ssh-rsa foo Generated-by-Nova",
@@ -39,15 +35,11 @@
fake_auth, 'compute', 'regionOne')
def _test_list_keypairs(self, bytes_body=False):
- body = '{"keypairs": []}'
- if bytes_body:
- body = body.encode('utf-8')
- expected = {"keypairs": []}
- response = (httplib2.Response({'status': 200}), body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.list_keypairs,
'tempest.common.service_client.ServiceClient.get',
- return_value=response))
- self.assertEqual(expected, self.client.list_keypairs())
+ {"keypairs": []},
+ bytes_body)
def test_list_keypairs_with_str_body(self):
self._test_list_keypairs()
@@ -64,16 +56,13 @@
"deleted_at": None,
"id": 1
})
- serialized_body = json.dumps(fake_keypair)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_keypair,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_keypair("test")
- self.assertEqual(fake_keypair, resp)
+ fake_keypair,
+ bytes_body,
+ keypair_name="test")
def test_show_keypair_with_str_body(self):
self._test_show_keypair()
@@ -84,16 +73,13 @@
def _test_create_keypair(self, bytes_body=False):
fake_keypair = copy.deepcopy(self.FAKE_KEYPAIR)
fake_keypair["keypair"].update({"private_key": "foo"})
- serialized_body = json.dumps(fake_keypair)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.create_keypair,
'tempest.common.service_client.ServiceClient.post',
- return_value=mocked_resp))
- resp = self.client.create_keypair(name='test')
- self.assertEqual(fake_keypair, resp)
+ fake_keypair,
+ bytes_body,
+ name="test")
def test_create_keypair_with_str_body(self):
self._test_create_keypair()
@@ -102,10 +88,7 @@
self._test_create_keypair(bytes_body=True)
def test_delete_keypair(self):
- expected = {}
- mocked_resp = (httplib2.Response({'status': 202}), None)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.delete_keypair,
'tempest.common.service_client.ServiceClient.delete',
- return_value=mocked_resp))
- resp = self.client.delete_keypair('test')
- self.assertEqual(expected, resp)
+ {}, status=202, keypair_name='test')
diff --git a/tempest/tests/services/compute/test_limits_client.py b/tempest/tests/services/compute/test_limits_client.py
index 4086210..0036a3d 100644
--- a/tempest/tests/services/compute/test_limits_client.py
+++ b/tempest/tests/services/compute/test_limits_client.py
@@ -12,17 +12,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
from tempest.services.compute.json import limits_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestLimitsClient(base.TestCase):
+class TestLimitsClient(base.BaseComputeServiceTest):
def setUp(self):
super(TestLimitsClient, self).setUp()
@@ -31,36 +26,38 @@
fake_auth, 'compute', 'regionOne')
def _test_show_limits(self, bytes_body=False):
- expected = {"rate": [],
- "absolute": {"maxServerMeta": 128,
- "maxPersonality": 5,
- "totalServerGroupsUsed": 0,
- "maxImageMeta": 128,
- "maxPersonalitySize": 10240,
- "maxServerGroups": 10,
- "maxSecurityGroupRules": 20,
- "maxTotalKeypairs": 100,
- "totalCoresUsed": 0,
- "totalRAMUsed": 0,
- "totalInstancesUsed": 0,
- "maxSecurityGroups": 10,
- "totalFloatingIpsUsed": 0,
- "maxTotalCores": 20,
- "totalSecurityGroupsUsed": 0,
- "maxTotalFloatingIps": 10,
- "maxTotalInstances": 10,
- "maxTotalRAMSize": 51200,
- "maxServerGroupMembers": 10}}
- serialized_body = json.dumps({"limits": expected})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
+ expected = {
+ "limits": {
+ "rate": [],
+ "absolute": {
+ "maxServerMeta": 128,
+ "maxPersonality": 5,
+ "totalServerGroupsUsed": 0,
+ "maxImageMeta": 128,
+ "maxPersonalitySize": 10240,
+ "maxServerGroups": 10,
+ "maxSecurityGroupRules": 20,
+ "maxTotalKeypairs": 100,
+ "totalCoresUsed": 0,
+ "totalRAMUsed": 0,
+ "totalInstancesUsed": 0,
+ "maxSecurityGroups": 10,
+ "totalFloatingIpsUsed": 0,
+ "maxTotalCores": 20,
+ "totalSecurityGroupsUsed": 0,
+ "maxTotalFloatingIps": 10,
+ "maxTotalInstances": 10,
+ "maxTotalRAMSize": 51200,
+ "maxServerGroupMembers": 10
+ }
+ }
+ }
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_limits,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_limits()
- self.assertEqual(expected, resp)
+ expected,
+ bytes_body)
def test_show_limits_with_str_body(self):
self._test_show_limits()
diff --git a/tempest/tests/services/compute/test_migrations_client.py b/tempest/tests/services/compute/test_migrations_client.py
new file mode 100644
index 0000000..83fe461
--- /dev/null
+++ b/tempest/tests/services/compute/test_migrations_client.py
@@ -0,0 +1,52 @@
+# 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.services.compute.json import migrations_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestMigrationsClient(base.BaseComputeServiceTest):
+ FAKE_MIGRATION_INFO = {"migrations": [{
+ "created_at": "2012-10-29T13:42:02",
+ "dest_compute": "compute2",
+ "dest_host": "1.2.3.4",
+ "dest_node": "node2",
+ "id": 1234,
+ "instance_uuid": "e9e4fdd7-f956-44ff-bfeb-d654a96ab3a2",
+ "new_instance_type_id": 2,
+ "old_instance_type_id": 1,
+ "source_compute": "compute1",
+ "source_node": "node1",
+ "status": "finished",
+ "updated_at": "2012-10-29T13:42:02"}]}
+
+ def setUp(self):
+ super(TestMigrationsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.mg_client_obj = migrations_client.MigrationsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_migrations(self, bytes_body=False):
+ self.check_service_client_function(
+ self.mg_client_obj.list_migrations,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_MIGRATION_INFO,
+ bytes_body)
+
+ def test_list_migration_with_str_body(self):
+ self._test_list_migrations()
+
+ def test_list_migration_with_bytes_body(self):
+ self._test_list_migrations(True)
diff --git a/tempest/tests/services/compute/test_networks_client.py b/tempest/tests/services/compute/test_networks_client.py
index cbeaefc..b47430b 100644
--- a/tempest/tests/services/compute/test_networks_client.py
+++ b/tempest/tests/services/compute/test_networks_client.py
@@ -12,17 +12,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
-
from tempest.services.compute.json import networks_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestNetworksClient(base.TestCase):
+class TestNetworksClient(base.BaseComputeServiceTest):
FAKE_NETWORK = {
"bridge": None,
@@ -70,17 +65,12 @@
fake_auth, 'compute', 'regionOne')
def _test_list_networks(self, bytes_body=False):
- expected = {"networks": self.FAKE_NETWORKS}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ fake_list = {"networks": self.FAKE_NETWORKS}
+ self.check_service_client_function(
+ self.client.list_networks,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.list_networks()
- self.assertEqual(expected, resp)
+ fake_list,
+ bytes_body)
def test_list_networks_with_str_body(self):
self._test_list_networks()
@@ -89,17 +79,13 @@
self._test_list_networks(bytes_body=True)
def _test_show_network(self, bytes_body=False):
- expected = {"network": self.FAKE_NETWORKS}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_network,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_network(self.network_id)
- self.assertEqual(expected, resp)
+ {"network": self.FAKE_NETWORK},
+ bytes_body,
+ network_id=self.network_id
+ )
def test_show_network_with_str_body(self):
self._test_show_network()
diff --git a/tempest/tests/services/compute/test_quota_classes_client.py b/tempest/tests/services/compute/test_quota_classes_client.py
index ff9b310..f4fc51a 100644
--- a/tempest/tests/services/compute/test_quota_classes_client.py
+++ b/tempest/tests/services/compute/test_quota_classes_client.py
@@ -13,17 +13,13 @@
# under the License.
import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
from tempest.services.compute.json import quota_classes_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestQuotaClassesClient(base.TestCase):
+class TestQuotaClassesClient(base.BaseComputeServiceTest):
FAKE_QUOTA_CLASS_SET = {
"injected_file_content_bytes": 10240,
@@ -50,17 +46,13 @@
fake_auth, 'compute', 'regionOne')
def _test_show_quota_class_set(self, bytes_body=False):
- serialized_body = json.dumps({
- "quota_class_set": self.FAKE_QUOTA_CLASS_SET})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ fake_body = {'quota_class_set': self.FAKE_QUOTA_CLASS_SET}
+ self.check_service_client_function(
+ self.client.show_quota_class_set,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_quota_class_set("test")
- self.assertEqual(self.FAKE_QUOTA_CLASS_SET, resp)
+ fake_body,
+ bytes_body,
+ quota_class_id="test")
def test_show_quota_class_set_with_str_body(self):
self._test_show_quota_class_set()
@@ -71,11 +63,9 @@
def test_update_quota_class_set(self):
fake_quota_class_set = copy.deepcopy(self.FAKE_QUOTA_CLASS_SET)
fake_quota_class_set.pop("id")
- serialized_body = json.dumps({"quota_class_set": fake_quota_class_set})
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ fake_body = {'quota_class_set': fake_quota_class_set}
+ self.check_service_client_function(
+ self.client.update_quota_class_set,
'tempest.common.service_client.ServiceClient.put',
- return_value=mocked_resp))
- resp = self.client.update_quota_class_set("test")
- self.assertEqual(fake_quota_class_set, resp)
+ fake_body,
+ quota_class_id="test")
diff --git a/tempest/tests/services/compute/test_quotas_client.py b/tempest/tests/services/compute/test_quotas_client.py
index a9bd0a1..68f74aa 100644
--- a/tempest/tests/services/compute/test_quotas_client.py
+++ b/tempest/tests/services/compute/test_quotas_client.py
@@ -13,33 +13,32 @@
# under the License.
import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
from tempest.services.compute.json import quotas_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestQuotasClient(base.TestCase):
+class TestQuotasClient(base.BaseComputeServiceTest):
- FAKE_QUOTA_SET = {"injected_file_content_bytes": 10240,
- "metadata_items": 128,
- "server_group_members": 10,
- "server_groups": 10,
- "ram": 51200,
- "floating_ips": 10,
- "key_pairs": 100,
- "id": "8421f7be61064f50b680465c07f334af",
- "instances": 10,
- "security_group_rules": 20,
- "injected_files": 5,
- "cores": 20,
- "fixed_ips": -1,
- "injected_file_path_bytes": 255,
- "security_groups": 10}
+ FAKE_QUOTA_SET = {
+ "quota_set": {
+ "injected_file_content_bytes": 10240,
+ "metadata_items": 128,
+ "server_group_members": 10,
+ "server_groups": 10,
+ "ram": 51200,
+ "floating_ips": 10,
+ "key_pairs": 100,
+ "id": "8421f7be61064f50b680465c07f334af",
+ "instances": 10,
+ "security_group_rules": 20,
+ "injected_files": 5,
+ "cores": 20,
+ "fixed_ips": -1,
+ "injected_file_path_bytes": 255,
+ "security_groups": 10}
+ }
project_id = "8421f7be61064f50b680465c07f334af"
@@ -50,16 +49,12 @@
fake_auth, 'compute', 'regionOne')
def _test_show_quota_set(self, bytes_body=False):
- serialized_body = json.dumps({"quota_set": self.FAKE_QUOTA_SET})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_quota_set,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_quota_set(self.project_id)
- self.assertEqual(self.FAKE_QUOTA_SET, resp)
+ self.FAKE_QUOTA_SET,
+ to_utf=bytes_body,
+ tenant_id=self.project_id)
def test_show_quota_set_with_str_body(self):
self._test_show_quota_set()
@@ -68,16 +63,12 @@
self._test_show_quota_set(bytes_body=True)
def _test_show_default_quota_set(self, bytes_body=False):
- serialized_body = json.dumps({"quota_set": self.FAKE_QUOTA_SET})
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.show_default_quota_set,
'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.show_default_quota_set(self.project_id)
- self.assertEqual(self.FAKE_QUOTA_SET, resp)
+ self.FAKE_QUOTA_SET,
+ to_utf=bytes_body,
+ tenant_id=self.project_id)
def test_show_default_quota_set_with_str_body(self):
self._test_show_quota_set()
@@ -87,20 +78,15 @@
def test_update_quota_set(self):
fake_quota_set = copy.deepcopy(self.FAKE_QUOTA_SET)
- fake_quota_set.pop("id")
- serialized_body = json.dumps({"quota_set": fake_quota_set})
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ fake_quota_set['quota_set'].pop("id")
+ self.check_service_client_function(
+ self.client.update_quota_set,
'tempest.common.service_client.ServiceClient.put',
- return_value=mocked_resp))
- resp = self.client.update_quota_set(self.project_id)
- self.assertEqual(fake_quota_set, resp)
+ fake_quota_set,
+ tenant_id=self.project_id)
def test_delete_quota_set(self):
- expected = {}
- mocked_resp = (httplib2.Response({'status': 202}), None)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.delete_quota_set,
'tempest.common.service_client.ServiceClient.delete',
- return_value=mocked_resp))
- resp = self.client.delete_quota_set(self.project_id)
- self.assertEqual(expected, resp)
+ {}, status=202, tenant_id=self.project_id)
diff --git a/tempest/tests/services/compute/test_security_group_default_rules_client.py b/tempest/tests/services/compute/test_security_group_default_rules_client.py
new file mode 100644
index 0000000..75fa1cb
--- /dev/null
+++ b/tempest/tests/services/compute/test_security_group_default_rules_client.py
@@ -0,0 +1,88 @@
+# 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.services.compute.json import security_group_default_rules_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestSecurityGroupDefaultRulesClient(base.BaseComputeServiceTest):
+ FAKE_RULE = {
+ "from_port": 80,
+ "id": 1,
+ "ip_protocol": "TCP",
+ "ip_range": {
+ "cidr": "10.10.10.0/24"
+ },
+ "to_port": 80
+ }
+
+ def setUp(self):
+ super(TestSecurityGroupDefaultRulesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = (security_group_default_rules_client.
+ SecurityGroupDefaultRulesClient(fake_auth, 'compute',
+ 'regionOne'))
+
+ def _test_list_security_group_default_rules(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_security_group_default_rules,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group_default_rules": [self.FAKE_RULE]},
+ to_utf=bytes_body)
+
+ def test_list_security_group_default_rules_with_str_body(self):
+ self._test_list_security_group_default_rules()
+
+ def test_list_security_group_default_rules_with_bytes_body(self):
+ self._test_list_security_group_default_rules(bytes_body=True)
+
+ def _test_show_security_group_default_rule(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_security_group_default_rule,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group_default_rule": self.FAKE_RULE},
+ to_utf=bytes_body,
+ security_group_default_rule_id=1)
+
+ def test_show_security_group_default_rule_with_str_body(self):
+ self._test_show_security_group_default_rule()
+
+ def test_show_security_group_default_rule_with_bytes_body(self):
+ self._test_show_security_group_default_rule(bytes_body=True)
+
+ def _test_create_security_default_group_rule(self, bytes_body=False):
+ request_body = {
+ "to_port": 80,
+ "from_port": 80,
+ "ip_protocol": "TCP",
+ "cidr": "10.10.10.0/24"
+ }
+ self.check_service_client_function(
+ self.client.create_security_default_group_rule,
+ 'tempest.common.service_client.ServiceClient.post',
+ {"security_group_default_rule": self.FAKE_RULE},
+ to_utf=bytes_body, **request_body)
+
+ def test_create_security_default_group_rule_with_str_body(self):
+ self._test_create_security_default_group_rule()
+
+ def test_create_security_default_group_rule_with_bytes_body(self):
+ self._test_create_security_default_group_rule(bytes_body=True)
+
+ def test_delete_security_group_default_rule(self):
+ self.check_service_client_function(
+ self.client.delete_security_group_default_rule,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=204, security_group_default_rule_id=1)
diff --git a/tempest/tests/services/compute/test_security_groups_client.py b/tempest/tests/services/compute/test_security_groups_client.py
new file mode 100644
index 0000000..7a39048
--- /dev/null
+++ b/tempest/tests/services/compute/test_security_groups_client.py
@@ -0,0 +1,113 @@
+# 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 oslotest import mockpatch
+from tempest_lib import exceptions as lib_exc
+
+from tempest.services.compute.json import security_groups_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestSecurityGroupsClient(base.BaseComputeServiceTest):
+
+ FAKE_SECURITY_GROUP_INFO = [{
+ "description": "default",
+ "id": "3fb26eb3-581b-4420-9963-b0879a026506",
+ "name": "default",
+ "rules": [],
+ "tenant_id": "openstack"
+ }]
+
+ def setUp(self):
+ super(TestSecurityGroupsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = security_groups_client.SecurityGroupsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_security_groups(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_security_groups,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_groups": self.FAKE_SECURITY_GROUP_INFO},
+ to_utf=bytes_body)
+
+ def test_list_security_groups_with_str_body(self):
+ self._test_list_security_groups()
+
+ def test_list_security_groups_with_bytes_body(self):
+ self._test_list_security_groups(bytes_body=True)
+
+ def _test_show_security_group(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_security_group,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
+ to_utf=bytes_body,
+ security_group_id='fake-id')
+
+ def test_show_security_group_with_str_body(self):
+ self._test_show_security_group()
+
+ def test_show_security_group_with_bytes_body(self):
+ self._test_show_security_group(bytes_body=True)
+
+ def _test_create_security_group(self, bytes_body=False):
+ post_body = {"name": "test", "description": "test_group"}
+ self.check_service_client_function(
+ self.client.create_security_group,
+ 'tempest.common.service_client.ServiceClient.post',
+ {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
+ to_utf=bytes_body,
+ kwargs=post_body)
+
+ def test_create_security_group_with_str_body(self):
+ self._test_create_security_group()
+
+ def test_create_security_group_with_bytes_body(self):
+ self._test_create_security_group(bytes_body=True)
+
+ def _test_update_security_group(self, bytes_body=False):
+ req_body = {"name": "test", "description": "test_group"}
+ self.check_service_client_function(
+ self.client.update_security_group,
+ 'tempest.common.service_client.ServiceClient.put',
+ {"security_group": self.FAKE_SECURITY_GROUP_INFO[0]},
+ to_utf=bytes_body,
+ security_group_id='fake-id',
+ kwargs=req_body)
+
+ def test_update_security_group_with_str_body(self):
+ self._test_update_security_group()
+
+ def test_update_security_group_with_bytes_body(self):
+ self._test_update_security_group(bytes_body=True)
+
+ def test_delete_security_group(self):
+ self.check_service_client_function(
+ self.client.delete_security_group,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=202, security_group_id='fake-id')
+
+ def test_is_resource_deleted_true(self):
+ mod = ('tempest.services.compute.json.security_groups_client.'
+ 'SecurityGroupsClient.show_security_group')
+ self.useFixture(mockpatch.Patch(mod, side_effect=lib_exc.NotFound))
+ self.assertTrue(self.client.is_resource_deleted('fake-id'))
+
+ def test_is_resource_deleted_false(self):
+ mod = ('tempest.services.compute.json.security_groups_client.'
+ 'SecurityGroupsClient.show_security_group')
+ self.useFixture(mockpatch.Patch(mod, return_value='success'))
+ self.assertFalse(self.client.is_resource_deleted('fake-id'))
diff --git a/tempest/tests/services/compute/test_services_client.py b/tempest/tests/services/compute/test_services_client.py
index 7d87711..e5a25ab 100644
--- a/tempest/tests/services/compute/test_services_client.py
+++ b/tempest/tests/services/compute/test_services_client.py
@@ -13,34 +13,36 @@
# under the License.
import copy
-import httplib2
-
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
from tempest.services.compute.json import services_client
-from tempest.tests import base
from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
-class TestServicesClient(base.TestCase):
+class TestServicesClient(base.BaseComputeServiceTest):
- FAKE_SERVICES = [{
- "status": "enabled",
- "binary": "nova-conductor",
- "zone": "internal",
- "state": "up",
- "updated_at": "2015-08-19T06:50:55.000000",
- "host": "controller",
- "disabled_reason": None,
- "id": 1
+ FAKE_SERVICES = {
+ "services":
+ [{
+ "status": "enabled",
+ "binary": "nova-conductor",
+ "zone": "internal",
+ "state": "up",
+ "updated_at": "2015-08-19T06:50:55.000000",
+ "host": "controller",
+ "disabled_reason": None,
+ "id": 1
}]
+ }
FAKE_SERVICE = {
- "status": "enabled",
- "binary": "nova-conductor",
- "host": "controller"
+ "service":
+ {
+ "status": "enabled",
+ "binary": "nova-conductor",
+ "host": "controller"
}
+ }
def setUp(self):
super(TestServicesClient, self).setUp()
@@ -48,37 +50,25 @@
self.client = services_client.ServicesClient(
fake_auth, 'compute', 'regionOne')
- def _test_list_services(self, bytes_body=False):
- expected = {"services": self.FAKE_SERVICES}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
- 'tempest.common.service_client.ServiceClient.get',
- return_value=mocked_resp))
- resp = self.client.list_services()
- self.assertEqual(expected, resp)
-
def test_list_services_with_str_body(self):
- self._test_list_services()
+ self.check_service_client_function(
+ self.client.list_services,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_SERVICES)
def test_list_services_with_bytes_body(self):
- self._test_list_services(bytes_body=True)
+ self.check_service_client_function(
+ self.client.list_services,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_SERVICES, to_utf=True)
def _test_enable_service(self, bytes_body=False):
- expected = {"service": self.FAKE_SERVICE}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
-
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.enable_service,
'tempest.common.service_client.ServiceClient.put',
- return_value=mocked_resp))
- resp = self.client.enable_service("nova-conductor", "controller")
- self.assertEqual(expected, resp)
+ self.FAKE_SERVICE,
+ bytes_body,
+ host_name="nova-conductor", binary="controller")
def test_enable_service_with_str_body(self):
self._test_enable_service()
@@ -88,21 +78,17 @@
def _test_disable_service(self, bytes_body=False):
fake_service = copy.deepcopy(self.FAKE_SERVICE)
- fake_service["status"] = "disable"
- expected = {"service": self.FAKE_SERVICE}
- serialized_body = json.dumps(expected)
- if bytes_body:
- serialized_body = serialized_body.encode('utf-8')
+ fake_service["service"]["status"] = "disable"
- mocked_resp = (httplib2.Response({'status': 200}), serialized_body)
- self.useFixture(mockpatch.Patch(
+ self.check_service_client_function(
+ self.client.disable_service,
'tempest.common.service_client.ServiceClient.put',
- return_value=mocked_resp))
- resp = self.client.disable_service("nova-conductor", "controller")
- self.assertEqual(expected, resp)
+ fake_service,
+ bytes_body,
+ host_name="nova-conductor", binary="controller")
def test_disable_service_with_str_body(self):
- self._test_enable_service()
+ self._test_disable_service()
def test_disable_service_with_bytes_body(self):
- self._test_enable_service(bytes_body=True)
+ self._test_disable_service(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_tenant_networks_client.py b/tempest/tests/services/compute/test_tenant_networks_client.py
new file mode 100644
index 0000000..dc2de00
--- /dev/null
+++ b/tempest/tests/services/compute/test_tenant_networks_client.py
@@ -0,0 +1,63 @@
+# 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.services.compute.json import tenant_networks_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestTenantNetworksClient(base.BaseComputeServiceTest):
+
+ FAKE_NETWORK = {
+ "cidr": "None",
+ "id": "c2329eb4-cc8e-4439-ac4c-932369309e36",
+ "label": u'\u30d7'
+ }
+
+ FAKE_NETWORKS = [FAKE_NETWORK]
+
+ NETWORK_ID = FAKE_NETWORK['id']
+
+ def setUp(self):
+ super(TestTenantNetworksClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = tenant_networks_client.TenantNetworksClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_tenant_networks(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_tenant_networks,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"networks": self.FAKE_NETWORKS},
+ bytes_body)
+
+ def test_list_tenant_networks_with_str_body(self):
+ self._test_list_tenant_networks()
+
+ def test_list_tenant_networks_with_bytes_body(self):
+ self._test_list_tenant_networks(bytes_body=True)
+
+ def _test_show_tenant_network(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_tenant_network,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"network": self.FAKE_NETWORK},
+ bytes_body,
+ network_id=self.NETWORK_ID)
+
+ def test_show_tenant_network_with_str_body(self):
+ self._test_show_tenant_network()
+
+ def test_show_tenant_network_with_bytes_body(self):
+ self._test_show_tenant_network(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_tenant_usages_client.py b/tempest/tests/services/compute/test_tenant_usages_client.py
new file mode 100644
index 0000000..8a2c1a4
--- /dev/null
+++ b/tempest/tests/services/compute/test_tenant_usages_client.py
@@ -0,0 +1,79 @@
+# 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.services.compute.json import tenant_usages_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestTenantUsagesClient(base.BaseComputeServiceTest):
+
+ FAKE_SERVER_USAGES = [{
+ "ended_at": None,
+ "flavor": "m1.tiny",
+ "hours": 1.0,
+ "instance_id": "1f1deceb-17b5-4c04-84c7-e0d4499c8fe0",
+ "local_gb": 1,
+ "memory_mb": 512,
+ "name": "new-server-test",
+ "started_at": "2012-10-08T20:10:44.541277",
+ "state": "active",
+ "tenant_id": "openstack",
+ "uptime": 3600,
+ "vcpus": 1
+ }]
+
+ FAKE_TENANT_USAGES = [{
+ "server_usages": FAKE_SERVER_USAGES,
+ "start": "2012-10-08T21:10:44.587336",
+ "stop": "2012-10-08T22:10:44.587336",
+ "tenant_id": "openstack",
+ "total_hours": 1,
+ "total_local_gb_usage": 1,
+ "total_memory_mb_usage": 512,
+ "total_vcpus_usage": 1
+ }]
+
+ def setUp(self):
+ super(TestTenantUsagesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = tenant_usages_client.TenantUsagesClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_tenant_usages(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_tenant_usages,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"tenant_usages": self.FAKE_TENANT_USAGES},
+ to_utf=bytes_body)
+
+ def test_list_tenant_usages_with_str_body(self):
+ self._test_list_tenant_usages()
+
+ def test_list_tenant_usages_with_bytes_body(self):
+ self._test_list_tenant_usages(bytes_body=True)
+
+ def _test_show_tenant_usage(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_tenant_usage,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"tenant_usage": self.FAKE_TENANT_USAGES[0]},
+ to_utf=bytes_body,
+ tenant_id='openstack')
+
+ def test_show_tenant_usage_with_str_body(self):
+ self._test_show_tenant_usage()
+
+ def test_show_tenant_usage_with_bytes_body(self):
+ self._test_show_tenant_usage(bytes_body=True)
diff --git a/tempest/tests/test_hacking.py b/tempest/tests/test_hacking.py
index 9bc9cfe..62d2aee 100644
--- a/tempest/tests/test_hacking.py
+++ b/tempest/tests/test_hacking.py
@@ -138,3 +138,11 @@
self.assertEqual(0, len(list(checks.no_mutable_default_args(
"defined, undefined = [], {}"))))
+
+ def test_no_testtools_skip_decorator(self):
+ self.assertEqual(1, len(list(checks.no_testtools_skip_decorator(
+ " @testtools.skip('Bug xxx')"))))
+ self.assertEqual(0, len(list(checks.no_testtools_skip_decorator(
+ " @testtools.skipUnless(CONF.something, 'msg')"))))
+ self.assertEqual(0, len(list(checks.no_testtools_skip_decorator(
+ " @testtools.skipIf(CONF.something, 'msg')"))))
diff --git a/tempest/tests/test_tempest_plugin.py b/tempest/tests/test_tempest_plugin.py
new file mode 100644
index 0000000..c07e98c
--- /dev/null
+++ b/tempest/tests/test_tempest_plugin.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2015 Deutsche Telekom AG
+# 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.test_discover import plugins
+from tempest.tests import base
+from tempest.tests import fake_tempest_plugin as fake_plugin
+
+
+class TestPluginDiscovery(base.TestCase):
+ def test_load_tests_with_one_plugin(self):
+ # we can't mock stevedore since it's a singleton and already executed
+ # during test discovery. So basically this test covers the plugin loop
+ # and the abstract plugin interface.
+ manager = plugins.TempestTestPluginManager()
+ fake_obj = fake_plugin.FakeStevedoreObj()
+ manager.ext_plugins = [fake_obj]
+ result = manager.get_plugin_load_tests_tuple()
+
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result[fake_obj.name])
+
+ def test_load_tests_with_two_plugins(self):
+ manager = plugins.TempestTestPluginManager()
+ obj1 = fake_plugin.FakeStevedoreObj('fake01')
+ obj2 = fake_plugin.FakeStevedoreObj('fake02')
+ manager.ext_plugins = [obj1, obj2]
+ result = manager.get_plugin_load_tests_tuple()
+
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result['fake01'])
+ self.assertEqual(fake_plugin.FakePlugin.expected_load_test,
+ result['fake02'])
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index fa1b6f7..7bdc1d7 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -37,7 +37,7 @@
self.useFixture(fake_config.ConfigFixture())
self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
self.fake_http = fake_http.fake_httplib2(return_type=200)
- self.stubs.Set(json_token_client.TokenClientJSON, 'raw_request',
+ self.stubs.Set(json_token_client.TokenClient, 'raw_request',
fake_identity._fake_v2_response)
cfg.CONF.set_default('operator_role', 'FakeRole',
group='object-storage')
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index 55b8b12..8c371a7 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -377,7 +377,7 @@
state = self.waitSnapshotStatus(lfunction, wait_for)
self.assertIn(state, wait_for)
- def assertAddressDissasociatedWait(self, address):
+ def assertAddressDisassociatedWait(self, address):
def _disassociate():
cli = self.ec2_client
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 920f602..49a1854 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -348,7 +348,7 @@
instance.stop()
address.disassociate()
- self.assertAddressDissasociatedWait(address)
+ self.assertAddressDisassociatedWait(address)
self.cancelResourceCleanUp(rcuk_da)
address.release()
self.assertAddressReleasedWait(address)
diff --git a/tox.ini b/tox.ini
index 15652e8..3250344 100644
--- a/tox.ini
+++ b/tox.ini
@@ -108,7 +108,6 @@
commands = {posargs}
[testenv:docs]
-# The sample config file we generate is included in the sphinxdoc, so build that first.
commands =
python setup.py build_sphinx {posargs}