Merge "Deprecate credential config options"
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 1c29de9..dd2f56b 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/plugin.rst b/doc/source/plugin.rst
index 4e97dbe..f92f63e 100644
--- a/doc/source/plugin.rst
+++ b/doc/source/plugin.rst
@@ -91,6 +91,21 @@
of the tempest developer and reviewer documentation to ensure that the tests
being added in the plugin act and behave like the rest of tempest.
+Dealing with configuration options
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Historically Tempest didn't provide external guarantees on its configuration
+options. However, with the introduction of the plugin interface this is no
+longer the case. An external plugin can rely on using any configuration option
+coming from Tempest, there will be at least a full deprecation cycle for any
+option before it's removed. However, just the options provided by Tempest
+may not be sufficient for the plugin. If you need to add any plugin specific
+configuration options you should use the ``register_opts`` and
+``get_opt_lists`` methods to pass them to Tempest when the plugin is loaded.
+When adding configuration options the ``register_opts`` method gets passed the
+CONF object from tempest. This enables the plugin to add options to both
+existing sections and also create new configuration sections for new options.
+
Using Plugins
=============
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..811580a 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>=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
@@ -22,6 +22,6 @@
iso8601>=0.1.9
fixtures>=1.3.1
testscenarios>=0.4
-tempest-lib>=0.6.1
+tempest-lib>=0.8.0
PyYAML>=3.1.0
stevedore>=1.5.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/setup.py b/setup.py
index d8080d0..782bb21 100644
--- a/setup.py
+++ b/setup.py
@@ -25,5 +25,5 @@
pass
setuptools.setup(
- setup_requires=['pbr>=1.3'],
+ setup_requires=['pbr>=1.8'],
pbr=True)
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_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index e42131d..4d05ff7 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -57,7 +57,8 @@
def test_aggregate_create_delete(self):
# Create and delete an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self._try_delete_aggregate, aggregate['id'])
self.assertEqual(aggregate_name, aggregate['name'])
self.assertIsNone(aggregate['availability_zone'])
@@ -71,7 +72,7 @@
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
az_name = data_utils.rand_name(self.az_name_prefix)
aggregate = self.client.create_aggregate(
- name=aggregate_name, availability_zone=az_name)
+ name=aggregate_name, availability_zone=az_name)['aggregate']
self.addCleanup(self._try_delete_aggregate, aggregate['id'])
self.assertEqual(aggregate_name, aggregate['name'])
self.assertEqual(az_name, aggregate['availability_zone'])
@@ -83,10 +84,11 @@
def test_aggregate_create_verify_entry_in_list(self):
# Create an aggregate and ensure it is listed.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- aggregates = self.client.list_aggregates()
+ aggregates = self.client.list_aggregates()['aggregates']
self.assertIn((aggregate['id'], aggregate['availability_zone']),
map(lambda x: (x['id'], x['availability_zone']),
aggregates))
@@ -95,10 +97,11 @@
def test_aggregate_create_update_metadata_get_details(self):
# Create an aggregate and ensure its details are returned.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- body = self.client.show_aggregate(aggregate['id'])
+ body = self.client.show_aggregate(aggregate['id'])['aggregate']
self.assertEqual(aggregate['name'], body['name'])
self.assertEqual(aggregate['availability_zone'],
body['availability_zone'])
@@ -107,10 +110,10 @@
# set the metadata of the aggregate
meta = {"key": "value"}
body = self.client.set_metadata(aggregate['id'], metadata=meta)
- self.assertEqual(meta, body["metadata"])
+ self.assertEqual(meta, body['aggregate']["metadata"])
# verify the metadata has been set
- body = self.client.show_aggregate(aggregate['id'])
+ body = self.client.show_aggregate(aggregate['id'])['aggregate']
self.assertEqual(meta, body["metadata"])
@test.idempotent_id('4d2b2004-40fa-40a1-aab2-66f4dab81beb')
@@ -119,7 +122,7 @@
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
az_name = data_utils.rand_name(self.az_name_prefix)
aggregate = self.client.create_aggregate(
- name=aggregate_name, availability_zone=az_name)
+ name=aggregate_name, availability_zone=az_name)['aggregate']
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertEqual(aggregate_name, aggregate['name'])
@@ -133,11 +136,11 @@
resp_aggregate = self.client.update_aggregate(
aggregate_id,
name=new_aggregate_name,
- availability_zone=new_az_name)
+ availability_zone=new_az_name)['aggregate']
self.assertEqual(new_aggregate_name, resp_aggregate['name'])
self.assertEqual(new_az_name, resp_aggregate['availability_zone'])
- aggregates = self.client.list_aggregates()
+ aggregates = self.client.list_aggregates()['aggregates']
self.assertIn((aggregate_id, new_aggregate_name, new_az_name),
map(lambda x:
(x['id'], x['name'], x['availability_zone']),
@@ -148,16 +151,19 @@
# Add an host to the given aggregate and remove.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- body = self.client.add_host(aggregate['id'], host=self.host)
+ body = (self.client.add_host(aggregate['id'], host=self.host)
+ ['aggregate'])
self.assertEqual(aggregate_name, body['name'])
self.assertEqual(aggregate['availability_zone'],
body['availability_zone'])
self.assertIn(self.host, body['hosts'])
- body = self.client.remove_host(aggregate['id'], host=self.host)
+ body = (self.client.remove_host(aggregate['id'], host=self.host)
+ ['aggregate'])
self.assertEqual(aggregate_name, body['name'])
self.assertEqual(aggregate['availability_zone'],
body['availability_zone'])
@@ -168,13 +174,14 @@
# Add an host to the given aggregate and list.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], host=self.host)
self.addCleanup(self.client.remove_host, aggregate['id'],
host=self.host)
- aggregates = self.client.list_aggregates()
+ aggregates = self.client.list_aggregates()['aggregates']
aggs = filter(lambda x: x['id'] == aggregate['id'], aggregates)
self.assertEqual(1, len(aggs))
agg = aggs[0]
@@ -187,13 +194,14 @@
# Add an host to the given aggregate and get details.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], host=self.host)
self.addCleanup(self.client.remove_host, aggregate['id'],
host=self.host)
- body = self.client.show_aggregate(aggregate['id'])
+ body = self.client.show_aggregate(aggregate['id'])['aggregate']
self.assertEqual(aggregate_name, body['name'])
self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
@@ -205,7 +213,7 @@
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
az_name = data_utils.rand_name(self.az_name_prefix)
aggregate = self.client.create_aggregate(
- name=aggregate_name, availability_zone=az_name)
+ name=aggregate_name, availability_zone=az_name)['aggregate']
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], host=self.host)
self.addCleanup(self.client.remove_host, aggregate['id'],
@@ -215,5 +223,5 @@
server = self.create_test_server(name=server_name,
availability_zone=az_name,
wait_until='ACTIVE')
- body = admin_servers_client.show_server(server['id'])
+ body = admin_servers_client.show_server(server['id'])['server']
self.assertEqual(self.host, body[self._host_key])
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index 02e0af0..bc1a854 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -76,7 +76,8 @@
# creating an aggregate with existent aggregate name is forbidden
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
aggregate = self.client.create_aggregate(name=aggregate_name)
- self.addCleanup(self.client.delete_aggregate, aggregate['id'])
+ self.addCleanup(self.client.delete_aggregate,
+ aggregate['aggregate']['id'])
self.assertRaises(lib_exc.Conflict,
self.client.create_aggregate,
@@ -87,7 +88,8 @@
def test_aggregate_delete_as_user(self):
# Regular user is not allowed to delete an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(lib_exc.Forbidden,
@@ -106,7 +108,8 @@
def test_aggregate_get_details_as_user(self):
# Regular user is not allowed to get aggregate details.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(lib_exc.Forbidden,
@@ -139,7 +142,8 @@
break
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(lib_exc.NotFound, self.client.add_host,
@@ -150,7 +154,8 @@
def test_aggregate_add_host_as_user(self):
# Regular user is not allowed to add a host to an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(lib_exc.Forbidden,
@@ -162,7 +167,8 @@
def test_aggregate_add_existent_host(self):
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], host=self.host)
@@ -178,7 +184,8 @@
# Regular user is not allowed to remove a host from an aggregate.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], host=self.host)
self.addCleanup(self.client.remove_host, aggregate['id'],
@@ -193,7 +200,8 @@
def test_aggregate_remove_nonexistent_host(self):
non_exist_host = data_utils.rand_name('nonexist_host')
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = (self.client.create_aggregate(name=aggregate_name)
+ ['aggregate'])
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(lib_exc.NotFound, self.client.remove_host,
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index 669585c..9cda0cd 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -38,7 +38,7 @@
def resource_setup(cls):
super(FixedIPsTestJson, cls).resource_setup()
server = cls.create_test_server(wait_until='ACTIVE')
- server = cls.servers_client.show_server(server['id'])
+ server = cls.servers_client.show_server(server['id'])['server']
for ip_set in server['addresses']:
for ip in server['addresses'][ip_set]:
if ip['OS-EXT-IPS:type'] == 'fixed':
diff --git a/tempest/api/compute/admin/test_fixed_ips_negative.py b/tempest/api/compute/admin/test_fixed_ips_negative.py
index e67936c..8d745c9 100644
--- a/tempest/api/compute/admin/test_fixed_ips_negative.py
+++ b/tempest/api/compute/admin/test_fixed_ips_negative.py
@@ -40,7 +40,7 @@
def resource_setup(cls):
super(FixedIPsNegativeTestJson, cls).resource_setup()
server = cls.create_test_server(wait_until='ACTIVE')
- server = cls.servers_client.show_server(server['id'])
+ server = cls.servers_client.show_server(server['id'])['server']
for ip_set in server['addresses']:
for ip in server['addresses'][ip_set]:
if ip['OS-EXT-IPS:type'] == 'fixed':
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index a3c25a2..085916e 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -69,7 +69,7 @@
id=flavor_id,
ephemeral=self.ephemeral,
swap=self.swap,
- rxtx_factor=self.rxtx)
+ rxtx_factor=self.rxtx)['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
self.assertEqual(flavor['name'], flavor_name)
self.assertEqual(flavor['vcpus'], self.vcpus)
@@ -82,7 +82,7 @@
self.assertEqual(flavor['os-flavor-access:is_public'], True)
# Verify flavor is retrieved
- flavor = self.client.show_flavor(flavor['id'])
+ flavor = self.client.show_flavor(flavor['id'])['flavor']
self.assertEqual(flavor['name'], flavor_name)
return flavor['id']
@@ -121,11 +121,11 @@
id=new_flavor_id,
ephemeral=self.ephemeral,
swap=self.swap,
- rxtx_factor=self.rxtx)
+ rxtx_factor=self.rxtx)['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
flag = False
# Verify flavor is retrieved
- flavors = self.client.list_flavors(detail=True)
+ flavors = self.client.list_flavors(detail=True)['flavors']
for flavor in flavors:
if flavor['name'] == flavor_name:
flag = True
@@ -150,7 +150,7 @@
flavor = self.client.create_flavor(name=flavor_name,
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
- id=new_flavor_id)
+ id=new_flavor_id)['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
self.assertEqual(flavor['name'], flavor_name)
self.assertEqual(flavor['ram'], self.ram)
@@ -160,12 +160,12 @@
verify_flavor_response_extension(flavor)
# Verify flavor is retrieved
- flavor = self.client.show_flavor(new_flavor_id)
+ flavor = self.client.show_flavor(new_flavor_id)['flavor']
self.assertEqual(flavor['name'], flavor_name)
verify_flavor_response_extension(flavor)
# Check if flavor is present in list
- flavors = self.user_client.list_flavors(detail=True)
+ flavors = self.user_client.list_flavors(detail=True)['flavors']
for flavor in flavors:
if flavor['name'] == flavor_name:
verify_flavor_response_extension(flavor)
@@ -186,11 +186,11 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public="False")
+ is_public="False")['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
# Verify flavor is retrieved
flag = False
- flavors = self.client.list_flavors(detail=True)
+ flavors = self.client.list_flavors(detail=True)['flavors']
for flavor in flavors:
if flavor['name'] == flavor_name:
flag = True
@@ -198,7 +198,7 @@
# Verify flavor is not retrieved with other user
flag = False
- flavors = self.user_client.list_flavors(detail=True)
+ flavors = self.user_client.list_flavors(detail=True)['flavors']
for flavor in flavors:
if flavor['name'] == flavor_name:
flag = True
@@ -215,13 +215,14 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public="False")
+ is_public="False")['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
# Verify flavor is not used by other user
self.assertRaises(lib_exc.BadRequest,
self.os.servers_client.create_server,
- 'test', self.image_ref, flavor['id'])
+ name='test', imageRef=self.image_ref,
+ flavorRef=flavor['id'])
@test.idempotent_id('b345b196-bfbd-4231-8ac1-6d7fe15ff3a3')
def test_list_public_flavor_with_other_user(self):
@@ -235,12 +236,12 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public="True")
+ is_public="True")['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
flag = False
self.new_client = self.flavors_client
# Verify flavor is retrieved with new user
- flavors = self.new_client.list_flavors(detail=True)
+ flavors = self.new_client.list_flavors(detail=True)['flavors']
for flavor in flavors:
if flavor['name'] == flavor_name:
flag = True
@@ -258,7 +259,7 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=flavor_id_not_public,
- is_public="False")
+ is_public="False")['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
# Create a public flavor
@@ -266,7 +267,7 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=flavor_id_public,
- is_public="True")
+ is_public="True")['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
def _flavor_lookup(flavors, flavor_name):
@@ -278,7 +279,8 @@
def _test_string_variations(variations, flavor_name):
for string in variations:
params = {'is_public': string}
- flavors = self.client.list_flavors(detail=True, **params)
+ flavors = (self.client.list_flavors(detail=True, **params)
+ ['flavors'])
flavor = _flavor_lookup(flavors, flavor_name)
self.assertIsNotNone(flavor)
@@ -297,7 +299,7 @@
flavor = self.client.create_flavor(name=flavor_name,
ram=ram, vcpus=self.vcpus,
disk=self.disk,
- id=new_flavor_id)
+ id=new_flavor_id)['flavor']
self.addCleanup(self.flavor_clean_up, flavor['id'])
self.assertEqual(flavor['name'], flavor_name)
self.assertEqual(flavor['vcpus'], self.vcpus)
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index ccfe20b..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
@@ -60,9 +58,10 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public='False')
+ is_public='False')['flavor']
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
- flavor_access = self.client.list_flavor_access(new_flavor_id)
+ flavor_access = (self.client.list_flavor_access(new_flavor_id)
+ ['flavor_access'])
self.assertEqual(len(flavor_access), 0, str(flavor_access))
@test.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
@@ -74,26 +73,28 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public='False')
+ is_public='False')['flavor']
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
# Add flavor access to a tenant.
resp_body = {
"tenant_id": str(self.tenant_id),
"flavor_id": str(new_flavor['id']),
}
- add_body = \
- self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
+ add_body = (self.client.add_flavor_access(new_flavor['id'],
+ self.tenant_id)
+ ['flavor_access'])
self.assertIn(resp_body, add_body)
# The flavor is present in list.
- flavors = self.flavors_client.list_flavors(detail=True)
+ flavors = self.flavors_client.list_flavors(detail=True)['flavors']
self.assertIn(new_flavor['id'], map(lambda x: x['id'], flavors))
# Remove flavor access from a tenant.
- remove_body = \
- self.client.remove_flavor_access(new_flavor['id'], self.tenant_id)
+ remove_body = (self.client.remove_flavor_access(new_flavor['id'],
+ self.tenant_id)
+ ['flavor_access'])
self.assertNotIn(resp_body, remove_body)
# The flavor is not present in list.
- flavors = self.flavors_client.list_flavors(detail=True)
+ flavors = self.flavors_client.list_flavors(detail=True)['flavors']
self.assertNotIn(new_flavor['id'], map(lambda x: x['id'], flavors))
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index 03898c2..89ae1b5 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -61,7 +61,7 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public='True')
+ is_public='True')['flavor']
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
self.assertRaises(lib_exc.NotFound,
self.client.list_flavor_access,
@@ -77,7 +77,7 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public='False')
+ is_public='False')['flavor']
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
self.assertRaises(lib_exc.Forbidden,
self.flavors_client.add_flavor_access,
@@ -94,7 +94,7 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public='False')
+ is_public='False')['flavor']
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
# Add flavor access to a tenant.
self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
@@ -115,7 +115,7 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public='False')
+ is_public='False')['flavor']
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
# Add flavor access to a tenant.
@@ -140,7 +140,7 @@
ram=self.ram, vcpus=self.vcpus,
disk=self.disk,
id=new_flavor_id,
- is_public='False')
+ is_public='False')['flavor']
self.addCleanup(self.client.delete_flavor, new_flavor['id'])
# An exception should be raised when flavor access is not found
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 6039cb2..25dce6a 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -55,7 +55,8 @@
disk=disk,
id=cls.new_flavor_id,
ephemeral=ephemeral,
- swap=swap, rxtx_factor=rxtx)
+ swap=swap,
+ rxtx_factor=rxtx)['flavor']
@classmethod
def resource_cleanup(cls):
@@ -70,11 +71,12 @@
# Assigning extra specs values that are to be set
specs = {"key1": "value1", "key2": "value2"}
# SET extra specs to the flavor created in setUp
- set_body = \
- self.client.set_flavor_extra_spec(self.flavor['id'], **specs)
+ set_body = self.client.set_flavor_extra_spec(self.flavor['id'],
+ **specs)['extra_specs']
self.assertEqual(set_body, specs)
# GET extra specs and verify
- get_body = self.client.list_flavor_extra_specs(self.flavor['id'])
+ get_body = (self.client.list_flavor_extra_specs(self.flavor['id'])
+ ['extra_specs'])
self.assertEqual(get_body, specs)
# UPDATE the value of the extra specs key1
@@ -86,7 +88,8 @@
# GET extra specs and verify the value of the key2
# is the same as before
- get_body = self.client.list_flavor_extra_specs(self.flavor['id'])
+ get_body = (self.client.list_flavor_extra_specs(self.flavor['id'])
+ ['extra_specs'])
self.assertEqual(get_body, {"key1": "value", "key2": "value2"})
# UNSET extra specs that were set in this test
@@ -97,7 +100,8 @@
def test_flavor_non_admin_get_all_keys(self):
specs = {"key1": "value1", "key2": "value2"}
self.client.set_flavor_extra_spec(self.flavor['id'], **specs)
- body = self.flavors_client.list_flavor_extra_specs(self.flavor['id'])
+ body = (self.flavors_client.list_flavor_extra_specs(self.flavor['id'])
+ ['extra_specs'])
for key in specs:
self.assertEqual(body[key], specs[key])
@@ -105,7 +109,8 @@
@test.idempotent_id('12805a7f-39a3-4042-b989-701d5cad9c90')
def test_flavor_non_admin_get_specific_key(self):
body = self.client.set_flavor_extra_spec(self.flavor['id'],
- key1="value1", key2="value2")
+ key1="value1",
+ key2="value2")['extra_specs']
self.assertEqual(body['key1'], 'value1')
self.assertIn('key2', body)
body = self.flavors_client.show_flavor_extra_spec(
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
index f1e11f4..aa95454 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -58,7 +58,8 @@
disk=disk,
id=cls.new_flavor_id,
ephemeral=ephemeral,
- swap=swap, rxtx_factor=rxtx)
+ swap=swap,
+ rxtx_factor=rxtx)['flavor']
@classmethod
def resource_cleanup(cls):
@@ -80,7 +81,7 @@
def test_flavor_non_admin_update_specific_key(self):
# non admin user is not allowed to update flavor extra spec
body = self.client.set_flavor_extra_spec(
- self.flavor['id'], key1="value1", key2="value2")
+ self.flavor['id'], key1="value1", key2="value2")['extra_specs']
self.assertEqual(body['key1'], 'value1')
self.assertRaises(lib_exc.Forbidden,
self.flavors_client.
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_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index 2ea7f1a..4c8d8a2 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -71,19 +71,6 @@
maintenance_mode='enable')
@test.attr(type=['negative'])
- @test.idempotent_id('76e396fe-5418-4dd3-a186-5b301edc0721')
- def test_update_host_with_extra_param(self):
- # only 'status' and 'maintenance_mode' are the valid params.
- hostname = self._get_host_name()
-
- self.assertRaises(lib_exc.BadRequest,
- self.client.update_host,
- hostname,
- status='enable',
- maintenance_mode='enable',
- param='XXX')
-
- @test.attr(type=['negative'])
@test.idempotent_id('fbe2bf3e-3246-4a95-a59f-94e4e298ec77')
def test_update_host_with_invalid_status(self):
# 'status' can only be 'enable' or 'disable'
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 47f66af..186867e 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -30,7 +30,7 @@
def _list_hypervisors(self):
# List of hypervisors
- hypers = self.client.list_hypervisors()
+ hypers = self.client.list_hypervisors()['hypervisors']
return hypers
def assertHypervisors(self, hypers):
@@ -45,7 +45,7 @@
@test.idempotent_id('1e7fdac2-b672-4ad1-97a4-bad0e3030118')
def test_get_hypervisor_list_details(self):
# Display the details of the all hypervisor
- hypers = self.client.list_hypervisors(detail=True)
+ hypers = self.client.list_hypervisors(detail=True)['hypervisors']
self.assertHypervisors(hypers)
@test.idempotent_id('94ff9eae-a183-428e-9cdb-79fde71211cc')
@@ -54,7 +54,7 @@
hypers = self._list_hypervisors()
self.assertHypervisors(hypers)
- details = self.client.show_hypervisor(hypers[0]['id'])
+ details = self.client.show_hypervisor(hypers[0]['id'])['hypervisor']
self.assertTrue(len(details) > 0)
self.assertEqual(details['hypervisor_hostname'],
hypers[0]['hypervisor_hostname'])
@@ -66,13 +66,15 @@
self.assertHypervisors(hypers)
hostname = hypers[0]['hypervisor_hostname']
- hypervisors = self.client.list_servers_on_hypervisor(hostname)
+ hypervisors = (self.client.list_servers_on_hypervisor(hostname)
+ ['hypervisors'])
self.assertTrue(len(hypervisors) > 0)
@test.idempotent_id('797e4f28-b6e0-454d-a548-80cc77c00816')
def test_get_hypervisor_stats(self):
# Verify the stats of the all hypervisor
- stats = self.client.show_hypervisor_statistics()
+ stats = (self.client.show_hypervisor_statistics()
+ ['hypervisor_statistics'])
self.assertTrue(len(stats) > 0)
@test.idempotent_id('91a50d7d-1c2b-4f24-b55a-a1fe20efca70')
@@ -88,7 +90,8 @@
ironic_only = True
hypers_without_ironic = []
for hyper in hypers:
- details = self.client.show_hypervisor(hypers[0]['id'])
+ details = (self.client.show_hypervisor(hypers[0]['id'])
+ ['hypervisor'])
if details['hypervisor_type'] != 'ironic':
hypers_without_ironic.append(hyper)
ironic_only = False
@@ -102,7 +105,8 @@
# because hypervisors might be disabled, this loops looking
# for any good hit.
try:
- uptime = self.client.show_hypervisor_uptime(hyper['id'])
+ uptime = (self.client.show_hypervisor_uptime(hyper['id'])
+ ['hypervisor'])
if len(uptime) > 0:
has_valid_uptime = True
break
@@ -117,5 +121,5 @@
hypers = self._list_hypervisors()
self.assertHypervisors(hypers)
hypers = self.client.search_hypervisor(
- hypers[0]['hypervisor_hostname'])
+ hypers[0]['hypervisor_hostname'])['hypervisors']
self.assertHypervisors(hypers)
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index 701b4bb..ca4a691 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -36,7 +36,7 @@
def _list_hypervisors(self):
# List of hypervisors
- hypers = self.client.list_hypervisors()
+ hypers = self.client.list_hypervisors()['hypervisors']
return hypers
@test.attr(type=['negative'])
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log.py b/tempest/api/compute/admin/test_instance_usage_audit_log.py
index 189c316..6976783 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log.py
@@ -31,7 +31,8 @@
@test.idempotent_id('25319919-33d9-424f-9f99-2c203ee48b9d')
def test_list_instance_usage_audit_logs(self):
# list instance usage audit logs
- body = self.adm_client.list_instance_usage_audit_logs()
+ body = (self.adm_client.list_instance_usage_audit_logs()
+ ["instance_usage_audit_logs"])
expected_items = ['total_errors', 'total_instances', 'log',
'num_hosts_running', 'num_hosts_done',
'num_hosts', 'hosts_not_run', 'overall_status',
@@ -44,8 +45,9 @@
def test_get_instance_usage_audit_log(self):
# Get instance usage audit log before specified time
now = datetime.datetime.now()
- body = self.adm_client.show_instance_usage_audit_log(
+ body = (self.adm_client.show_instance_usage_audit_log(
urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
+ ["instance_usage_audit_log"])
expected_items = ['total_errors', 'total_instances', 'log',
'num_hosts_running', 'num_hosts_done', 'num_hosts',
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index d6bc6f5..34ec78d 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -14,6 +14,8 @@
# under the License.
+from collections import namedtuple
+
import testtools
from tempest.api.compute import base
@@ -24,6 +26,9 @@
CONF = config.CONF
+CreatedServer = namedtuple('CreatedServer', 'server_id, volume_backed')
+
+
class LiveBlockMigrationTestJSON(base.BaseV2ComputeAdminTest):
_host_key = 'OS-EXT-SRV-ATTR:host'
@@ -38,7 +43,9 @@
def resource_setup(cls):
super(LiveBlockMigrationTestJSON, cls).resource_setup()
- cls.created_server_ids = []
+ # list of CreatedServer namedtuples
+ # TODO(mriedem): Remove the instance variable and shared server re-use
+ cls.created_servers = []
def _get_compute_hostnames(self):
body = self.admin_hosts_client.list_hosts()['hosts']
@@ -49,14 +56,22 @@
]
def _get_server_details(self, server_id):
- body = self.admin_servers_client.show_server(server_id)
+ body = self.admin_servers_client.show_server(server_id)['server']
return body
def _get_host_for_server(self, server_id):
return self._get_server_details(server_id)[self._host_key]
def _migrate_server_to(self, server_id, dest_host):
- bmflm = CONF.compute_feature_enabled.block_migration_for_live_migration
+ # volume backed instances shouldn't be block migrated
+ for id, volume_backed in self.created_servers:
+ if server_id == id:
+ use_block_migration = not volume_backed
+ break
+ else:
+ raise ValueError('Server with id %s not found.' % server_id)
+ bmflm = (CONF.compute_feature_enabled.
+ block_migration_for_live_migration and use_block_migration)
body = self.admin_servers_client.live_migrate_server(
server_id, host=dest_host, block_migration=bmflm,
disk_over_commit=False)
@@ -70,37 +85,43 @@
def _get_server_status(self, server_id):
return self._get_server_details(server_id)['status']
- def _get_an_active_server(self):
- for server_id in self.created_server_ids:
- if 'ACTIVE' == self._get_server_status(server_id):
+ def _get_an_active_server(self, volume_backed=False):
+ for server_id, vol_backed in self.created_servers:
+ if ('ACTIVE' == self._get_server_status(server_id) and
+ volume_backed == vol_backed):
return server_id
else:
- server = self.create_test_server(wait_until="ACTIVE")
+ server = self.create_test_server(wait_until="ACTIVE",
+ volume_backed=volume_backed)
server_id = server['id']
- self.created_server_ids.append(server_id)
+ new_server = CreatedServer(server_id=server_id,
+ volume_backed=volume_backed)
+ self.created_servers.append(new_server)
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')
self.volumes_client.delete_volume(volume_id)
- def _test_live_block_migration(self, state='ACTIVE'):
- """Tests live block migration between two hosts.
+ def _test_live_migration(self, state='ACTIVE', volume_backed=False):
+ """Tests live migration between two hosts.
Requires CONF.compute_feature_enabled.live_migration to be True.
:param state: The vm_state the migrated server should be in before and
after the live migration. Supported values are 'ACTIVE'
and 'PAUSED'.
+ :param volume_backed: If the instance is volume backed or not. If
+ volume_backed, *block* migration is not used.
"""
# Live block migrate an instance to another host
if len(self._get_compute_hostnames()) < 2:
raise self.skipTest(
"Less than 2 compute nodes, skipping migration test.")
- server_id = self._get_an_active_server()
+ server_id = self._get_an_active_server(volume_backed=volume_backed)
actual_host = self._get_host_for_server(server_id)
target_host = self._get_host_other_than(actual_host)
@@ -111,7 +132,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)
@@ -126,7 +148,7 @@
@testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
'Live migration not available')
def test_live_block_migration(self):
- self._test_live_block_migration()
+ self._test_live_migration()
@test.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
@testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
@@ -138,7 +160,14 @@
'Live migration of paused instances is not '
'available.')
def test_live_block_migration_paused(self):
- self._test_live_block_migration(state='PAUSED')
+ self._test_live_migration(state='PAUSED')
+
+ @test.idempotent_id('5071cf17-3004-4257-ae61-73a84e28badd')
+ @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
+ 'Live migration not available')
+ @test.services('volume')
+ def test_volume_backed_live_migration(self):
+ self._test_live_migration(volume_backed=True)
@test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
@testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
@@ -157,7 +186,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 5af7406..f81d665 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -42,14 +42,14 @@
server = self.create_test_server(wait_until="ACTIVE")
server_id = server['id']
- self.servers_client.resize(server_id, self.flavor_ref_alt)
+ 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_networks.py b/tempest/api/compute/admin/test_networks.py
index 981a5c9..1da3f6e 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -32,11 +32,11 @@
@classmethod
def setup_clients(cls):
super(NetworksTest, cls).setup_clients()
- cls.client = cls.os_adm.networks_client
+ cls.client = cls.os_adm.compute_networks_client
@test.idempotent_id('d206d211-8912-486f-86e2-a9d090d1f416')
def test_get_network(self):
- networks = self.client.list_networks()
+ networks = self.client.list_networks()['networks']
if CONF.compute.fixed_network_name:
configured_network = [x for x in networks if x['label'] ==
CONF.compute.fixed_network_name]
@@ -47,12 +47,13 @@
else:
configured_network = networks
configured_network = configured_network[0]
- network = self.client.show_network(configured_network['id'])
+ network = (self.client.show_network(configured_network['id'])
+ ['network'])
self.assertEqual(configured_network['label'], network['label'])
@test.idempotent_id('df3d1046-6fa5-4b2c-ad0c-cfa46a351cb9')
def test_list_all_networks(self):
- networks = self.client.list_networks()
+ networks = self.client.list_networks()['networks']
# Check the configured network is in the list
if CONF.compute.fixed_network_name:
configured_network = CONF.compute.fixed_network_name
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 3416eae..dbca6bb 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
@@ -97,57 +97,56 @@
# TODO(afazekas): merge these test cases
@test.idempotent_id('ce9e0815-8091-4abd-8345-7fe5b85faa1d')
def test_get_updated_quotas(self):
- # Verify that GET shows the updated quota set of tenant
- tenant_name = data_utils.rand_name('cpu_quota_tenant')
- tenant_desc = tenant_name + '-desc'
- identity_client = self.os_adm.identity_client
- tenant = identity_client.create_tenant(name=tenant_name,
- description=tenant_desc)
- tenant_id = tenant['id']
- self.addCleanup(identity_client.delete_tenant, tenant_id)
+ # Verify that GET shows the updated quota set of project
+ project_name = data_utils.rand_name('cpu_quota_project')
+ project_desc = project_name + '-desc'
+ project = self.identity_utils.create_project(name=project_name,
+ description=project_desc)
+ project_id = project['id']
+ self.addCleanup(self.identity_utils.delete_project, project_id)
- self.adm_client.update_quota_set(tenant_id, ram='5120')
- quota_set = self.adm_client.show_quota_set(tenant_id)
+ self.adm_client.update_quota_set(project_id, ram='5120')
+ quota_set = self.adm_client.show_quota_set(project_id)['quota_set']
self.assertEqual(5120, quota_set['ram'])
# Verify that GET shows the updated quota set of user
user_name = data_utils.rand_name('cpu_quota_user')
password = data_utils.rand_name('password')
email = user_name + '@testmail.tm'
- user = identity_client.create_user(name=user_name,
- password=password,
- tenant_id=tenant_id,
- email=email)
+ user = self.identity_utils.create_user(username=user_name,
+ password=password,
+ project=project,
+ email=email)
if 'user' in user:
user = user['user']
user_id = user['id']
- self.addCleanup(identity_client.delete_user, user_id)
+ self.addCleanup(self.identity_utils.delete_user, user_id)
- self.adm_client.update_quota_set(tenant_id,
+ self.adm_client.update_quota_set(project_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(
+ project_id, user_id=user_id)['quota_set']
self.assertEqual(2048, quota_set['ram'])
@test.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
def test_delete_quota(self):
- # Admin can delete the resource quota set for a tenant
- tenant_name = data_utils.rand_name('ram_quota_tenant')
- tenant_desc = tenant_name + '-desc'
- identity_client = self.os_adm.identity_client
- tenant = identity_client.create_tenant(name=tenant_name,
- 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)
+ # Admin can delete the resource quota set for a project
+ project_name = data_utils.rand_name('ram_quota_project')
+ project_desc = project_name + '-desc'
+ project = self.identity_utils.create_project(name=project_name,
+ description=project_desc)
+ project_id = project['id']
+ self.addCleanup(self.identity_utils.delete_project, project_id)
+ quota_set_default = (self.adm_client.show_quota_set(project_id)
+ ['quota_set'])
ram_default = quota_set_default['ram']
- self.adm_client.update_quota_set(tenant_id, ram='5120')
+ self.adm_client.update_quota_set(project_id, ram='5120')
- self.adm_client.delete_quota_set(tenant_id)
+ self.adm_client.delete_quota_set(project_id)
- quota_set_new = self.adm_client.show_quota_set(tenant_id)
+ quota_set_new = self.adm_client.show_quota_set(project_id)['quota_set']
self.assertEqual(ram_default, quota_set_new['ram'])
@@ -169,7 +168,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 +177,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 +190,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 8dcd0b2..bdbfde4 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -49,19 +49,20 @@
self.demo_tenant_id,
ram=0)
- # TODO(afazekas): Add dedicated tenant to the skiped quota tests
- # it can be moved into the setUpClass as well
+ # TODO(afazekas): Add dedicated tenant to the skipped quota tests.
+ # It can be moved into the setUpClass as well.
@test.attr(type=['negative'])
@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,
@@ -156,9 +158,8 @@
s_name = data_utils.rand_name('securitygroup')
s_description = data_utils.rand_name('description')
- securitygroup =\
- self.sg_client.create_security_group(name=s_name,
- description=s_description)
+ securitygroup = self.sg_client.create_security_group(
+ name=s_name, description=s_description)['security_group']
self.addCleanup(self.sg_client.delete_security_group,
securitygroup['id'])
diff --git a/tempest/api/compute/admin/test_security_group_default_rules.py b/tempest/api/compute/admin/test_security_group_default_rules.py
index 5ae6553..74f3caa 100644
--- a/tempest/api/compute/admin/test_security_group_default_rules.py
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -48,7 +48,7 @@
ip_protocol=ip_protocol,
from_port=from_port,
to_port=to_port,
- cidr=cidr)
+ cidr=cidr)['security_group_default_rule']
self.assertEqual(ip_protocol, rule['ip_protocol'])
self.assertEqual(from_port, rule['from_port'])
self.assertEqual(to_port, rule['to_port'])
@@ -75,7 +75,7 @@
rule = self.adm_client.create_security_default_group_rule(
ip_protocol=ip_protocol,
from_port=from_port,
- to_port=to_port)
+ to_port=to_port)['security_group_default_rule']
self.addCleanup(self.adm_client.delete_security_group_default_rule,
rule['id'])
self.assertNotEqual(0, rule['id'])
@@ -91,7 +91,7 @@
ip_protocol=ip_protocol,
from_port=from_port,
to_port=to_port,
- cidr=cidr)
+ cidr=cidr)['security_group_default_rule']
self.addCleanup(self.adm_client.delete_security_group_default_rule,
rule['id'])
self.assertNotEqual(0, rule['id'])
@@ -109,7 +109,8 @@
cidr)
self.addCleanup(self.adm_client.delete_security_group_default_rule,
rule['id'])
- rules = self.adm_client.list_security_group_default_rules()
+ rules = (self.adm_client.list_security_group_default_rules()
+ ['security_group_default_rules'])
self.assertNotEqual(0, len(rules))
self.assertIn(rule, rules)
@@ -126,5 +127,5 @@
self.addCleanup(self.adm_client.delete_security_group_default_rule,
rule['id'])
fetched_rule = self.adm_client.show_security_group_default_rule(
- rule['id'])
+ rule['id'])['security_group_default_rule']
self.assertEqual(rule, fetched_rule)
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index b2a1b98..b0a3086 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -50,9 +50,8 @@
for i in range(2):
name = data_utils.rand_name('securitygroup')
description = data_utils.rand_name('description')
- securitygroup = (self.client
- .create_security_group(name=name,
- description=description))
+ securitygroup = self.client.create_security_group(
+ name=name, description=description)['security_group']
self.addCleanup(self._delete_security_group,
securitygroup['id'], admin=False)
security_group_list.append(securitygroup)
@@ -63,13 +62,14 @@
name = data_utils.rand_name('securitygroup')
description = data_utils.rand_name('description')
adm_securitygroup = self.adm_client.create_security_group(
- name=name, description=description)
+ name=name, description=description)['security_group']
self.addCleanup(self._delete_security_group,
adm_securitygroup['id'])
security_group_list.append(adm_securitygroup)
# Fetch all security groups based on 'all_tenants' search filter
- fetched_list = self.adm_client.list_security_groups(all_tenants='true')
+ fetched_list = self.adm_client.list_security_groups(
+ all_tenants='true')['security_groups']
sec_group_id_list = map(lambda sg: sg['id'], fetched_list)
# Now check if all created Security Groups are present in fetched list
for sec_group in security_group_list:
@@ -77,7 +77,8 @@
# Fetch all security groups for non-admin user with 'all_tenants'
# search filter
- fetched_list = self.client.list_security_groups(all_tenants='true')
+ fetched_list = (self.client.list_security_groups(all_tenants='true')
+ ['security_groups'])
# Now check if all created Security Groups are present in fetched list
for sec_group in fetched_list:
self.assertEqual(sec_group['tenant_id'], client_tenant_id,
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 1982eda..dfaa5d5 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -66,7 +66,7 @@
# Reset server's state to 'active'
self.client.reset_state(self.s1_id, state='active')
# Verify server's state
- server = self.client.show_server(self.s1_id)
+ server = self.client.show_server(self.s1_id)['server']
self.assertEqual(server['status'], 'ACTIVE')
servers = body['servers']
# Verify error server in list result
@@ -111,12 +111,13 @@
image_id = self.image_ref
network = self.get_tenant_network()
network_kwargs = fixed_network.set_networks_kwarg(network)
- test_server = self.client.create_server(name, image_id, flavor,
- **network_kwargs)
+ test_server = self.client.create_server(name=name, imageRef=image_id,
+ flavorRef=flavor,
+ **network_kwargs)['server']
self.addCleanup(self.client.delete_server, test_server['id'])
waiters.wait_for_server_status(self.client,
test_server['id'], 'ACTIVE')
- server = self.client.show_server(test_server['id'])
+ server = self.client.show_server(test_server['id'])['server']
self.assertEqual(server['status'], 'ACTIVE')
hostname = server[self._host_key]
params = {'host': hostname}
@@ -135,14 +136,14 @@
self.client.reset_state(self.s1_id)
# Verify server's state
- server = self.client.show_server(self.s1_id)
+ server = self.client.show_server(self.s1_id)['server']
self.assertEqual(server['status'], 'ERROR')
# Reset server's state to 'active'
self.client.reset_state(self.s1_id, state='active')
# Verify server's state
- server = self.client.show_server(self.s1_id)
+ server = self.client.show_server(self.s1_id)['server']
self.assertEqual(server['status'], 'ACTIVE')
@decorators.skip_because(bug="1240043")
@@ -163,11 +164,11 @@
# resetting vm state require admin privilege
self.client.reset_state(self.s1_id, state='error')
- rebuilt_server = self.non_admin_client.rebuild(
- self.s1_id, self.image_ref_alt)
+ rebuilt_server = self.non_admin_client.rebuild_server(
+ self.s1_id, self.image_ref_alt)['server']
self.addCleanup(waiters.wait_for_server_status, self.non_admin_client,
self.s1_id, 'ACTIVE')
- self.addCleanup(self.non_admin_client.rebuild, self.s1_id,
+ self.addCleanup(self.non_admin_client.rebuild_server, self.s1_id,
self.image_ref)
# Verify the properties in the initial response are correct
@@ -179,7 +180,8 @@
rebuilt_server['id'], 'ACTIVE',
raise_on_error=False)
# Verify the server properties after rebuilding
- server = self.non_admin_client.show_server(rebuilt_server['id'])
+ server = (self.non_admin_client.show_server(rebuilt_server['id'])
+ ['server'])
rebuilt_image_id = server['image']['id']
self.assertEqual(self.image_ref_alt, rebuilt_image_id)
@@ -197,5 +199,5 @@
hints = {
'same_host': self.s1_id
}
- self.create_test_server(sched_hints=hints,
+ self.create_test_server(scheduler_hints=hints,
wait_until='ACTIVE')
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 0241e70..c2dc94c 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -69,16 +69,18 @@
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
flavor_ref = self.flavors_client.create_flavor(name=flavor_name,
ram=ram, vcpus=vcpus,
- disk=disk, id=flavor_id)
+ disk=disk,
+ id=flavor_id)['flavor']
self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
- self.client.resize,
+ self.client.resize_server,
self.servers[0]['id'],
flavor_ref['id'])
@@ -92,15 +94,17 @@
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,
ram=ram, vcpus=vcpus,
- disk=disk, id=flavor_id)
+ disk=disk,
+ id=flavor_id)['flavor']
self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
- self.client.resize,
+ self.client.resize_server,
self.servers[0]['id'],
flavor_ref['id'])
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index db22925..4d7dea5 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -31,25 +31,25 @@
@test.idempotent_id('5be41ef4-53d1-41cc-8839-5c2a48a1b283')
def test_list_services(self):
- services = self.client.list_services()
+ services = self.client.list_services()['services']
self.assertNotEqual(0, len(services))
@test.idempotent_id('f345b1ec-bc6e-4c38-a527-3ca2bc00bef5')
def test_get_service_by_service_binary_name(self):
binary_name = 'nova-compute'
- services = self.client.list_services(binary=binary_name)
+ services = self.client.list_services(binary=binary_name)['services']
self.assertNotEqual(0, len(services))
for service in services:
self.assertEqual(binary_name, service['binary'])
@test.idempotent_id('affb42d5-5b4b-43c8-8b0b-6dca054abcca')
def test_get_service_by_host_name(self):
- services = self.client.list_services()
+ services = self.client.list_services()['services']
host_name = services[0]['host']
services_on_host = [service for service in services if
service['host'] == host_name]
- services = self.client.list_services(host=host_name)
+ services = self.client.list_services(host=host_name)['services']
# we could have a periodic job checkin between the 2 service
# lookups, so only compare binary lists.
@@ -62,12 +62,12 @@
@test.idempotent_id('39397f6f-37b8-4234-8671-281e44c74025')
def test_get_service_by_service_and_host_name(self):
- services = self.client.list_services()
+ services = self.client.list_services()['services']
host_name = services[0]['host']
binary_name = services[0]['binary']
services = self.client.list_services(host=host_name,
- binary=binary_name)
+ binary=binary_name)['services']
self.assertEqual(1, len(services))
self.assertEqual(host_name, services[0]['host'])
self.assertEqual(binary_name, services[0]['binary'])
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index b9335c9..0c81ccb 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -40,22 +40,25 @@
@test.idempotent_id('d0884a69-f693-4e79-a9af-232d15643bf7')
def test_get_service_by_invalid_params(self):
# return all services if send the request with invalid parameter
- services = self.client.list_services()
- services_xxx = self.client.list_services(xxx='nova-compute')
+ services = self.client.list_services()['services']
+ services_xxx = (self.client.list_services(xxx='nova-compute')
+ ['services'])
self.assertEqual(len(services), len(services_xxx))
@test.attr(type=['negative'])
@test.idempotent_id('1e966d4a-226e-47c7-b601-0b18a27add54')
def test_get_service_by_invalid_service_and_valid_host(self):
- services = self.client.list_services()
+ services = self.client.list_services()['services']
host_name = services[0]['host']
- services = self.client.list_services(host=host_name, binary='xxx')
+ services = self.client.list_services(host=host_name,
+ binary='xxx')['services']
self.assertEqual(0, len(services))
@test.attr(type=['negative'])
@test.idempotent_id('64e7e7fb-69e8-4cb6-a71d-8d5eb0c98655')
def test_get_service_with_valid_service_and_invalid_host(self):
- services = self.client.list_services()
+ services = self.client.list_services()['services']
binary_name = services[0]['binary']
- services = self.client.list_services(host='xxx', binary=binary_name)
+ services = self.client.list_services(host='xxx',
+ binary=binary_name)['services']
self.assertEqual(0, len(services))
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index 204281c..7333acb 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -50,14 +50,14 @@
def test_list_usage_all_tenants(self):
# Get usage for all tenants
tenant_usage = self.adm_client.list_tenant_usages(
- start=self.start, end=self.end, detailed="1")
+ start=self.start, end=self.end, detailed="1")['tenant_usages'][0]
self.assertEqual(len(tenant_usage), 8)
@test.idempotent_id('94135049-a4c5-4934-ad39-08fa7da4f22e')
def test_get_usage_tenant(self):
# Get usage for a specific tenant
tenant_usage = self.adm_client.show_tenant_usage(
- self.tenant_id, start=self.start, end=self.end)
+ self.tenant_id, start=self.start, end=self.end)['tenant_usage']
self.assertEqual(len(tenant_usage), 8)
@@ -65,6 +65,6 @@
def test_get_usage_tenant_with_non_admin_user(self):
# Get usage for a specific tenant with non admin user
tenant_usage = self.client.show_tenant_usage(
- self.tenant_id, start=self.start, end=self.end)
+ self.tenant_id, start=self.start, end=self.end)['tenant_usage']
self.assertEqual(len(tenant_usage), 8)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 1ec2b56..b0fdbac 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -43,6 +43,8 @@
@classmethod
def skip_checks(cls):
super(BaseComputeTest, cls).skip_checks()
+ if not CONF.service_available.nova:
+ raise cls.skipException("Nova is not available")
if cls._api_version != 2:
msg = ("Unexpected API version is specified (%s)" %
cls._api_version)
@@ -67,13 +69,11 @@
cls.security_group_rules_client = cls.os.security_group_rules_client
cls.security_groups_client = cls.os.security_groups_client
cls.quotas_client = cls.os.quotas_client
- # NOTE(mriedem): os-quota-class-sets is v2 API only
cls.quota_classes_client = cls.os.quota_classes_client
- # NOTE(mriedem): os-networks is v2 API only
- cls.networks_client = cls.os.networks_client
+ cls.compute_networks_client = cls.os.compute_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.snapshots_extensions_client = cls.os.snapshots_extensions_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
@@ -87,6 +87,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):
@@ -197,13 +203,17 @@
server_group_id)
@classmethod
- def create_test_server(cls, validatable=False, **kwargs):
+ def create_test_server(cls, validatable=False, volume_backed=False,
+ **kwargs):
"""Wrapper utility that returns a test server.
This wrapper utility calls the common create test server and
returns a test server. The purpose of this wrapper is to minimize
the impact on the code of the tests already using this
function.
+
+ :param validatable: Whether the server will be pingable or sshable.
+ :param volume_backed: Whether the instance is volume backed or not.
"""
tenant_network = cls.get_tenant_network()
body, servers = compute.create_test_server(
@@ -211,6 +221,7 @@
validatable,
validation_resources=cls.validation_resources,
tenant_network=tenant_network,
+ volume_backed=volume_backed,
**kwargs)
cls.servers.extend(servers)
@@ -223,9 +234,8 @@
name = data_utils.rand_name(cls.__name__ + "-securitygroup")
if description is None:
description = data_utils.rand_name('description')
- body = \
- cls.security_groups_client.create_security_group(
- name=name, description=description)
+ body = cls.security_groups_client.create_security_group(
+ name=name, description=description)['security_group']
cls.security_groups.append(body)
return body
@@ -236,7 +246,8 @@
name = data_utils.rand_name(cls.__name__ + "-Server-Group")
if policy is None:
policy = ['affinity']
- body = cls.server_groups_client.create_server_group(name, policy)
+ body = (cls.server_groups_client.create_server_group(name, policy)
+ ['server_group'])
cls.server_groups.append(body['id'])
return body
@@ -288,7 +299,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/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 728fefb..e114c80 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -32,8 +32,8 @@
@test.idempotent_id('e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59')
def test_list_flavors(self):
# List of all flavors should contain the expected flavor
- flavors = self.client.list_flavors()
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavors = self.client.list_flavors()['flavors']
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
flavor_min_detail = {'id': flavor['id'], 'links': flavor['links'],
'name': flavor['name']}
self.assertIn(flavor_min_detail, flavors)
@@ -41,89 +41,89 @@
@test.idempotent_id('6e85fde4-b3cd-4137-ab72-ed5f418e8c24')
def test_list_flavors_with_detail(self):
# Detailed list of all flavors should contain the expected flavor
- flavors = self.client.list_flavors(detail=True)
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavors = self.client.list_flavors(detail=True)['flavors']
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
self.assertIn(flavor, flavors)
@test.attr(type='smoke')
@test.idempotent_id('1f12046b-753d-40d2-abb6-d8eb8b30cb2f')
def test_get_flavor(self):
# The expected flavor details should be returned
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
self.assertEqual(self.flavor_ref, flavor['id'])
@test.idempotent_id('8d7691b3-6ed4-411a-abc9-2839a765adab')
def test_list_flavors_limit_results(self):
# Only the expected number of flavors should be returned
params = {'limit': 1}
- flavors = self.client.list_flavors(**params)
+ flavors = self.client.list_flavors(**params)['flavors']
self.assertEqual(1, len(flavors))
@test.idempotent_id('b26f6327-2886-467a-82be-cef7a27709cb')
def test_list_flavors_detailed_limit_results(self):
# Only the expected number of flavors (detailed) should be returned
params = {'limit': 1}
- flavors = self.client.list_flavors(detail=True, **params)
+ flavors = self.client.list_flavors(detail=True, **params)['flavors']
self.assertEqual(1, len(flavors))
@test.idempotent_id('e800f879-9828-4bd0-8eae-4f17189951fb')
def test_list_flavors_using_marker(self):
# The list of flavors should start from the provided marker
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {'marker': flavor_id}
- flavors = self.client.list_flavors(**params)
+ flavors = self.client.list_flavors(**params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
'The list of flavors did not start after the marker.')
@test.idempotent_id('6db2f0c0-ddee-4162-9c84-0703d3dd1107')
def test_list_flavors_detailed_using_marker(self):
# The list of flavors should start from the provided marker
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {'marker': flavor_id}
- flavors = self.client.list_flavors(detail=True, **params)
+ flavors = self.client.list_flavors(detail=True, **params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
'The list of flavors did not start after the marker.')
@test.idempotent_id('3df2743e-3034-4e57-a4cb-b6527f6eac79')
def test_list_flavors_detailed_filter_by_min_disk(self):
# The detailed list of flavors should be filtered by disk space
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {self._min_disk: flavor['disk'] + 1}
- flavors = self.client.list_flavors(detail=True, **params)
+ flavors = self.client.list_flavors(detail=True, **params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
@test.idempotent_id('09fe7509-b4ee-4b34-bf8b-39532dc47292')
def test_list_flavors_detailed_filter_by_min_ram(self):
# The detailed list of flavors should be filtered by RAM
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {self._min_ram: flavor['ram'] + 1}
- flavors = self.client.list_flavors(detail=True, **params)
+ flavors = self.client.list_flavors(detail=True, **params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
@test.idempotent_id('10645a4d-96f5-443f-831b-730711e11dd4')
def test_list_flavors_filter_by_min_disk(self):
# The list of flavors should be filtered by disk space
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {self._min_disk: flavor['disk'] + 1}
- flavors = self.client.list_flavors(**params)
+ flavors = self.client.list_flavors(**params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
@test.idempotent_id('935cf550-e7c8-4da6-8002-00f92d5edfaa')
def test_list_flavors_filter_by_min_ram(self):
# The list of flavors should be filtered by RAM
- flavor = self.client.show_flavor(self.flavor_ref)
+ flavor = self.client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {self._min_ram: flavor['ram'] + 1}
- flavors = self.client.list_flavors(**params)
+ flavors = self.client.list_flavors(**params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 8bb4fac..5b90641 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -39,7 +39,7 @@
server = cls.create_test_server(wait_until='ACTIVE')
cls.server_id = server['id']
# Floating IP creation
- body = cls.client.create_floating_ip()
+ body = cls.client.create_floating_ip()['floating_ip']
cls.floating_ip_id = body['id']
cls.floating_ip = body['ip']
@@ -63,14 +63,14 @@
def test_allocate_floating_ip(self):
# Positive test:Allocation of a new floating IP to a project
# should be successful
- body = self.client.create_floating_ip()
+ body = self.client.create_floating_ip()['floating_ip']
floating_ip_id_allocated = body['id']
self.addCleanup(self.client.delete_floating_ip,
floating_ip_id_allocated)
- floating_ip_details = \
- self.client.show_floating_ip(floating_ip_id_allocated)
+ floating_ip_details = self.client.show_floating_ip(
+ floating_ip_id_allocated)['floating_ip']
# Checking if the details of allocated IP is in list of floating IP
- body = self.client.list_floating_ips()
+ body = self.client.list_floating_ips()['floating_ips']
self.assertIn(floating_ip_details, body)
@test.idempotent_id('de45e989-b5ca-4a9b-916b-04a52e7bbb8b')
@@ -79,7 +79,7 @@
# Positive test:Deletion of valid floating IP from project
# should be successful
# Creating the floating IP that is to be deleted in this method
- floating_ip_body = self.client.create_floating_ip()
+ floating_ip_body = self.client.create_floating_ip()['floating_ip']
self.addCleanup(self._try_delete_floating_ip, floating_ip_body['id'])
# Deleting the floating IP from the project
self.client.delete_floating_ip(floating_ip_body['id'])
@@ -98,7 +98,8 @@
self.server_id)
# Check instance_id in the floating_ip body
- body = self.client.show_floating_ip(self.floating_ip_id)
+ body = (self.client.show_floating_ip(self.floating_ip_id)
+ ['floating_ip'])
self.assertEqual(self.server_id, body['instance_id'])
# Disassociation of floating IP that was associated in this method
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index c07af72..64aac80 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -42,7 +42,7 @@
cls.server_id = server['id']
# Generating a nonexistent floatingIP id
cls.floating_ip_ids = []
- body = cls.client.list_floating_ips()
+ body = cls.client.list_floating_ips()['floating_ips']
for i in range(len(body)):
cls.floating_ip_ids.append(body[i]['id'])
while True:
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 7a5bcff..d003967 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -31,7 +31,7 @@
cls.floating_ip = []
cls.floating_ip_id = []
for i in range(3):
- body = cls.client.create_floating_ip()
+ body = cls.client.create_floating_ip()['floating_ip']
cls.floating_ip.append(body)
cls.floating_ip_id.append(body['id'])
@@ -45,7 +45,7 @@
@test.services('network')
def test_list_floating_ips(self):
# Positive test:Should return the list of floating IPs
- body = self.client.list_floating_ips()
+ body = self.client.list_floating_ips()['floating_ips']
floating_ips = body
self.assertNotEqual(0, len(floating_ips),
"Expected floating IPs. Got zero.")
@@ -57,14 +57,14 @@
def test_get_floating_ip_details(self):
# Positive test:Should be able to GET the details of floatingIP
# Creating a floating IP for which details are to be checked
- body = self.client.create_floating_ip()
+ body = self.client.create_floating_ip()['floating_ip']
floating_ip_id = body['id']
self.addCleanup(self.client.delete_floating_ip,
floating_ip_id)
floating_ip_instance_id = body['instance_id']
floating_ip_ip = body['ip']
floating_ip_fixed_ip = body['fixed_ip']
- body = self.client.show_floating_ip(floating_ip_id)
+ body = self.client.show_floating_ip(floating_ip_id)['floating_ip']
# Comparing the details of floating IP
self.assertEqual(floating_ip_instance_id,
body['instance_id'])
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 06b7cac..37c2bb6 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -71,7 +71,7 @@
cls.server_id = server['id']
def _get_default_flavor_disk_size(self, flavor_id):
- flavor = self.flavors_client.show_flavor(flavor_id)
+ flavor = self.flavors_client.show_flavor(flavor_id)['flavor']
return flavor['disk']
@test.idempotent_id('3731d080-d4c5-4872-b41a-64d0d0021314')
@@ -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..73e852f 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.
@@ -55,4 +55,4 @@
# A 403 Forbidden or 413 Overlimit (old behaviour) exception
# will be raised when out of quota
self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
- self.create_test_server, meta=meta_data)
+ self.create_test_server, metadata=meta_data)
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index b5eff70..9aa59f7 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -73,7 +73,7 @@
parent_group_id=securitygroup_id,
ip_protocol=self.ip_protocol,
from_port=self.from_port,
- to_port=self.to_port)
+ to_port=self.to_port)['security_group_rule']
self.expected['parent_group_id'] = securitygroup_id
self.expected['ip_range'] = {'cidr': '0.0.0.0/0'}
self._check_expected_response(rule)
@@ -96,7 +96,7 @@
ip_protocol=self.ip_protocol,
from_port=self.from_port,
to_port=self.to_port,
- cidr=cidr)
+ cidr=cidr)['security_group_rule']
self.expected['parent_group_id'] = parent_group_id
self.expected['ip_range'] = {'cidr': cidr}
self._check_expected_response(rule)
@@ -123,7 +123,7 @@
ip_protocol=self.ip_protocol,
from_port=self.from_port,
to_port=self.to_port,
- group_id=group_id)
+ group_id=group_id)['security_group_rule']
self.expected['parent_group_id'] = parent_group_id
self.expected['group'] = {'tenant_id': self.client.tenant_id,
'name': group_name}
@@ -144,7 +144,7 @@
parent_group_id=securitygroup_id,
ip_protocol=self.ip_protocol,
from_port=self.from_port,
- to_port=self.to_port)
+ to_port=self.to_port)['security_group_rule']
rule1_id = rule['id']
# Add a second rule to the created Security Group
@@ -155,14 +155,14 @@
parent_group_id=securitygroup_id,
ip_protocol=ip_protocol2,
from_port=from_port2,
- to_port=to_port2)
+ to_port=to_port2)['security_group_rule']
rule2_id = rule['id']
# Delete the Security Group rule2 at the end of this method
self.addCleanup(self.client.delete_security_group_rule, rule2_id)
# Get rules of the created Security Group
- rules = \
- self.client.list_security_group_rules(securitygroup_id)
+ rules = self.security_groups_client.show_security_group(
+ securitygroup_id)['security_group']['rules']
self.assertTrue(any([i for i in rules if i['id'] == rule1_id]))
self.assertTrue(any([i for i in rules if i['id'] == rule2_id]))
@@ -182,12 +182,12 @@
ip_protocol=self.ip_protocol,
from_port=self.from_port,
to_port=self.to_port,
- group_id=sg2_id)
+ group_id=sg2_id)['security_group_rule']
# Delete group2
self.security_groups_client.delete_security_group(sg2_id)
# Get rules of the Group1
- rules = \
- self.client.list_security_group_rules(sg1_id)
+ rules = (self.security_groups_client.show_security_group(sg1_id)
+ ['security_group']['rules'])
# The group1 has no rules because group2 has deleted
self.assertEqual(0, len(rules))
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index d12306a..816038a 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -87,7 +87,7 @@
rule = self.rules_client.create_security_group_rule(
parent_group_id=parent_group_id, ip_protocol=ip_protocol,
- from_port=from_port, to_port=to_port)
+ from_port=from_port, to_port=to_port)['security_group_rule']
self.addCleanup(self.rules_client.delete_security_group_rule,
rule['id'])
# Add the same rule to the group should fail
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 7fff8bf..dbbeb70 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -40,7 +40,7 @@
security_group_list.append(body)
# Fetch all Security Groups and verify the list
# has all created Security Groups
- fetched_list = self.client.list_security_groups()
+ fetched_list = self.client.list_security_groups()['security_groups']
# Now check if all the created Security Groups are in fetched list
missing_sgs = \
[sg for sg in security_group_list if sg not in fetched_list]
@@ -53,7 +53,7 @@
self.client.delete_security_group(sg['id'])
self.client.wait_for_resource_deletion(sg['id'])
# Now check if all the created Security Groups are deleted
- fetched_list = self.client.list_security_groups()
+ fetched_list = self.client.list_security_groups()['security_groups']
deleted_sgs = \
[sg for sg in security_group_list if sg in fetched_list]
self.assertFalse(deleted_sgs,
@@ -75,8 +75,8 @@
"The created Security Group name is "
"not equal to the requested name")
# Now fetch the created Security Group by its 'id'
- fetched_group = \
- self.client.show_security_group(securitygroup['id'])
+ fetched_group = (self.client.show_security_group(securitygroup['id'])
+ ['security_group'])
self.assertEqual(securitygroup, fetched_group,
"The fetched Security Group is different "
"from the created Group")
@@ -109,7 +109,7 @@
sg['id'])
# Reboot and add the other security group
- self.servers_client.reboot(server_id, 'HARD')
+ self.servers_client.reboot_server(server_id, 'HARD')
waiters.wait_for_server_status(self.servers_client, server_id,
'ACTIVE')
self.servers_client.add_security_group(server_id, sg2['name'])
@@ -143,7 +143,7 @@
name=s_new_name,
description=s_new_des)
# get the security group
- fetched_group = \
- self.client.show_security_group(securitygroup_id)
+ fetched_group = (self.client.show_security_group(securitygroup_id)
+ ['security_group'])
self.assertEqual(s_new_name, fetched_group['name'])
self.assertEqual(s_new_des, fetched_group['description'])
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index 642aca1..120d327 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -39,7 +39,7 @@
def _generate_a_non_existent_security_group_id(self):
security_group_id = []
- body = self.client.list_security_groups()
+ body = self.client.list_security_groups()['security_groups']
for i in range(len(body)):
security_group_id.append(body[i]['id'])
# Generate a non-existent security group id
@@ -122,7 +122,7 @@
def test_delete_the_default_security_group(self):
# Negative test:Deletion of the "default" Security Group should Fail
default_security_group_id = None
- body = self.client.list_security_groups()
+ body = self.client.list_security_groups()['security_groups']
for i in range(len(body)):
if body[i]['name'] == 'default':
default_security_group_id = body[i]['id']
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 9e27f33..24d503f 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -48,13 +48,15 @@
def wait_for_interface_status(self, server, port_id, status):
"""Waits for a interface to reach a given status."""
- body = self.client.show_interface(server, port_id)
+ body = (self.client.show_interface(server, port_id)
+ ['interfaceAttachment'])
interface_status = body['port_state']
start = int(time.time())
while(interface_status != status):
time.sleep(self.build_interval)
- body = self.client.show_interface(server, port_id)
+ body = (self.client.show_interface(server, port_id)
+ ['interfaceAttachment'])
interface_status = body['port_state']
timed_out = int(time.time()) - start >= self.build_timeout
@@ -82,14 +84,16 @@
def _create_server_get_interfaces(self):
server = self.create_test_server(wait_until='ACTIVE')
- ifs = self.client.list_interfaces(server['id'])
+ ifs = (self.client.list_interfaces(server['id'])
+ ['interfaceAttachments'])
body = self.wait_for_interface_status(
server['id'], ifs[0]['port_id'], 'ACTIVE')
ifs[0]['port_state'] = body['port_state']
return server, ifs
def _test_create_interface(self, server):
- iface = self.client.create_interface(server['id'])
+ iface = (self.client.create_interface(server['id'])
+ ['interfaceAttachment'])
iface = self.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface)
@@ -97,8 +101,8 @@
def _test_create_interface_by_network_id(self, server, ifs):
network_id = ifs[0]['net_id']
- iface = self.client.create_interface(server['id'],
- net_id=network_id)
+ iface = self.client.create_interface(
+ server['id'], net_id=network_id)['interfaceAttachment']
iface = self.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface, network_id=network_id)
@@ -106,8 +110,8 @@
def _test_show_interface(self, server, ifs):
iface = ifs[0]
- _iface = self.client.show_interface(server['id'],
- iface['port_id'])
+ _iface = self.client.show_interface(
+ server['id'], iface['port_id'])['interfaceAttachment']
self._check_interface(iface, port_id=_iface['port_id'],
network_id=_iface['net_id'],
fixed_ip=_iface['fixed_ips'][0]['ip_address'],
@@ -117,12 +121,14 @@
# NOTE(danms): delete not the first or last, but one in the middle
iface = ifs[1]
self.client.delete_interface(server['id'], iface['port_id'])
- _ifs = self.client.list_interfaces(server['id'])
+ _ifs = (self.client.list_interfaces(server['id'])
+ ['interfaceAttachments'])
start = int(time.time())
while len(ifs) == len(_ifs):
time.sleep(self.build_interval)
- _ifs = self.client.list_interfaces(server['id'])
+ _ifs = (self.client.list_interfaces(server['id'])
+ ['interfaceAttachments'])
timed_out = int(time.time()) - start >= self.build_timeout
if len(ifs) == len(_ifs) and timed_out:
message = ('Failed to delete interface within '
@@ -161,7 +167,8 @@
iface = self._test_create_interface_by_network_id(server, ifs)
ifs.append(iface)
- _ifs = self.client.list_interfaces(server['id'])
+ _ifs = (self.client.list_interfaces(server['id'])
+ ['interfaceAttachments'])
self._compare_iface_list(ifs, _ifs)
self._test_show_interface(server, ifs)
@@ -179,10 +186,10 @@
self.assertTrue(interface_count > 0)
self._check_interface(ifs[0])
network_id = ifs[0]['net_id']
- self.client.add_fixed_ip(server['id'], networkId=network_id)
+ self.servers_client.add_fixed_ip(server['id'], networkId=network_id)
# Remove the fixed IP from server.
server_detail = self.os.servers_client.show_server(
- server['id'])
+ server['id'])['server']
# Get the Fixed IP from server.
fixed_ip = None
for ip_set in server_detail['addresses']:
@@ -192,4 +199,4 @@
break
if fixed_ip is not None:
break
- self.client.remove_fixed_ip(server['id'], address=fixed_ip)
+ self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip)
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index c6fb2fb..2fd7520 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -41,6 +41,7 @@
super(ServersTestJSON, cls).setup_clients()
cls.client = cls.servers_client
cls.network_client = cls.os.network_client
+ cls.networks_client = cls.os.networks_client
@classmethod
def resource_setup(cls):
@@ -58,18 +59,19 @@
validatable=True,
wait_until='ACTIVE',
name=cls.name,
- meta=cls.meta,
+ metadata=cls.meta,
accessIPv4=cls.accessIPv4,
accessIPv6=cls.accessIPv6,
personality=personality,
disk_config=disk_config)
cls.password = cls.server_initial['adminPass']
- cls.server = cls.client.show_server(cls.server_initial['id'])
+ cls.server = (cls.client.show_server(cls.server_initial['id'])
+ ['server'])
def _create_net_subnet_ret_net_from_cidr(self, cidr):
name_net = data_utils.rand_name(self.__class__.__name__)
- net = self.network_client.create_network(name=name_net)
- self.addCleanup(self.network_client.delete_network,
+ net = self.networks_client.create_network(name=name_net)
+ self.addCleanup(self.networks_client.delete_network,
net['network']['id'])
subnet = self.network_client.create_subnet(
@@ -117,7 +119,7 @@
def test_verify_created_server_vcpus(self):
# Verify that the number of vcpus reported by the instance matches
# the amount stated by the flavor
- flavor = self.flavors_client.show_flavor(self.flavor_ref)
+ flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
linux_client = remote_client.RemoteClient(
self.get_server_ip(self.server),
self.ssh_user,
@@ -143,17 +145,18 @@
name = data_utils.rand_name('server_group')
policies = ['affinity']
body = self.server_groups_client.create_server_group(
- name=name, policies=policies)
+ name=name, policies=policies)['server_group']
group_id = body['id']
self.addCleanup(self.server_groups_client.delete_server_group,
group_id)
hints = {'group': group_id}
- server = self.create_test_server(sched_hints=hints,
+ server = self.create_test_server(scheduler_hints=hints,
wait_until='ACTIVE')
# Check a server is in the group
- server_group = self.server_groups_client.get_server_group(group_id)
+ server_group = (self.server_groups_client.get_server_group(group_id)
+ ['server_group'])
self.assertIn(server['id'], server_group['members'])
@test.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2')
@@ -184,7 +187,8 @@
self.addCleanup(cleanup_server)
- addresses = self.client.list_addresses(server_multi_nics['id'])
+ addresses = (self.client.list_addresses(server_multi_nics['id'])
+ ['addresses'])
# We can't predict the ip addresses assigned to the server on networks.
# Sometimes the assigned addresses are ['19.80.0.2', '19.86.0.2'], at
@@ -225,7 +229,8 @@
self.addCleanup(cleanup_server)
- addresses = self.client.list_addresses(server_multi_nics['id'])
+ addresses = (self.client.list_addresses(server_multi_nics['id'])
+ ['addresses'])
addr = [addresses[net1['network']['name']][0]['addr'],
addresses[net2['network']['name']][0]['addr'],
@@ -275,7 +280,7 @@
create_flavor(name=flavor_with_eph_disk_name,
ram=ram, vcpus=vcpus, disk=disk,
id=flavor_with_eph_disk_id,
- ephemeral=1))
+ ephemeral=1))['flavor']
self.addCleanup(flavor_clean_up, flavor['id'])
return flavor['id']
@@ -292,7 +297,7 @@
flavor = (self.flavor_client.
create_flavor(name=flavor_no_eph_disk_name,
ram=ram, vcpus=vcpus, disk=disk,
- id=flavor_no_eph_disk_id))
+ id=flavor_no_eph_disk_id))['flavor']
self.addCleanup(flavor_clean_up, flavor['id'])
return flavor['id']
@@ -306,15 +311,15 @@
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(
- server_no_eph_disk['id'])
+ server_no_eph_disk['id'])['server']
linux_client = remote_client.RemoteClient(
self.get_server_ip(server_no_eph_disk),
self.ssh_user,
@@ -325,14 +330,14 @@
# 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'])
+ server_with_eph_disk['id'])['server']
linux_client = remote_client.RemoteClient(
self.get_server_ip(server_with_eph_disk),
self.ssh_user,
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index 551f8b4..6796bb5 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'])
@@ -103,7 +103,7 @@
def test_delete_server_while_in_verify_resize_state(self):
# Delete a server while it's VM state is VERIFY_RESIZE
server = self.create_test_server(wait_until='ACTIVE')
- self.client.resize(server['id'], self.flavor_ref_alt)
+ self.client.resize_server(server['id'], self.flavor_ref_alt)
waiters.wait_for_server_status(self.client, server['id'],
'VERIFY_RESIZE')
self.client.delete_server(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')
@@ -149,7 +150,7 @@
server = self.create_test_server(wait_until='ACTIVE')
self.admin_client.reset_state(server['id'], state='error')
# Verify server's state
- server = self.non_admin_client.show_server(server['id'])
+ server = self.non_admin_client.show_server(server['id'])['server']
self.assertEqual(server['status'], 'ERROR')
self.non_admin_client.delete_server(server['id'])
waiters.wait_for_server_termination(self.servers_client,
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 3e8a0d2..617cdd5 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -44,12 +44,12 @@
cls.server_id = server['id']
def _update_server_with_disk_config(self, disk_config):
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
if disk_config != server['OS-DCF:diskConfig']:
- server = self.client.update_server(self.server_id,
- disk_config=disk_config)
+ server = self.client.update_server(
+ self.server_id, disk_config=disk_config)['server']
waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
- server = self.client.show_server(server['id'])
+ server = self.client.show_server(server['id'])['server']
self.assertEqual(disk_config, server['OS-DCF:diskConfig'])
@test.idempotent_id('bef56b09-2e8c-4883-a370-4950812f430e')
@@ -57,15 +57,15 @@
# A server should be rebuilt using the manual disk config option
self._update_server_with_disk_config(disk_config='AUTO')
- server = self.client.rebuild(self.server_id,
- self.image_ref_alt,
- disk_config='MANUAL')
+ server = self.client.rebuild_server(self.server_id,
+ self.image_ref_alt,
+ disk_config='MANUAL')['server']
# Wait for the server to become active
waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the specified attributes are set correctly
- server = self.client.show_server(server['id'])
+ server = self.client.show_server(server['id'])['server']
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
@test.idempotent_id('9c9fae77-4feb-402f-8450-bf1c8b609713')
@@ -73,19 +73,19 @@
# A server should be rebuilt using the auto disk config option
self._update_server_with_disk_config(disk_config='MANUAL')
- server = self.client.rebuild(self.server_id,
- self.image_ref_alt,
- disk_config='AUTO')
+ server = self.client.rebuild_server(self.server_id,
+ self.image_ref_alt,
+ disk_config='AUTO')['server']
# Wait for the server to become active
waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the specified attributes are set correctly
- server = self.client.show_server(server['id'])
+ server = self.client.show_server(server['id'])['server']
self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
def _get_alternative_flavor(self):
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
if server['flavor']['id'] == self.flavor_ref:
return self.flavor_ref_alt
@@ -101,13 +101,14 @@
# Resize with auto option
flavor_id = self._get_alternative_flavor()
- self.client.resize(self.server_id, flavor_id, disk_config='AUTO')
+ self.client.resize_server(self.server_id, flavor_id,
+ 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)
+ server = self.client.show_server(self.server_id)['server']
self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
@test.idempotent_id('693d16f3-556c-489a-8bac-3d0ca2490bad')
@@ -119,13 +120,14 @@
# Resize with manual option
flavor_id = self._get_alternative_flavor()
- self.client.resize(self.server_id, flavor_id, disk_config='MANUAL')
+ self.client.resize_server(self.server_id, flavor_id,
+ 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)
+ server = self.client.show_server(self.server_id)['server']
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
@test.idempotent_id('5ef18867-358d-4de9-b3c9-94d4ba35742f')
@@ -135,9 +137,9 @@
# Update the disk_config attribute to manual
server = self.client.update_server(self.server_id,
- disk_config='MANUAL')
+ disk_config='MANUAL')['server']
waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the disk_config attribute is set correctly
- server = self.client.show_server(server['id'])
+ server = self.client.show_server(server['id'])['server']
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index dc126a5..97d47fd 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -35,10 +35,11 @@
@test.idempotent_id('77ca5cc5-9990-45e0-ab98-1de8fead201a')
def test_list_instance_actions(self):
# List actions of the provided server
- self.client.reboot(self.server_id, 'HARD')
+ self.client.reboot_server(self.server_id, 'HARD')
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
- body = self.client.list_instance_actions(self.server_id)
+ body = (self.client.list_instance_actions(self.server_id)
+ ['instanceActions'])
self.assertTrue(len(body) == 2, str(body))
self.assertTrue(any([i for i in body if i['action'] == 'create']))
self.assertTrue(any([i for i in body if i['action'] == 'reboot']))
@@ -46,7 +47,7 @@
@test.idempotent_id('aacc71ca-1d70-4aa5-bbf6-0ff71470e43c')
def test_get_instance_action(self):
# Get the action details of the provided server
- body = self.client.get_instance_action(self.server_id,
- self.request_id)
+ body = self.client.get_instance_action(
+ self.server_id, self.request_id)['instanceAction']
self.assertEqual(self.server_id, body['instance_uuid'])
self.assertEqual('create', body['action'])
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 6160844..3acff98 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']
@@ -274,7 +274,7 @@
if not self.fixed_network_name:
msg = 'fixed_network_name needs to be configured to run this test'
raise self.skipException(msg)
- self.s1 = self.client.show_server(self.s1['id'])
+ self.s1 = self.client.show_server(self.s1['id'])['server']
for addr_spec in self.s1['addresses'][self.fixed_network_name]:
ip = addr_spec['addr']
if addr_spec['version'] == 4:
@@ -298,7 +298,7 @@
if not self.fixed_network_name:
msg = 'fixed_network_name needs to be configured to run this test'
raise self.skipException(msg)
- self.s1 = self.client.show_server(self.s1['id'])
+ self.s1 = self.client.show_server(self.s1['id'])['server']
addr_spec = self.s1['addresses'][self.fixed_network_name][0]
ip = addr_spec['addr'][0:-3]
if addr_spec['version'] == 4:
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index a20f7f5..f0cd2a1 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -52,8 +52,8 @@
self.__class__.server_id = server['id']
except Exception:
# Rebuild server if something happened to it during a test
- self.__class__.server_id = self.rebuild_server(self.server_id,
- validatable=True)
+ self.__class__.server_id = self.rebuild_server(
+ self.server_id, validatable=True)['server']
def tearDown(self):
self.server_check_teardown()
@@ -87,7 +87,7 @@
if CONF.validation.run_validation:
# Verify that the user can authenticate with the new password
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
linux_client = remote_client.RemoteClient(
self.get_server_ip(server),
self.ssh_user,
@@ -97,7 +97,7 @@
def _test_reboot_server(self, reboot_type):
if CONF.validation.run_validation:
# Get the time the server was last rebooted,
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
linux_client = remote_client.RemoteClient(
self.get_server_ip(server),
self.ssh_user,
@@ -105,7 +105,7 @@
self.validation_resources['keypair']['private_key'])
boot_time = linux_client.get_boot_time()
- self.client.reboot(self.server_id, reboot_type)
+ self.client.reboot_server(self.server_id, reboot_type)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
if CONF.validation.run_validation:
@@ -132,7 +132,8 @@
self._test_reboot_server('SOFT')
def _rebuild_server_and_check(self, image_ref):
- rebuilt_server = self.client.rebuild(self.server_id, image_ref)
+ rebuilt_server = (self.client.rebuild_server(self.server_id, image_ref)
+ ['server'])
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
msg = ('Server was not rebuilt to the original image. '
'The original image: {0}. The current image: {1}'
@@ -148,12 +149,13 @@
personality = [{'path': 'rebuild.txt',
'contents': base64.b64encode(file_contents)}]
password = 'rebuildPassw0rd'
- rebuilt_server = self.client.rebuild(self.server_id,
- self.image_ref_alt,
- name=new_name,
- metadata=meta,
- personality=personality,
- adminPass=password)
+ rebuilt_server = self.client.rebuild_server(
+ self.server_id,
+ self.image_ref_alt,
+ name=new_name,
+ metadata=meta,
+ personality=personality,
+ adminPass=password)['server']
# If the server was rebuilt on a different image, restore it to the
# original image once the test ends
@@ -169,7 +171,7 @@
# Verify the server properties after the rebuild completes
waiters.wait_for_server_status(self.client,
rebuilt_server['id'], 'ACTIVE')
- server = self.client.show_server(rebuilt_server['id'])
+ server = self.client.show_server(rebuilt_server['id'])['server']
rebuilt_image_id = server['image']['id']
self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
self.assertEqual(new_name, server['name'])
@@ -187,13 +189,14 @@
def test_rebuild_server_in_stop_state(self):
# The server in stop state should be rebuilt using the provided
# image and remain in SHUTOFF state
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
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(self.server_id, new_image)
+ rebuilt_server = (self.client.rebuild_server(self.server_id, new_image)
+ ['server'])
# If the server was rebuilt on a different image, restore it to the
# original image once the test ends
if self.image_ref_alt != self.image_ref:
@@ -208,36 +211,36 @@
# Verify the server properties after the rebuild completes
waiters.wait_for_server_status(self.client,
rebuilt_server['id'], 'SHUTOFF')
- server = self.client.show_server(rebuilt_server['id'])
+ server = self.client.show_server(rebuilt_server['id'])['server']
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')
- self.client.resize(self.server_id, self.flavor_ref_alt)
+ self.client.resize_server(self.server_id, self.flavor_ref_alt)
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)
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
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.
@@ -262,14 +265,14 @@
# The server's RAM and disk space should return to its original
# values after a resize is reverted
- self.client.resize(self.server_id, self.flavor_ref_alt)
+ self.client.resize_server(self.server_id, self.flavor_ref_alt)
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)
+ server = self.client.show_server(self.server_id)['server']
self.assertEqual(self.flavor_ref, server['flavor']['id'])
@test.idempotent_id('b963d4f1-94b3-4c40-9e97-7b583f46e470')
@@ -358,7 +361,7 @@
def _get_output(self):
output = self.client.get_console_output(
- self.server_id, 10).data
+ self.server_id, 10)['output']
self.assertTrue(output, "Console output was empty.")
lines = len(output.split('\n'))
self.assertEqual(lines, 10)
@@ -371,11 +374,11 @@
# for a given server_id and number of lines
# This reboot is necessary for outputting some console log after
- # creating a instance backup. If a instance backup, the console
+ # creating an instance backup. If an instance backup, the console
# log file is truncated and we cannot get any console log through
# "console-log" API.
# The detail is https://bugs.launchpad.net/nova/+bug/1251920
- self.client.reboot(self.server_id, 'HARD')
+ self.client.reboot_server(self.server_id, 'HARD')
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
self.wait_for(self._get_output)
@@ -387,7 +390,7 @@
def _check_full_length_console_log():
output = self.client.get_console_output(server['id'],
- None).data
+ None)['output']
self.assertTrue(output, "Console output was empty.")
lines = len(output.split('\n'))
@@ -411,7 +414,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)
@@ -453,10 +456,10 @@
waiters.wait_for_server_status(self.client, self.server_id,
'SHELVED_OFFLOADED')
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
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 +468,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')
@@ -475,15 +478,15 @@
# Lock the server,try server stop(exceptions throw),unlock it and retry
self.client.lock_server(self.server_id)
self.addCleanup(self.client.unlock_server, self.server_id)
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
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):
@@ -501,7 +504,7 @@
console_types = ['novnc', 'xvpvnc']
for console_type in console_types:
body = self.client.get_vnc_console(self.server_id,
- console_type)
+ console_type)['console']
self.assertEqual(console_type, body['type'])
self.assertNotEqual('', body['url'])
self._validate_url(body['url'])
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index a17f581..864f38f 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -45,7 +45,7 @@
# All public and private addresses for
# a server should be returned
- addresses = self.client.list_addresses(self.server['id'])
+ addresses = self.client.list_addresses(self.server['id'])['addresses']
# We do not know the exact network configuration, but an instance
# should at least have a single public or private address
@@ -63,7 +63,7 @@
# Providing a network type should filter
# the addresses return by that type
- addresses = self.client.list_addresses(self.server['id'])
+ addresses = self.client.list_addresses(self.server['id'])['addresses']
# Once again we don't know the environment's exact network config,
# but the response for each individual network should be the same
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index 0e7c1eb..0da7912 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -61,7 +61,7 @@
# delete the test server-group
self.client.delete_server_group(server_group['id'])
# validation of server-group deletion
- server_group_list = self.client.list_server_groups()
+ server_group_list = self.client.list_server_groups()['server_groups']
self.assertNotIn(server_group, server_group_list)
def _create_delete_server_group(self, policy):
@@ -107,11 +107,11 @@
def test_get_server_group(self):
# Get the server-group
body = self.client.get_server_group(
- self.created_server_group['id'])
+ self.created_server_group['id'])['server_group']
self.assertEqual(self.created_server_group, body)
@test.idempotent_id('d4874179-27b4-4d7d-80e4-6c560cdfe321')
def test_list_server_groups(self):
# List the server-group
- body = self.client.list_server_groups()
+ body = self.client.list_server_groups()['server_groups']
self.assertIn(self.created_server_group, body)
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 234633b..77ddb3b 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -28,18 +28,19 @@
@classmethod
def resource_setup(cls):
super(ServerMetadataTestJSON, cls).resource_setup()
- server = cls.create_test_server(meta={}, wait_until='ACTIVE')
+ server = cls.create_test_server(metadata={}, wait_until='ACTIVE')
cls.server_id = server['id']
def setUp(self):
super(ServerMetadataTestJSON, self).setUp()
meta = {'key1': 'value1', 'key2': 'value2'}
- self.client.set_server_metadata(self.server_id, meta)
+ self.client.set_server_metadata(self.server_id, meta)['metadata']
@test.idempotent_id('479da087-92b3-4dcf-aeb3-fd293b2d14ce')
def test_list_server_metadata(self):
# All metadata key/value pairs for a server should be returned
- resp_metadata = self.client.list_server_metadata(self.server_id)
+ resp_metadata = (self.client.list_server_metadata(self.server_id)
+ ['metadata'])
# Verify the expected metadata items are in the list
expected = {'key1': 'value1', 'key2': 'value2'}
@@ -50,11 +51,13 @@
# The server's metadata should be replaced with the provided values
# Create a new set of metadata for the server
req_metadata = {'meta2': 'data2', 'meta3': 'data3'}
- self.client.set_server_metadata(self.server_id, req_metadata)
+ self.client.set_server_metadata(self.server_id,
+ req_metadata)['metadata']
# Verify the expected values are correct, and that the
# previous values have been removed
- resp_metadata = self.client.list_server_metadata(self.server_id)
+ resp_metadata = (self.client.list_server_metadata(self.server_id)
+ ['metadata'])
self.assertEqual(resp_metadata, req_metadata)
@test.idempotent_id('344d981e-0c33-4997-8a5d-6c1d803e4134')
@@ -65,7 +68,8 @@
self.client.update_server_metadata(self.server_id, meta)
# Verify the values have been updated to the proper values
- resp_metadata = self.client.list_server_metadata(self.server_id)
+ resp_metadata = (self.client.list_server_metadata(self.server_id)
+ ['metadata'])
expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
self.assertEqual(expected, resp_metadata)
@@ -75,14 +79,16 @@
# passed
meta = {}
self.client.update_server_metadata(self.server_id, meta)
- resp_metadata = self.client.list_server_metadata(self.server_id)
+ resp_metadata = (self.client.list_server_metadata(self.server_id)
+ ['metadata'])
expected = {'key1': 'value1', 'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
@test.idempotent_id('3043c57d-7e0e-49a6-9a96-ad569c265e6a')
def test_get_server_metadata_item(self):
# The value for a specific metadata key should be returned
- meta = self.client.get_server_metadata_item(self.server_id, 'key2')
+ meta = self.client.get_server_metadata_item(self.server_id,
+ 'key2')['meta']
self.assertEqual('value2', meta['key2'])
@test.idempotent_id('58c02d4f-5c67-40be-8744-d3fa5982eb1c')
@@ -93,7 +99,8 @@
self.client.set_server_metadata_item(self.server_id, 'nova', meta)
# Verify the meta item's value has been updated
- resp_metadata = self.client.list_server_metadata(self.server_id)
+ resp_metadata = (self.client.list_server_metadata(self.server_id)
+ ['metadata'])
expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
self.assertEqual(expected, resp_metadata)
@@ -103,6 +110,7 @@
self.client.delete_server_metadata_item(self.server_id, 'key1')
# Verify the metadata item has been removed
- resp_metadata = self.client.list_server_metadata(self.server_id)
+ resp_metadata = (self.client.list_server_metadata(self.server_id)
+ ['metadata'])
expected = {'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index c42ec3d..cee60fb 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -32,7 +32,7 @@
def resource_setup(cls):
super(ServerMetadataNegativeTestJSON, cls).resource_setup()
cls.tenant_id = cls.client.tenant_id
- server = cls.create_test_server(meta={}, wait_until='ACTIVE')
+ server = cls.create_test_server(metadata={}, wait_until='ACTIVE')
cls.server_id = server['id']
@@ -48,7 +48,7 @@
meta = {key: 'data1'}
self.assertRaises((lib_exc.BadRequest, lib_exc.OverLimit),
self.create_test_server,
- meta=meta)
+ metadata=meta)
# no teardown - all creates should fail
@@ -59,7 +59,7 @@
meta = {'': 'data1'}
self.assertRaises(lib_exc.BadRequest,
self.create_test_server,
- meta=meta)
+ metadata=meta)
@test.attr(type=['negative'])
@test.idempotent_id('4d9cd7a3-2010-4b41-b8fe-3bbf0b169466')
@@ -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.py b/tempest/api/compute/servers/test_server_rescue.py
index 7e09096..96ce45e 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -41,7 +41,7 @@
super(ServerRescueTestJSON, cls).resource_setup()
# Floating IP creation
- body = cls.floating_ips_client.create_floating_ip()
+ body = cls.floating_ips_client.create_floating_ip()['floating_ip']
cls.floating_ip_id = str(body['id']).strip()
cls.floating_ip = str(body['ip']).strip()
@@ -49,7 +49,7 @@
cls.sg_name = data_utils.rand_name('sg')
cls.sg_desc = data_utils.rand_name('sg-desc')
cls.sg = cls.security_groups_client.create_security_group(
- name=cls.sg_name, description=cls.sg_desc)
+ name=cls.sg_name, description=cls.sg_desc)['security_group']
cls.sg_id = cls.sg['id']
# Server for positive tests
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 7a25526..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')
@@ -100,7 +100,7 @@
@test.attr(type=['negative'])
@test.idempotent_id('db22b618-f157-4566-a317-1b6d467a8094')
def test_rescued_vm_reboot(self):
- self.assertRaises(lib_exc.Conflict, self.servers_client.reboot,
+ self.assertRaises(lib_exc.Conflict, self.servers_client.reboot_server,
self.rescue_id, 'HARD')
@test.attr(type=['negative'])
@@ -116,7 +116,7 @@
@test.idempotent_id('70cdb8a1-89f8-437d-9448-8844fd82bf46')
def test_rescued_vm_rebuild(self):
self.assertRaises(lib_exc.Conflict,
- self.servers_client.rebuild,
+ self.servers_client.rebuild_server,
self.rescue_id,
self.image_ref_alt)
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index c243adf..d2fb652 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -52,9 +52,9 @@
wait_until='ACTIVE')
id2 = server['id']
self.assertNotEqual(id1, id2, "Did not create a new server")
- server = self.client.show_server(id1)
+ server = self.client.show_server(id1)['server']
name1 = server['name']
- server = self.client.show_server(id2)
+ server = self.client.show_server(id2)['server']
name2 = server['name']
self.assertEqual(name1, name2)
@@ -68,7 +68,7 @@
self.keypairs_client.list_keypairs()
server = self.create_test_server(key_name=key_name)
waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
- server = self.client.show_server(server['id'])
+ server = self.client.show_server(server['id'])['server']
self.assertEqual(key_name, server['key_name'])
def _update_server_name(self, server_id, status):
@@ -80,7 +80,7 @@
waiters.wait_for_server_status(self.client, server_id, status)
# Verify the name of the server has changed
- server = self.client.show_server(server_id)
+ server = self.client.show_server(server_id)['server']
self.assertEqual(new_name, server['name'])
return server
@@ -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)
@@ -112,7 +112,7 @@
waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the access addresses have been updated
- server = self.client.show_server(server['id'])
+ server = self.client.show_server(server['id'])['server']
self.assertEqual('1.1.1.1', server['accessIPv4'])
self.assertEqual('::babe:202:202', server['accessIPv6'])
@@ -121,5 +121,5 @@
# Create a server without an IPv4 address(only IPv6 address).
server = self.create_test_server(accessIPv6='2001:2001::3')
waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
- server = self.client.show_server(server['id'])
+ server = self.client.show_server(server['id'])['server']
self.assertEqual('2001:2001::3', server['accessIPv6'])
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index f5d99fc..6946be4 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -122,7 +122,7 @@
# Resize a non-existent server
nonexistent_server = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound,
- self.client.resize,
+ self.client.resize_server,
nonexistent_server, self.flavor_ref)
@test.idempotent_id('ced1a1d7-2ab6-45c9-b90f-b27d87b30efd')
@@ -132,7 +132,7 @@
def test_resize_server_with_non_existent_flavor(self):
# Resize a server with non-existent flavor
nonexistent_flavor = data_utils.rand_uuid()
- self.assertRaises(lib_exc.BadRequest, self.client.resize,
+ self.assertRaises(lib_exc.BadRequest, self.client.resize_server,
self.server_id, flavor_ref=nonexistent_flavor)
@test.idempotent_id('45436a7d-a388-4a35-a9d8-3adc5d0d940b')
@@ -141,7 +141,7 @@
@test.attr(type=['negative'])
def test_resize_server_with_null_flavor(self):
# Resize a server with null flavor
- self.assertRaises(lib_exc.BadRequest, self.client.resize,
+ self.assertRaises(lib_exc.BadRequest, self.client.resize_server,
self.server_id, flavor_ref="")
@test.attr(type=['negative'])
@@ -149,7 +149,7 @@
def test_reboot_non_existent_server(self):
# Reboot a non existent server
nonexistent_server = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound, self.client.reboot,
+ self.assertRaises(lib_exc.NotFound, self.client.reboot_server,
nonexistent_server, 'SOFT')
@test.idempotent_id('d1417e7f-a509-41b5-a102-d5eed8613369')
@@ -174,9 +174,9 @@
waiters.wait_for_server_termination(self.client, server['id'])
self.assertRaises(lib_exc.NotFound,
- self.client.rebuild,
+ self.client.rebuild_server,
server['id'], self.image_ref_alt)
- self.assertRaises(lib_exc.NotFound, self.client.reboot,
+ self.assertRaises(lib_exc.NotFound, self.client.reboot_server,
server['id'], 'SOFT')
@test.attr(type=['negative'])
@@ -185,7 +185,7 @@
# Rebuild a non existent server
nonexistent_server = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound,
- self.client.rebuild,
+ self.client.rebuild_server,
nonexistent_server,
self.image_ref_alt)
@@ -236,29 +236,28 @@
metadata = {'a': 'b' * 260}
self.assertRaises((lib_exc.BadRequest, lib_exc.OverLimit),
self.create_test_server,
- meta=metadata)
+ metadata=metadata)
@test.attr(type=['negative'])
@test.idempotent_id('aa8eed43-e2cb-4ebf-930b-da14f6a21d81')
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')
@@ -477,10 +476,10 @@
self.server_id,
'SHELVED')
- server = self.client.show_server(self.server_id)
+ server = self.client.show_server(self.server_id)['server']
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 b542d7f..484c156 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -64,7 +64,7 @@
def resource_setup(cls):
super(AuthorizationTestJSON, cls).resource_setup()
server = cls.create_test_server(wait_until='ACTIVE')
- cls.server = cls.client.show_server(server['id'])
+ cls.server = cls.client.show_server(server['id'])['server']
name = data_utils.rand_name('image')
body = cls.glance_client.create_image(name=name,
@@ -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)
@@ -84,7 +84,7 @@
name = data_utils.rand_name('security')
description = data_utils.rand_name('description')
cls.security_group = cls.security_client.create_security_group(
- name=name, description=description)
+ name=name, description=description)['security_group']
parent_group_id = cls.security_group['id']
ip_protocol = 'tcp'
@@ -92,7 +92,7 @@
to_port = 22
cls.rule = cls.rule_client.create_security_group_rule(
parent_group_id=parent_group_id, ip_protocol=ip_protocol,
- from_port=from_port, to_port=to_port)
+ from_port=from_port, to_port=to_port)['security_group_rule']
@classmethod
def resource_cleanup(cls):
@@ -155,19 +155,19 @@
@test.idempotent_id('14cb5ff5-f646-45ca-8f51-09081d6c0c24')
def test_reboot_server_for_alt_account_fails(self):
# A reboot request for another user's server should fail
- self.assertRaises(lib_exc.NotFound, self.alt_client.reboot,
+ self.assertRaises(lib_exc.NotFound, self.alt_client.reboot_server,
self.server['id'], 'HARD')
@test.idempotent_id('8a0bce51-cd00-480b-88ba-dbc7d8408a37')
def test_rebuild_server_for_alt_account_fails(self):
# A rebuild request for another user's server should fail
- self.assertRaises(lib_exc.NotFound, self.alt_client.rebuild,
+ self.assertRaises(lib_exc.NotFound, self.alt_client.rebuild_server,
self.server['id'], self.image_ref_alt)
@test.idempotent_id('e4da647e-f982-4e61-9dad-1d1abebfb933')
def test_resize_server_for_alt_account_fails(self):
# A resize request for another user's server should fail
- self.assertRaises(lib_exc.NotFound, self.alt_client.resize,
+ self.assertRaises(lib_exc.NotFound, self.alt_client.resize_server,
self.server['id'], self.flavor_ref_alt)
@test.idempotent_id('a9fe8112-0ffa-4902-b061-f892bd5fe0d3')
@@ -181,7 +181,8 @@
def test_create_server_with_unauthorized_image(self):
# Server creation with another user's image should fail
self.assertRaises(lib_exc.BadRequest, self.alt_client.create_server,
- 'test', self.image['id'], self.flavor_ref)
+ name='test', imageRef=self.image['id'],
+ flavorRef=self.flavor_ref)
@test.idempotent_id('acf8724b-142b-4044-82c3-78d31a533f24')
def test_create_server_fails_when_tenant_incorrect(self):
@@ -193,8 +194,8 @@
auth_data=self.client.auth_provider.auth_data
)
self.assertRaises(lib_exc.BadRequest,
- self.alt_client.create_server, 'test',
- self.image['id'], self.flavor_ref)
+ self.alt_client.create_server, name='test',
+ imageRef=self.image['id'], flavorRef=self.flavor_ref)
@test.idempotent_id('f03d1ded-7fd4-4d29-bc13-e2391f29c625')
def test_create_keypair_in_analt_user_tenant(self):
diff --git a/tempest/api/compute/test_networks.py b/tempest/api/compute/test_networks.py
index deb9ee2..d4b8003 100644
--- a/tempest/api/compute/test_networks.py
+++ b/tempest/api/compute/test_networks.py
@@ -19,19 +19,19 @@
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()
- cls.client = cls.os.networks_client
+ super(ComputeNetworksTest, cls).setup_clients()
+ cls.client = cls.os.compute_networks_client
@test.idempotent_id('3fe07175-312e-49a5-a623-5f52eeada4c2')
def test_list_networks(self):
- networks = self.client.list_networks()
+ networks = self.client.list_networks()['networks']
self.assertNotEmpty(networks, "No networks found.")
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..f94cee6
--- /dev/null
+++ b/tempest/api/compute/test_versions.py
@@ -0,0 +1,72 @@
+# 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):
+ """Test that a get of the unversioned url returns the choices doc.
+
+ A key feature in OpenStack services is the idea that you can
+ GET / on the service and get a list of the versioned endpoints
+ that you can access. This comes back as a status 300
+ request. It's important that this is available to API
+ consumers to discover the API they can use.
+
+ """
+ result = self.versions_client.list_versions()
+ versions = result['versions']
+ # NOTE(sdague): at a later point we may want to loosen this
+ # up, but for now this should be true of all Novas deployed.
+ self.assertEqual(versions[0]['id'], 'v2.0',
+ "The first listed version should be v2.0")
+
+ @test.idempotent_id('b953a29e-929c-4a8e-81be-ec3a7e03cb76')
+ def test_get_version_details(self):
+ """Test individual version endpoints info works.
+
+ In addition to the GET / version request, there is also a
+ version info document stored at the top of the versioned
+ endpoints. This provides access to details about that
+ endpoint, including min / max version if that implements
+ microversions.
+
+ This test starts with the version list, iterates all the
+ returned endpoints, and fetches them. This will also ensure
+ that all the version links are followable constructs which
+ will help detect configuration issues when SSL termination
+ isn't done completely for a site.
+
+ """
+ result = self.versions_client.list_versions()
+ versions = result['versions']
+
+ # iterate through all the versions that are returned and
+ # attempt to get their version documents.
+ for version in versions:
+ links = [x for x in version['links'] if x['rel'] == 'self']
+ self.assertEqual(
+ len(links), 1,
+ "There should only be 1 self link in %s" % version)
+ link = links[0]
+ # this is schema validated
+ result = self.versions_client.get_version_by_url(link['href'])
+ # ensure the new self link matches the old one
+ newlinks = [x for x in result['version']['links']
+ if x['rel'] == 'self']
+ self.assertEqual(links, newlinks)
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..ab4ddf7 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -70,12 +70,12 @@
adminPass=admin_pass)
# Record addresses so that we can ssh later
- self.server['addresses'] = (
- self.servers_client.list_addresses(self.server['id']))
+ self.server['addresses'] = self.servers_client.list_addresses(
+ self.server['id'])['addresses']
# 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')
@@ -84,7 +84,7 @@
self.attachment = self.servers_client.attach_volume(
self.server['id'],
volumeId=self.volume['id'],
- device='/dev/%s' % self.device)
+ device='/dev/%s' % self.device)['volumeAttachment']
self.volumes_client.wait_for_volume_status(self.volume['id'], 'in-use')
self.addCleanup(self._detach, self.server['id'], self.volume['id'])
@@ -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')
@@ -139,14 +139,14 @@
self._create_and_attach()
# List Volume attachment of the server
body = self.servers_client.list_volume_attachments(
- self.server['id'])
+ self.server['id'])['volumeAttachments']
self.assertEqual(1, len(body))
self.assertIn(self.attachment, body)
# Get Volume attachment of the server
body = self.servers_client.get_volume_attachment(
self.server['id'],
- self.attachment['id'])
+ self.attachment['id'])['volumeAttachment']
self.assertEqual(self.server['id'], body['serverId'])
self.assertEqual(self.volume['id'], body['volumeId'])
self.assertEqual(self.attachment['id'], body['id'])
diff --git a/tempest/api/compute/volumes/test_volume_snapshots.py b/tempest/api/compute/volumes/test_volume_snapshots.py
new file mode 100644
index 0000000..a00c0ba
--- /dev/null
+++ b/tempest/api/compute/volumes/test_volume_snapshots.py
@@ -0,0 +1,73 @@
+# Copyright 2015 Fujitsu(fnst) 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.api.compute import base
+from tempest.common.utils import data_utils
+from tempest.common import waiters
+from tempest import config
+from tempest import test
+
+
+CONF = config.CONF
+
+
+class VolumesSnapshotsTestJSON(base.BaseV2ComputeTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(VolumesSnapshotsTestJSON, cls).skip_checks()
+ if not CONF.service_available.cinder:
+ skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
+ raise cls.skipException(skip_msg)
+
+ @classmethod
+ def setup_clients(cls):
+ super(VolumesSnapshotsTestJSON, cls).setup_clients()
+ cls.volumes_client = cls.volumes_extensions_client
+ cls.snapshots_client = cls.snapshots_extensions_client
+
+ @test.idempotent_id('cd4ec87d-7825-450d-8040-6e2068f2da8f')
+ def test_volume_snapshot_create_get_list_delete(self):
+ v_name = data_utils.rand_name('Volume')
+ volume = self.volumes_client.create_volume(
+ size=CONF.volume.volume_size,
+ display_name=v_name)['volume']
+ self.addCleanup(self.delete_volume, volume['id'])
+ waiters.wait_for_volume_status(self.volumes_client, volume['id'],
+ 'available')
+ s_name = data_utils.rand_name('Snapshot')
+ # Create snapshot
+ snapshot = self.snapshots_client.create_snapshot(
+ volume['id'],
+ display_name=s_name)['snapshot']
+
+ def delete_snapshot(snapshot_id):
+ waiters.wait_for_snapshot_status(self.snapshots_client,
+ snapshot_id,
+ 'available')
+ # Delete snapshot
+ self.snapshots_client.delete_snapshot(snapshot_id)
+ self.snapshots_client.wait_for_resource_deletion(snapshot_id)
+
+ self.addCleanup(delete_snapshot, snapshot['id'])
+ self.assertEqual(volume['id'], snapshot['volumeId'])
+ # Get snapshot
+ fetched_snapshot = self.snapshots_client.show_snapshot(
+ snapshot['id'])['snapshot']
+ self.assertEqual(s_name, fetched_snapshot['displayName'])
+ self.assertEqual(volume['id'], fetched_snapshot['volumeId'])
+ # Fetch all snapshots
+ snapshots = self.snapshots_client.list_snapshots()['snapshots']
+ self.assertIn(snapshot['id'], map(lambda x: x['id'], snapshots))
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/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
index e698baa..62c1e05 100644
--- a/tempest/api/database/flavors/test_flavors.py
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -28,7 +28,8 @@
@test.idempotent_id('c94b825e-0132-4686-8049-8a4a2bc09525')
def test_get_db_flavor(self):
# The expected flavor details should be returned
- flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+ flavor = (self.client.get_db_flavor_details(self.db_flavor_ref)
+ ['flavor'])
self.assertEqual(self.db_flavor_ref, str(flavor['id']))
self.assertIn('ram', flavor)
self.assertIn('links', flavor)
@@ -37,9 +38,10 @@
@test.attr(type='smoke')
@test.idempotent_id('685025d6-0cec-4673-8a8d-995cb8e0d3bb')
def test_list_db_flavors(self):
- flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
+ flavor = (self.client.get_db_flavor_details(self.db_flavor_ref)
+ ['flavor'])
# List of all flavors should contain the expected flavor
- flavors = self.client.list_db_flavors()
+ flavors = self.client.list_db_flavors()['flavors']
self.assertIn(flavor, flavors)
def _check_values(self, names, db_flavor, os_flavor, in_db=True):
@@ -57,14 +59,15 @@
@test.idempotent_id('afb2667f-4ec2-4925-bcb7-313fdcffb80d')
@test.services('compute')
def test_compare_db_flavors_with_os(self):
- db_flavors = self.client.list_db_flavors()
- os_flavors = self.os_flavors_client.list_flavors(detail=True)
+ db_flavors = self.client.list_db_flavors()['flavors']
+ os_flavors = (self.os_flavors_client.list_flavors(detail=True)
+ ['flavors'])
self.assertEqual(len(os_flavors), len(db_flavors),
"OS flavors %s do not match DB flavors %s" %
(os_flavors, db_flavors))
for os_flavor in os_flavors:
db_flavor =\
- self.client.get_db_flavor_details(os_flavor['id'])
+ self.client.get_db_flavor_details(os_flavor['id'])['flavor']
self._check_values(['id', 'name', 'ram'], db_flavor, os_flavor)
self._check_values(['disk', 'vcpus', 'swap'], db_flavor, os_flavor,
in_db=False)
diff --git a/tempest/api/database/limits/test_limits.py b/tempest/api/database/limits/test_limits.py
index 4b7f2d6..ee51b1d 100644
--- a/tempest/api/database/limits/test_limits.py
+++ b/tempest/api/database/limits/test_limits.py
@@ -27,7 +27,7 @@
@test.attr(type='smoke')
@test.idempotent_id('73024538-f316-4829-b3e9-b459290e137a')
def test_absolute_limits(self):
- # Test to verify if all absolute limit paramaters are
+ # Test to verify if all absolute limit parameters are
# present when verb is ABSOLUTE
limits = self.client.list_db_limits()['limits']
expected_abs_limits = ['max_backups', 'max_volumes',
diff --git a/tempest/api/identity/admin/v2/test_endpoints.py b/tempest/api/identity/admin/v2/test_endpoints.py
index 3af2e90..bff4f91 100644
--- a/tempest/api/identity/admin/v2/test_endpoints.py
+++ b/tempest/api/identity/admin/v2/test_endpoints.py
@@ -27,9 +27,8 @@
s_name = data_utils.rand_name('service')
s_type = data_utils.rand_name('type')
s_description = data_utils.rand_name('description')
- cls.service_data =\
- cls.client.create_service(s_name, s_type,
- description=s_description)
+ cls.service_data = cls.client.create_service(
+ s_name, s_type, description=s_description)['OS-KSADM:service']
cls.service_id = cls.service_data['id']
cls.service_ids.append(cls.service_id)
# Create endpoints so as to use for LIST and GET test cases
@@ -41,7 +40,7 @@
region,
publicurl=url,
adminurl=url,
- internalurl=url)
+ internalurl=url)['endpoint']
# list_endpoints() will return 'enabled' field
endpoint['enabled'] = True
cls.setup_endpoints.append(endpoint)
@@ -57,7 +56,7 @@
@test.idempotent_id('11f590eb-59d8-4067-8b2b-980c7f387f51')
def test_list_endpoints(self):
# Get a list of endpoints
- fetched_endpoints = self.client.list_endpoints()
+ fetched_endpoints = self.client.list_endpoints()['endpoints']
# Asserting LIST endpoints
missing_endpoints =\
[e for e in self.setup_endpoints if e not in fetched_endpoints]
@@ -73,18 +72,18 @@
region,
publicurl=url,
adminurl=url,
- internalurl=url)
+ internalurl=url)['endpoint']
# Asserting Create Endpoint response body
self.assertIn('id', endpoint)
self.assertEqual(region, endpoint['region'])
self.assertEqual(url, endpoint['publicurl'])
# Checking if created endpoint is present in the list of endpoints
- fetched_endpoints = self.client.list_endpoints()
+ fetched_endpoints = self.client.list_endpoints()['endpoints']
fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
self.assertIn(endpoint['id'], fetched_endpoints_id)
# Deleting the endpoint created in this method
self.client.delete_endpoint(endpoint['id'])
# Checking whether endpoint is deleted successfully
- fetched_endpoints = self.client.list_endpoints()
+ fetched_endpoints = self.client.list_endpoints()['endpoints']
fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
self.assertNotIn(endpoint['id'], fetched_endpoints_id)
diff --git a/tempest/api/identity/admin/v2/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
index 0b28a07..78beead 100644
--- a/tempest/api/identity/admin/v2/test_roles.py
+++ b/tempest/api/identity/admin/v2/test_roles.py
@@ -27,7 +27,7 @@
super(RolesTestJSON, cls).resource_setup()
for _ in moves.xrange(5):
role_name = data_utils.rand_name(name='role')
- role = cls.client.create_role(role_name)
+ role = cls.client.create_role(role_name)['role']
cls.data.roles.append(role)
def _get_role_params(self):
@@ -48,7 +48,7 @@
@test.idempotent_id('75d9593f-50b7-4fcf-bd64-e3fb4a278e23')
def test_list_roles(self):
"""Return a list of all roles."""
- body = self.client.list_roles()
+ body = self.client.list_roles()['roles']
found = [role for role in body if role in self.data.roles]
self.assertTrue(any(found))
self.assertEqual(len(found), len(self.data.roles))
@@ -57,16 +57,16 @@
def test_role_create_delete(self):
"""Role should be created, verified, and deleted."""
role_name = data_utils.rand_name(name='role-test')
- body = self.client.create_role(role_name)
+ body = self.client.create_role(role_name)['role']
self.assertEqual(role_name, body['name'])
- body = self.client.list_roles()
+ body = self.client.list_roles()['roles']
found = [role for role in body if role['name'] == role_name]
self.assertTrue(any(found))
body = self.client.delete_role(found[0]['id'])
- body = self.client.list_roles()
+ body = self.client.list_roles()['roles']
found = [role for role in body if role['name'] == role_name]
self.assertFalse(any(found))
@@ -85,7 +85,7 @@
"""Assign a role to a user on a tenant."""
(user, tenant, role) = self._get_role_params()
self.client.assign_user_role(tenant['id'], user['id'], role['id'])
- roles = self.client.list_user_roles(tenant['id'], user['id'])
+ roles = self.client.list_user_roles(tenant['id'], user['id'])['roles']
self.assert_role_in_role_list(role, roles)
@test.idempotent_id('f0b9292c-d3ba-4082-aa6c-440489beef69')
@@ -93,7 +93,8 @@
"""Remove a role assigned to a user on a tenant."""
(user, tenant, role) = self._get_role_params()
user_role = self.client.assign_user_role(tenant['id'],
- user['id'], role['id'])
+ user['id'],
+ role['id'])['role']
self.client.remove_user_role(tenant['id'], user['id'],
user_role['id'])
@@ -102,5 +103,5 @@
"""List roles assigned to a user on tenant."""
(user, tenant, role) = self._get_role_params()
self.client.assign_user_role(tenant['id'], user['id'], role['id'])
- roles = self.client.list_user_roles(tenant['id'], user['id'])
+ roles = self.client.list_user_roles(tenant['id'], user['id'])['roles']
self.assert_role_in_role_list(role, roles)
diff --git a/tempest/api/identity/admin/v2/test_roles_negative.py b/tempest/api/identity/admin/v2/test_roles_negative.py
index b38b7dd..5932aba 100644
--- a/tempest/api/identity/admin/v2/test_roles_negative.py
+++ b/tempest/api/identity/admin/v2/test_roles_negative.py
@@ -78,7 +78,7 @@
def test_role_create_duplicate(self):
# Role names should be unique
role_name = data_utils.rand_name(name='role-dup')
- body = self.client.create_role(role_name)
+ body = self.client.create_role(role_name)['role']
role1_id = body.get('id')
self.addCleanup(self.client.delete_role, role1_id)
self.assertRaises(lib_exc.Conflict, self.client.create_role,
@@ -89,7 +89,7 @@
def test_delete_role_by_unauthorized_user(self):
# Non-administrator user should not be able to delete role
role_name = data_utils.rand_name(name='role')
- body = self.client.create_role(role_name)
+ body = self.client.create_role(role_name)['role']
self.data.roles.append(body)
role_id = body.get('id')
self.assertRaises(lib_exc.Forbidden,
@@ -100,7 +100,7 @@
def test_delete_role_request_without_token(self):
# Request to delete role without a valid token should fail
role_name = data_utils.rand_name(name='role')
- body = self.client.create_role(role_name)
+ body = self.client.create_role(role_name)['role']
self.data.roles.append(body)
role_id = body.get('id')
token = self.client.auth_provider.get_token()
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index ef93981..eebeedb 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -38,7 +38,7 @@
type = data_utils.rand_name('type')
description = data_utils.rand_name('description')
service_data = self.client.create_service(
- name, type, description=description)
+ name, type, description=description)['OS-KSADM:service']
self.assertFalse(service_data['id'] is None)
self.addCleanup(self._del_service, service_data['id'])
# Verifying response body of create service
@@ -50,7 +50,8 @@
self.assertIn('description', service_data)
self.assertEqual(description, service_data['description'])
# Get service
- fetched_service = self.client.get_service(service_data['id'])
+ fetched_service = (self.client.get_service(service_data['id'])
+ ['OS-KSADM:service'])
# verifying the existence of service created
self.assertIn('id', fetched_service)
self.assertEqual(fetched_service['id'], service_data['id'])
@@ -67,7 +68,7 @@
# Create a service only with name and type
name = data_utils.rand_name('service')
type = data_utils.rand_name('type')
- service = self.client.create_service(name, type)
+ service = self.client.create_service(name, type)['OS-KSADM:service']
self.assertIn('id', service)
self.addCleanup(self._del_service, service['id'])
self.assertIn('name', service)
@@ -85,7 +86,7 @@
type = data_utils.rand_name('type')
description = data_utils.rand_name('description')
service = self.client.create_service(
- name, type, description=description)
+ name, type, description=description)['OS-KSADM:service']
services.append(service)
service_ids = map(lambda x: x['id'], services)
@@ -95,6 +96,6 @@
self.addCleanup(delete_services)
# List and Verify Services
- body = self.client.list_services()
+ body = self.client.list_services()['OS-KSADM:services']
found = [serv for serv in body if serv['id'] in service_ids]
self.assertEqual(len(found), len(services), 'Services not found')
diff --git a/tempest/api/identity/admin/v2/test_tenant_negative.py b/tempest/api/identity/admin/v2/test_tenant_negative.py
index bccb5ca..74558d1 100644
--- a/tempest/api/identity/admin/v2/test_tenant_negative.py
+++ b/tempest/api/identity/admin/v2/test_tenant_negative.py
@@ -45,7 +45,7 @@
def test_tenant_delete_by_unauthorized_user(self):
# Non-administrator user should not be able to delete a tenant
tenant_name = data_utils.rand_name(name='tenant')
- tenant = self.client.create_tenant(tenant_name)
+ tenant = self.client.create_tenant(tenant_name)['tenant']
self.data.tenants.append(tenant)
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.delete_tenant, tenant['id'])
@@ -55,7 +55,7 @@
def test_tenant_delete_request_without_token(self):
# Request to delete a tenant without a valid token should fail
tenant_name = data_utils.rand_name(name='tenant')
- tenant = self.client.create_tenant(tenant_name)
+ tenant = self.client.create_tenant(tenant_name)['tenant']
self.data.tenants.append(tenant)
token = self.client.auth_provider.get_token()
self.client.delete_token(token)
@@ -75,7 +75,7 @@
def test_tenant_create_duplicate(self):
# Tenant names should be unique
tenant_name = data_utils.rand_name(name='tenant')
- body = self.client.create_tenant(tenant_name)
+ body = self.client.create_tenant(tenant_name)['tenant']
tenant = body
self.data.tenants.append(tenant)
tenant1_id = body.get('id')
@@ -131,7 +131,7 @@
def test_tenant_update_by_unauthorized_user(self):
# Non-administrator user should not be able to update a tenant
tenant_name = data_utils.rand_name(name='tenant')
- tenant = self.client.create_tenant(tenant_name)
+ tenant = self.client.create_tenant(tenant_name)['tenant']
self.data.tenants.append(tenant)
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.update_tenant, tenant['id'])
@@ -141,7 +141,7 @@
def test_tenant_update_request_without_token(self):
# Request to update a tenant without a valid token should fail
tenant_name = data_utils.rand_name(name='tenant')
- tenant = self.client.create_tenant(tenant_name)
+ tenant = self.client.create_tenant(tenant_name)['tenant']
self.data.tenants.append(tenant)
token = self.client.auth_provider.get_token()
self.client.delete_token(token)
diff --git a/tempest/api/identity/admin/v2/test_tenants.py b/tempest/api/identity/admin/v2/test_tenants.py
index 9fff5f3..2ec5c4f 100644
--- a/tempest/api/identity/admin/v2/test_tenants.py
+++ b/tempest/api/identity/admin/v2/test_tenants.py
@@ -28,7 +28,7 @@
tenants = []
for _ in moves.xrange(3):
tenant_name = data_utils.rand_name(name='tenant-new')
- tenant = self.client.create_tenant(tenant_name)
+ tenant = self.client.create_tenant(tenant_name)['tenant']
self.data.tenants.append(tenant)
tenants.append(tenant)
tenant_ids = map(lambda x: x['id'], tenants)
@@ -50,14 +50,14 @@
tenant_name = data_utils.rand_name(name='tenant')
tenant_desc = data_utils.rand_name(name='desc')
body = self.client.create_tenant(tenant_name,
- description=tenant_desc)
+ description=tenant_desc)['tenant']
tenant = body
self.data.tenants.append(tenant)
tenant_id = body['id']
desc1 = body['description']
self.assertEqual(desc1, tenant_desc, 'Description should have '
'been sent in response for create')
- body = self.client.get_tenant(tenant_id)
+ body = self.client.get_tenant(tenant_id)['tenant']
desc2 = body['description']
self.assertEqual(desc2, tenant_desc, 'Description does not appear'
'to be set')
@@ -68,13 +68,13 @@
def test_tenant_create_enabled(self):
# Create a tenant that is enabled
tenant_name = data_utils.rand_name(name='tenant')
- body = self.client.create_tenant(tenant_name, enabled=True)
+ body = self.client.create_tenant(tenant_name, enabled=True)['tenant']
tenant = body
self.data.tenants.append(tenant)
tenant_id = body['id']
en1 = body['enabled']
self.assertTrue(en1, 'Enable should be True in response')
- body = self.client.get_tenant(tenant_id)
+ body = self.client.get_tenant(tenant_id)['tenant']
en2 = body['enabled']
self.assertTrue(en2, 'Enable should be True in lookup')
self.client.delete_tenant(tenant_id)
@@ -84,14 +84,14 @@
def test_tenant_create_not_enabled(self):
# Create a tenant that is not enabled
tenant_name = data_utils.rand_name(name='tenant')
- body = self.client.create_tenant(tenant_name, enabled=False)
+ body = self.client.create_tenant(tenant_name, enabled=False)['tenant']
tenant = body
self.data.tenants.append(tenant)
tenant_id = body['id']
en1 = body['enabled']
self.assertEqual('false', str(en1).lower(),
'Enable should be False in response')
- body = self.client.get_tenant(tenant_id)
+ body = self.client.get_tenant(tenant_id)['tenant']
en2 = body['enabled']
self.assertEqual('false', str(en2).lower(),
'Enable should be False in lookup')
@@ -102,7 +102,7 @@
def test_tenant_update_name(self):
# Update name attribute of a tenant
t_name1 = data_utils.rand_name(name='tenant')
- body = self.client.create_tenant(t_name1)
+ body = self.client.create_tenant(t_name1)['tenant']
tenant = body
self.data.tenants.append(tenant)
@@ -110,11 +110,11 @@
resp1_name = body['name']
t_name2 = data_utils.rand_name(name='tenant2')
- body = self.client.update_tenant(t_id, name=t_name2)
+ body = self.client.update_tenant(t_id, name=t_name2)['tenant']
resp2_name = body['name']
self.assertNotEqual(resp1_name, resp2_name)
- body = self.client.get_tenant(t_id)
+ body = self.client.get_tenant(t_id)['tenant']
resp3_name = body['name']
self.assertNotEqual(resp1_name, resp3_name)
@@ -129,7 +129,7 @@
# Update description attribute of a tenant
t_name = data_utils.rand_name(name='tenant')
t_desc = data_utils.rand_name(name='desc')
- body = self.client.create_tenant(t_name, description=t_desc)
+ body = self.client.create_tenant(t_name, description=t_desc)['tenant']
tenant = body
self.data.tenants.append(tenant)
@@ -137,11 +137,11 @@
resp1_desc = body['description']
t_desc2 = data_utils.rand_name(name='desc2')
- body = self.client.update_tenant(t_id, description=t_desc2)
+ body = self.client.update_tenant(t_id, description=t_desc2)['tenant']
resp2_desc = body['description']
self.assertNotEqual(resp1_desc, resp2_desc)
- body = self.client.get_tenant(t_id)
+ body = self.client.get_tenant(t_id)['tenant']
resp3_desc = body['description']
self.assertNotEqual(resp1_desc, resp3_desc)
@@ -156,7 +156,7 @@
# Update the enabled attribute of a tenant
t_name = data_utils.rand_name(name='tenant')
t_en = False
- body = self.client.create_tenant(t_name, enabled=t_en)
+ body = self.client.create_tenant(t_name, enabled=t_en)['tenant']
tenant = body
self.data.tenants.append(tenant)
@@ -164,11 +164,11 @@
resp1_en = body['enabled']
t_en2 = True
- body = self.client.update_tenant(t_id, enabled=t_en2)
+ body = self.client.update_tenant(t_id, enabled=t_en2)['tenant']
resp2_en = body['enabled']
self.assertNotEqual(resp1_en, resp2_en)
- body = self.client.get_tenant(t_id)
+ body = self.client.get_tenant(t_id)['tenant']
resp3_en = body['enabled']
self.assertNotEqual(resp1_en, resp3_en)
diff --git a/tempest/api/identity/admin/v2/test_tokens.py b/tempest/api/identity/admin/v2/test_tokens.py
index 66d00d1..981a9ea 100644
--- a/tempest/api/identity/admin/v2/test_tokens.py
+++ b/tempest/api/identity/admin/v2/test_tokens.py
@@ -27,11 +27,11 @@
user_password = data_utils.rand_name(name='pass')
# first:create a tenant
tenant_name = data_utils.rand_name(name='tenant')
- tenant = self.client.create_tenant(tenant_name)
+ tenant = self.client.create_tenant(tenant_name)['tenant']
self.data.tenants.append(tenant)
# second:create a user
user = self.client.create_user(user_name, user_password,
- tenant['id'], '')
+ tenant['id'], '')['user']
self.data.users.append(user)
# then get a token for the user
body = self.token_client.auth(user_name,
@@ -41,7 +41,7 @@
tenant['name'])
# Perform GET Token
token_id = body['token']['id']
- token_details = self.client.get_token(token_id)
+ token_details = self.client.get_token(token_id)['access']
self.assertEqual(token_id, token_details['token']['id'])
self.assertEqual(user['id'], token_details['user']['id'])
self.assertEqual(user_name, token_details['user']['name'])
@@ -62,21 +62,21 @@
tenant_id = None # No default tenant so will get unscoped token.
email = ''
user = self.client.create_user(user_name, user_password,
- tenant_id, email)
+ tenant_id, email)['user']
self.data.users.append(user)
# Create a couple tenants.
tenant1_name = data_utils.rand_name(name='tenant')
- tenant1 = self.client.create_tenant(tenant1_name)
+ tenant1 = self.client.create_tenant(tenant1_name)['tenant']
self.data.tenants.append(tenant1)
tenant2_name = data_utils.rand_name(name='tenant')
- tenant2 = self.client.create_tenant(tenant2_name)
+ tenant2 = self.client.create_tenant(tenant2_name)['tenant']
self.data.tenants.append(tenant2)
# Create a role
role_name = data_utils.rand_name(name='role')
- role = self.client.create_role(role_name)
+ role = self.client.create_role(role_name)['role']
self.data.roles.append(role)
# Grant the user the role on the tenants.
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index bfbcfe7..6ee5218 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -36,7 +36,7 @@
self.data.setup_test_tenant()
user = self.client.create_user(self.alt_user, self.alt_password,
self.data.tenant['id'],
- self.alt_email)
+ self.alt_email)['user']
self.data.users.append(user)
self.assertEqual(self.alt_user, user['name'])
@@ -47,7 +47,7 @@
name = data_utils.rand_name('test_user')
user = self.client.create_user(name, self.alt_password,
self.data.tenant['id'],
- self.alt_email, enabled=False)
+ self.alt_email, enabled=False)['user']
self.data.users.append(user)
self.assertEqual(name, user['name'])
self.assertEqual(False, user['enabled'])
@@ -60,7 +60,7 @@
self.data.setup_test_tenant()
user = self.client.create_user(test_user, self.alt_password,
self.data.tenant['id'],
- self.alt_email)
+ self.alt_email)['user']
# Delete the User at the end of this method
self.addCleanup(self.client.delete_user, user['id'])
# Updating user details with new values
@@ -68,12 +68,12 @@
u_email2 = u_name2 + '@testmail.tm'
update_user = self.client.update_user(user['id'], name=u_name2,
email=u_email2,
- enabled=False)
+ enabled=False)['user']
self.assertEqual(u_name2, update_user['name'])
self.assertEqual(u_email2, update_user['email'])
self.assertEqual(False, update_user['enabled'])
# GET by id after updating
- updated_user = self.client.get_user(user['id'])
+ updated_user = self.client.get_user(user['id'])['user']
# Assert response body of GET after updating
self.assertEqual(u_name2, updated_user['name'])
self.assertEqual(u_email2, updated_user['email'])
@@ -86,7 +86,7 @@
self.data.setup_test_tenant()
user = self.client.create_user(test_user, self.alt_password,
self.data.tenant['id'],
- self.alt_email)
+ self.alt_email)['user']
self.client.delete_user(user['id'])
@test.idempotent_id('aca696c3-d645-4f45-b728-63646045beb1')
@@ -121,7 +121,7 @@
def test_get_users(self):
# Get a list of users and find the test user
self.data.setup_test_user()
- users = self.client.get_users()
+ users = self.client.get_users()['users']
self.assertThat([u['name'] for u in users],
matchers.Contains(self.data.test_user),
"Could not find %s" % self.data.test_user)
@@ -135,18 +135,19 @@
alt_tenant_user1 = data_utils.rand_name('tenant_user1')
user1 = self.client.create_user(alt_tenant_user1, 'password1',
self.data.tenant['id'],
- 'user1@123')
+ 'user1@123')['user']
user_ids.append(user1['id'])
self.data.users.append(user1)
alt_tenant_user2 = data_utils.rand_name('tenant_user2')
user2 = self.client.create_user(alt_tenant_user2, 'password2',
self.data.tenant['id'],
- 'user2@123')
+ 'user2@123')['user']
user_ids.append(user2['id'])
self.data.users.append(user2)
# List of users for the respective tenant ID
- body = self.client.list_users_for_tenant(self.data.tenant['id'])
+ body = (self.client.list_users_for_tenant(self.data.tenant['id'])
+ ['users'])
for i in body:
fetched_user_ids.append(i['id'])
# verifying the user Id in the list
@@ -169,19 +170,20 @@
fetched_user_ids = list()
user_ids.append(user['id'])
role = self.client.assign_user_role(tenant['id'], user['id'],
- role['id'])
+ role['id'])['role']
alt_user2 = data_utils.rand_name('second_user')
second_user = self.client.create_user(alt_user2, 'password1',
self.data.tenant['id'],
- 'user2@123')
+ 'user2@123')['user']
user_ids.append(second_user['id'])
self.data.users.append(second_user)
role = self.client.assign_user_role(tenant['id'],
second_user['id'],
- role['id'])
+ role['id'])['role']
# List of users with roles for the respective tenant ID
- body = self.client.list_users_for_tenant(self.data.tenant['id'])
+ body = (self.client.list_users_for_tenant(self.data.tenant['id'])
+ ['users'])
for i in body:
fetched_user_ids.append(i['id'])
# verifying the user Id in the list
@@ -198,7 +200,7 @@
# Updating the user with new password
new_pass = data_utils.rand_name('pass')
update_user = self.client.update_user_password(
- self.data.user['id'], new_pass)
+ self.data.user['id'], new_pass)['user']
self.assertEqual(update_user['id'], self.data.user['id'])
# Validate the updated password
diff --git a/tempest/api/identity/admin/v3/test_policies.py b/tempest/api/identity/admin/v3/test_policies.py
index 8b67945..d079fec 100644
--- a/tempest/api/identity/admin/v3/test_policies.py
+++ b/tempest/api/identity/admin/v3/test_policies.py
@@ -32,12 +32,12 @@
blob = data_utils.rand_name('BlobName')
policy_type = data_utils.rand_name('PolicyType')
policy = self.policy_client.create_policy(blob,
- policy_type)
+ policy_type)['policy']
# Delete the Policy at the end of this method
self.addCleanup(self._delete_policy, policy['id'])
policy_ids.append(policy['id'])
# List and Verify Policies
- body = self.policy_client.list_policies()
+ body = self.policy_client.list_policies()['policies']
for p in body:
fetched_ids.append(p['id'])
missing_pols = [p for p in policy_ids if p not in fetched_ids]
@@ -49,7 +49,7 @@
# Test to update policy
blob = data_utils.rand_name('BlobName')
policy_type = data_utils.rand_name('PolicyType')
- policy = self.policy_client.create_policy(blob, policy_type)
+ policy = self.policy_client.create_policy(blob, policy_type)['policy']
self.addCleanup(self._delete_policy, policy['id'])
self.assertIn('id', policy)
self.assertIn('type', policy)
@@ -60,10 +60,10 @@
# Update policy
update_type = data_utils.rand_name('UpdatedPolicyType')
data = self.policy_client.update_policy(
- policy['id'], type=update_type)
+ policy['id'], type=update_type)['policy']
self.assertIn('type', data)
# Assertion for updated value with fetched value
- fetched_policy = self.policy_client.get_policy(policy['id'])
+ fetched_policy = self.policy_client.get_policy(policy['id'])['policy']
self.assertIn('id', fetched_policy)
self.assertIn('blob', fetched_policy)
self.assertIn('type', fetched_policy)
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..95826b0 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -39,7 +39,7 @@
@classmethod
def get_user_by_name(cls, name):
- users = cls.client.get_users()
+ users = cls.client.get_users()['users']
user = [u for u in users if u['name'] == name]
if len(user) > 0:
return user[0]
@@ -47,11 +47,7 @@
@classmethod
def get_tenant_by_name(cls, name):
try:
- tenants = cls.client.list_tenants()
- # TODO(jswarren): always retrieve 'tenants' value
- # once both clients return full response objects
- if 'tenants' in tenants:
- tenants = tenants['tenants']
+ tenants = cls.client.list_tenants()['tenants']
except AttributeError:
tenants = cls.client.list_projects()['projects']
tenant = [t for t in tenants if t['name'] == name]
@@ -60,7 +56,7 @@
@classmethod
def get_role_by_name(cls, name):
- roles = cls.client.list_roles()
+ roles = cls.client.list_roles()['roles']
role = [r for r in roles if r['name'] == name]
if len(role) > 0:
return role[0]
@@ -77,7 +73,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 +93,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
@@ -213,7 +210,7 @@
self.user = self.client.create_user(self.test_user,
self.test_password,
self.tenant['id'],
- self.test_email)
+ self.test_email)['user']
self.users.append(self.user)
def setup_test_tenant(self):
@@ -222,13 +219,13 @@
self.test_description = data_utils.rand_name('desc')
self.tenant = self.client.create_tenant(
name=self.test_tenant,
- description=self.test_description)
+ description=self.test_description)['tenant']
self.tenants.append(self.tenant)
def setup_test_role(self):
"""Set up a test role."""
self.test_role = data_utils.rand_name('role')
- self.role = self.client.create_role(self.test_role)
+ self.role = self.client.create_role(self.test_role)['role']
self.roles.append(self.role)
def setup_test_v3_user(self):
diff --git a/tempest/api/identity/test_extension.py b/tempest/api/identity/test_extension.py
index b1d65b4..01e5661 100644
--- a/tempest/api/identity/test_extension.py
+++ b/tempest/api/identity/test_extension.py
@@ -22,7 +22,7 @@
@test.idempotent_id('85f3f661-f54c-4d48-b563-72ae952b9383')
def test_list_extensions(self):
# List all the extensions
- body = self.non_admin_client.list_extensions()
+ body = self.non_admin_client.list_extensions()['extensions']['values']
self.assertNotEmpty(body)
keys = ['name', 'updated', 'alias', 'links',
'namespace', 'description']
diff --git a/tempest/api/identity/v2/test_api_discovery.py b/tempest/api/identity/v2/test_api_discovery.py
index 8132ee1..57c78ef 100644
--- a/tempest/api/identity/v2/test_api_discovery.py
+++ b/tempest/api/identity/v2/test_api_discovery.py
@@ -23,7 +23,7 @@
@test.attr(type='smoke')
@test.idempotent_id('ea889a68-a15f-4166-bfb1-c12456eae853')
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('007a0be0-78fe-4fdb-bbee-e9216cc17bb2')
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('77fd6be0-8801-48e6-b9bf-38cdd2f253ec')
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/v2/test_ec2_credentials.py b/tempest/api/identity/v2/test_ec2_credentials.py
new file mode 100644
index 0000000..763d8de
--- /dev/null
+++ b/tempest/api/identity/v2/test_ec2_credentials.py
@@ -0,0 +1,113 @@
+# 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 EC2CredentialsTest(base.BaseIdentityV2Test):
+
+ @classmethod
+ def skip_checks(cls):
+ super(EC2CredentialsTest, cls).skip_checks()
+ if not test.is_extension_enabled('OS-EC2', 'identity'):
+ msg = "OS-EC2 identity extension not enabled."
+ raise cls.skipException(msg)
+
+ @classmethod
+ def resource_setup(cls):
+ super(EC2CredentialsTest, cls).resource_setup()
+ cls.creds = cls.os.credentials
+
+ @test.idempotent_id('b580fab9-7ae9-46e8-8138-417260cb6f9f')
+ def test_create_ec2_credentials(self):
+ """Create user ec2 credentials."""
+ resp = self.non_admin_client.create_user_ec2_credentials(
+ self.creds.credentials.user_id,
+ self.creds.credentials.tenant_id)["credential"]
+ access = resp['access']
+ self.addCleanup(
+ self.non_admin_client.delete_user_ec2_credentials,
+ self.creds.credentials.user_id, access)
+ self.assertNotEmpty(resp['access'])
+ self.assertNotEmpty(resp['secret'])
+ self.assertEqual(self.creds.credentials.user_id, resp['user_id'])
+ self.assertEqual(self.creds.credentials.tenant_id, resp['tenant_id'])
+
+ @test.idempotent_id('9e2ea42f-0a4f-468c-a768-51859ce492e0')
+ def test_list_ec2_credentials(self):
+ """Get the list of user ec2 credentials."""
+ created_creds = []
+ fetched_creds = []
+ # create first ec2 credentials
+ creds1 = self.non_admin_client.create_user_ec2_credentials(
+ self.creds.credentials.user_id,
+ self.creds.credentials.tenant_id)["credential"]
+ created_creds.append(creds1['access'])
+ # create second ec2 credentials
+ creds2 = self.non_admin_client.create_user_ec2_credentials(
+ self.creds.credentials.user_id,
+ self.creds.credentials.tenant_id)["credential"]
+ created_creds.append(creds2['access'])
+ # add credentials to be cleaned up
+ self.addCleanup(
+ self.non_admin_client.delete_user_ec2_credentials,
+ self.creds.credentials.user_id, creds1['access'])
+ self.addCleanup(
+ self.non_admin_client.delete_user_ec2_credentials,
+ self.creds.credentials.user_id, creds2['access'])
+ # get the list of user ec2 credentials
+ resp = self.non_admin_client.list_user_ec2_credentials(
+ self.creds.credentials.user_id)["credentials"]
+ fetched_creds = [cred['access'] for cred in resp]
+ # created credentials should be in a fetched list
+ missing = [cred for cred in created_creds
+ if cred not in fetched_creds]
+ self.assertEmpty(missing,
+ "Failed to find ec2_credentials %s in fetched list" %
+ ', '.join(cred for cred in missing))
+
+ @test.idempotent_id('cb284075-b613-440d-83ca-fe0b33b3c2b8')
+ def test_show_ec2_credentials(self):
+ """Get the definite user ec2 credentials."""
+ resp = self.non_admin_client.create_user_ec2_credentials(
+ self.creds.credentials.user_id,
+ self.creds.credentials.tenant_id)["credential"]
+ self.addCleanup(
+ self.non_admin_client.delete_user_ec2_credentials,
+ self.creds.credentials.user_id, resp['access'])
+
+ ec2_creds = self.non_admin_client.show_user_ec2_credentials(
+ self.creds.credentials.user_id, resp['access']
+ )["credential"]
+ for key in ['access', 'secret', 'user_id', 'tenant_id']:
+ self.assertEqual(ec2_creds[key], resp[key])
+
+ @test.idempotent_id('6aba0d4c-b76b-4e46-aa42-add79bc1551d')
+ def test_delete_ec2_credentials(self):
+ """Delete user ec2 credentials."""
+ resp = self.non_admin_client.create_user_ec2_credentials(
+ self.creds.credentials.user_id,
+ self.creds.credentials.tenant_id)["credential"]
+ access = resp['access']
+ self.non_admin_client.delete_user_ec2_credentials(
+ self.creds.credentials.user_id, access)
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.non_admin_client.show_user_ec2_credentials,
+ self.creds.credentials.user_id,
+ access)
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..3b89b66
--- /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)['access']
+
+ # 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/admin/v2/test_images.py b/tempest/api/image/admin/v2/test_images.py
index 1608b76..09877ba 100644
--- a/tempest/api/image/admin/v2/test_images.py
+++ b/tempest/api/image/admin/v2/test_images.py
@@ -20,7 +20,7 @@
from tempest.api.image import base
from tempest import config
from tempest import test
-
+from tempest_lib import exceptions as lib_exc
CONF = config.CONF
@@ -43,13 +43,20 @@
image_id = body['id']
self.addCleanup(self.client.delete_image, image_id)
# upload an image file
- image_file = moves.cStringIO(data_utils.random_bytes())
+ content = data_utils.random_bytes()
+ image_file = moves.cStringIO(content)
self.client.store_image_file(image_id, image_file)
# deactivate image
self.admin_client.deactivate_image(image_id)
body = self.client.show_image(image_id)
self.assertEqual("deactivated", body['status'])
+ # non-admin user unable to download deactivated image
+ self.assertRaises(lib_exc.Forbidden, self.client.load_image_file,
+ image_id)
# reactivate image
self.admin_client.reactivate_image(image_id)
body = self.client.show_image(image_id)
self.assertEqual("active", body['status'])
+ # non-admin user able to download image after reactivation by admin
+ body = self.client.load_image_file(image_id)
+ self.assertEqual(content, body.data)
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/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index b446ec3..a336507 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -172,7 +172,7 @@
self.assertEqual(params[key], image[key], msg)
@test.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
- def test_index_no_params(self):
+ def test_list_no_params(self):
# Simple test to see all fixture images returned
images_list = self.client.list_images()['images']
image_list = map(lambda x: x['id'], images_list)
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/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index d942641..62aa18e 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -26,9 +26,10 @@
post_body = {'name': data_utils.rand_name('network-')}
if external:
post_body['router:external'] = external
- body = self.admin_client.create_network(**post_body)
+ body = self.admin_networks_client.create_network(**post_body)
network = body['network']
- self.addCleanup(self.admin_client.delete_network, network['id'])
+ self.addCleanup(
+ self.admin_networks_client.delete_network, network['id'])
return network
@test.idempotent_id('462be770-b310-4df9-9c42-773217e4c8b1')
@@ -47,8 +48,8 @@
network = self._create_network(external=False)
self.assertFalse(network.get('router:external', False))
update_body = {'router:external': True}
- body = self.admin_client.update_network(network['id'],
- **update_body)
+ body = self.admin_networks_client.update_network(network['id'],
+ **update_body)
updated_network = body['network']
# Verify that router:external parameter was updated
self.assertTrue(updated_network['router:external'])
@@ -60,7 +61,7 @@
# List networks as a normal user and confirm the external
# network extension attribute is returned for those networks
# that were created as external
- body = self.client.list_networks()
+ body = self.networks_client.list_networks()
networks_list = [net['id'] for net in body['networks']]
self.assertIn(external_network['id'], networks_list)
self.assertIn(self.network['id'], networks_list)
@@ -76,12 +77,12 @@
external_network = self._create_network()
# Show an external network as a normal user and confirm the
# external network extension attribute is returned.
- body = self.client.show_network(external_network['id'])
+ body = self.networks_client.show_network(external_network['id'])
show_ext_net = body['network']
self.assertEqual(external_network['name'], show_ext_net['name'])
self.assertEqual(external_network['id'], show_ext_net['id'])
self.assertTrue(show_ext_net['router:external'])
- body = self.client.show_network(self.network['id'])
+ body = self.networks_client.show_network(self.network['id'])
show_net = body['network']
# Verify with show that router:external is False for network
self.assertEqual(self.network['name'], show_net['name'])
@@ -96,10 +97,11 @@
"""
# Set cls.client to admin to use base.create_subnet()
client = self.admin_client
- body = client.create_network(**{'router:external': True})
+ body = self.admin_networks_client.create_network(
+ **{'router:external': True})
external_network = body['network']
self.addCleanup(self._try_delete_resource,
- client.delete_network,
+ self.admin_networks_client.delete_network,
external_network['id'])
subnet = self.create_subnet(external_network, client=client,
enable_dhcp=False)
@@ -113,7 +115,7 @@
network=external_network['id'])
self.assertIn(created_floating_ip['id'],
(f['id'] for f in floatingip_list['floatingips']))
- client.delete_network(external_network['id'])
+ self.admin_networks_client.delete_network(external_network['id'])
# Verifies floating ip is deleted
floatingip_list = client.list_floatingips()
self.assertNotIn(created_floating_ip['id'],
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 63395cc..f5c5784 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -51,18 +51,17 @@
def _check_quotas(self, new_quotas):
# Add a tenant to conduct the test
- test_tenant = data_utils.rand_name('test_tenant_')
- test_description = data_utils.rand_name('desc_')
- tenant = self.identity_admin_client.create_tenant(
- name=test_tenant,
- description=test_description)
- tenant_id = tenant['id']
- self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
+ project = data_utils.rand_name('test_project_')
+ description = data_utils.rand_name('desc_')
+ project = self.identity_utils.create_project(name=project,
+ description=description)
+ project_id = project['id']
+ self.addCleanup(self.identity_utils.delete_project, project_id)
# Change quotas for tenant
- quota_set = self.admin_client.update_quotas(tenant_id,
+ quota_set = self.admin_client.update_quotas(project_id,
**new_quotas)['quota']
- self.addCleanup(self.admin_client.reset_quotas, tenant_id)
+ self.addCleanup(self.admin_client.reset_quotas, project_id)
for key, value in six.iteritems(new_quotas):
self.assertEqual(value, quota_set[key])
@@ -70,21 +69,21 @@
non_default_quotas = self.admin_client.list_quotas()
found = False
for qs in non_default_quotas['quotas']:
- if qs['tenant_id'] == tenant_id:
+ if qs['tenant_id'] == project_id:
found = True
self.assertTrue(found)
# Confirm from API quotas were changed as requested for tenant
- quota_set = self.admin_client.show_quotas(tenant_id)
+ quota_set = self.admin_client.show_quotas(project_id)
quota_set = quota_set['quota']
for key, value in six.iteritems(new_quotas):
self.assertEqual(value, quota_set[key])
# Reset quotas to default and confirm
- self.admin_client.reset_quotas(tenant_id)
+ self.admin_client.reset_quotas(project_id)
non_default_quotas = self.admin_client.list_quotas()
for q in non_default_quotas['quotas']:
- self.assertNotEqual(tenant_id, q['tenant_id'])
+ self.assertNotEqual(project_id, q['tenant_id'])
@test.idempotent_id('2390f766-836d-40ef-9aeb-e810d78207fb')
def test_quotas(self):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index fda8fc3..39bdcff 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -73,11 +73,11 @@
def setup_clients(cls):
super(BaseNetworkTest, cls).setup_clients()
cls.client = cls.os.network_client
+ cls.networks_client = cls.os.networks_client
@classmethod
def resource_setup(cls):
super(BaseNetworkTest, cls).resource_setup()
- cls.network_cfg = CONF.network
cls.networks = []
cls.subnets = []
cls.ports = []
@@ -119,7 +119,7 @@
subnet['id'])
# Clean up networks
for network in cls.networks:
- cls._try_delete_resource(cls.client.delete_network,
+ cls._try_delete_resource(cls.networks_client.delete_network,
network['id'])
super(BaseNetworkTest, cls).resource_cleanup()
@@ -148,7 +148,7 @@
"""Wrapper utility that returns a test network."""
network_name = network_name or data_utils.rand_name('test-network-')
- body = cls.client.create_network(name=network_name)
+ body = cls.networks_client.create_network(name=network_name)
network = body['network']
cls.networks.append(network)
return network
@@ -266,6 +266,7 @@
def setup_clients(cls):
super(BaseAdminNetworkTest, cls).setup_clients()
cls.admin_client = cls.os_adm.network_client
+ cls.admin_networks_client = cls.os_adm.networks_client
@classmethod
def create_metering_label(cls, name, description):
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index be7174b..d6b03eb 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -39,7 +39,8 @@
'ext-gw-mode', 'binding', 'quotas',
'agent', 'dhcp_agent_scheduler', 'provider',
'router', 'extraroute', 'external-net',
- 'allowed-address-pairs', 'extra_dhcp_opt']
+ 'allowed-address-pairs', 'extra_dhcp_opt',
+ '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..a4ab43a 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':
@@ -147,7 +146,7 @@
def _delete_network(self, network):
# Deleting network also deletes its subnets if exists
- self.client.delete_network(network['id'])
+ self.networks_client.delete_network(network['id'])
if network in self.networks:
self.networks.remove(network)
for subnet in self.subnets:
@@ -172,7 +171,7 @@
del subnet['dns_nameservers'], compare_args['dns_nameservers']
self._compare_resource_attrs(subnet, compare_args)
- self.client.delete_network(net_id)
+ self.networks_client.delete_network(net_id)
self.networks.pop()
self.subnets.pop()
@@ -187,7 +186,7 @@
self.assertEqual('ACTIVE', network['status'])
# Verify network update
new_name = "New_network"
- body = self.client.update_network(net_id, name=new_name)
+ body = self.networks_client.update_network(net_id, name=new_name)
updated_net = body['network']
self.assertEqual(updated_net['name'], new_name)
# Find a cidr that is not in use yet and create a subnet with it
@@ -203,7 +202,7 @@
@test.idempotent_id('2bf13842-c93f-4a69-83ed-717d2ec3b44e')
def test_show_network(self):
# Verify the details of a network
- body = self.client.show_network(self.network['id'])
+ body = self.networks_client.show_network(self.network['id'])
network = body['network']
for key in ['id', 'name']:
self.assertEqual(network[key], self.network[key])
@@ -212,8 +211,8 @@
def test_show_network_fields(self):
# Verify specific fields of a network
fields = ['id', 'name']
- body = self.client.show_network(self.network['id'],
- fields=fields)
+ body = self.networks_client.show_network(self.network['id'],
+ fields=fields)
network = body['network']
self.assertEqual(sorted(network.keys()), sorted(fields))
for field_name in fields:
@@ -223,7 +222,7 @@
@test.idempotent_id('f7ffdeda-e200-4a7a-bcbe-05716e86bf43')
def test_list_networks(self):
# Verify the network exists in the list of all networks
- body = self.client.list_networks()
+ body = self.networks_client.list_networks()
networks = [network['id'] for network in body['networks']
if network['id'] == self.network['id']]
self.assertNotEmpty(networks, "Created network not found in the list")
@@ -232,7 +231,7 @@
def test_list_networks_fields(self):
# Verify specific fields of the networks
fields = ['id', 'name']
- body = self.client.list_networks(fields=fields)
+ body = self.networks_client.list_networks(fields=fields)
networks = body['networks']
self.assertNotEmpty(networks, "Network list returned is empty")
for network in networks:
@@ -282,7 +281,7 @@
def _try_delete_network(self, net_id):
# delete network, if it exists
try:
- self.client.delete_network(net_id)
+ self.networks_client.delete_network(net_id)
# if network is not found, this means it was deleted in the test
except lib_exc.NotFound:
pass
@@ -291,7 +290,7 @@
def test_delete_network_with_subnet(self):
# Creates a network
name = data_utils.rand_name('network-')
- body = self.client.create_network(name=name)
+ body = self.networks_client.create_network(name=name)
network = body['network']
net_id = network['id']
self.addCleanup(self._try_delete_network, net_id)
@@ -301,7 +300,7 @@
subnet_id = subnet['id']
# Delete network while the subnet still exists
- body = self.client.delete_network(net_id)
+ body = self.networks_client.delete_network(net_id)
# Verify that the subnet got automatically deleted.
self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
@@ -383,7 +382,7 @@
@test.idempotent_id('af774677-42a9-4e4b-bb58-16fe6a5bc1ec')
def test_external_network_visibility(self):
"""Verifies user can see external networks but not subnets."""
- body = self.client.list_networks(**{'router:external': True})
+ body = self.networks_client.list_networks(**{'router:external': True})
networks = [network['id'] for network in body['networks']]
self.assertNotEmpty(networks, "No external networks found")
@@ -427,9 +426,9 @@
def _delete_networks(self, created_networks):
for n in created_networks:
- self.client.delete_network(n['id'])
+ self.networks_client.delete_network(n['id'])
# Asserting that the networks are not found in the list after deletion
- body = self.client.list_networks()
+ body = self.networks_client.list_networks()
networks_list = [network['id'] for network in body['networks']]
for n in created_networks:
self.assertNotIn(n['id'], networks_list)
@@ -462,7 +461,7 @@
created_networks = body['networks']
self.addCleanup(self._delete_networks, created_networks)
# Asserting that the networks are found in the list after creation
- body = self.client.list_networks()
+ body = self.networks_client.list_networks()
networks_list = [network['id'] for network in body['networks']]
for n in created_networks:
self.assertIsNotNone(n['id'])
@@ -534,7 +533,7 @@
_ip_version = 6
-class NetworksIpV6TestJSON(NetworksTestJSON):
+class NetworksIpV6TestJSON(NetworksTest):
_ip_version = 6
@test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
@@ -631,7 +630,7 @@
self.assertRaisesRegexp(
lib_exc.Conflict,
"There are one or more ports still in use on the network",
- self.client.delete_network,
+ self.networks_client.delete_network,
slaac_network['id'])
@test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index 5dc1c21..4d1971f 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -26,36 +26,38 @@
@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')
- self.assertRaises(lib_exc.NotFound, self.client.show_network,
+ non_exist_id = data_utils.rand_uuid()
+ self.assertRaises(lib_exc.NotFound, self.networks_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')
- self.assertRaises(lib_exc.NotFound, self.client.update_network,
- non_exist_id, name="new_name")
+ non_exist_id = data_utils.rand_uuid()
+ self.assertRaises(
+ lib_exc.NotFound, self.networks_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')
- self.assertRaises(lib_exc.NotFound, self.client.delete_network,
+ non_exist_id = data_utils.rand_uuid()
+ self.assertRaises(lib_exc.NotFound,
+ self.networks_client.delete_network,
non_exist_id)
@test.attr(type=['negative'])
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 6a8fbec..321473c 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -167,17 +167,25 @@
port_list = self.client.list_ports(fixed_ips=fixed_ips)
# Check that we got the desired port
ports = port_list['ports']
- self.assertEqual(len(ports), 1)
- self.assertEqual(ports[0]['id'], port_1['port']['id'])
- self.assertEqual(ports[0]['fixed_ips'][0]['ip_address'],
- port_1_fixed_ip)
- self.assertEqual(ports[0]['network_id'], network['id'])
+ tenant_ids = set([port['tenant_id'] for port in ports])
+ self.assertEqual(len(tenant_ids), 1,
+ 'Ports from multiple tenants are in the list resp')
+ port_ids = [port['id'] for port in ports]
+ fixed_ips = [port['fixed_ips'] for port in ports]
+ port_ips = []
+ for addr in fixed_ips:
+ port_ips.extend([port['ip_address'] for port in addr])
+
+ port_net_ids = [port['network_id'] for port in ports]
+ self.assertIn(port_1['port']['id'], port_ids)
+ self.assertIn(port_1_fixed_ip, port_ips)
+ self.assertIn(network['id'], port_net_ids)
@test.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
def test_port_list_filter_by_router_id(self):
# Create a router
network = self.create_network()
- self.addCleanup(self.client.delete_network, network['id'])
+ self.addCleanup(self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(network)
self.addCleanup(self.client.delete_subnet, subnet['id'])
router = self.create_router(data_utils.rand_name('router-'))
@@ -210,7 +218,7 @@
def test_create_update_port_with_second_ip(self):
# Create a network with two subnets
network = self.create_network()
- self.addCleanup(self.client.delete_network, network['id'])
+ self.addCleanup(self.networks_client.delete_network, network['id'])
subnet_1 = self.create_subnet(network)
self.addCleanup(self.client.delete_subnet, subnet_1['id'])
subnet_2 = self.create_subnet(network)
@@ -318,7 +326,7 @@
@test.idempotent_id('4179dcb9-1382-4ced-84fe-1b91c54f5735')
def test_create_port_with_no_securitygroups(self):
network = self.create_network()
- self.addCleanup(self.client.delete_network, network['id'])
+ self.addCleanup(self.networks_client.delete_network, network['id'])
subnet = self.create_subnet(network)
self.addCleanup(self.client.delete_subnet, subnet['id'])
port = self.create_port(network, security_groups=[])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 1308414..29855e1 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -85,21 +85,21 @@
self.assertEqual(show_body['router']['name'], updated_name)
@test.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397')
- def test_create_router_setting_tenant_id(self):
- # Test creating router from admin user setting tenant_id.
- test_tenant = data_utils.rand_name('test_tenant_')
- test_description = data_utils.rand_name('desc_')
- tenant = self.identity_admin_client.create_tenant(
- name=test_tenant, description=test_description)
- tenant_id = tenant['id']
- self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
+ def test_create_router_setting_project_id(self):
+ # Test creating router from admin user setting project_id.
+ project = data_utils.rand_name('test_tenant_')
+ description = data_utils.rand_name('desc_')
+ project = self.identity_utils.create_project(name=project,
+ description=description)
+ project_id = project['id']
+ self.addCleanup(self.identity_utils.delete_project, project_id)
name = data_utils.rand_name('router-')
create_body = self.admin_client.create_router(name,
- tenant_id=tenant_id)
+ tenant_id=project_id)
self.addCleanup(self.admin_client.delete_router,
create_body['router']['id'])
- self.assertEqual(tenant_id, create_body['router']['tenant_id'])
+ self.assertEqual(project_id, create_body['router']['tenant_id'])
@test.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
@test.requires_ext(extension='ext-gw-mode', service='network')
@@ -188,7 +188,7 @@
gw_port = list_body['ports'][0]
fixed_ips = gw_port['fixed_ips']
self.assertGreaterEqual(len(fixed_ips), 1)
- public_net_body = self.admin_client.show_network(
+ public_net_body = self.admin_networks_client.show_network(
CONF.network.public_network_id)
public_subnet_id = public_net_body['network']['subnets'][0]
self.assertIn(public_subnet_id,
@@ -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_quotas.py b/tempest/api/object_storage/test_container_quotas.py
index c78b4c3..896352b 100644
--- a/tempest/api/object_storage/test_container_quotas.py
+++ b/tempest/api/object_storage/test_container_quotas.py
@@ -26,7 +26,7 @@
class ContainerQuotasTest(base.BaseObjectTest):
- """Attemps to test the perfect behavior of quotas in a container."""
+ """Attempts to test the perfect behavior of quotas in a container."""
def setUp(self):
"""Creates and sets a container with quotas.
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/base.py b/tempest/api/orchestration/base.py
index 5b6b0fa..4968835 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -50,9 +50,15 @@
cls.servers_client = cls.os.servers_client
cls.keypairs_client = cls.os.keypairs_client
cls.network_client = cls.os.network_client
+ cls.networks_client = cls.os.networks_client
cls.volumes_client = cls.os.volumes_client
cls.images_v2_client = cls.os.image_client_v2
+ if CONF.volume_feature_enabled.api_v2:
+ cls.volumes_client = cls.os.volumes_v2_client
+ else:
+ cls.volumes_client = cls.os.volumes_client
+
@classmethod
def resource_setup(cls):
super(BaseOrchestrationTest, cls).resource_setup()
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index cb6d1db..99c2a97 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -87,7 +87,7 @@
server_id = body['physical_resource_id']
LOG.debug('Console output for %s', server_id)
output = cls.servers_client.get_console_output(
- server_id, None).data
+ server_id, None)['output']
LOG.debug(output)
raise e
@@ -118,7 +118,7 @@
def test_created_network(self):
"""Verifies created network."""
network_id = self.test_resources.get('Network')['physical_resource_id']
- body = self.network_client.show_network(network_id)
+ body = self.networks_client.show_network(network_id)
network = body['network']
self.assertIsInstance(network, dict)
self.assertEqual(network_id, network['id'])
@@ -184,7 +184,7 @@
def test_created_server(self):
"""Verifies created sever."""
server_id = self.test_resources.get('Server')['physical_resource_id']
- server = self.servers_client.show_server(server_id)
+ server = self.servers_client.show_server(server_id)['server']
self.assertEqual(self.keypair_name, server['key_name'])
self.assertEqual('ACTIVE', server['status'])
network = server['addresses'][self.neutron_basic_template['resources'][
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index d8f117e..ae9a411 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -34,14 +34,23 @@
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'))
+
+ # Some volume properties have been renamed with Cinder v2
+ if CONF.volume_feature_enabled.api_v2:
+ description_field = 'description'
+ name_field = 'name'
+ else:
+ description_field = 'display_description'
+ name_field = 'display_name'
+
self.assertEqual(template['resources']['volume']['properties'][
- 'description'], volume.get('display_description'))
+ 'description'], volume.get(description_field))
self.assertEqual(template['resources']['volume']['properties'][
- 'name'], volume.get('display_name'))
+ 'name'], volume.get(name_field))
def _outputs_verify(self, stack_identifier, template):
self.assertEqual('available',
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_alarming_api_negative.py b/tempest/api/telemetry/test_alarming_api_negative.py
new file mode 100644
index 0000000..7d5a0bf
--- /dev/null
+++ b/tempest/api/telemetry/test_alarming_api_negative.py
@@ -0,0 +1,71 @@
+# Copyright 2015 GlobalLogic. 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.api.telemetry import base
+from tempest.common.utils import data_utils
+from tempest import test
+from tempest_lib import exceptions as lib_exc
+
+import uuid
+
+
+class TelemetryAlarmingNegativeTest(base.BaseTelemetryTest):
+ """here we have negative tests for show_alarm, update_alarm, show_alarm_history
+ Tests
+ ** show non-existent alarm
+ ** show the deleted alarm
+ ** delete deleted alarm
+ ** update deleted alarm
+ """
+
+ @test.attr(type=['negative'])
+ @test.idempotent_id('668743d5-08ad-4480-b2b8-15da34f81e7d')
+ def test_get_non_existent_alarm(self):
+ # get the non-existent alarm
+ non_existent_id = str(uuid.uuid4())
+ self.assertRaises(lib_exc.NotFound, self.telemetry_client.show_alarm,
+ non_existent_id)
+
+ @test.attr(type=['negative'])
+ @test.idempotent_id('ef45000d-0a72-4781-866d-4cb7bf2582ad')
+ def test_get_update_show_history_delete_deleted_alarm(self):
+ # get, update and delete the deleted alarm
+ alarm_name = data_utils.rand_name('telemetry_alarm')
+ rule = {'meter_name': 'cpu',
+ 'comparison_operator': 'eq',
+ 'threshold': 100.0,
+ 'period': 90}
+ body = self.telemetry_client.create_alarm(
+ name=alarm_name,
+ type='threshold',
+ threshold_rule=rule)
+ alarm_id = body['alarm_id']
+ self.telemetry_client.delete_alarm(alarm_id)
+ # get the deleted alarm
+ self.assertRaises(lib_exc.NotFound, self.telemetry_client.show_alarm,
+ alarm_id)
+
+ # update the deleted alarm
+ updated_alarm_name = data_utils.rand_name('telemetry_alarm_updated')
+ updated_rule = {'meter_name': 'cpu_new',
+ 'comparison_operator': 'eq',
+ 'threshold': 70,
+ 'period': 50}
+ self.assertRaises(lib_exc.NotFound, self.telemetry_client.update_alarm,
+ alarm_id, threshold_rule=updated_rule,
+ name=updated_alarm_name,
+ type='threshold')
+ # delete the deleted alarm
+ self.assertRaises(lib_exc.NotFound, self.telemetry_client.delete_alarm,
+ alarm_id)
diff --git a/tempest/api/telemetry/test_telemetry_alarming_api.py b/tempest/api/telemetry/test_telemetry_alarming_api.py
index 13da9cb..6c84b98 100644
--- a/tempest/api/telemetry/test_telemetry_alarming_api.py
+++ b/tempest/api/telemetry/test_telemetry_alarming_api.py
@@ -56,18 +56,24 @@
'comparison_operator': 'eq',
'threshold': 70.0,
'period': 60}
- alarm_name = data_utils.rand_name('telemetry-alarm-update')
+ alarm_name_updated = data_utils.rand_name('telemetry-alarm-update')
body = self.telemetry_client.update_alarm(
alarm_id,
threshold_rule=new_rule,
- name=alarm_name,
+ name=alarm_name_updated,
type='threshold')
- self.assertEqual(alarm_name, body['name'])
+ self.assertEqual(alarm_name_updated, body['name'])
self.assertDictContainsSubset(new_rule, body['threshold_rule'])
# Get and verify details of an alarm after update
body = self.telemetry_client.show_alarm(alarm_id)
- self.assertEqual(alarm_name, body['name'])
+ self.assertEqual(alarm_name_updated, body['name'])
self.assertDictContainsSubset(new_rule, body['threshold_rule'])
+ # Get history for the alarm and verify the same
+ body = self.telemetry_client.show_alarm_history(alarm_id)
+ self.assertEqual("rule change", body[0]['type'])
+ self.assertIn(alarm_name_updated, body[0]['detail'])
+ self.assertEqual("creation", body[1]['type'])
+ self.assertIn(alarm_name, body[1]['detail'])
# Delete alarm and verify if deleted
self.telemetry_client.delete_alarm(alarm_id)
self.assertRaises(lib_exc.NotFound,
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..aa6bfdf 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -15,10 +15,18 @@
from tempest.api.volume import base
from tempest.common.utils import data_utils
+from tempest import config
from tempest import test
+CONF = config.CONF
+
class SnapshotsActionsV2Test(base.BaseVolumeAdminTest):
+ @classmethod
+ def skip_checks(cls):
+ super(SnapshotsActionsV2Test, cls).skip_checks()
+ if not CONF.volume_feature_enabled.snapshot:
+ raise cls.skipException("Cinder snapshot feature disabled")
@classmethod
def setup_clients(cls):
@@ -34,7 +42,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..b2e52bb 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'])
@@ -97,21 +98,23 @@
@test.idempotent_id('874b35a9-51f1-4258-bec5-cd561b6690d3')
def test_delete_quota(self):
- # Admin can delete the resource quota set for a tenant
- tenant_name = data_utils.rand_name('quota_tenant')
- identity_client = self.os_adm.identity_client
- tenant = identity_client.create_tenant(tenant_name)
- tenant_id = tenant['id']
- self.addCleanup(identity_client.delete_tenant, tenant_id)
+ # Admin can delete the resource quota set for a project
+ project_name = data_utils.rand_name('quota_tenant')
+ description = data_utils.rand_name('desc_')
+ project = self.identity_utils.create_project(project_name,
+ description=description)
+ project_id = project['id']
+ self.addCleanup(self.identity_utils.delete_project, project_id)
quota_set_default = self.quotas_client.show_default_quota_set(
- tenant_id)
+ project_id)['quota_set']
volume_default = quota_set_default['volumes']
- self.quotas_client.update_quota_set(tenant_id,
+ self.quotas_client.update_quota_set(project_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)
+ self.quotas_client.delete_quota_set(project_id)
+ quota_set_new = (self.quotas_client.show_quota_set(project_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 8015c35..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
@@ -48,7 +49,7 @@
backup_name = data_utils.rand_name('Backup')
create_backup = self.backups_adm_client.create_backup
backup = create_backup(self.volume['id'],
- name=backup_name)
+ name=backup_name)['backup']
self.addCleanup(self.backups_adm_client.delete_backup,
backup['id'])
self.assertEqual(backup_name, backup['name'])
@@ -58,16 +59,17 @@
'available')
# Get a given backup
- backup = self.backups_adm_client.show_backup(backup['id'])
+ backup = self.backups_adm_client.show_backup(backup['id'])['backup']
self.assertEqual(backup_name, backup['name'])
# Get all backups with detail
- backups = self.backups_adm_client.list_backups(detail=True)
+ backups = self.backups_adm_client.list_backups(detail=True)['backups']
self.assertIn((backup['name'], backup['id']),
[(m['name'], m['id']) for m in backups])
# Restore backup
- restore = self.backups_adm_client.restore_backup(backup['id'])
+ restore = self.backups_adm_client.restore_backup(
+ backup['id'])['restore']
# Delete backup
self.addCleanup(self.admin_volume_client.delete_volume,
@@ -78,19 +80,22 @@
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
backup_name = data_utils.rand_name('Backup')
- backup = self.backups_adm_client.create_backup(self.volume['id'],
- name=backup_name)
+ backup = (self.backups_adm_client.create_backup(self.volume['id'],
+ name=backup_name)
+ ['backup'])
self.addCleanup(self._delete_backup, backup['id'])
self.assertEqual(backup_name, backup['name'])
self.backups_adm_client.wait_for_backup_status(backup['id'],
'available')
# Export Backup
- export_backup = self.backups_adm_client.export_backup(backup['id'])
+ export_backup = (self.backups_adm_client.export_backup(backup['id'])
+ ['backup-record'])
self.assertIn('backup_service', export_backup)
self.assertIn('backup_url', export_backup)
self.assertTrue(export_backup['backup_service'].startswith(
@@ -100,18 +105,19 @@
# Import Backup
import_backup = self.backups_adm_client.import_backup(
backup_service=export_backup['backup_service'],
- backup_url=export_backup['backup_url'])
+ backup_url=export_backup['backup_url'])['backup']
self.addCleanup(self._delete_backup, import_backup['id'])
self.assertIn("id", import_backup)
self.backups_adm_client.wait_for_backup_status(import_backup['id'],
'available')
# Verify Import Backup
- backups = self.backups_adm_client.list_backups(detail=True)
+ backups = self.backups_adm_client.list_backups(detail=True)['backups']
self.assertIn(import_backup['id'], [b['id'] for b in backups])
# Restore backup
- restore = self.backups_adm_client.restore_backup(import_backup['id'])
+ restore = (self.backups_adm_client.restore_backup(import_backup['id'])
+ ['restore'])
self.addCleanup(self.admin_volume_client.delete_volume,
restore['volume_id'])
self.assertEqual(import_backup['id'], restore['backup_id'])
@@ -119,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..12e6761 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
@@ -61,7 +61,7 @@
def setup_clients(cls):
super(BaseVolumeTest, cls).setup_clients()
cls.servers_client = cls.os.servers_client
- cls.networks_client = cls.os.networks_client
+ cls.compute_networks_client = cls.os.compute_networks_client
cls.images_client = cls.os.images_client
if cls._api_version == 1:
@@ -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_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index ce6ba90..e50ca95 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -16,10 +16,18 @@
from testtools import matchers
from tempest.api.volume import base
+from tempest import config
from tempest import test
+CONF = config.CONF
+
class SnapshotV2MetadataTestJSON(base.BaseVolumeTest):
+ @classmethod
+ def skip_checks(cls):
+ super(SnapshotV2MetadataTestJSON, cls).skip_checks()
+ if not CONF.volume_feature_enabled.snapshot:
+ raise cls.skipException("Cinder snapshot feature disabled")
@classmethod
def setup_clients(cls):
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..9866da3 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'],
@@ -86,9 +85,7 @@
snapshot = self.create_snapshot(self.volume_origin['id'],
force=True)
# Delete the snapshot
- self.snapshots_client.delete_snapshot(snapshot['id'])
- self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
- self.snapshots.remove(snapshot)
+ self.cleanup_snapshot(snapshot)
@test.idempotent_id('2a8abbe4-d871-46db-b049-c41f5af8216e')
def test_snapshot_create_get_list_update_delete(self):
@@ -127,9 +124,7 @@
self.assertEqual(new_desc, updated_snapshot[self.descrip_field])
# Delete the snapshot
- self.snapshots_client.delete_snapshot(snapshot['id'])
- self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
- self.snapshots.remove(snapshot)
+ self.cleanup_snapshot(snapshot)
@test.idempotent_id('59f41f43-aebf-48a9-ab5d-d76340fab32b')
def test_snapshots_list_with_params(self):
@@ -138,6 +133,7 @@
display_name = data_utils.rand_name('snap')
params = {self.name_field: display_name}
snapshot = self.create_snapshot(self.volume_origin['id'], **params)
+ self.addCleanup(self.cleanup_snapshot, snapshot)
# Verify list snapshots by display_name filter
params = {self.name_field: snapshot[self.name_field]}
@@ -159,6 +155,7 @@
display_name = data_utils.rand_name('snap')
params = {self.name_field: display_name}
snapshot = self.create_snapshot(self.volume_origin['id'], **params)
+ self.addCleanup(self.cleanup_snapshot, snapshot)
# Verify list snapshot details by display_name filter
params = {self.name_field: snapshot[self.name_field]}
@@ -178,11 +175,17 @@
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'])
- self.clear_snapshots()
+ self.cleanup_snapshot(snapshot)
+
+ def cleanup_snapshot(self, snapshot):
+ # Delete the snapshot
+ self.snapshots_client.delete_snapshot(snapshot['id'])
+ self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
+ self.snapshots.remove(snapshot)
class VolumesV1SnapshotTestJSON(VolumesV2SnapshotTestJSON):
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/snapshots.py b/tempest/api_schema/response/compute/v2_1/snapshots.py
new file mode 100644
index 0000000..01a524b
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_1/snapshots.py
@@ -0,0 +1,61 @@
+# Copyright 2015 Fujitsu(fnst) 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.
+
+common_snapshot_info = {
+ 'type': 'object',
+ 'properties': {
+ 'id': {'type': 'string'},
+ 'volumeId': {'type': 'string'},
+ 'status': {'type': 'string'},
+ 'size': {'type': 'integer'},
+ 'createdAt': {'type': 'string'},
+ 'displayName': {'type': ['string', 'null']},
+ 'displayDescription': {'type': ['string', 'null']}
+ },
+ 'additionalProperties': False,
+ 'required': ['id', 'volumeId', 'status', 'size',
+ 'createdAt', 'displayName', 'displayDescription']
+}
+
+create_get_snapshot = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'snapshot': common_snapshot_info
+ },
+ 'additionalProperties': False,
+ 'required': ['snapshot']
+ }
+}
+
+list_snapshots = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'snapshots': {
+ 'type': 'array',
+ 'items': common_snapshot_info
+ }
+ },
+ 'additionalProperties': False,
+ 'required': ['snapshots']
+ }
+}
+
+delete_snapshot = {
+ 'status_code': [202]
+}
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..08a9fab
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_1/versions.py
@@ -0,0 +1,110 @@
+# 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
+
+
+_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'],
+ 'additionalProperties': False
+ }
+ },
+ 'status': {'type': 'string'},
+ 'updated': {'type': 'string', 'format': 'date-time'},
+ 'version': {'type': 'string'},
+ 'min_version': {'type': 'string'},
+ 'media-types': {
+ 'type': 'array',
+ 'properties': {
+ 'base': {'type': 'string'},
+ 'type': {'type': 'string'},
+ }
+ },
+ },
+ # NOTE: version and min_version have been added since Kilo,
+ # so they should not be required.
+ # NOTE(sdague): media-types only shows up in single version requests.
+ '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
+ }
+}
+
+
+_detail_get_version = copy.deepcopy(_version)
+_detail_get_version['properties'].pop('min_version')
+_detail_get_version['properties'].pop('version')
+_detail_get_version['properties'].pop('updated')
+_detail_get_version['properties']['media-types'] = {
+ 'type': 'array',
+ 'items': {
+ 'type': 'object',
+ 'properties': {
+ 'base': {'type': 'string'},
+ 'type': {'type': 'string'}
+ }
+ }
+}
+_detail_get_version['required'] = ['id', 'links', 'status', 'media-types']
+
+get_version = {
+ 'status_code': [300],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'choices': {
+ 'type': 'array',
+ 'items': _detail_get_version
+ }
+ },
+ 'required': ['choices'],
+ 'additionalProperties': False
+ }
+}
+
+get_one_version = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'version': _version
+ },
+ 'additionalProperties': False
+ }
+}
diff --git a/tempest/clients.py b/tempest/clients.py
index 7cb4347..dd0d145 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -16,8 +16,8 @@
import copy
from oslo_log import log as logging
-from tempest_lib.services.identity.v2.token_client import TokenClientJSON
-from tempest_lib.services.identity.v3.token_client import V3TokenClientJSON
+from tempest_lib.services.identity.v2.token_client import TokenClient
+from tempest_lib.services.identity.v3.token_client import V3TokenClient
from tempest.common import cred_provider
from tempest.common import negative_rest_client
@@ -59,7 +59,8 @@
from tempest.services.compute.json.limits_client import LimitsClient
from tempest.services.compute.json.migrations_client import \
MigrationsClient
-from tempest.services.compute.json.networks_client import NetworksClient
+from tempest.services.compute.json.networks_client import NetworksClient \
+ as ComputeNetworksClient
from tempest.services.compute.json.quota_classes_client import \
QuotaClassesClient
from tempest.services.compute.json.quotas_client import QuotasClient
@@ -73,10 +74,13 @@
ServerGroupsClient
from tempest.services.compute.json.servers_client import ServersClient
from tempest.services.compute.json.services_client import ServicesClient
+from tempest.services.compute.json.snapshots_client import \
+ SnapshotsClient as ComputeSnapshotsClient
from tempest.services.compute.json.tenant_networks_client import \
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 \
@@ -104,6 +108,7 @@
from tempest.services.messaging.json.messaging_client import \
MessagingClient
from tempest.services.network.json.network_client import NetworkClient
+from tempest.services.network.json.networks_client import NetworksClient
from tempest.services.object_storage.account_client import AccountClient
from tempest.services.object_storage.container_client import ContainerClient
from tempest.services.object_storage.object_client import ObjectClient
@@ -193,6 +198,14 @@
build_interval=CONF.network.build_interval,
build_timeout=CONF.network.build_timeout,
**self.default_params)
+ self.networks_client = NetworksClient(
+ self.auth_provider,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type=CONF.network.endpoint_type,
+ build_interval=CONF.network.build_interval,
+ build_timeout=CONF.network.build_timeout,
+ **self.default_params)
self.messaging_client = MessagingClient(
self.auth_provider,
CONF.messaging.catalog_type,
@@ -259,7 +272,8 @@
params.update(self.default_params)
self.agents_client = AgentsClient(self.auth_provider, **params)
- self.networks_client = NetworksClient(self.auth_provider, **params)
+ self.compute_networks_client = ComputeNetworksClient(
+ self.auth_provider, **params)
self.migrations_client = MigrationsClient(self.auth_provider,
**params)
self.security_group_default_rules_client = (
@@ -321,8 +335,11 @@
'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)
+ self.snapshots_extensions_client = ComputeSnapshotsClient(
+ self.auth_provider, **params_volume)
def _set_database_clients(self):
self.database_flavors_client = DatabaseFlavorsClient(
@@ -375,14 +392,14 @@
# API version is marked as enabled
if CONF.identity_feature_enabled.api_v2:
if CONF.identity.uri:
- self.token_client = TokenClientJSON(
+ self.token_client = TokenClient(
CONF.identity.uri, **self.default_params)
else:
msg = 'Identity v2 API enabled, but no identity.uri set'
raise exceptions.InvalidConfiguration(msg)
if CONF.identity_feature_enabled.api_v3:
if CONF.identity.uri_v3:
- self.token_v3_client = V3TokenClientJSON(
+ self.token_v3_client = V3TokenClient(
CONF.identity.uri_v3, **self.default_params)
else:
msg = 'Identity v3 API enabled, but no identity.uri_v3 set'
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
index 9df0cca..c26df96 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.
@@ -93,6 +93,7 @@
from tempest import exceptions as exc
from tempest.services.identity.v2.json import identity_client
from tempest.services.network.json import network_client
+from tempest.services.network.json import networks_client
import tempest_lib.auth
from tempest_lib.common.utils import data_utils
import tempest_lib.exceptions
@@ -136,19 +137,29 @@
**params
)
network_admin = None
+ networks_admin = None
+ neutron_iso_networks = False
if (CONF.service_available.neutron and
CONF.auth.create_isolated_networks):
+ neutron_iso_networks = True
network_admin = network_client.NetworkClient(
_auth,
CONF.network.catalog_type,
CONF.network.region or CONF.identity.region,
endpoint_type='adminURL',
**params)
- return identity_admin, network_admin
+ networks_admin = networks_client.NetworksClient(
+ _auth,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type='adminURL',
+ **params)
+ return identity_admin, neutron_iso_networks, network_admin, networks_admin
def create_resources(opts, resources):
- identity_admin, network_admin = get_admin_clients(opts)
+ (identity_admin, neutron_iso_networks,
+ network_admin, networks_admin) = get_admin_clients(opts)
roles = identity_admin.list_roles()
for u in resources['users']:
u['role_ids'] = []
@@ -187,12 +198,11 @@
u['name'] = random_user_name(opts.tag, u['prefix'])
LOG.info('Users created')
- if network_admin:
+ if neutron_iso_networks:
for u in resources['users']:
tenant = identity_admin.get_tenant_by_name(u['tenant'])
- network_name, router_name = create_network_resources(network_admin,
- tenant['id'],
- u['name'])
+ network_name, router_name = create_network_resources(
+ network_admin, networks_admin, tenant['id'], u['name'])
u['network'] = network_name
u['router'] = router_name
LOG.info('Networks created')
@@ -218,10 +228,11 @@
LOG.info('Resources deployed successfully!')
-def create_network_resources(network_admin_client, tenant_id, name):
+def create_network_resources(network_admin_client, networks_admin_client,
+ tenant_id, name):
def _create_network(name):
- resp_body = network_admin_client.create_network(
+ resp_body = networks_admin_client.create_network(
name=name, tenant_id=tenant_id)
return resp_body['network']
@@ -287,10 +298,13 @@
[CONF.object_storage.operator_role])}]
if CONF.service_available.swift:
spec.append({'number': 1,
- 'prefix': 'swift_admin',
+ 'prefix': 'swift_operator',
'roles': (CONF.auth.tempest_roles +
- [CONF.object_storage.operator_role,
- CONF.object_storage.reseller_admin_role])})
+ [CONF.object_storage.operator_role])})
+ spec.append({'number': 1,
+ 'prefix': 'swift_reseller_admin',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.reseller_admin_role])})
if CONF.service_available.heat:
spec.append({'number': 1,
'prefix': 'stack_owner',
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 26e4569..6c79abc 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -83,7 +83,7 @@
def _get_network_id(net_name, tenant_name):
am = clients.AdminManager()
- net_cl = am.network_client
+ net_cl = am.networks_client
id_cl = am.identity_client
networks = net_cl.list_networks()
@@ -195,7 +195,7 @@
def list(self):
client = self.client
- sgs = client.list_server_groups()
+ sgs = client.list_server_groups()['server_groups']
LOG.debug("List count, %s Server Groups" % len(sgs))
return sgs
@@ -271,7 +271,7 @@
def list(self):
client = self.client
- secgrps = client.list_security_groups()
+ secgrps = client.list_security_groups()['security_groups']
secgrp_del = [grp for grp in secgrps if grp['name'] != 'default']
LOG.debug("List count, %s Security Groups" % len(secgrp_del))
return secgrp_del
@@ -297,7 +297,7 @@
def list(self):
client = self.client
- floating_ips = client.list_floating_ips()
+ floating_ips = client.list_floating_ips()['floating_ips']
LOG.debug("List count, %s Floating IPs" % len(floating_ips))
return floating_ips
@@ -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']
@@ -381,6 +381,7 @@
def __init__(self, manager, **kwargs):
super(NetworkService, self).__init__(kwargs)
self.client = manager.network_client
+ self.networks_client = manager.networks_client
def _filter_by_conf_networks(self, item_list):
if not item_list or not all(('network_id' in i for i in item_list)):
@@ -390,7 +391,7 @@
not in CONF_NETWORKS]
def list(self):
- client = self.client
+ client = self.networks_client
networks = client.list_networks(**self.tenant_filter)
networks = networks['networks']
# filter out networks declared in tempest.conf
@@ -401,7 +402,7 @@
return networks
def delete(self):
- client = self.client
+ client = self.networks_client
networks = self.list()
for n in networks:
try:
@@ -731,7 +732,7 @@
def list(self):
client = self.client
- flavors = client.list_flavors({"is_public": None})
+ flavors = client.list_flavors({"is_public": None})['flavors']
if not self.is_save_state:
# recreate list removing saved flavors
flavors = [flavor for flavor in flavors if flavor['id']
@@ -770,7 +771,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 +931,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 71aacbd..2dbcd98 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -278,7 +278,7 @@
existing = [x['name'] for x in body]
for tenant in tenants:
if tenant not in existing:
- admin.identity.create_tenant(tenant)
+ admin.identity.create_tenant(tenant)['tenant']
else:
LOG.warn("Tenant '%s' already exists in this environment" % tenant)
@@ -423,7 +423,7 @@
LOG.info("checking users")
for name, user in six.iteritems(self.users):
client = keystone_admin()
- found = client.identity.get_user(user['id'])
+ found = client.identity.get_user(user['id'])['user']
self.assertEqual(found['name'], user['name'])
self.assertEqual(found['tenantId'], user['tenant_id'])
@@ -457,7 +457,7 @@
found,
"Couldn't find expected server %s" % server['name'])
- found = client.servers.show_server(found['id'])
+ found = client.servers.show_server(found['id'])['server']
# validate neutron is enabled and ironic disabled:
if (CONF.service_available.neutron and
not CONF.baremetal.driver_enabled):
@@ -840,7 +840,7 @@
def _get_flavor_by_name(client, name):
- body = client.flavors.list_flavors()
+ body = client.flavors.list_flavors()['flavors']
for flavor in body:
if name == flavor['name']:
return flavor
@@ -869,7 +869,8 @@
kwargs['networks'] = [{'uuid': get_net_id(network)}
for network in server['networks']]
body = client.servers.create_server(
- server['name'], image_id, flavor_id, **kwargs)
+ name=server['name'], imageRef=image_id, flavorRef=flavor_id,
+ **kwargs)['server']
server_id = body['id']
client.servers.wait_for_server_status(server_id, 'ACTIVE')
# create security group(s) after server spawning
@@ -878,7 +879,7 @@
if CONF.compute.use_floatingip_for_ssh:
floating_ip_pool = server.get('floating_ip_pool')
floating_ip = client.floating_ips.create_floating_ip(
- pool_name=floating_ip_pool)
+ pool_name=floating_ip_pool)['floating_ip']
client.floating_ips.associate_floating_ip_to_server(
floating_ip['ip'], server_id)
@@ -909,14 +910,15 @@
# only create a security group if the name isn't here
# i.e. a security group may be used by another server
# only create a router if the name isn't here
- body = client.secgroups.list_security_groups()
+ body = client.secgroups.list_security_groups()['security_groups']
if any(item['name'] == secgroup['name'] for item in body):
LOG.warning("Security group '%s' already exists" %
secgroup['name'])
continue
body = client.secgroups.create_security_group(
- name=secgroup['name'], description=secgroup['description'])
+ name=secgroup['name'],
+ description=secgroup['description'])['security_group']
secgroup_id = body['id']
# for each security group, create the rules
for rule in secgroup['rules']:
@@ -944,7 +946,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
@@ -966,7 +968,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..4fcdf8b 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -65,10 +65,10 @@
# Check glance api versions
_, versions = os.image_client.get_versions()
if CONF.image_feature_enabled.api_v1 != contains_version('v1.', versions):
- print_and_or_update('api_v1', 'image_feature_enabled',
+ print_and_or_update('api_v1', 'image-feature-enabled',
not CONF.image_feature_enabled.api_v1, update)
if CONF.image_feature_enabled.api_v2 != contains_version('v2.', versions):
- print_and_or_update('api_v2', 'image_feature_enabled',
+ print_and_or_update('api_v2', 'image-feature-enabled',
not CONF.image_feature_enabled.api_v2, update)
@@ -105,11 +105,11 @@
versions = _get_api_versions(os, 'keystone')
if (CONF.identity_feature_enabled.api_v2 !=
contains_version('v2.', versions)):
- print_and_or_update('api_v2', 'identity_feature_enabled',
+ print_and_or_update('api_v2', 'identity-feature-enabled',
not CONF.identity_feature_enabled.api_v2, update)
if (CONF.identity_feature_enabled.api_v3 !=
contains_version('v3.', versions)):
- print_and_or_update('api_v3', 'identity_feature_enabled',
+ print_and_or_update('api_v3', 'identity-feature-enabled',
not CONF.identity_feature_enabled.api_v3, update)
@@ -118,11 +118,11 @@
versions = _get_api_versions(os, 'cinder')
if (CONF.volume_feature_enabled.api_v1 !=
contains_version('v1.', versions)):
- print_and_or_update('api_v1', 'volume_feature_enabled',
+ print_and_or_update('api_v1', 'volume-feature-enabled',
not CONF.volume_feature_enabled.api_v1, update)
if (CONF.volume_feature_enabled.api_v2 !=
contains_version('v2.', versions)):
- print_and_or_update('api_v2', 'volume_feature_enabled',
+ print_and_or_update('api_v2', 'volume-feature-enabled',
not CONF.volume_feature_enabled.api_v2, update)
@@ -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/accounts.py b/tempest/common/accounts.py
index 27b44f6..5fab85b 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -102,7 +102,7 @@
if resource == 'network':
hash_dict['networks'][temp_hash_key] = resources[resource]
else:
- LOG.warning('Unkown resource type %s, ignoring this field'
+ LOG.warning('Unknown resource type %s, ignoring this field'
% resource)
return hash_dict
@@ -284,7 +284,7 @@
identity_version=self.identity_version, **creds_dict)
net_creds = cred_provider.TestResources(credential)
net_clients = clients.Manager(credentials=credential)
- compute_network_client = net_clients.networks_client
+ compute_network_client = net_clients.compute_networks_client
net_name = self.hash_dict['networks'].get(hash, None)
try:
network = fixed_network.get_network_from_name(
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 05ea393..41b0529 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -18,6 +18,7 @@
from tempest_lib.common.utils import data_utils
from tempest.common import fixed_network
+from tempest.common import service_client
from tempest.common import waiters
from tempest import config
@@ -27,16 +28,21 @@
def create_test_server(clients, validatable=False, validation_resources=None,
- tenant_network=None, **kwargs):
+ tenant_network=None, wait_until=None,
+ volume_backed=False, **kwargs):
"""Common wrapper utility returning a test server.
This method is a common wrapper returning a test server that can be
pingable or sshable.
- :param clients: Client manager which provides Openstack Tempest clients.
+ :param clients: Client manager which provides OpenStack Tempest clients.
: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.
+ :param volume_backed: Whether the instance is volume backed or not.
:returns a tuple
"""
@@ -47,8 +53,8 @@
else:
name = data_utils.rand_name(__name__ + "-instance")
- flavor = kwargs.get('flavor', CONF.compute.flavor_ref)
- image_id = kwargs.get('image_id', CONF.compute.image_ref)
+ flavor = kwargs.pop('flavor', CONF.compute.flavor_ref)
+ image_id = kwargs.pop('image_id', CONF.compute.image_ref)
kwargs = fixed_network.set_networks_kwarg(
tenant_network, kwargs) or {}
@@ -78,29 +84,56 @@
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,
+ if volume_backed:
+ volume_name = data_utils.rand_name('volume')
+ volumes_client = clients.volumes_v2_client
+ if CONF.volume_feature_enabled.api_v1:
+ volumes_client = clients.volumes_client
+ volume = volumes_client.create_volume(
+ display_name=volume_name,
+ imageRef=image_id)
+ volumes_client.wait_for_volume_status(volume['volume']['id'],
+ 'available')
+
+ bd_map_v2 = [{
+ 'uuid': volume['volume']['id'],
+ 'source_type': 'volume',
+ 'destination_type': 'volume',
+ 'boot_index': 0,
+ 'delete_on_termination': True}]
+ kwargs['block_device_mapping_v2'] = bd_map_v2
+
+ # Since this is boot from volume an image does not need
+ # to be specified.
+ image_id = ''
+
+ body = clients.servers_client.create_server(name=name, imageRef=image_id,
+ flavorRef=flavor,
**kwargs)
# handle the case of multiple servers
- servers = [body]
+ servers = []
if 'min_count' in kwargs or 'max_count' in kwargs:
# Get servers created which name match with name param.
body_servers = clients.servers_client.list_servers()
servers = \
[s for s in body_servers['servers'] if s['name'].startswith(name)]
+ else:
+ body = service_client.ResponseBody(body.response, body['server'])
+ servers = [body]
# The name of the method to associate a floating IP to as server is too
# 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/cred_client.py b/tempest/common/cred_client.py
new file mode 100644
index 0000000..4d391d0
--- /dev/null
+++ b/tempest/common/cred_client.py
@@ -0,0 +1,146 @@
+# 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 abc
+
+from oslo_log import log as logging
+import six
+from tempest_lib import exceptions as lib_exc
+
+from tempest.common import cred_provider
+from tempest import config
+from tempest import exceptions
+from tempest.services.identity.v2.json import identity_client as v2_identity
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+@six.add_metaclass(abc.ABCMeta)
+class CredsClient(object):
+ """This class is a wrapper around the identity clients, to provide a
+ single interface for managing credentials in both v2 and v3 cases.
+ It's not bound to created credentials, only to a specific set of admin
+ credentials used for generating credentials.
+ """
+
+ def __init__(self, identity_client):
+ # The client implies version and credentials
+ self.identity_client = identity_client
+ self.credentials = self.identity_client.auth_provider.credentials
+
+ def create_user(self, username, password, project, email):
+ user = self.identity_client.create_user(
+ username, password, project['id'], email)
+ if 'user' in user:
+ user = user['user']
+ return user
+
+ @abc.abstractmethod
+ def create_project(self, name, description):
+ pass
+
+ def _check_role_exists(self, role_name):
+ try:
+ roles = self._list_roles()
+ role = next(r for r in roles if r['name'] == role_name)
+ except StopIteration:
+ return None
+ return role
+
+ def create_user_role(self, role_name):
+ if not self._check_role_exists(role_name):
+ self.identity_client.create_role(role_name)
+
+ def assign_user_role(self, user, project, role_name):
+ role = self._check_role_exists(role_name)
+ if not role:
+ msg = 'No "%s" role found' % role_name
+ raise lib_exc.NotFound(msg)
+ try:
+ self.identity_client.assign_user_role(project['id'], user['id'],
+ role['id'])
+ except lib_exc.Conflict:
+ LOG.debug("Role %s already assigned on project %s for user %s" % (
+ role['id'], project['id'], user['id']))
+
+ @abc.abstractmethod
+ def get_credentials(self, user, project, password):
+ pass
+
+ def delete_user(self, user_id):
+ self.identity_client.delete_user(user_id)
+
+ def _list_roles(self):
+ roles = self.identity_client.list_roles()['roles']
+ return roles
+
+
+class V2CredsClient(CredsClient):
+
+ def create_project(self, name, description):
+ tenant = self.identity_client.create_tenant(
+ name=name, description=description)['tenant']
+ return tenant
+
+ def get_credentials(self, user, project, password):
+ return cred_provider.get_credentials(
+ identity_version='v2',
+ username=user['name'], user_id=user['id'],
+ tenant_name=project['name'], tenant_id=project['id'],
+ password=password)
+
+ def delete_project(self, project_id):
+ self.identity_client.delete_tenant(project_id)
+
+
+class V3CredsClient(CredsClient):
+
+ def __init__(self, identity_client, domain_name):
+ super(V3CredsClient, self).__init__(identity_client)
+ try:
+ # Domain names must be unique, in any case a list is returned,
+ # selecting the first (and only) element
+ self.creds_domain = self.identity_client.list_domains(
+ params={'name': domain_name})['domains'][0]
+ except lib_exc.NotFound:
+ # TODO(andrea) we could probably create the domain on the fly
+ msg = "Configured domain %s could not be found" % domain_name
+ raise exceptions.InvalidConfiguration(msg)
+
+ def create_project(self, name, description):
+ project = self.identity_client.create_project(
+ name=name, description=description,
+ domain_id=self.creds_domain['id'])['project']
+ return project
+
+ def get_credentials(self, user, project, password):
+ return cred_provider.get_credentials(
+ identity_version='v3',
+ username=user['name'], user_id=user['id'],
+ project_name=project['name'], project_id=project['id'],
+ password=password,
+ project_domain_name=self.creds_domain['name'])
+
+ def delete_project(self, project_id):
+ self.identity_client.delete_project(project_id)
+
+ def _list_roles(self):
+ roles = self.identity_client.list_roles()['roles']
+ return roles
+
+
+def get_creds_client(identity_client, project_domain_name=None):
+ if isinstance(identity_client, v2_identity.IdentityClient):
+ return V2CredsClient(identity_client)
+ else:
+ return V3CredsClient(identity_client, project_domain_name)
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
index 9ec0ec6..b81830a 100644
--- a/tempest/common/fixed_network.py
+++ b/tempest/common/fixed_network.py
@@ -40,7 +40,7 @@
if not name:
raise exceptions.InvalidConfiguration()
- networks = compute_networks_client.list_networks()
+ networks = compute_networks_client.list_networks()['networks']
networks = [n for n in networks if n['label'] == name]
# Check that a network exists, else raise an InvalidConfigurationException
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 6dca3a3..3850e0e 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -12,144 +12,22 @@
# License for the specific language governing permissions and limitations
# under the License.
-import abc
import netaddr
from oslo_log import log as logging
import six
from tempest_lib import exceptions as lib_exc
from tempest import clients
+from tempest.common import cred_client
from tempest.common import cred_provider
from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
-from tempest.services.identity.v2.json import identity_client as v2_identity
CONF = config.CONF
LOG = logging.getLogger(__name__)
-@six.add_metaclass(abc.ABCMeta)
-class CredsClient(object):
- """This class is a wrapper around the identity clients, to provide a
- single interface for managing credentials in both v2 and v3 cases.
- It's not bound to created credentials, only to a specific set of admin
- credentials used for generating credentials.
- """
-
- def __init__(self, identity_client):
- # The client implies version and credentials
- self.identity_client = identity_client
- self.credentials = self.identity_client.auth_provider.credentials
-
- def create_user(self, username, password, project, email):
- user = self.identity_client.create_user(
- username, password, project['id'], email)
- if 'user' in user:
- user = user['user']
- return user
-
- @abc.abstractmethod
- def create_project(self, name, description):
- pass
-
- def _check_role_exists(self, role_name):
- try:
- roles = self._list_roles()
- role = next(r for r in roles if r['name'] == role_name)
- except StopIteration:
- return None
- return role
-
- def create_user_role(self, role_name):
- if not self._check_role_exists(role_name):
- self.identity_client.create_role(role_name)
-
- def assign_user_role(self, user, project, role_name):
- role = self._check_role_exists(role_name)
- if not role:
- msg = 'No "%s" role found' % role_name
- raise lib_exc.NotFound(msg)
- try:
- self.identity_client.assign_user_role(project['id'], user['id'],
- role['id'])
- except lib_exc.Conflict:
- LOG.debug("Role %s already assigned on project %s for user %s" % (
- role['id'], project['id'], user['id']))
-
- @abc.abstractmethod
- def get_credentials(self, user, project, password):
- pass
-
- def delete_user(self, user_id):
- self.identity_client.delete_user(user_id)
-
- def _list_roles(self):
- roles = self.identity_client.list_roles()
- return roles
-
-
-class V2CredsClient(CredsClient):
-
- def create_project(self, name, description):
- tenant = self.identity_client.create_tenant(
- name=name, description=description)
- return tenant
-
- def get_credentials(self, user, project, password):
- return cred_provider.get_credentials(
- identity_version='v2',
- username=user['name'], user_id=user['id'],
- tenant_name=project['name'], tenant_id=project['id'],
- password=password)
-
- def delete_project(self, project_id):
- self.identity_client.delete_tenant(project_id)
-
-
-class V3CredsClient(CredsClient):
-
- def __init__(self, identity_client, domain_name):
- super(V3CredsClient, self).__init__(identity_client)
- try:
- # Domain names must be unique, in any case a list is returned,
- # selecting the first (and only) element
- self.creds_domain = self.identity_client.list_domains(
- params={'name': domain_name})['domains'][0]
- except lib_exc.NotFound:
- # TODO(andrea) we could probably create the domain on the fly
- msg = "Configured domain %s could not be found" % domain_name
- raise exceptions.InvalidConfiguration(msg)
-
- def create_project(self, name, description):
- project = self.identity_client.create_project(
- name=name, description=description,
- domain_id=self.creds_domain['id'])['project']
- return project
-
- def get_credentials(self, user, project, password):
- return cred_provider.get_credentials(
- identity_version='v3',
- username=user['name'], user_id=user['id'],
- project_name=project['name'], project_id=project['id'],
- password=password,
- project_domain_name=self.creds_domain['name'])
-
- def delete_project(self, project_id):
- self.identity_client.delete_project(project_id)
-
- def _list_roles(self):
- roles = self.identity_client.list_roles()['roles']
- return roles
-
-
-def get_creds_client(identity_client, project_domain_name=None):
- if isinstance(identity_client, v2_identity.IdentityClient):
- return V2CredsClient(identity_client)
- else:
- return V3CredsClient(identity_client, project_domain_name)
-
-
class IsolatedCreds(cred_provider.CredentialProvider):
def __init__(self, identity_version=None, name=None,
@@ -162,8 +40,8 @@
self.default_admin_creds = cred_provider.get_configured_credentials(
'identity_admin', fill_in=True,
identity_version=self.identity_version)
- self.identity_admin_client, self.network_admin_client = (
- self._get_admin_clients())
+ (self.identity_admin_client, self.network_admin_client,
+ self.networks_admin_client) = self._get_admin_clients()
# Domain where isolated credentials are provisioned (v3 only).
# Use that of the admin account is None is configured.
self.creds_domain_name = None
@@ -171,7 +49,7 @@
self.creds_domain_name = (
self.default_admin_creds.project_domain_name or
CONF.auth.default_credentials_domain_name)
- self.creds_client = get_creds_client(
+ self.creds_client = cred_client.get_creds_client(
self.identity_admin_client, self.creds_domain_name)
def _get_admin_clients(self):
@@ -183,9 +61,9 @@
"""
os = clients.Manager(self.default_admin_creds)
if self.identity_version == 'v2':
- return os.identity_client, os.network_client
+ return os.identity_client, os.network_client, os.networks_client
else:
- return os.identity_v3_client, os.network_client
+ return os.identity_v3_client, os.network_client, os.networks_client
def _create_creds(self, suffix="", admin=False, roles=None):
"""Create random credentials under the following schema.
@@ -280,7 +158,7 @@
return network, subnet, router
def _create_network(self, name, tenant_id):
- resp_body = self.network_admin_client.create_network(
+ resp_body = self.networks_admin_client.create_network(
name=name, tenant_id=tenant_id)
return resp_body['network']
@@ -390,7 +268,7 @@
subnet_name)
def _clear_isolated_network(self, network_id, network_name):
- net_client = self.network_admin_client
+ net_client = self.networks_admin_client
try:
net_client.delete_network(network_id)
except lib_exc.NotFound:
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index a567c6a..3bead88 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -163,11 +163,22 @@
* dhclient
"""
# TODO(yfried): add support for dhcpcd
- suported_clients = ['udhcpc', 'dhclient']
+ supported_clients = ['udhcpc', 'dhclient']
dhcp_client = CONF.scenario.dhcp_client
- if dhcp_client not in suported_clients:
+ if dhcp_client not in supported_clients:
raise exceptions.InvalidConfiguration('%s DHCP client unsupported'
% dhcp_client)
if dhcp_client == 'udhcpc' and not fixed_ip:
raise ValueError("need to set 'fixed_ip' for udhcpc client")
return getattr(self, '_renew_lease_' + dhcp_client)(fixed_ip=fixed_ip)
+
+ def mount(self, dev_name, mount_path='/mnt'):
+ cmd_mount = 'sudo mount /dev/%s %s' % (dev_name, mount_path)
+ self.exec_command(cmd_mount)
+
+ def umount(self, mount_path='/mnt'):
+ self.exec_command('sudo umount %s' % mount_path)
+
+ def make_fs(self, dev_name, fs='ext4'):
+ cmd_mkfs = 'sudo /usr/sbin/mke2fs -t %s /dev/%s' % (fs, dev_name)
+ self.exec_command(cmd_mkfs)
diff --git a/tempest/common/validation_resources.py b/tempest/common/validation_resources.py
index d018aed..debc200 100644
--- a/tempest/common/validation_resources.py
+++ b/tempest/common/validation_resources.py
@@ -28,7 +28,7 @@
sg_name = data_utils.rand_name('securitygroup-')
sg_description = data_utils.rand_name('description-')
security_group = security_groups_client.create_security_group(
- name=sg_name, description=sg_description)
+ name=sg_name, description=sg_description)['security_group']
if add_rule:
security_group_rules_client.create_security_group_rule(
parent_group_id=security_group['id'], ip_protocol='tcp',
@@ -59,8 +59,7 @@
create_ssh_security_group(os, add_rule)
if validation_resources['floating_ip']:
floating_client = os.floating_ips_client
- validation_data['floating_ip'] = \
- floating_client.create_floating_ip()
+ validation_data.update(floating_client.create_floating_ip())
return validation_data
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 7aa4fc2..867d3f6 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -34,7 +34,7 @@
# NOTE(afazekas): UNKNOWN status possible on ERROR
# or in a very early stage.
- body = client.show_server(server_id)
+ body = client.show_server(server_id)['server']
old_status = server_status = body['status']
old_task_state = task_state = _get_task_state(body)
start_time = int(time.time())
@@ -51,7 +51,7 @@
return
# NOTE(afazekas): The instance is in "ready for action state"
# when no task in progress
- # NOTE(afazekas): Converted to string bacuse of the XML
+ # NOTE(afazekas): Converted to string because of the XML
# responses
if str(task_state) == "None":
# without state api extension 3 sec usually enough
@@ -61,7 +61,7 @@
return
time.sleep(client.build_interval)
- body = client.show_server(server_id)
+ body = client.show_server(server_id)['server']
server_status = body['status']
task_state = _get_task_state(body)
if (server_status != old_status) or (task_state != old_task_state):
@@ -102,7 +102,7 @@
start_time = int(time.time())
while True:
try:
- body = client.show_server(server_id)
+ body = client.show_server(server_id)['server']
except lib_exc.NotFound:
return
@@ -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)
@@ -175,6 +183,27 @@
raise exceptions.TimeoutException(message)
+def wait_for_snapshot_status(client, snapshot_id, status):
+ """Waits for a Snapshot to reach a given status."""
+ body = client.show_snapshot(snapshot_id)['snapshot']
+ snapshot_status = body['status']
+ start = int(time.time())
+
+ while snapshot_status != status:
+ time.sleep(client.build_interval)
+ body = client.show_snapshot(snapshot_id)['snapshot']
+ snapshot_status = body['status']
+ if snapshot_status == 'error':
+ raise exceptions.SnapshotBuildErrorException(
+ snapshot_id=snapshot_id)
+ if int(time.time()) - start >= client.build_timeout:
+ message = ('Snapshot %s failed to reach %s status (current %s) '
+ 'within the required time (%s s).' %
+ (snapshot_id, status, snapshot_status,
+ client.build_timeout))
+ raise exceptions.TimeoutException(message)
+
+
def wait_for_bm_node_status(client, node_id, attr, status):
"""Waits for a baremetal node attribute to reach given status.
diff --git a/tempest/config.py b/tempest/config.py
index ad0ddfc..b7aafeb 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 "
@@ -137,9 +137,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',
@@ -153,9 +151,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.",
deprecated_for_removal=True),
@@ -208,6 +204,12 @@
cfg.BoolOpt('api_v3',
default=True,
help='Is the v3 identity API enabled'),
+ cfg.ListOpt('api_extensions',
+ default=['all'],
+ help="A list of enabled identity extensions with a special "
+ "entry all which indicates every extension is enabled. "
+ "Empty list indicates all extensions are disabled. "
+ "To get the list of extensions run: 'keystone discover'")
]
compute_group = cfg.OptGroup(name='compute',
@@ -438,6 +440,9 @@
help='Does the test environment support creating instances '
'with multiple ports on the same network? This is only '
'valid when using Neutron.'),
+ cfg.BoolOpt('config_drive',
+ default=True,
+ help='Enable special configuration drive with metadata.'),
]
@@ -627,6 +632,12 @@
' validation resources to enable remote access',
deprecated_opts=[cfg.DeprecatedOpt('run_ssh',
group='compute')]),
+ cfg.BoolOpt('security_group',
+ default=True,
+ help='Enable/disable security groups.'),
+ cfg.BoolOpt('security_group_rules',
+ default=True,
+ help='Enable/disable security group rules.'),
cfg.StrOpt('connect_method',
default='floating',
choices=['fixed', 'floating'],
@@ -718,6 +729,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 '
@@ -873,6 +887,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")
]
@@ -897,7 +912,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),
]
@@ -1051,7 +1067,7 @@
# TODO(yfried): add support for dhcpcd
cfg.StrOpt('dhcp_client',
default='udhcpc',
- choices=["udhcpc", "dhclient"],
+ choices=["udhcpc", "dhclient", ""],
help='DHCP client used by images to renew DCHP lease. '
'If left empty, update operation will be skipped. '
'Supported clients: "udhcpc", "dhclient"')
@@ -1152,7 +1168,7 @@
title='Baremetal provisioning service options',
help='When enabling baremetal tests, Nova '
'must be configured to use the Ironic '
- 'driver. The following paremeters for the '
+ 'driver. The following parameters for the '
'[compute] section must be disabled: '
'console_output, interface_attach, '
'live_migration, pause, rescue, resize '
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 15482ab..b3d60f6 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -64,7 +64,7 @@
class InvalidIdentityVersion(TempestException):
- message = "Invalid version %(identity_version) of the identity service"
+ message = "Invalid version %(identity_version)s of the identity service"
class TimeoutException(TempestException):
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 7eb718e..fd84570 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,20 @@
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
+ cls.networks_client = cls.manager.networks_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):
@@ -172,8 +179,9 @@
LOG.debug("Creating a server (name: %s, image: %s, flavor: %s)",
name, image, flavor)
- server = self.servers_client.create_server(name, image, flavor,
- **create_kwargs)
+ server = self.servers_client.create_server(name=name, imageRef=image,
+ flavorRef=flavor,
+ **create_kwargs)['server']
if wait_on_delete:
self.addCleanup(waiters.wait_for_server_termination,
self.servers_client,
@@ -191,7 +199,7 @@
# The instance retrieved on creation is missing network
# details, necessitating retrieval after it becomes active to
# ensure correct details.
- server = self.servers_client.show_server(server['id'])
+ server = self.servers_client.show_server(server['id'])['server']
self.assertEqual(server['name'], name)
return server
@@ -201,7 +209,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,18 +223,22 @@
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):
_client = self.security_groups_client
_client_rules = self.security_group_rules_client
if secgroup_id is None:
- sgs = _client.list_security_groups()
+ sgs = _client.list_security_groups()['security_groups']
for sg in sgs:
if sg['name'] == 'default':
secgroup_id = sg['id']
@@ -254,7 +266,7 @@
rules = list()
for ruleset in rulesets:
sg_rule = _client_rules.create_security_group_rule(
- parent_group_id=secgroup_id, **ruleset)
+ parent_group_id=secgroup_id, **ruleset)['security_group_rule']
self.addCleanup(self.delete_wrapper,
_client_rules.delete_security_group_rule,
sg_rule['id'])
@@ -266,7 +278,7 @@
sg_name = data_utils.rand_name(self.__class__.__name__)
sg_desc = sg_name + " description"
secgroup = self.security_groups_client.create_security_group(
- name=sg_name, description=sg_desc)
+ name=sg_name, description=sg_desc)['security_group']
self.assertEqual(secgroup['name'], sg_name)
self.assertEqual(secgroup['description'], sg_desc)
self.addCleanup(self.delete_wrapper,
@@ -390,7 +402,7 @@
servers = servers['servers']
for server in servers:
console_output = self.servers_client.get_console_output(
- server['id'], length=None).data
+ server['id'], length=None)['output']
LOG.debug('Console output for %s\nbody=\n%s',
server['id'], console_output)
@@ -416,6 +428,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",
@@ -425,18 +452,18 @@
def nova_volume_attach(self):
volume = self.servers_client.attach_volume(
self.server['id'], volumeId=self.volume['id'], device='/dev/%s'
- % CONF.compute.volume_device_name)
+ % CONF.compute.volume_device_name)['volumeAttachment']
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,
@@ -449,9 +476,10 @@
LOG.debug("Rebuilding server (id: %s, image: %s, preserve eph: %s)",
server_id, image, preserve_ephemeral)
- self.servers_client.rebuild(server_id=server_id, image_ref=image,
- preserve_ephemeral=preserve_ephemeral,
- **rebuild_kwargs)
+ self.servers_client.rebuild_server(
+ server_id=server_id, image_ref=image,
+ preserve_ephemeral=preserve_ephemeral,
+ **rebuild_kwargs)
if wait:
waiters.wait_for_server_status(self.servers_client,
server_id, 'ACTIVE')
@@ -521,7 +549,8 @@
Nova clients
"""
- floating_ip = self.floating_ips_client.create_floating_ip(pool_name)
+ floating_ip = (self.floating_ips_client.create_floating_ip(pool_name)
+ ['floating_ip'])
self.addCleanup(self.delete_wrapper,
self.floating_ips_client.delete_floating_ip,
floating_ip['id'])
@@ -529,6 +558,29 @@
floating_ip['ip'], thing['id'])
return floating_ip
+ def create_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt'):
+ ssh_client = self.get_remote_client(server_or_ip)
+ if dev_name is not None:
+ ssh_client.make_fs(dev_name)
+ ssh_client.mount(dev_name, mount_path)
+ cmd_timestamp = 'sudo sh -c "date > %s/timestamp; sync"' % mount_path
+ ssh_client.exec_command(cmd_timestamp)
+ timestamp = ssh_client.exec_command('sudo cat %s/timestamp'
+ % mount_path)
+ if dev_name is not None:
+ ssh_client.umount(mount_path)
+ return timestamp
+
+ def get_timestamp(self, server_or_ip, dev_name=None, mount_path='/mnt'):
+ ssh_client = self.get_remote_client(server_or_ip)
+ if dev_name is not None:
+ ssh_client.mount(dev_name, mount_path)
+ timestamp = ssh_client.exec_command('sudo cat %s/timestamp'
+ % mount_path)
+ if dev_name is not None:
+ ssh_client.umount(mount_path)
+ return timestamp
+
class NetworkScenarioTest(ScenarioTest):
"""Base class for network scenario tests.
@@ -554,23 +606,25 @@
super(NetworkScenarioTest, cls).resource_setup()
cls.tenant_id = cls.manager.identity_client.tenant_id
- def _create_network(self, client=None, tenant_id=None,
- namestart='network-smoke-'):
+ def _create_network(self, client=None, networks_client=None,
+ tenant_id=None, namestart='network-smoke-'):
if not client:
client = self.network_client
+ if not networks_client:
+ networks_client = self.networks_client
if not tenant_id:
tenant_id = client.tenant_id
name = data_utils.rand_name(namestart)
- result = client.create_network(name=name, tenant_id=tenant_id)
- network = net_resources.DeletableNetwork(client=client,
- **result['network'])
+ result = networks_client.create_network(name=name, tenant_id=tenant_id)
+ network = net_resources.DeletableNetwork(
+ networks_client=networks_client, **result['network'])
self.assertEqual(network.name, name)
self.addCleanup(self.delete_wrapper, network.delete)
return network
def _list_networks(self, *args, **kwargs):
"""List networks using admin creds """
- networks_list = self.admin_manager.network_client.list_networks(
+ networks_list = self.admin_manager.networks_client.list_networks(
*args, **kwargs)
return networks_list['networks']
@@ -592,6 +646,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):
"""
@@ -1001,8 +1061,8 @@
router.update(admin_state_up=admin_state_up)
self.assertEqual(admin_state_up, router.admin_state_up)
- def create_networks(self, client=None, tenant_id=None,
- dns_nameservers=None):
+ def create_networks(self, client=None, networks_client=None,
+ tenant_id=None, dns_nameservers=None):
"""Create a network with a subnet connected to a router.
The baremetal driver is a special case since all nodes are
@@ -1027,7 +1087,9 @@
router = None
subnet = None
else:
- network = self._create_network(client=client, tenant_id=tenant_id)
+ network = self._create_network(
+ client=client, networks_client=networks_client,
+ tenant_id=tenant_id)
router = self._get_router(client=client, tenant_id=tenant_id)
subnet_kwargs = dict(network=network, client=client)
@@ -1040,7 +1102,13 @@
def create_server(self, name=None, image=None, flavor=None,
wait_on_boot=True, wait_on_delete=True,
+ network_client=None, networks_client=None,
create_kwargs=None):
+ if network_client is None:
+ network_client = self.network_client
+ if networks_client is None:
+ networks_client = self.networks_client
+
vnic_type = CONF.network.port_vnic_type
# If vnic_type is configured create port for
@@ -1051,19 +1119,16 @@
create_port_body = {'binding:vnic_type': vnic_type,
'namestart': 'port-smoke'}
if create_kwargs:
- net_client = create_kwargs.get("network_client",
- self.network_client)
-
# Convert security group names to security group ids
# to pass to create_port
if create_kwargs.get('security_groups'):
- security_groups = net_client.list_security_groups().get(
- 'security_groups')
+ security_groups = network_client.list_security_groups(
+ ).get('security_groups')
sec_dict = dict([(s['name'], s['id'])
for s in security_groups])
- sec_groups_names = [s['name'] for s in create_kwargs[
- 'security_groups']]
+ sec_groups_names = [s['name'] for s in create_kwargs.get(
+ 'security_groups')]
security_groups_ids = [sec_dict[s]
for s in sec_groups_names]
@@ -1071,15 +1136,14 @@
create_port_body[
'security_groups'] = security_groups_ids
networks = create_kwargs.get('networks')
- else:
- net_client = self.network_client
+
# If there are no networks passed to us we look up
# for the tenant's private networks and create a port
# if there is only one private network. The same behaviour
# as we would expect when passing the call to the clients
# with no networks
if not networks:
- networks = net_client.list_networks(filters={
+ networks = networks_client.list_networks(filters={
'router:external': False})
self.assertEqual(1, len(networks),
"There is more than one"
@@ -1087,11 +1151,12 @@
for net in networks:
net_id = net['uuid']
port = self._create_port(network_id=net_id,
- client=net_client,
+ client=network_client,
**create_port_body)
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,
@@ -1244,7 +1309,8 @@
waiters.wait_for_server_status(self.servers_client,
self.instance['id'], 'ACTIVE')
self.node = self.get_node(instance_id=self.instance['id'])
- self.instance = self.servers_client.show_server(self.instance['id'])
+ self.instance = (self.servers_client.show_server(self.instance['id'])
+ ['server'])
def terminate_instance(self):
self.servers_client.delete_server(self.instance['id'])
@@ -1266,7 +1332,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(
@@ -1305,9 +1374,9 @@
control_location=control_location)['encryption']
-class SwiftScenarioTest(ScenarioTest):
+class ObjectStorageScenarioTest(ScenarioTest):
"""
- Provide harness to do Swift scenario tests.
+ Provide harness to do Object Storage scenario tests.
Subclasses implement the tests that use the methods provided by this
class.
@@ -1315,7 +1384,7 @@
@classmethod
def skip_checks(cls):
- super(SwiftScenarioTest, cls).skip_checks()
+ super(ObjectStorageScenarioTest, cls).skip_checks()
if not CONF.service_available.swift:
skip_msg = ("%s skipped as swift is not available" %
cls.__name__)
@@ -1324,13 +1393,13 @@
@classmethod
def setup_credentials(cls):
cls.set_network_resources()
- super(SwiftScenarioTest, cls).setup_credentials()
+ super(ObjectStorageScenarioTest, cls).setup_credentials()
operator_role = CONF.object_storage.operator_role
cls.os_operator = cls.get_client_manager(roles=[operator_role])
@classmethod
def setup_clients(cls):
- super(SwiftScenarioTest, cls).setup_clients()
+ super(ObjectStorageScenarioTest, cls).setup_clients()
# Clients for Swift
cls.account_client = cls.os_operator.account_client
cls.container_client = cls.os_operator.container_client
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index fcde561..22d2603 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -46,7 +46,8 @@
cls.hosts_client = cls.manager.hosts_client
def _create_aggregate(self, **kwargs):
- aggregate = self.aggregates_client.create_aggregate(**kwargs)
+ aggregate = (self.aggregates_client.create_aggregate(**kwargs)
+ ['aggregate'])
self.addCleanup(self._delete_aggregate, aggregate)
aggregate_name = kwargs['name']
availability_zone = kwargs['availability_zone']
@@ -64,17 +65,19 @@
return computes[0]['host_name']
def _add_host(self, aggregate_id, host):
- aggregate = self.aggregates_client.add_host(aggregate_id, host=host)
+ aggregate = (self.aggregates_client.add_host(aggregate_id, host=host)
+ ['aggregate'])
self.addCleanup(self._remove_host, aggregate['id'], host)
self.assertIn(host, aggregate['hosts'])
def _remove_host(self, aggregate_id, host):
aggregate = self.aggregates_client.remove_host(aggregate_id, host=host)
- self.assertNotIn(host, aggregate['hosts'])
+ self.assertNotIn(host, aggregate['aggregate']['hosts'])
def _check_aggregate_details(self, aggregate, aggregate_name, azone,
hosts, metadata):
- aggregate = self.aggregates_client.show_aggregate(aggregate['id'])
+ aggregate = (self.aggregates_client.show_aggregate(aggregate['id'])
+ ['aggregate'])
self.assertEqual(aggregate_name, aggregate['name'])
self.assertEqual(azone, aggregate['availability_zone'])
self.assertEqual(hosts, aggregate['hosts'])
@@ -88,13 +91,14 @@
metadata=meta)
for key, value in meta.items():
- self.assertEqual(meta[key], aggregate['metadata'][key])
+ self.assertEqual(meta[key],
+ aggregate['aggregate']['metadata'][key])
def _update_aggregate(self, aggregate, aggregate_name,
availability_zone):
aggregate = self.aggregates_client.update_aggregate(
aggregate['id'], name=aggregate_name,
- availability_zone=availability_zone)
+ availability_zone=availability_zone)['aggregate']
self.assertEqual(aggregate['name'], aggregate_name)
self.assertEqual(aggregate['availability_zone'], availability_zone)
return aggregate
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index 346f56b..c0b5a44 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -101,14 +101,15 @@
def get_flavor_ephemeral_size(self):
"""Returns size of the ephemeral partition in GiB."""
f_id = self.instance['flavor']['id']
- flavor = self.flavors_client.show_flavor(f_id)
+ flavor = self.flavors_client.show_flavor(f_id)['flavor']
ephemeral = flavor.get('OS-FLV-EXT-DATA:ephemeral')
if not ephemeral or ephemeral == 'N/A':
return None
return int(ephemeral)
def add_floating_ip(self):
- floating_ip = self.floating_ips_client.create_floating_ip()
+ floating_ip = (self.floating_ips_client.create_floating_ip()
+ ['floating_ip'])
self.floating_ips_client.associate_floating_ip_to_server(
floating_ip['ip'], self.instance['id'])
return floating_ip['ip']
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 8e91a6d..f6d9f88 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -88,9 +88,9 @@
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:]
+ login_url = parse.urljoin(CONF.dashboard.dashboard_url, parser.login)
# Prepare login form request
req = request.Request(login_url)
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index 4e6358e..63dd4f0 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -87,7 +87,8 @@
# Since no traffic is tested, we don't need to actually add rules to
# secgroup
secgroup = self.security_groups_client.create_security_group(
- name='secgroup-%s' % name, description='secgroup-desc-%s' % name)
+ name='secgroup-%s' % name,
+ description='secgroup-desc-%s' % name)['security_group']
self.addCleanupClass(self.security_groups_client.delete_security_group,
secgroup['id'])
create_kwargs = {
@@ -98,9 +99,9 @@
create_kwargs = fixed_network.set_networks_kwarg(network,
create_kwargs)
self.servers_client.create_server(
- name,
- self.image,
- flavor_id,
+ name=name,
+ imageRef=self.image,
+ flavorRef=flavor_id,
**create_kwargs)
# needed because of bug 1199788
params = {'name': name}
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index f868382..eac8311 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -62,24 +62,28 @@
self.assertIn(self.server['id'], [x['id'] for x in servers])
def nova_show(self):
- got_server = self.servers_client.show_server(self.server['id'])
+ got_server = (self.servers_client.show_server(self.server['id'])
+ ['server'])
+ 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):
- self.servers_client.reboot(self.server['id'], 'SOFT')
+ self.servers_client.reboot_server(self.server['id'], 'SOFT')
self._wait_for_server_status('ACTIVE')
def check_partitions(self):
@@ -95,7 +99,8 @@
self.server['id'], secgroup['name'])
def wait_for_secgroup_add():
- body = self.servers_client.show_server(self.server['id'])
+ body = (self.servers_client.show_server(self.server['id'])
+ ['server'])
return {'name': secgroup['name']} in body['security_groups']
if not test.call_until_true(wait_for_secgroup_add,
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 3d233d8..62b2976 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -100,18 +100,19 @@
@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')
@test.services('compute', 'network')
def test_server_connectivity_reboot(self):
self._setup_network_and_servers()
- self.servers_client.reboot(self.server['id'], reboot_type='SOFT')
+ self.servers_client.reboot_server(self.server['id'],
+ reboot_type='SOFT')
self._wait_server_status_and_check_network_connectivity()
@test.idempotent_id('88a529c2-1daa-4c85-9aec-d541ba3eb699')
@@ -119,8 +120,8 @@
def test_server_connectivity_rebuild(self):
self._setup_network_and_servers()
image_ref_alt = CONF.compute.image_ref_alt
- self.servers_client.rebuild(self.server['id'],
- image_ref=image_ref_alt)
+ self.servers_client.rebuild_server(self.server['id'],
+ image_ref=image_ref_alt)
self._wait_server_status_and_check_network_connectivity()
@test.idempotent_id('2b2642db-6568-4b35-b812-eceed3fa20ce')
@@ -159,8 +160,9 @@
msg = "Skipping test - flavor_ref and flavor_ref_alt are identical"
raise self.skipException(msg)
self._setup_network_and_servers()
- self.servers_client.resize(self.server['id'], flavor_ref=resize_flavor)
+ self.servers_client.resize_server(self.server['id'],
+ 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 c194103..31ccd5b 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)
@@ -245,7 +247,7 @@
old_port = port_list[0]
interface = self.interface_client.create_interface(
server_id=server['id'],
- net_id=self.new_net.id)
+ net_id=self.new_net.id)['interfaceAttachment']
self.addCleanup(self.network_client.wait_for_resource_deletion,
'port',
interface['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,87 @@
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.requires_ext(service='network', extension='l3_agent_scheduler')
+ @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_swift_basic_ops.py b/tempest/scenario/test_object_storage_basic_ops.py
similarity index 97%
rename from tempest/scenario/test_swift_basic_ops.py
rename to tempest/scenario/test_object_storage_basic_ops.py
index 69e0c4c..49768c5 100644
--- a/tempest/scenario/test_swift_basic_ops.py
+++ b/tempest/scenario/test_object_storage_basic_ops.py
@@ -24,7 +24,7 @@
LOG = logging.getLogger(__name__)
-class TestSwiftBasicOps(manager.SwiftScenarioTest):
+class TestObjectStorageBasicOps(manager.ObjectStorageScenarioTest):
"""
Test swift basic ops.
* get swift stat.
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_object_storage_telemetry_middleware.py
similarity index 92%
rename from tempest/scenario/test_swift_telemetry_middleware.py
rename to tempest/scenario/test_object_storage_telemetry_middleware.py
index 29ce1a0..3376a7c 100644
--- a/tempest/scenario/test_swift_telemetry_middleware.py
+++ b/tempest/scenario/test_object_storage_telemetry_middleware.py
@@ -34,7 +34,7 @@
NOTIFICATIONS_SLEEP = 1
-class TestSwiftTelemetry(manager.SwiftScenarioTest):
+class TestObjectStorageTelemetry(manager.ObjectStorageScenarioTest):
"""
Test that swift uses the ceilometer middleware.
* create container.
@@ -45,18 +45,15 @@
@classmethod
def skip_checks(cls):
- super(TestSwiftTelemetry, cls).skip_checks()
+ super(TestObjectStorageTelemetry, cls).skip_checks()
if not CONF.service_available.ceilometer:
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):
- super(TestSwiftTelemetry, cls).setup_clients()
+ super(TestObjectStorageTelemetry, cls).setup_clients()
cls.telemetry_client = cls.os_operator.telemetry_client
def _confirm_notifications(self, container_name, obj_name):
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 18fd09d..a35c0b2 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)
@@ -247,11 +244,13 @@
{'uuid': tenant.network.id},
],
'key_name': tenant.keypair['name'],
- 'security_groups': security_groups_names,
- 'tenant_id': tenant.creds.tenant_id,
- 'network_client': tenant.manager.network_client
+ 'security_groups': security_groups_names
}
- server = self.create_server(name=name, create_kwargs=create_kwargs)
+ server = self.create_server(
+ name=name,
+ network_client=tenant.manager.network_client,
+ networks_client=tenant.manager.networks_client,
+ create_kwargs=create_kwargs)
self.assertEqual(
sorted([s['name'] for s in security_groups]),
sorted([s['name'] for s in server['security_groups']]))
@@ -291,7 +290,8 @@
def _create_tenant_network(self, tenant):
network, subnet, router = self.create_networks(
- client=tenant.manager.network_client)
+ client=tenant.manager.network_client,
+ networks_client=tenant.manager.networks_client)
tenant.set_network(network, subnet, router)
def _set_compute_context(self, tenant):
@@ -556,3 +556,44 @@
username=ssh_login,
private_key=private_key,
should_connect=True)
+
+ @test.requires_ext(service='network', extension='port-security')
+ @test.idempotent_id('7c811dcc-263b-49a3-92d2-1b4d8405f50c')
+ @test.services('compute', 'network')
+ def test_port_security_disable_security_group(self):
+ """
+ This test verifies port_security_enabled=False disables
+ the default security group rules.
+ """
+ new_tenant = self.primary_tenant
+
+ # Create server
+ name = 'server-{tenant}-gen-1'.format(
+ tenant=new_tenant.creds.tenant_name
+ )
+ name = data_utils.rand_name(name)
+ server = self._create_server(name, new_tenant)
+
+ access_point_ssh = self._connect_to_access_point(new_tenant)
+ server_id = server['id']
+ port_id = self._list_ports(device_id=server_id)[0]['id']
+
+ # Flip the port's port security and check connectivity
+ try:
+ self.network_client.update_port(port_id,
+ port_security_enabled=True,
+ security_groups=[])
+ self._check_connectivity(access_point=access_point_ssh,
+ ip=self._get_server_ip(server),
+ should_succeed=False)
+
+ self.network_client.update_port(port_id,
+ port_security_enabled=False,
+ security_groups=[])
+ self._check_connectivity(
+ access_point=access_point_ssh,
+ ip=self._get_server_ip(server))
+ except Exception:
+ for tenant in self.tenants.values():
+ self._log_console_output(servers=tenant.servers)
+ raise
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index e405cf5..c83dbb1 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -58,12 +58,12 @@
resize_flavor = CONF.compute.flavor_ref_alt
LOG.debug("Resizing instance %s from flavor %s to flavor %s",
instance['id'], instance['flavor']['id'], resize_flavor)
- self.servers_client.resize(instance_id, resize_flavor)
+ self.servers_client.resize_server(instance_id, resize_flavor)
waiters.wait_for_server_status(self.servers_client, instance_id,
'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')
@@ -81,19 +81,22 @@
self.servers_client.suspend_server(instance_id)
waiters.wait_for_server_status(self.servers_client, instance_id,
'SUSPENDED')
- fetched_instance = self.servers_client.show_server(instance_id)
+ fetched_instance = (self.servers_client.show_server(instance_id)
+ ['server'])
LOG.debug("Resuming instance %s. Current status: %s",
instance_id, fetched_instance['status'])
self.servers_client.resume_server(instance_id)
waiters.wait_for_server_status(self.servers_client, instance_id,
'ACTIVE')
- fetched_instance = self.servers_client.show_server(instance_id)
+ fetched_instance = (self.servers_client.show_server(instance_id)
+ ['server'])
LOG.debug("Suspending instance %s. Current status: %s",
instance_id, fetched_instance['status'])
self.servers_client.suspend_server(instance_id)
waiters.wait_for_server_status(self.servers_client, instance_id,
'SUSPENDED')
- fetched_instance = self.servers_client.show_server(instance_id)
+ fetched_instance = (self.servers_client.show_server(instance_id)
+ ['server'])
LOG.debug("Resuming instance %s. Current status: %s",
instance_id, fetched_instance['status'])
self.servers_client.resume_server(instance_id)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 3019cc4..e2f8adb 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import json
+
from oslo_log import log as logging
from tempest import config
@@ -39,6 +41,7 @@
* Launch an instance
* Perform ssh to instance
* Verify metadata service
+ * Verify metadata on config_drive
* Terminate the instance
"""
@@ -72,9 +75,12 @@
def boot_instance(self):
# Create server with image and flavor from input scenario
security_groups = [{'name': self.security_group['name']}]
+ self.md = {'meta1': 'data1', 'meta2': 'data2', 'metaN': 'dataN'}
create_kwargs = {
'key_name': self.keypair['name'],
- 'security_groups': security_groups
+ 'security_groups': security_groups,
+ 'config_drive': CONF.compute_feature_enabled.config_drive,
+ 'metadata': self.md
}
self.instance = self.create_server(image=self.image_ref,
flavor=self.flavor_ref,
@@ -83,7 +89,8 @@
def verify_ssh(self):
if self.run_ssh:
# Obtain a floating IP
- self.floating_ip = self.floating_ips_client.create_floating_ip()
+ self.floating_ip = (self.floating_ips_client.create_floating_ip()
+ ['floating_ip'])
self.addCleanup(self.delete_wrapper,
self.floating_ips_client.delete_floating_ip,
self.floating_ip['id'])
@@ -118,6 +125,22 @@
'verify metadata on server. '
'%s is empty.' % md_url)
+ def verify_metadata_on_config_drive(self):
+ if self.run_ssh and CONF.compute_feature_enabled.config_drive:
+ # Verify metadata on config_drive
+ cmd_blkid = 'blkid -t LABEL=config-2 -o device'
+ dev_name = self.ssh_client.exec_command(cmd_blkid)
+ dev_name = dev_name.rstrip()
+ self.ssh_client.exec_command('sudo mount %s /mnt' % dev_name)
+ cmd_md = 'sudo cat /mnt/openstack/latest/meta_data.json'
+ result = self.ssh_client.exec_command(cmd_md)
+ self.ssh_client.exec_command('sudo umount /mnt')
+ result = json.loads(result)
+ self.assertIn('meta', result)
+ msg = ('Failed while verifying metadata on config_drive on server.'
+ ' Result of command "%s" is NOT "%s".' % (cmd_md, self.md))
+ self.assertEqual(self.md, result['meta'], msg)
+
@test.idempotent_id('7fff3fb3-91d8-4fd0-bd7d-0204f1f180ba')
@test.attr(type='smoke')
@test.services('compute', 'network')
@@ -127,4 +150,5 @@
self.boot_instance()
self.verify_ssh()
self.verify_metadata()
+ self.verify_metadata_on_config_drive()
self.servers_client.delete_server(self.instance['id'])
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index 02ee7b9..dbc9bbb 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -30,23 +30,13 @@
"""
This test shelves then unshelves a Nova instance
The following is the scenario outline:
- * boot a instance and create a timestamp file in it
+ * boot an instance and create a timestamp file in it
* shelve the instance
* unshelve the instance
* check the existence of the timestamp file in the unshelved instance
"""
- def _write_timestamp(self, server_or_ip):
- ssh_client = self.get_remote_client(server_or_ip)
- ssh_client.exec_command('date > /tmp/timestamp; sync')
- self.timestamp = ssh_client.exec_command('cat /tmp/timestamp')
-
- def _check_timestamp(self, server_or_ip):
- ssh_client = self.get_remote_client(server_or_ip)
- got_timestamp = ssh_client.exec_command('cat /tmp/timestamp')
- self.assertEqual(self.timestamp, got_timestamp)
-
def _shelve_then_unshelve_server(self, server):
self.servers_client.shelve_server(server['id'])
offload_time = CONF.compute.shelved_offload_time
@@ -64,39 +54,62 @@
waiters.wait_for_server_status(self.servers_client, server['id'],
'ACTIVE')
- @test.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
- @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
- 'Shelve is not available.')
- @test.services('compute', 'network', 'image')
- def test_shelve_instance(self):
+ def _create_server_then_shelve_and_unshelve(self, boot_from_volume=False):
self.keypair = self.create_keypair()
self.security_group = self._create_security_group()
security_groups = [{'name': self.security_group['name']}]
-
create_kwargs = {
'key_name': self.keypair['name'],
'security_groups': security_groups
}
- server = self.create_server(image=CONF.compute.image_ref,
- create_kwargs=create_kwargs)
+
+ if boot_from_volume:
+ volume = self.create_volume(size=CONF.volume.volume_size,
+ imageRef=CONF.compute.image_ref)
+ bd_map = [{
+ 'device_name': 'vda',
+ 'volume_id': volume['id'],
+ 'delete_on_termination': '0'}]
+
+ create_kwargs['block_device_mapping'] = bd_map
+ server = self.create_server(create_kwargs=create_kwargs)
+ else:
+ server = self.create_server(image=CONF.compute.image_ref,
+ create_kwargs=create_kwargs)
if CONF.compute.use_floatingip_for_ssh:
- floating_ip = self.floating_ips_client.create_floating_ip()
+ 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'])
- self._write_timestamp(floating_ip['ip'])
+ timestamp = self.create_timestamp(floating_ip['ip'])
else:
- self._write_timestamp(server)
+ timestamp = self.create_timestamp(server)
# Prevent bug #1257594 from coming back
# Unshelve used to boot the instance with the original image, not
# with the instance snapshot
self._shelve_then_unshelve_server(server)
if CONF.compute.use_floatingip_for_ssh:
- self._check_timestamp(floating_ip['ip'])
+ timestamp2 = self.get_timestamp(floating_ip['ip'])
else:
- self._check_timestamp(server)
+ timestamp2 = self.get_timestamp(server)
+ self.assertEqual(timestamp, timestamp2)
+
+ @test.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
+ @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+ 'Shelve is not available.')
+ @test.services('compute', 'network', 'image')
+ def test_shelve_instance(self):
+ self._create_server_then_shelve_and_unshelve()
+
+ @test.idempotent_id('c1b6318c-b9da-490b-9c67-9339b627271f')
+ @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+ 'Shelve is not available.')
+ @test.services('compute', 'volume', 'network', 'image')
+ def test_shelve_volume_backed_instance(self):
+ self._create_server_then_shelve_and_unshelve(boot_from_volume=True)
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 1298faa..79b809f 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -29,7 +29,7 @@
"""
This test is for snapshotting an instance and booting with it.
The following is the scenario outline:
- * boot a instance and create a timestamp file in it
+ * boot an instance and create a timestamp file in it
* snapshot the instance
* boot a second instance from the snapshot
* check the existence of the timestamp file in the second instance
@@ -47,32 +47,22 @@
def _add_keypair(self):
self.keypair = self.create_keypair()
- def _write_timestamp(self, server_or_ip):
- ssh_client = self.get_remote_client(server_or_ip)
- ssh_client.exec_command('date > /tmp/timestamp; sync')
- self.timestamp = ssh_client.exec_command('cat /tmp/timestamp')
-
- def _check_timestamp(self, server_or_ip):
- ssh_client = self.get_remote_client(server_or_ip)
- got_timestamp = ssh_client.exec_command('cat /tmp/timestamp')
- self.assertEqual(self.timestamp, got_timestamp)
-
@test.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
@test.services('compute', 'network', 'image')
def test_snapshot_pattern(self):
- # prepare for booting a instance
+ # prepare for booting an instance
self._add_keypair()
self.security_group = self._create_security_group()
- # boot a instance and create a timestamp file in it
+ # boot an instance and create a timestamp file in it
server = self._boot_image(CONF.compute.image_ref)
if CONF.compute.use_floatingip_for_ssh:
fip_for_server = self.create_floating_ip(server)
- self._write_timestamp(fip_for_server['ip'])
+ timestamp = self.create_timestamp(fip_for_server['ip'])
else:
- self._write_timestamp(server)
+ timestamp = self.create_timestamp(server)
# snapshot the instance
snapshot_image = self.create_server_snapshot(server=server)
@@ -83,6 +73,7 @@
# check the existence of the timestamp file in the second instance
if CONF.compute.use_floatingip_for_ssh:
fip_for_snapshot = self.create_floating_ip(server_from_snapshot)
- self._check_timestamp(fip_for_snapshot['ip'])
+ timestamp2 = self.get_timestamp(fip_for_snapshot['ip'])
else:
- self._check_timestamp(server_from_snapshot)
+ timestamp2 = self.get_timestamp(server_from_snapshot)
+ self.assertEqual(timestamp, timestamp2)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index a7bdba3..a4f9896 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -74,9 +74,6 @@
def _add_keypair(self):
self.keypair = self.create_keypair()
- def _ssh_to_server(self, server_or_ip):
- return self.get_remote_client(server_or_ip)
-
def _create_volume_snapshot(self, volume):
snapshot_name = data_utils.rand_name('scenario-snapshot')
_, snapshot = self.snapshots_client.create_snapshot(
@@ -106,7 +103,7 @@
def _attach_volume(self, server, volume):
attached_volume = self.servers_client.attach_volume(
server['id'], volumeId=volume['id'], device='/dev/%s'
- % CONF.compute.volume_device_name)
+ % CONF.compute.volume_device_name)['volumeAttachment']
self.assertEqual(volume['id'], attached_volume['id'])
self._wait_for_volume_status(attached_volume, 'in-use')
@@ -127,30 +124,13 @@
CONF.compute.build_interval):
raise exceptions.TimeoutException
- def _create_timestamp(self, server_or_ip):
- ssh_client = self._ssh_to_server(server_or_ip)
- ssh_client.exec_command('sudo /usr/sbin/mkfs.ext4 /dev/%s'
- % CONF.compute.volume_device_name)
- ssh_client.exec_command('sudo mount /dev/%s /mnt'
- % CONF.compute.volume_device_name)
- ssh_client.exec_command('sudo sh -c "date > /mnt/timestamp;sync"')
- self.timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
- ssh_client.exec_command('sudo umount /mnt')
-
- def _check_timestamp(self, server_or_ip):
- ssh_client = self._ssh_to_server(server_or_ip)
- ssh_client.exec_command('sudo mount /dev/%s /mnt'
- % CONF.compute.volume_device_name)
- got_timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
- self.assertEqual(self.timestamp, got_timestamp)
-
@decorators.skip_because(bug="1205344")
@test.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
@tempest.test.services('compute', 'network', 'volume', 'image')
def test_stamp_pattern(self):
- # prepare for booting a instance
+ # prepare for booting an instance
self._add_keypair()
self.security_group = self._create_security_group()
@@ -167,7 +147,8 @@
self._attach_volume(server, volume)
self._wait_for_volume_available_on_the_system(ip_for_server)
- self._create_timestamp(ip_for_server)
+ timestamp = self.create_timestamp(ip_for_server,
+ CONF.compute.volume_device_name)
self._detach_volume(server, volume)
# snapshot the volume
@@ -196,4 +177,6 @@
self._wait_for_volume_available_on_the_system(ip_for_snapshot)
# check the existence of the timestamp file in the volume2
- self._check_timestamp(ip_for_snapshot)
+ timestamp2 = self.get_timestamp(ip_for_snapshot,
+ CONF.compute.volume_device_name)
+ self.assertEqual(timestamp, timestamp2)
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index f69b7d2..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,27 +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()
- 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
@@ -174,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 b1246d2..2841060 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,15 +57,15 @@
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)
- _flavor = self.flavors_client.show_flavor(flavor_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)
@@ -91,8 +91,8 @@
def test_create_server_metadata(self):
name = rand_name('instance')
self.servers_client.create_server(name=name,
- flavor_ref=self.flavor_ref,
- image_ref=self.image_ref)
+ flavorRef=self.flavor_ref,
+ imageRef=self.image_ref)
"""
validchars = "-_.{ascii}{digit}".format(ascii=string.ascii_letters,
digit=string.digits)
@@ -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,
@@ -148,7 +148,7 @@
"""
if not hasattr(self, '_scenario_flavors'):
try:
- flavors = self.flavors_client.list_flavors()
+ flavors = self.flavors_client.list_flavors()['flavors']
self._scenario_flavors = [
(self._normalize_name(f['name']), dict(flavor_ref=f['id']))
for f in flavors if re.search(self.flavor_pattern,
diff --git a/tempest/services/botoclients.py b/tempest/services/botoclients.py
index ede464f..bedb9ec 100644
--- a/tempest/services/botoclients.py
+++ b/tempest/services/botoclients.py
@@ -94,14 +94,15 @@
:return: EC2 credentials
"""
ec2_cred_list = identity_client.list_user_ec2_credentials(
- identity_client.user_id)
+ identity_client.user_id)['credentials']
for cred in ec2_cred_list:
if cred['tenant_id'] == identity_client.tenant_id:
ec2_cred = cred
break
else:
- ec2_cred = identity_client.create_user_ec2_credentials(
+ ec2_cred = (identity_client.create_user_ec2_credentials(
identity_client.user_id, identity_client.tenant_id)
+ ['credential'])
if not all((ec2_cred, ec2_cred['access'], ec2_cred['secret'])):
raise lib_exc.NotFound("Unable to get access and secret keys")
else:
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 4114b8b..c9895db 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -27,14 +27,14 @@
resp, body = self.get("os-aggregates")
body = json.loads(body)
self.validate_response(schema.list_aggregates, resp, body)
- return service_client.ResponseBodyList(resp, body['aggregates'])
+ return service_client.ResponseBody(resp, body)
def show_aggregate(self, aggregate_id):
"""Get details of the given aggregate."""
resp, body = self.get("os-aggregates/%s" % aggregate_id)
body = json.loads(body)
self.validate_response(schema.get_aggregate, resp, body)
- return service_client.ResponseBody(resp, body['aggregate'])
+ return service_client.ResponseBody(resp, body)
def create_aggregate(self, **kwargs):
"""Creates a new aggregate."""
@@ -43,7 +43,7 @@
body = json.loads(body)
self.validate_response(schema.create_aggregate, resp, body)
- return service_client.ResponseBody(resp, body['aggregate'])
+ return service_client.ResponseBody(resp, body)
def update_aggregate(self, aggregate_id, **kwargs):
"""Update a aggregate."""
@@ -52,7 +52,7 @@
body = json.loads(body)
self.validate_response(schema.update_aggregate, resp, body)
- return service_client.ResponseBody(resp, body['aggregate'])
+ return service_client.ResponseBody(resp, body)
def delete_aggregate(self, aggregate_id):
"""Deletes the given aggregate."""
@@ -79,7 +79,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.aggregate_add_remove_host, resp, body)
- return service_client.ResponseBody(resp, body['aggregate'])
+ return service_client.ResponseBody(resp, body)
def remove_host(self, aggregate_id, **kwargs):
"""Removes a host from the given aggregate."""
@@ -88,7 +88,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.aggregate_add_remove_host, resp, body)
- return service_client.ResponseBody(resp, body['aggregate'])
+ return service_client.ResponseBody(resp, body)
def set_metadata(self, aggregate_id, **kwargs):
"""Replaces the aggregate's existing metadata with new metadata."""
@@ -97,4 +97,4 @@
post_body)
body = json.loads(body)
self.validate_response(schema.aggregate_set_metadata, resp, body)
- return service_client.ResponseBody(resp, body['aggregate'])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 1422944..2c32d30 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -39,13 +39,13 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(_schema, resp, body)
- return service_client.ResponseBodyList(resp, body['flavors'])
+ return service_client.ResponseBody(resp, body)
def show_flavor(self, flavor_id):
resp, body = self.get("flavors/%s" % flavor_id)
body = json.loads(body)
self.validate_response(schema.create_get_flavor_details, resp, body)
- return service_client.ResponseBody(resp, body['flavor'])
+ return service_client.ResponseBody(resp, body)
def create_flavor(self, **kwargs):
"""Creates a new flavor or instance type.
@@ -64,7 +64,7 @@
body = json.loads(body)
self.validate_response(schema.create_get_flavor_details, resp, body)
- return service_client.ResponseBody(resp, body['flavor'])
+ return service_client.ResponseBody(resp, body)
def delete_flavor(self, flavor_id):
"""Deletes the given flavor."""
@@ -76,7 +76,7 @@
# Did not use show_flavor(id) for verification as it gives
# 200 ok even for deleted id. LP #981263
# we can remove the loop here and use get by ID when bug gets sortedout
- flavors = self.list_flavors(detail=True)
+ flavors = self.list_flavors(detail=True)['flavors']
for flavor in flavors:
if flavor['id'] == id:
return False
@@ -95,7 +95,7 @@
body = json.loads(body)
self.validate_response(schema_extra_specs.set_get_flavor_extra_specs,
resp, body)
- return service_client.ResponseBody(resp, body['extra_specs'])
+ return service_client.ResponseBody(resp, body)
def list_flavor_extra_specs(self, flavor_id):
"""Gets extra Specs details of the mentioned flavor."""
@@ -103,7 +103,7 @@
body = json.loads(body)
self.validate_response(schema_extra_specs.set_get_flavor_extra_specs,
resp, body)
- return service_client.ResponseBody(resp, body['extra_specs'])
+ return service_client.ResponseBody(resp, body)
def show_flavor_extra_spec(self, flavor_id, key):
"""Gets extra Specs key-value of the mentioned flavor and key."""
@@ -138,7 +138,7 @@
body = json.loads(body)
self.validate_response(schema_access.add_remove_list_flavor_access,
resp, body)
- return service_client.ResponseBodyList(resp, body['flavor_access'])
+ return service_client.ResponseBody(resp, body)
def add_flavor_access(self, flavor_id, tenant_id):
"""Add flavor access for the specified tenant."""
@@ -152,7 +152,7 @@
body = json.loads(body)
self.validate_response(schema_access.add_remove_list_flavor_access,
resp, body)
- return service_client.ResponseBodyList(resp, body['flavor_access'])
+ return service_client.ResponseBody(resp, body)
def remove_flavor_access(self, flavor_id, tenant_id):
"""Remove flavor access from the specified tenant."""
@@ -166,4 +166,4 @@
body = json.loads(body)
self.validate_response(schema_access.add_remove_list_flavor_access,
resp, body)
- return service_client.ResponseBody(resp, body['flavor_access'])
+ return service_client.ResponseBody(resp, body)
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/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 2193949..69d06a3 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -32,7 +32,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_floating_ips, resp, body)
- return service_client.ResponseBodyList(resp, body['floating_ips'])
+ return service_client.ResponseBody(resp, body)
def show_floating_ip(self, floating_ip_id):
"""Get the details of a floating IP."""
@@ -40,7 +40,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.create_get_floating_ip, resp, body)
- return service_client.ResponseBody(resp, body['floating_ip'])
+ return service_client.ResponseBody(resp, body)
def create_floating_ip(self, pool_name=None):
"""Allocate a floating IP to the project."""
@@ -50,7 +50,7 @@
resp, body = self.post(url, post_body)
body = json.loads(body)
self.validate_response(schema.create_get_floating_ip, resp, body)
- return service_client.ResponseBody(resp, body['floating_ip'])
+ return service_client.ResponseBody(resp, body)
def delete_floating_ip(self, floating_ip_id):
"""Deletes the provided floating IP from the project."""
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index e894a5c..ba06f23 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -32,39 +32,39 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(_schema, resp, body)
- return service_client.ResponseBodyList(resp, body['hypervisors'])
+ return service_client.ResponseBody(resp, body)
def show_hypervisor(self, hypervisor_id):
"""Display the details of the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s' % hypervisor_id)
body = json.loads(body)
self.validate_response(schema.get_hypervisor, resp, body)
- return service_client.ResponseBody(resp, body['hypervisor'])
+ return service_client.ResponseBody(resp, body)
def list_servers_on_hypervisor(self, hypervisor_name):
"""List instances belonging to the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/servers' % hypervisor_name)
body = json.loads(body)
self.validate_response(schema.get_hypervisors_servers, resp, body)
- return service_client.ResponseBodyList(resp, body['hypervisors'])
+ return service_client.ResponseBody(resp, body)
def show_hypervisor_statistics(self):
"""Get hypervisor statistics over all compute nodes."""
resp, body = self.get('os-hypervisors/statistics')
body = json.loads(body)
self.validate_response(schema.get_hypervisor_statistics, resp, body)
- return service_client.ResponseBody(resp, body['hypervisor_statistics'])
+ return service_client.ResponseBody(resp, body)
def show_hypervisor_uptime(self, hypervisor_id):
"""Display the uptime of the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/uptime' % hypervisor_id)
body = json.loads(body)
self.validate_response(schema.get_hypervisor_uptime, resp, body)
- return service_client.ResponseBody(resp, body['hypervisor'])
+ return service_client.ResponseBody(resp, body)
def search_hypervisor(self, hypervisor_name):
"""Search specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/search' % hypervisor_name)
body = json.loads(body)
self.validate_response(schema.list_search_hypervisors, resp, body)
- return service_client.ResponseBodyList(resp, body['hypervisors'])
+ 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/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index f06a675..4d9625e 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -28,13 +28,11 @@
body = json.loads(body)
self.validate_response(schema.list_instance_usage_audit_log,
resp, body)
- return service_client.ResponseBody(resp,
- body["instance_usage_audit_logs"])
+ return service_client.ResponseBody(resp, body)
def show_instance_usage_audit_log(self, time_before):
url = 'os-instance_usage_audit_log/%s' % time_before
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.get_instance_usage_audit_log, resp, body)
- return service_client.ResponseBody(resp,
- body["instance_usage_audit_log"])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index c437c08..fe076d8 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -16,7 +16,6 @@
from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import interfaces as schema
-from tempest.api_schema.response.compute.v2_1 import servers as servers_schema
from tempest.common import service_client
@@ -26,8 +25,7 @@
resp, body = self.get('servers/%s/os-interface' % server_id)
body = json.loads(body)
self.validate_response(schema.list_interfaces, resp, body)
- return service_client.ResponseBodyList(resp,
- body['interfaceAttachments'])
+ return service_client.ResponseBody(resp, body)
def create_interface(self, server_id, **kwargs):
post_body = {'interfaceAttachment': kwargs}
@@ -36,35 +34,17 @@
body=post_body)
body = json.loads(body)
self.validate_response(schema.get_create_interfaces, resp, body)
- return service_client.ResponseBody(resp, body['interfaceAttachment'])
+ return service_client.ResponseBody(resp, body)
def show_interface(self, server_id, port_id):
resp, body = self.get('servers/%s/os-interface/%s' % (server_id,
port_id))
body = json.loads(body)
self.validate_response(schema.get_create_interfaces, resp, body)
- return service_client.ResponseBody(resp, body['interfaceAttachment'])
+ return service_client.ResponseBody(resp, body)
def delete_interface(self, server_id, port_id):
resp, body = self.delete('servers/%s/os-interface/%s' % (server_id,
port_id))
self.validate_response(schema.delete_interface, resp, body)
return service_client.ResponseBody(resp, body)
-
- def add_fixed_ip(self, server_id, **kwargs):
- """Add a fixed IP to input server instance."""
- post_body = json.dumps({'addFixedIp': kwargs})
- resp, body = self.post('servers/%s/action' % server_id,
- post_body)
- self.validate_response(servers_schema.server_actions_common_schema,
- resp, body)
- return service_client.ResponseBody(resp, body)
-
- def remove_fixed_ip(self, server_id, **kwargs):
- """Remove input fixed IP from input server instance."""
- post_body = json.dumps({'removeFixedIp': kwargs})
- resp, body = self.post('servers/%s/action' % server_id,
- post_body)
- self.validate_response(servers_schema.server_actions_common_schema,
- resp, body)
- return service_client.ResponseBody(resp, body)
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/networks_client.py b/tempest/services/compute/json/networks_client.py
index 6373f01..dd20ee5 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -24,10 +24,10 @@
resp, body = self.get("os-networks")
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, body['networks'])
+ return service_client.ResponseBody(resp, body)
def show_network(self, network_id):
resp, body = self.get("os-networks/%s" % network_id)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['network'])
+ 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_default_rules_client.py b/tempest/services/compute/json/security_group_default_rules_client.py
index 658b89a..6e4d1e4 100644
--- a/tempest/services/compute/json/security_group_default_rules_client.py
+++ b/tempest/services/compute/json/security_group_default_rules_client.py
@@ -36,8 +36,7 @@
body = json.loads(body)
self.validate_response(schema.create_get_security_group_default_rule,
resp, body)
- rule = body['security_group_default_rule']
- return service_client.ResponseBody(resp, rule)
+ return service_client.ResponseBody(resp, body)
def delete_security_group_default_rule(self,
security_group_default_rule_id):
@@ -54,8 +53,7 @@
body = json.loads(body)
self.validate_response(schema.list_security_group_default_rules,
resp, body)
- rules = body['security_group_default_rules']
- return service_client.ResponseBodyList(resp, rules)
+ return service_client.ResponseBody(resp, body)
def show_security_group_default_rule(self, security_group_default_rule_id):
"""Return the details of provided Security Group default rule."""
@@ -64,5 +62,4 @@
body = json.loads(body)
self.validate_response(schema.create_get_security_group_default_rule,
resp, body)
- rule = body['security_group_default_rule']
- return service_client.ResponseBody(resp, rule)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/security_group_rules_client.py b/tempest/services/compute/json/security_group_rules_client.py
index 9a7c881..9626f60 100644
--- a/tempest/services/compute/json/security_group_rules_client.py
+++ b/tempest/services/compute/json/security_group_rules_client.py
@@ -13,9 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
-from tempest_lib import exceptions as lib_exc
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import security_groups as schema
from tempest.common import service_client
@@ -39,7 +37,7 @@
resp, body = self.post(url, post_body)
body = json.loads(body)
self.validate_response(schema.create_security_group_rule, resp, body)
- return service_client.ResponseBody(resp, body['security_group_rule'])
+ return service_client.ResponseBody(resp, body)
def delete_security_group_rule(self, group_rule_id):
"""Deletes the provided Security Group rule."""
@@ -47,13 +45,3 @@
group_rule_id)
self.validate_response(schema.delete_security_group_rule, resp, body)
return service_client.ResponseBody(resp, body)
-
- def list_security_group_rules(self, security_group_id):
- """List all rules for a security group."""
- resp, body = self.get('os-security-groups')
- body = json.loads(body)
- self.validate_response(schema.list_security_groups, resp, body)
- for sg in body['security_groups']:
- if sg['id'] == security_group_id:
- return service_client.ResponseBodyList(resp, sg['rules'])
- raise lib_exc.NotFound('No such Security Group')
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index c0b667b..083d03a 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -33,7 +33,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_security_groups, resp, body)
- return service_client.ResponseBodyList(resp, body['security_groups'])
+ return service_client.ResponseBody(resp, body)
def show_security_group(self, security_group_id):
"""Get the details of a Security Group."""
@@ -41,7 +41,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.get_security_group, resp, body)
- return service_client.ResponseBody(resp, body['security_group'])
+ return service_client.ResponseBody(resp, body)
def create_security_group(self, **kwargs):
"""
@@ -53,7 +53,7 @@
resp, body = self.post('os-security-groups', post_body)
body = json.loads(body)
self.validate_response(schema.get_security_group, resp, body)
- return service_client.ResponseBody(resp, body['security_group'])
+ return service_client.ResponseBody(resp, body)
def update_security_group(self, security_group_id, **kwargs):
"""
@@ -67,7 +67,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.update_security_group, resp, body)
- return service_client.ResponseBody(resp, body['security_group'])
+ return service_client.ResponseBody(resp, body)
def delete_security_group(self, security_group_id):
"""Deletes the provided Security Group."""
diff --git a/tempest/services/compute/json/server_groups_client.py b/tempest/services/compute/json/server_groups_client.py
index 9fec930..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
@@ -38,7 +38,7 @@
body = json.loads(body)
self.validate_response(schema.create_get_server_group, resp, body)
- return service_client.ResponseBody(resp, body['server_group'])
+ return service_client.ResponseBody(resp, body)
def delete_server_group(self, server_group_id):
"""Delete the given server-group."""
@@ -51,11 +51,11 @@
resp, body = self.get("os-server-groups")
body = json.loads(body)
self.validate_response(schema.list_server_groups, resp, body)
- return service_client.ResponseBodyList(resp, body['server_groups'])
+ return service_client.ResponseBody(resp, body)
def get_server_group(self, server_group_id):
"""Get the details of given server_group."""
resp, body = self.get("os-server-groups/%s" % server_group_id)
body = json.loads(body)
self.validate_response(schema.create_get_server_group, resp, body)
- return service_client.ResponseBody(resp, body['server_group'])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 7022418..1d2c7b2 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -14,6 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import copy
+
from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
@@ -29,59 +31,28 @@
auth_provider, service, region, **kwargs)
self.enable_instance_password = enable_instance_password
- def create_server(self, name, image_ref, flavor_ref, **kwargs):
+ def create_server(self, **kwargs):
"""
Creates an instance of a server.
- name (Required): The name of the server.
- image_ref (Required): Reference to the image used to build the server.
- flavor_ref (Required): The flavor used to build the server.
- Following optional keyword arguments are accepted:
- adminPass: Sets the initial root password.
- key_name: Key name of keypair that was created earlier.
- meta: A dictionary of values to be used as metadata.
- personality: A list of dictionaries for files to be injected into
- the server.
- security_groups: A list of security group dicts.
- networks: A list of network dicts with UUID and fixed_ip.
- user_data: User data for instance.
- availability_zone: Availability zone in which to launch instance.
- accessIPv4: The IPv4 access address for the server.
- accessIPv6: The IPv6 access address for the server.
- min_count: Count of minimum number of instances to launch.
- max_count: Count of maximum number of instances to launch.
- disk_config: Determines if user or admin controls disk configuration.
- return_reservation_id: Enable/Disable the return of reservation id
- block_device_mapping: Block device mapping for the server.
- block_device_mapping_v2: Block device mapping V2 for the 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
+ :param scheduler_hints: The name is changed to os:scheduler_hints and
+ the parameter is set in the same level as the parameter 'server'.
"""
- post_body = {
- 'name': name,
- 'imageRef': image_ref,
- 'flavorRef': flavor_ref
- }
+ body = copy.deepcopy(kwargs)
+ if body.get('disk_config'):
+ body['OS-DCF:diskConfig'] = body.pop('disk_config')
- for option in ['personality', 'adminPass', 'key_name',
- 'security_groups', 'networks', 'user_data',
- 'availability_zone', 'accessIPv4', 'accessIPv6',
- 'min_count', 'max_count', ('metadata', 'meta'),
- ('OS-DCF:diskConfig', 'disk_config'),
- 'return_reservation_id', 'block_device_mapping',
- 'block_device_mapping_v2']:
- if isinstance(option, tuple):
- post_param = option[0]
- key = option[1]
- else:
- post_param = option
- key = option
- value = kwargs.get(key)
- if value is not None:
- post_body[post_param] = value
+ hints = None
+ if body.get('scheduler_hints'):
+ hints = {'os:scheduler_hints': body.pop('scheduler_hints')}
- post_body = {'server': post_body}
+ post_body = {'server': body}
- if 'sched_hints' in kwargs:
- hints = {'os:scheduler_hints': kwargs.get('sched_hints')}
+ if hints:
post_body = dict(post_body.items() + hints.items())
+
post_body = json.dumps(post_body)
resp, body = self.post('servers', post_body)
@@ -95,48 +66,29 @@
else:
create_schema = schema.create_server
self.validate_response(create_schema, resp, body)
- return service_client.ResponseBody(resp, body['server'])
+ return service_client.ResponseBody(resp, body)
- 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)
- return service_client.ResponseBody(resp, body['server'])
+ return service_client.ResponseBody(resp, body)
def show_server(self, server_id):
"""Returns the details of an existing server."""
resp, body = self.get("servers/%s" % server_id)
body = json.loads(body)
self.validate_response(schema.get_server, resp, body)
- return service_client.ResponseBody(resp, body['server'])
+ return service_client.ResponseBody(resp, body)
def delete_server(self, server_id):
"""Deletes the given server."""
@@ -166,7 +118,7 @@
resp, body = self.get("servers/%s/ips" % server_id)
body = json.loads(body)
self.validate_response(schema.list_addresses, resp, body)
- return service_client.ResponseBody(resp, body['addresses'])
+ return service_client.ResponseBody(resp, body)
def list_addresses_by_network(self, server_id, network_id):
"""Lists all addresses of a specific network type for a server."""
@@ -176,30 +128,27 @@
self.validate_response(schema.list_addresses_by_network, resp, body)
return service_client.ResponseBody(resp, body)
- def action(self, server_id, action_name, response_key,
+ def action(self, server_id, action_name,
schema=schema.server_actions_common_schema,
- response_class=service_client.ResponseBody, **kwargs):
+ **kwargs):
post_body = json.dumps({action_name: kwargs})
resp, body = self.post('servers/%s/action' % server_id,
post_body)
- if response_key is not None:
+ if body:
body = json.loads(body)
- self.validate_response(schema, resp, body)
- body = body[response_key]
- else:
- self.validate_response(schema, resp, body)
- return response_class(resp, body)
+ self.validate_response(schema, resp, body)
+ return service_client.ResponseBody(resp, body)
def create_backup(self, server_id, backup_type, rotation, name):
"""Backup a server instance."""
- return self.action(server_id, "createBackup", None,
+ return self.action(server_id, "createBackup",
backup_type=backup_type,
rotation=rotation,
name=name)
def change_password(self, server_id, adminPass):
"""Changes the root password for the server."""
- return self.action(server_id, 'changePassword', None,
+ return self.action(server_id, 'changePassword',
adminPass=adminPass)
def get_password(self, server_id):
@@ -221,46 +170,52 @@
resp, body)
return service_client.ResponseBody(resp, body)
- def reboot(self, server_id, reboot_type):
+ def reboot_server(self, server_id, reboot_type):
"""Reboots a server."""
- return self.action(server_id, 'reboot', None, type=reboot_type)
+ return self.action(server_id, 'reboot', type=reboot_type)
- def rebuild(self, server_id, image_ref, **kwargs):
- """Rebuilds a server with a new image."""
+ def rebuild_server(self, server_id, image_ref, **kwargs):
+ """Rebuilds a server with a new image.
+ Most parameters except the following are passed to the API without
+ any changes.
+ :param disk_config: The name is changed to OS-DCF:diskConfig
+ """
kwargs['imageRef'] = image_ref
if 'disk_config' in kwargs:
- kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
- del kwargs['disk_config']
+ kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config')
if self.enable_instance_password:
rebuild_schema = schema.rebuild_server_with_admin_pass
else:
rebuild_schema = schema.rebuild_server
- return self.action(server_id, 'rebuild', 'server',
+ return self.action(server_id, 'rebuild',
rebuild_schema, **kwargs)
- def resize(self, server_id, flavor_ref, **kwargs):
- """Changes the flavor of a server."""
+ def resize_server(self, server_id, flavor_ref, **kwargs):
+ """Changes the flavor of a 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
+ """
kwargs['flavorRef'] = flavor_ref
if 'disk_config' in kwargs:
- kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
- del kwargs['disk_config']
- return self.action(server_id, 'resize', None, **kwargs)
+ kwargs['OS-DCF:diskConfig'] = kwargs.pop('disk_config')
+ return self.action(server_id, 'resize', **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,
+ 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)
+ return self.action(server_id, 'revertResize', **kwargs)
def list_server_metadata(self, server_id):
resp, body = self.get("servers/%s/metadata" % server_id)
body = json.loads(body)
self.validate_response(schema.list_server_metadata, resp, body)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def set_server_metadata(self, server_id, meta, no_metadata_field=False):
if no_metadata_field:
@@ -271,7 +226,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.set_server_metadata, resp, body)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def update_server_metadata(self, server_id, meta):
post_body = json.dumps({'metadata': meta})
@@ -280,14 +235,14 @@
body = json.loads(body)
self.validate_response(schema.update_server_metadata,
resp, body)
- return service_client.ResponseBody(resp, body['metadata'])
+ return service_client.ResponseBody(resp, body)
def get_server_metadata_item(self, server_id, key):
resp, body = self.get("servers/%s/metadata/%s" % (server_id, key))
body = json.loads(body)
self.validate_response(schema.set_get_server_metadata_item,
resp, body)
- return service_client.ResponseBody(resp, body['meta'])
+ return service_client.ResponseBody(resp, body)
def set_server_metadata_item(self, server_id, key, meta):
post_body = json.dumps({'meta': meta})
@@ -296,7 +251,7 @@
body = json.loads(body)
self.validate_response(schema.set_get_server_metadata_item,
resp, body)
- return service_client.ResponseBody(resp, body['meta'])
+ return service_client.ResponseBody(resp, body)
def delete_server_metadata_item(self, server_id, key):
resp, body = self.delete("servers/%s/metadata/%s" %
@@ -305,11 +260,11 @@
resp, body)
return service_client.ResponseBody(resp, body)
- def stop(self, server_id, **kwargs):
- return self.action(server_id, 'os-stop', None, **kwargs)
+ def stop_server(self, server_id, **kwargs):
+ return self.action(server_id, 'os-stop', **kwargs)
- def start(self, server_id, **kwargs):
- return self.action(server_id, 'os-start', None, **kwargs)
+ def start_server(self, server_id, **kwargs):
+ return self.action(server_id, 'os-start', **kwargs)
def attach_volume(self, server_id, **kwargs):
"""Attaches a volume to a server instance."""
@@ -318,7 +273,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.attach_volume, resp, body)
- return service_client.ResponseBody(resp, body['volumeAttachment'])
+ return service_client.ResponseBody(resp, body)
def detach_volume(self, server_id, volume_id):
"""Detaches a volume from a server instance."""
@@ -333,7 +288,7 @@
server_id, attach_id))
body = json.loads(body)
self.validate_response(schema.get_volume_attachment, resp, body)
- return service_client.ResponseBody(resp, body['volumeAttachment'])
+ return service_client.ResponseBody(resp, body)
def list_volume_attachments(self, server_id):
"""Returns the list of volume attachments for a given instance."""
@@ -341,15 +296,15 @@
server_id))
body = json.loads(body)
self.validate_response(schema.list_volume_attachments, resp, body)
- return service_client.ResponseBodyList(resp, body['volumeAttachments'])
+ return service_client.ResponseBody(resp, body)
def add_security_group(self, server_id, name):
"""Adds a security group to the server."""
- return self.action(server_id, 'addSecurityGroup', None, name=name)
+ return self.action(server_id, 'addSecurityGroup', name=name)
def remove_security_group(self, server_id, name):
"""Removes a security group from the server."""
- return self.action(server_id, 'removeSecurityGroup', None, name=name)
+ return self.action(server_id, 'removeSecurityGroup', name=name)
def live_migrate_server(self, server_id, **kwargs):
"""This should be called with administrator privileges ."""
@@ -363,53 +318,52 @@
def migrate_server(self, server_id, **kwargs):
"""Migrates a server to a new host."""
- return self.action(server_id, 'migrate', None, **kwargs)
+ return self.action(server_id, 'migrate', **kwargs)
def lock_server(self, server_id, **kwargs):
"""Locks the given server."""
- return self.action(server_id, 'lock', None, **kwargs)
+ return self.action(server_id, 'lock', **kwargs)
def unlock_server(self, server_id, **kwargs):
"""UNlocks the given server."""
- return self.action(server_id, 'unlock', None, **kwargs)
+ return self.action(server_id, 'unlock', **kwargs)
def suspend_server(self, server_id, **kwargs):
"""Suspends the provided server."""
- return self.action(server_id, 'suspend', None, **kwargs)
+ return self.action(server_id, 'suspend', **kwargs)
def resume_server(self, server_id, **kwargs):
"""Un-suspends the provided server."""
- return self.action(server_id, 'resume', None, **kwargs)
+ return self.action(server_id, 'resume', **kwargs)
def pause_server(self, server_id, **kwargs):
"""Pauses the provided server."""
- return self.action(server_id, 'pause', None, **kwargs)
+ return self.action(server_id, 'pause', **kwargs)
def unpause_server(self, server_id, **kwargs):
"""Un-pauses the provided server."""
- return self.action(server_id, 'unpause', None, **kwargs)
+ return self.action(server_id, 'unpause', **kwargs)
def reset_state(self, server_id, state='error'):
"""Resets the state of a server to active/error."""
- return self.action(server_id, 'os-resetState', None, state=state)
+ return self.action(server_id, 'os-resetState', state=state)
def shelve_server(self, server_id, **kwargs):
"""Shelves the provided server."""
- return self.action(server_id, 'shelve', None, **kwargs)
+ return self.action(server_id, 'shelve', **kwargs)
def unshelve_server(self, server_id, **kwargs):
"""Un-shelves the provided server."""
- return self.action(server_id, 'unshelve', None, **kwargs)
+ return self.action(server_id, 'unshelve', **kwargs)
def shelve_offload_server(self, server_id, **kwargs):
"""Shelve-offload the provided server."""
- return self.action(server_id, 'shelveOffload', None, **kwargs)
+ return self.action(server_id, 'shelveOffload', **kwargs)
def get_console_output(self, server_id, length):
kwargs = {'length': length} if length else {}
- return self.action(server_id, 'os-getConsoleOutput', 'output',
+ return self.action(server_id, 'os-getConsoleOutput',
schema.get_console_output,
- response_class=service_client.ResponseBodyData,
**kwargs)
def list_virtual_interfaces(self, server_id):
@@ -424,14 +378,13 @@
def rescue_server(self, server_id, **kwargs):
"""Rescue the provided server."""
- return self.action(server_id, 'rescue', 'adminPass',
+ return self.action(server_id, 'rescue',
schema.rescue_server,
- response_class=service_client.ResponseBodyData,
**kwargs)
def unrescue_server(self, server_id):
"""Unrescue the provided server."""
- return self.action(server_id, 'unrescue', None)
+ return self.action(server_id, 'unrescue')
def get_server_diagnostics(self, server_id):
"""Get the usage data for a server."""
@@ -444,7 +397,7 @@
server_id)
body = json.loads(body)
self.validate_response(schema.list_instance_actions, resp, body)
- return service_client.ResponseBodyList(resp, body['instanceActions'])
+ return service_client.ResponseBody(resp, body)
def get_instance_action(self, server_id, request_id):
"""Returns the action details of the provided server."""
@@ -452,26 +405,34 @@
(server_id, request_id))
body = json.loads(body)
self.validate_response(schema.get_instance_action, resp, body)
- return service_client.ResponseBody(resp, body['instanceAction'])
+ return service_client.ResponseBody(resp, body)
def force_delete_server(self, server_id, **kwargs):
"""Force delete a server."""
- return self.action(server_id, 'forceDelete', None, **kwargs)
+ return self.action(server_id, 'forceDelete', **kwargs)
def restore_soft_deleted_server(self, server_id, **kwargs):
"""Restore a soft-deleted server."""
- return self.action(server_id, 'restore', None, **kwargs)
+ return self.action(server_id, 'restore', **kwargs)
def reset_network(self, server_id, **kwargs):
"""Resets the Network of a server"""
- return self.action(server_id, 'resetNetwork', None, **kwargs)
+ return self.action(server_id, 'resetNetwork', **kwargs)
def inject_network_info(self, server_id, **kwargs):
"""Inject the Network Info into server"""
- return self.action(server_id, 'injectNetworkInfo', None, **kwargs)
+ return self.action(server_id, 'injectNetworkInfo', **kwargs)
def get_vnc_console(self, server_id, console_type):
"""Get URL of VNC console."""
return self.action(server_id, "os-getVNCConsole",
- "console", schema.get_vnc_console,
+ schema.get_vnc_console,
type=console_type)
+
+ def add_fixed_ip(self, server_id, **kwargs):
+ """Add a fixed IP to input server instance."""
+ return self.action(server_id, 'addFixedIp', **kwargs)
+
+ def remove_fixed_ip(self, server_id, **kwargs):
+ """Remove input fixed IP from input server instance."""
+ return self.action(server_id, 'removeFixedIp', **kwargs)
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index 699d3e7..232b301 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -31,7 +31,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_services, resp, body)
- return service_client.ResponseBodyList(resp, body['services'])
+ return service_client.ResponseBody(resp, body)
def enable_service(self, host_name, binary):
"""
@@ -43,7 +43,7 @@
resp, body = self.put('os-services/enable', post_body)
body = json.loads(body)
self.validate_response(schema.enable_service, resp, body)
- return service_client.ResponseBody(resp, body['service'])
+ return service_client.ResponseBody(resp, body)
def disable_service(self, host_name, binary):
"""
@@ -54,4 +54,4 @@
post_body = json.dumps({'binary': binary, 'host': host_name})
resp, body = self.put('os-services/disable', post_body)
body = json.loads(body)
- return service_client.ResponseBody(resp, body['service'])
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/snapshots_client.py b/tempest/services/compute/json/snapshots_client.py
new file mode 100644
index 0000000..e3f92db
--- /dev/null
+++ b/tempest/services/compute/json/snapshots_client.py
@@ -0,0 +1,71 @@
+# Copyright 2015 Fujitsu(fnst) Corporation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+from tempest_lib import exceptions as lib_exc
+
+from tempest.api_schema.response.compute.v2_1 import snapshots as schema
+from tempest.common import service_client
+
+
+class SnapshotsClient(service_client.ServiceClient):
+
+ def create_snapshot(self, volume_id, **kwargs):
+ post_body = {
+ 'volume_id': volume_id
+ }
+ post_body.update(kwargs)
+ post_body = json.dumps({'snapshot': post_body})
+ resp, body = self.post('os-snapshots', post_body)
+ body = json.loads(body)
+ self.validate_response(schema.create_get_snapshot, resp, body)
+ return service_client.ResponseBody(resp, body)
+
+ def show_snapshot(self, snapshot_id):
+ url = "os-snapshots/%s" % snapshot_id
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.validate_response(schema.create_get_snapshot, resp, body)
+ return service_client.ResponseBody(resp, body)
+
+ def list_snapshots(self, detail=False, params=None):
+ url = 'os-snapshots'
+
+ if detail:
+ url += '/detail'
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.validate_response(schema.list_snapshots, resp, body)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_snapshot(self, snapshot_id):
+ resp, body = self.delete("os-snapshots/%s" % snapshot_id)
+ self.validate_response(schema.delete_snapshot, resp, body)
+ return service_client.ResponseBody(resp, body)
+
+ def is_resource_deleted(self, id):
+ try:
+ self.show_snapshot(id)
+ except lib_exc.NotFound:
+ return True
+ return False
+
+ @property
+ def resource_type(self):
+ """Returns the primary type of resource this client works with."""
+ return 'snapshot'
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/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index 72fcde2..73b4706 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -30,7 +30,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_tenant_usage, resp, body)
- return service_client.ResponseBodyList(resp, body['tenant_usages'][0])
+ return service_client.ResponseBody(resp, body)
def show_tenant_usage(self, tenant_id, **params):
url = 'os-simple-tenant-usage/%s' % tenant_id
@@ -40,4 +40,4 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.get_tenant_usage, resp, body)
- return service_client.ResponseBodyList(resp, body['tenant_usage'])
+ 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..48c0e8d
--- /dev/null
+++ b/tempest/services/compute/json/versions_client.py
@@ -0,0 +1,55 @@
+# 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 _get_base_version_url(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)
+ return '%s://%s/' % (url.scheme, url.netloc)
+
+ def list_versions(self):
+ version_url = self._get_base_version_url()
+ 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)
+
+ def get_version_by_url(self, version_url):
+ """Get the version document by url.
+
+ This gets the version document for a url, useful in testing
+ the contents of things like /v2/ or /v2.1/ in Nova. That
+ controller needs authenticated access, so we have to get
+ ourselves a token before making the request.
+
+ """
+ # we need a token for this request
+ resp, body = self.raw_request(version_url, 'GET',
+ {'X-Auth-Token': self.token})
+ body = json.loads(body)
+ self.validate_response(schema.get_one_version, 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/flavors_client.py b/tempest/services/database/json/flavors_client.py
index 4fe5a46..88feb17 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_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
import urllib
from tempest.common import service_client
@@ -27,9 +28,11 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def get_db_flavor_details(self, db_flavor_id):
resp, body = self.get("flavors/%s" % str(db_flavor_id))
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)
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..f37bc08 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -24,7 +24,8 @@
url = ''
resp, body = self.get(url)
self.expected_success([200, 203], resp.status)
- return service_client.ResponseBody(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def has_admin_extensions(self):
"""
@@ -49,7 +50,8 @@
post_body = json.dumps({'role': post_body})
resp, body = self.post('OS-KSADM/roles', post_body)
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 get_role(self, role_id):
"""Get a role by its id."""
@@ -73,7 +75,8 @@
post_body = json.dumps({'tenant': post_body})
resp, body = self.post('tenants', post_body)
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 delete_role(self, role_id):
"""Delete a role."""
@@ -86,14 +89,16 @@
url = '/tenants/%s/users/%s/roles' % (tenant_id, user_id)
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def assign_user_role(self, tenant_id, user_id, role_id):
"""Add roles to a user on a tenant."""
resp, body = self.put('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
(tenant_id, user_id, role_id), "")
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 remove_user_role(self, tenant_id, user_id, role_id):
"""Removes a role assignment for a user on a tenant."""
@@ -112,13 +117,15 @@
"""Get tenant details."""
resp, body = self.get('tenants/%s' % str(tenant_id))
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 list_roles(self):
"""Returns roles."""
resp, body = self.get('OS-KSADM/roles')
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def list_tenants(self):
"""Returns tenants."""
@@ -136,7 +143,7 @@
def update_tenant(self, tenant_id, **kwargs):
"""Updates a tenant."""
- body = self.get_tenant(tenant_id)
+ body = self.get_tenant(tenant_id)['tenant']
name = kwargs.get('name', body['name'])
desc = kwargs.get('description', body['description'])
en = kwargs.get('enabled', body['enabled'])
@@ -149,7 +156,8 @@
post_body = json.dumps({'tenant': post_body})
resp, body = self.post('tenants/%s' % tenant_id, post_body)
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, name, password, tenant_id, email, **kwargs):
"""Create a user."""
@@ -165,20 +173,23 @@
post_body = json.dumps({'user': post_body})
resp, body = self.post('users', post_body)
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 update_user(self, user_id, **kwargs):
"""Updates a user."""
put_body = json.dumps({'user': kwargs})
resp, body = self.put('users/%s' % user_id, put_body)
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 get_user(self, user_id):
"""GET a user."""
resp, body = self.get("users/%s" % user_id)
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 delete_user(self, user_id):
"""Delete a user."""
@@ -190,7 +201,8 @@
"""Get the list of users."""
resp, body = self.get("users")
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def enable_disable_user(self, user_id, enabled):
"""Enables or disables a user."""
@@ -200,13 +212,15 @@
put_body = json.dumps({'user': put_body})
resp, body = self.put('users/%s/enabled' % user_id, put_body)
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 get_token(self, token_id):
"""Get token details."""
resp, body = self.get("tokens/%s" % token_id)
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 delete_token(self, token_id):
"""Delete a token."""
@@ -218,10 +232,11 @@
"""List users for a Tenant."""
resp, body = self.get('/tenants/%s/users' % tenant_id)
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def get_user_by_username(self, tenant_id, username):
- users = self.list_users_for_tenant(tenant_id)
+ users = self.list_users_for_tenant(tenant_id)['users']
for user in users:
if user['name'] == username:
return user
@@ -237,20 +252,23 @@
post_body = json.dumps({'OS-KSADM:service': post_body})
resp, body = self.post('/OS-KSADM/services', post_body)
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 get_service(self, service_id):
"""Get Service."""
url = '/OS-KSADM/services/%s' % service_id
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 list_services(self):
"""List Service - Returns Services."""
resp, body = self.get('/OS-KSADM/services')
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def delete_service(self, service_id):
"""Delete Service."""
@@ -271,13 +289,15 @@
post_body = json.dumps({'endpoint': post_body})
resp, body = self.post('/endpoints', post_body)
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 list_endpoints(self):
"""List Endpoints - Returns Endpoints."""
resp, body = self.get('/endpoints')
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def delete_endpoint(self, endpoint_id):
"""Delete an endpoint."""
@@ -295,24 +315,51 @@
put_body = json.dumps({'user': put_body})
resp, body = self.put('users/%s/OS-KSADM/password' % user_id, put_body)
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 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)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
def list_extensions(self):
"""List all the extensions."""
resp, body = self.get('/extensions')
self.expected_success(200, resp.status)
body = json.loads(body)
- return service_client.ResponseBodyList(resp,
- body['extensions']['values'])
+ return service_client.ResponseBody(resp, body)
def create_user_ec2_credentials(self, user_id, tenant_id):
post_body = json.dumps({'tenant_id': tenant_id})
resp, body = self.post('/users/%s/credentials/OS-EC2' % user_id,
post_body)
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 delete_user_ec2_credentials(self, user_id, access):
+ resp, body = self.delete('/users/%s/credentials/OS-EC2/%s' %
+ (user_id, access))
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
def list_user_ec2_credentials(self, user_id):
resp, body = self.get('/users/%s/credentials/OS-EC2' % user_id)
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, self._parse_resp(body))
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
+
+ def show_user_ec2_credentials(self, user_id, access):
+ resp, body = self.get('/users/%s/credentials/OS-EC2/%s' %
+ (user_id, access))
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return service_client.ResponseBody(resp, body)
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/identity/v3/json/policy_client.py b/tempest/services/identity/v3/json/policy_client.py
index f820598..3231bb0 100644
--- a/tempest/services/identity/v3/json/policy_client.py
+++ b/tempest/services/identity/v3/json/policy_client.py
@@ -31,14 +31,14 @@
resp, body = self.post('policies', post_body)
self.expected_success(201, resp.status)
body = json.loads(body)
- return service_client.ResponseBody(resp, body['policy'])
+ return service_client.ResponseBody(resp, body)
def list_policies(self):
"""Lists the policies."""
resp, body = self.get('policies')
self.expected_success(200, resp.status)
body = json.loads(body)
- return service_client.ResponseBodyList(resp, body['policies'])
+ return service_client.ResponseBody(resp, body)
def get_policy(self, policy_id):
"""Lists out the given policy."""
@@ -46,7 +46,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return service_client.ResponseBody(resp, body['policy'])
+ return service_client.ResponseBody(resp, body)
def update_policy(self, policy_id, **kwargs):
"""Updates a policy."""
@@ -59,7 +59,7 @@
resp, body = self.patch(url, post_body)
self.expected_success(200, resp.status)
body = json.loads(body)
- return service_client.ResponseBody(resp, body['policy'])
+ return service_client.ResponseBody(resp, body)
def delete_policy(self, policy_id):
"""Deletes the policy."""
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/network/json/base.py b/tempest/services/network/json/base.py
new file mode 100644
index 0000000..fe150df
--- /dev/null
+++ b/tempest/services/network/json/base.py
@@ -0,0 +1,70 @@
+# 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.urllib import parse as urllib
+
+from tempest.common import service_client
+
+
+class BaseNetworkClient(service_client.ServiceClient):
+
+ """
+ Base class for Tempest REST clients for Neutron. Child classes use v2 of
+ the Neutron API, since the V1 API has been removed from the code base.
+ """
+
+ version = '2.0'
+ uri_prefix = "v2.0"
+
+ def list_resources(self, uri, **filters):
+ req_uri = self.uri_prefix + uri
+ if filters:
+ req_uri += '?' + urllib.urlencode(filters, doseq=1)
+ resp, body = self.get(req_uri)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def delete_resource(self, uri):
+ req_uri = self.uri_prefix + uri
+ resp, body = self.delete(req_uri)
+ self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def show_resource(self, uri, **fields):
+ # fields is a dict which key is 'fields' and value is a
+ # list of field's name. An example:
+ # {'fields': ['id', 'name']}
+ req_uri = self.uri_prefix + uri
+ if fields:
+ req_uri += '?' + urllib.urlencode(fields, doseq=1)
+ resp, body = self.get(req_uri)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def create_resource(self, uri, post_data):
+ req_uri = self.uri_prefix + uri
+ req_post_data = json.dumps(post_data)
+ resp, body = self.post(req_uri, req_post_data)
+ body = json.loads(body)
+ self.expected_success(201, resp.status)
+ return service_client.ResponseBody(resp, body)
+
+ def update_resource(self, uri, post_data):
+ req_uri = self.uri_prefix + uri
+ req_post_data = json.dumps(post_data)
+ resp, body = self.put(req_uri, req_post_data)
+ body = json.loads(body)
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index ce200d2..10bd23e 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -12,16 +12,14 @@
import time
-from oslo_serialization import jsonutils as json
-from six.moves.urllib import parse as urllib
from tempest_lib.common.utils import misc
from tempest_lib import exceptions as lib_exc
-from tempest.common import service_client
from tempest import exceptions
+from tempest.services.network.json import base
-class NetworkClient(service_client.ServiceClient):
+class NetworkClient(base.BaseNetworkClient):
"""
Tempest REST client for Neutron. Uses v2 of the Neutron API, since the
@@ -36,236 +34,168 @@
quotas
"""
- version = '2.0'
- uri_prefix = "v2.0"
-
- def _list_resources(self, uri, **filters):
- req_uri = self.uri_prefix + uri
- if filters:
- req_uri += '?' + urllib.urlencode(filters, doseq=1)
- resp, body = self.get(req_uri)
- body = json.loads(body)
- self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def _delete_resource(self, uri):
- req_uri = self.uri_prefix + uri
- resp, body = self.delete(req_uri)
- self.expected_success(204, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def _show_resource(self, uri, **fields):
- # fields is a dict which key is 'fields' and value is a
- # list of field's name. An example:
- # {'fields': ['id', 'name']}
- req_uri = self.uri_prefix + uri
- if fields:
- req_uri += '?' + urllib.urlencode(fields, doseq=1)
- resp, body = self.get(req_uri)
- body = json.loads(body)
- self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def _create_resource(self, uri, post_data):
- req_uri = self.uri_prefix + uri
- req_post_data = json.dumps(post_data)
- resp, body = self.post(req_uri, req_post_data)
- body = json.loads(body)
- self.expected_success(201, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def _update_resource(self, uri, post_data):
- req_uri = self.uri_prefix + uri
- req_post_data = json.dumps(post_data)
- resp, body = self.put(req_uri, req_post_data)
- body = json.loads(body)
- self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def create_network(self, **kwargs):
- uri = '/networks'
- post_data = {'network': kwargs}
- return self._create_resource(uri, post_data)
-
- def update_network(self, network_id, **kwargs):
- uri = '/networks/%s' % network_id
- post_data = {'network': kwargs}
- return self._update_resource(uri, post_data)
-
- def show_network(self, network_id, **fields):
- uri = '/networks/%s' % network_id
- return self._show_resource(uri, **fields)
-
- def delete_network(self, network_id):
- uri = '/networks/%s' % network_id
- return self._delete_resource(uri)
-
- def list_networks(self, **filters):
- uri = '/networks'
- return self._list_resources(uri, **filters)
-
def create_subnet(self, **kwargs):
uri = '/subnets'
post_data = {'subnet': kwargs}
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def update_subnet(self, subnet_id, **kwargs):
uri = '/subnets/%s' % subnet_id
post_data = {'subnet': kwargs}
- return self._update_resource(uri, post_data)
+ return self.update_resource(uri, post_data)
def show_subnet(self, subnet_id, **fields):
uri = '/subnets/%s' % subnet_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_subnet(self, subnet_id):
uri = '/subnets/%s' % subnet_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_subnets(self, **filters):
uri = '/subnets'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_port(self, **kwargs):
uri = '/ports'
post_data = {'port': kwargs}
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def update_port(self, port_id, **kwargs):
uri = '/ports/%s' % port_id
post_data = {'port': kwargs}
- return self._update_resource(uri, post_data)
+ return self.update_resource(uri, post_data)
def show_port(self, port_id, **fields):
uri = '/ports/%s' % port_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_port(self, port_id):
uri = '/ports/%s' % port_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_ports(self, **filters):
uri = '/ports'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_floatingip(self, **kwargs):
uri = '/floatingips'
post_data = {'floatingip': kwargs}
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def update_floatingip(self, floatingip_id, **kwargs):
uri = '/floatingips/%s' % floatingip_id
post_data = {'floatingip': kwargs}
- return self._update_resource(uri, post_data)
+ return self.update_resource(uri, post_data)
def show_floatingip(self, floatingip_id, **fields):
uri = '/floatingips/%s' % floatingip_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_floatingip(self, floatingip_id):
uri = '/floatingips/%s' % floatingip_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_floatingips(self, **filters):
uri = '/floatingips'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_metering_label(self, **kwargs):
uri = '/metering/metering-labels'
post_data = {'metering_label': kwargs}
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def show_metering_label(self, metering_label_id, **fields):
uri = '/metering/metering-labels/%s' % metering_label_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_metering_label(self, metering_label_id):
uri = '/metering/metering-labels/%s' % metering_label_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_metering_labels(self, **filters):
uri = '/metering/metering-labels'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_metering_label_rule(self, **kwargs):
uri = '/metering/metering-label-rules'
post_data = {'metering_label_rule': kwargs}
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def show_metering_label_rule(self, metering_label_rule_id, **fields):
uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_metering_label_rule(self, metering_label_rule_id):
uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_metering_label_rules(self, **filters):
uri = '/metering/metering-label-rules'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_security_group(self, **kwargs):
uri = '/security-groups'
post_data = {'security_group': kwargs}
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def update_security_group(self, security_group_id, **kwargs):
uri = '/security-groups/%s' % security_group_id
post_data = {'security_group': kwargs}
- return self._update_resource(uri, post_data)
+ return self.update_resource(uri, post_data)
def show_security_group(self, security_group_id, **fields):
uri = '/security-groups/%s' % security_group_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_security_group(self, security_group_id):
uri = '/security-groups/%s' % security_group_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_security_groups(self, **filters):
uri = '/security-groups'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_security_group_rule(self, **kwargs):
uri = '/security-group-rules'
post_data = {'security_group_rule': kwargs}
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def show_security_group_rule(self, security_group_rule_id, **fields):
uri = '/security-group-rules/%s' % security_group_rule_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_security_group_rule(self, security_group_rule_id):
uri = '/security-group-rules/%s' % security_group_rule_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_security_group_rules(self, **filters):
uri = '/security-group-rules'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def show_extension(self, ext_alias, **fields):
uri = '/extensions/%s' % ext_alias
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def list_extensions(self, **filters):
uri = '/extensions'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_bulk_network(self, names):
network_list = [{'name': name} for name in names]
post_data = {'networks': network_list}
uri = '/networks'
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def create_bulk_subnet(self, subnet_list):
post_data = {'subnets': subnet_list}
uri = '/subnets'
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def create_bulk_port(self, port_list):
post_data = {'ports': port_list}
uri = '/ports'
- return self._create_resource(uri, post_data)
+ return self.create_resource(uri, post_data)
def wait_for_resource_deletion(self, resource_type, id):
"""Waits for a resource to be deleted."""
@@ -327,30 +257,30 @@
def update_quotas(self, tenant_id, **kwargs):
put_body = {'quota': kwargs}
uri = '/quotas/%s' % tenant_id
- return self._update_resource(uri, put_body)
+ return self.update_resource(uri, put_body)
def reset_quotas(self, tenant_id):
uri = '/quotas/%s' % tenant_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def show_quotas(self, tenant_id, **fields):
uri = '/quotas/%s' % tenant_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def list_quotas(self, **filters):
uri = '/quotas'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def create_router(self, name, admin_state_up=True, **kwargs):
post_body = {'router': kwargs}
post_body['router']['name'] = name
post_body['router']['admin_state_up'] = admin_state_up
uri = '/routers'
- return self._create_resource(uri, post_body)
+ return self.create_resource(uri, post_body)
def _update_router(self, router_id, set_enable_snat, **kwargs):
uri = '/routers/%s' % router_id
- body = self._show_resource(uri)
+ body = self.show_resource(uri)
update_body = {}
update_body['name'] = kwargs.get('name', body['router']['name'])
update_body['admin_state_up'] = kwargs.get(
@@ -369,7 +299,7 @@
if 'distributed' in kwargs:
update_body['distributed'] = kwargs['distributed']
update_body = dict(router=update_body)
- return self._update_resource(uri, update_body)
+ return self.update_resource(uri, update_body)
def update_router(self, router_id, **kwargs):
"""Update a router leaving enable_snat to its default value."""
@@ -382,15 +312,15 @@
def show_router(self, router_id, **fields):
uri = '/routers/%s' % router_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def delete_router(self, router_id):
uri = '/routers/%s' % router_id
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_routers(self, **filters):
uri = '/routers'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def update_router_with_snat_gw_info(self, router_id, **kwargs):
"""Update a router passing also the enable_snat attribute.
@@ -403,26 +333,26 @@
def add_router_interface_with_subnet_id(self, router_id, subnet_id):
uri = '/routers/%s/add_router_interface' % router_id
update_body = {"subnet_id": subnet_id}
- return self._update_resource(uri, update_body)
+ return self.update_resource(uri, update_body)
def add_router_interface_with_port_id(self, router_id, port_id):
uri = '/routers/%s/add_router_interface' % router_id
update_body = {"port_id": port_id}
- return self._update_resource(uri, update_body)
+ return self.update_resource(uri, update_body)
def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
uri = '/routers/%s/remove_router_interface' % router_id
update_body = {"subnet_id": subnet_id}
- return self._update_resource(uri, update_body)
+ return self.update_resource(uri, update_body)
def remove_router_interface_with_port_id(self, router_id, port_id):
uri = '/routers/%s/remove_router_interface' % router_id
update_body = {"port_id": port_id}
- return self._update_resource(uri, update_body)
+ return self.update_resource(uri, update_body)
def list_router_interfaces(self, uuid):
uri = '/ports?device_id=%s' % uuid
- return self._list_resources(uri)
+ return self.list_resources(uri)
def update_agent(self, agent_id, agent_info):
"""
@@ -431,45 +361,45 @@
"""
uri = '/agents/%s' % agent_id
agent = {"agent": agent_info}
- return self._update_resource(uri, agent)
+ return self.update_resource(uri, agent)
def show_agent(self, agent_id, **fields):
uri = '/agents/%s' % agent_id
- return self._show_resource(uri, **fields)
+ return self.show_resource(uri, **fields)
def list_agents(self, **filters):
uri = '/agents'
- return self._list_resources(uri, **filters)
+ return self.list_resources(uri, **filters)
def list_routers_on_l3_agent(self, agent_id):
uri = '/agents/%s/l3-routers' % agent_id
- return self._list_resources(uri)
+ return self.list_resources(uri)
def list_l3_agents_hosting_router(self, router_id):
uri = '/routers/%s/l3-agents' % router_id
- return self._list_resources(uri)
+ return self.list_resources(uri)
def add_router_to_l3_agent(self, agent_id, router_id):
uri = '/agents/%s/l3-routers' % agent_id
post_body = {"router_id": router_id}
- return self._create_resource(uri, post_body)
+ return self.create_resource(uri, post_body)
def remove_router_from_l3_agent(self, agent_id, router_id):
uri = '/agents/%s/l3-routers/%s' % (agent_id, router_id)
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def list_dhcp_agent_hosting_network(self, network_id):
uri = '/networks/%s/dhcp-agents' % network_id
- return self._list_resources(uri)
+ return self.list_resources(uri)
def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
uri = '/agents/%s/dhcp-networks' % agent_id
- return self._list_resources(uri)
+ return self.list_resources(uri)
def remove_network_from_dhcp_agent(self, agent_id, network_id):
uri = '/agents/%s/dhcp-networks/%s' % (agent_id,
network_id)
- return self._delete_resource(uri)
+ return self.delete_resource(uri)
def update_extra_routes(self, router_id, routes):
uri = '/routers/%s' % router_id
@@ -478,7 +408,7 @@
'routes': routes
}
}
- return self._update_resource(uri, put_body)
+ return self.update_resource(uri, put_body)
def delete_extra_routes(self, router_id):
uri = '/routers/%s' % router_id
@@ -487,9 +417,9 @@
'routes': None
}
}
- return self._update_resource(uri, put_body)
+ return self.update_resource(uri, put_body)
def add_dhcp_agent_to_network(self, agent_id, network_id):
post_body = {'network_id': network_id}
uri = '/agents/%s/dhcp-networks' % agent_id
- return self._create_resource(uri, post_body)
+ return self.create_resource(uri, post_body)
diff --git a/tempest/services/network/json/networks_client.py b/tempest/services/network/json/networks_client.py
new file mode 100644
index 0000000..2907d44
--- /dev/null
+++ b/tempest/services/network/json/networks_client.py
@@ -0,0 +1,38 @@
+# 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.network.json import base
+
+
+class NetworksClient(base.BaseNetworkClient):
+
+ def create_network(self, **kwargs):
+ uri = '/networks'
+ post_data = {'network': kwargs}
+ return self.create_resource(uri, post_data)
+
+ def update_network(self, network_id, **kwargs):
+ uri = '/networks/%s' % network_id
+ post_data = {'network': kwargs}
+ return self.update_resource(uri, post_data)
+
+ def show_network(self, network_id, **fields):
+ uri = '/networks/%s' % network_id
+ return self.show_resource(uri, **fields)
+
+ def delete_network(self, network_id):
+ uri = '/networks/%s' % network_id
+ return self.delete_resource(uri)
+
+ def list_networks(self, **filters):
+ uri = '/networks'
+ return self.list_resources(uri, **filters)
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 4d45515..23d936e 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -41,6 +41,7 @@
def __init__(self, *args, **kwargs):
self.client = kwargs.pop('client', None)
+ self.networks_client = kwargs.pop('networks_client', None)
super(DeletableResource, self).__init__(*args, **kwargs)
def __str__(self):
@@ -72,7 +73,7 @@
class DeletableNetwork(DeletableResource):
def delete(self):
- self.client.delete_network(self.id)
+ self.networks_client.delete_network(self.id)
class DeletableSubnet(DeletableResource):
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 1f181e3..fc8951e 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -140,3 +140,10 @@
self.expected_success(200, resp.status)
body = self.deserialize(body)
return service_client.ResponseBodyData(resp, body)
+
+ def show_alarm_history(self, alarm_id):
+ uri = "%s/alarms/%s/history" % (self.uri_prefix, alarm_id)
+ resp, body = self.get(uri)
+ self.expected_success(200, resp.status)
+ body = self.deserialize(body)
+ return service_client.ResponseBodyList(resp, body)
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/backups_client.py b/tempest/services/volume/json/backups_client.py
index 8d34230..6827c93 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/json/backups_client.py
@@ -42,7 +42,7 @@
resp, body = self.post('backups', post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
- return service_client.ResponseBody(resp, body['backup'])
+ return service_client.ResponseBody(resp, body)
def restore_backup(self, backup_id, volume_id=None):
"""Restore volume from backup."""
@@ -51,7 +51,7 @@
resp, body = self.post('backups/%s/restore' % (backup_id), post_body)
body = json.loads(body)
self.expected_success(202, resp.status)
- return service_client.ResponseBody(resp, body['restore'])
+ return service_client.ResponseBody(resp, body)
def delete_backup(self, backup_id):
"""Delete a backup of volume."""
@@ -65,7 +65,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['backup'])
+ return service_client.ResponseBody(resp, body)
def list_backups(self, detail=False):
"""Information for all the tenant's backups."""
@@ -75,7 +75,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, body['backups'])
+ return service_client.ResponseBody(resp, body)
def export_backup(self, backup_id):
"""Export backup metadata record."""
@@ -83,7 +83,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body['backup-record'])
+ return service_client.ResponseBody(resp, body)
def import_backup(self, backup_service, backup_url):
"""Import backup metadata record."""
@@ -93,17 +93,17 @@
resp, body = self.post("backups/import_record", post_body)
body = json.loads(body)
self.expected_success(201, resp.status)
- return service_client.ResponseBody(resp, body['backup'])
+ return service_client.ResponseBody(resp, body)
def wait_for_backup_status(self, backup_id, status):
"""Waits for a Backup to reach a given status."""
- body = self.show_backup(backup_id)
+ body = self.show_backup(backup_id)['backup']
backup_status = body['status']
start = int(time.time())
while backup_status != status:
time.sleep(self.build_interval)
- body = self.show_backup(backup_id)
+ body = self.show_backup(backup_id)['backup']
backup_status = body['status']
if backup_status == 'error':
raise exceptions.VolumeBackupException(backup_id=backup_id)
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/server_create_destroy.py b/tempest/stress/actions/server_create_destroy.py
index 17f4bc9..44b6f62 100644
--- a/tempest/stress/actions/server_create_destroy.py
+++ b/tempest/stress/actions/server_create_destroy.py
@@ -30,7 +30,7 @@
name = data_utils.rand_name("instance")
self.logger.info("creating %s" % name)
server = self.manager.servers_client.create_server(
- name, self.image, self.flavor)
+ name=name, imageRef=self.image, flavorRef=self.flavor)['server']
server_id = server['id']
waiters.wait_for_server_status(self.manager.servers_client, server_id,
'ACTIVE')
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index 2a7a85c..d912b25 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -75,9 +75,9 @@
self.logger.info("creating %s" % name)
vm_args = self.vm_extra_args.copy()
vm_args['security_groups'] = [self.sec_grp]
- server = servers_client.create_server(name, self.image,
- self.flavor,
- **vm_args)
+ server = servers_client.create_server(name=name, imageRef=self.image,
+ flavorRef=self.flavor,
+ **vm_args)['server']
self.server_id = server['id']
if self.wait_after_vm_create:
waiters.wait_for_server_status(self.manager.servers_client,
@@ -95,7 +95,7 @@
s_name = data_utils.rand_name('sec_grp')
s_description = data_utils.rand_name('desc')
self.sec_grp = sec_grp_cli.create_security_group(
- name=s_name, description=s_description)
+ name=s_name, description=s_description)['security_group']
create_rule = sec_grp_cli.create_security_group_rule
create_rule(parent_group_id=self.sec_grp['id'], ip_protocol='tcp',
from_port=22, to_port=22)
@@ -108,7 +108,8 @@
def _create_floating_ip(self):
floating_cli = self.manager.floating_ips_client
- self.floating = floating_cli.create_floating_ip(self.floating_pool)
+ self.floating = (floating_cli.create_floating_ip(self.floating_pool)
+ ['floating_ip'])
def _destroy_floating_ip(self):
cli = self.manager.floating_ips_client
@@ -148,7 +149,8 @@
cli = self.manager.floating_ips_client
def func():
- floating = cli.show_floating_ip(self.floating['id'])
+ floating = (cli.show_floating_ip(self.floating['id'])
+ ['floating_ip'])
return floating['instance_id'] is None
if not tempest.test.call_until_true(func, self.check_timeout,
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index 68e2989..847f342 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'])
@@ -39,7 +39,7 @@
vm_name = data_utils.rand_name("instance")
self.logger.info("creating vm: %s" % vm_name)
server = self.manager.servers_client.create_server(
- vm_name, self.image, self.flavor)
+ name=vm_name, imageRef=self.image, flavorRef=self.flavor)['server']
server_id = server['id']
waiters.wait_for_server_status(self.manager.servers_client, server_id,
'ACTIVE')
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 038569a..95841a9 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -39,9 +39,9 @@
vm_args = self.vm_extra_args.copy()
vm_args['security_groups'] = [self.sec_grp]
vm_args['key_name'] = self.key['name']
- server = servers_client.create_server(name, self.image,
- self.flavor,
- **vm_args)
+ server = servers_client.create_server(name=name, imageRef=self.image,
+ flavorRef=self.flavor,
+ **vm_args)['server']
self.server_id = server['id']
waiters.wait_for_server_status(self.manager.servers_client,
self.server_id, 'ACTIVE')
@@ -58,7 +58,7 @@
s_name = data_utils.rand_name('sec_grp')
s_description = data_utils.rand_name('desc')
self.sec_grp = sec_grp_cli.create_security_group(
- name=s_name, description=s_description)
+ name=s_name, description=s_description)['security_group']
create_rule = sec_grp_cli.create_security_group_rule
create_rule(parent_group_id=self.sec_grp['id'], ip_protocol='tcp',
from_port=22, to_port=22)
@@ -71,7 +71,8 @@
def _create_floating_ip(self):
floating_cli = self.manager.floating_ips_client
- self.floating = floating_cli.create_floating_ip(self.floating_pool)
+ self.floating = (floating_cli.create_floating_ip(self.floating_pool)
+ ['floating_ip'])
def _destroy_floating_ip(self):
cli = self.manager.floating_ips_client
@@ -84,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'])
@@ -100,7 +101,8 @@
cli = self.manager.floating_ips_client
def func():
- floating = cli.show_floating_ip(self.floating['id'])
+ floating = (cli.show_floating_ip(self.floating['id'])
+ ['floating_ip'])
return floating['instance_id'] is None
if not tempest.test.call_until_true(func, CONF.compute.build_timeout,
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/stress/cleanup.py b/tempest/stress/cleanup.py
index 9e21326..1350d95 100644
--- a/tempest/stress/cleanup.py
+++ b/tempest/stress/cleanup.py
@@ -49,7 +49,8 @@
pass
secgrp_client = admin_manager.security_groups_client
- secgrp = secgrp_client.list_security_groups(all_tenants=True)
+ secgrp = (secgrp_client.list_security_groups(all_tenants=True)
+ ['security_groups'])
secgrp_del = [grp for grp in secgrp if grp['name'] != 'default']
LOG.info("Cleanup::remove %s Security Group" % len(secgrp_del))
for g in secgrp_del:
@@ -58,7 +59,8 @@
except Exception:
pass
- floating_ips = admin_manager.floating_ips_client.list_floating_ips()
+ floating_ips = (admin_manager.floating_ips_client.list_floating_ips()
+ ['floating_ips'])
LOG.info("Cleanup::remove %s floating ips" % len(floating_ips))
for f in floating_ips:
try:
@@ -66,7 +68,7 @@
except Exception:
pass
- users = admin_manager.identity_client.get_users()
+ users = admin_manager.identity_client.get_users()['users']
LOG.info("Cleanup::remove %s users" % len(users))
for user in users:
if user['name'].startswith("stress_user"):
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index bdb39d8..7634d2c 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -25,7 +25,7 @@
from tempest import clients
-from tempest.common import isolated_creds
+from tempest.common import cred_client
from tempest.common.utils import data_utils
from tempest import config
from tempest import exceptions
@@ -155,7 +155,7 @@
identity_client = admin_manager.identity_client
else:
identity_client = admin_manager.identity_v3_client
- credentials_client = isolated_creds.get_creds_client(
+ credentials_client = cred_client.get_creds_client(
identity_client)
project = credentials_client.create_project(
name=tenant_name, description=tenant_name)
diff --git a/tempest/test.py b/tempest/test.py
index df6b30d..142488c 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -31,6 +31,7 @@
import testtools
from tempest import clients
+from tempest.common import cred_client
from tempest.common import credentials
from tempest.common import fixed_network
import tempest.common.generator.valid_generator as valid
@@ -182,6 +183,7 @@
'volume': CONF.volume_feature_enabled.api_extensions,
'network': CONF.network_feature_enabled.api_extensions,
'object': CONF.object_storage_feature_enabled.discoverable_apis,
+ 'identity': CONF.identity_feature_enabled.api_extensions
}
if len(config_dict[service]) == 0:
return False
@@ -432,6 +434,25 @@
def credentials_provider(self):
return self._get_credentials_provider()
+ @property
+ def identity_utils(self):
+ """A client that abstracts v2 and v3 identity operations.
+
+ This can be used for creating and tearing down projects in tests. It
+ should not be used for testing identity features.
+ """
+ if CONF.identity.auth_version == 'v2':
+ client = self.os_admin.identity_client
+ else:
+ client = self.os_admin.identity_v3_client
+
+ try:
+ domain = client.auth_provider.credentials.project_domain_name
+ except AttributeError:
+ domain = 'Default'
+
+ return cred_client.get_creds_client(client, domain)
+
@classmethod
def _get_credentials_provider(cls):
"""Returns a credentials provider
@@ -530,9 +551,10 @@
else:
floating_ip = False
if security_group is None:
- security_group = True
+ security_group = CONF.validation.security_group
if security_group_rules is None:
- security_group_rules = True
+ security_group_rules = CONF.validation.security_group_rules
+
if not cls.validation_resources:
cls.validation_resources = {
'keypair': keypair,
@@ -568,7 +590,7 @@
:return: network dict including 'id' and 'name'
"""
# Make sure isolated_creds exists and get a network client
- networks_client = cls.get_client_manager().networks_client
+ networks_client = cls.get_client_manager().compute_networks_client
cred_provider = cls._get_credentials_provider()
# In case of nova network, isolated tenants are not able to list the
# network configured in fixed_network_name, even if the can use it
@@ -577,7 +599,8 @@
if (not CONF.service_available.neutron and
credentials.is_admin_available()):
admin_creds = cred_provider.get_admin_creds()
- networks_client = clients.Manager(admin_creds).networks_client
+ admin_manager = clients.Manager(admin_creds)
+ networks_client = admin_manager.compute_networks_client
return fixed_network.get_tenant_network(cred_provider,
networks_client)
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index d1dee54..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):
@@ -270,9 +270,10 @@
def test_create_secgroup(self):
self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
return_value=self.fake_client))
- self.fake_client.secgroups.list_security_groups.return_value = []
+ self.fake_client.secgroups.list_security_groups.return_value = (
+ {'security_groups': []})
self.fake_client.secgroups.create_security_group.return_value = \
- {'id': self.fake_object['secgroup_id']}
+ {'security_group': {'id': self.fake_object['secgroup_id']}}
javelin.create_secgroups([self.fake_object])
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 6bc96f2..a5dea54 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -113,7 +113,7 @@
'print_and_or_update') as print_mock:
verify_tempest_config.verify_keystone_api_versions(fake_os, True)
print_mock.assert_called_once_with('api_v3',
- 'identity_feature_enabled',
+ 'identity-feature-enabled',
False, True)
def test_verify_keystone_api_versions_no_v2(self):
@@ -129,7 +129,7 @@
'print_and_or_update') as print_mock:
verify_tempest_config.verify_keystone_api_versions(fake_os, True)
print_mock.assert_called_once_with('api_v2',
- 'identity_feature_enabled',
+ 'identity-feature-enabled',
False, True)
def test_verify_cinder_api_versions_no_v2(self):
@@ -144,7 +144,7 @@
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_cinder_api_versions(fake_os, True)
- print_mock.assert_called_once_with('api_v2', 'volume_feature_enabled',
+ print_mock.assert_called_once_with('api_v2', 'volume-feature-enabled',
False, True)
def test_verify_cinder_api_versions_no_v1(self):
@@ -159,7 +159,7 @@
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_cinder_api_versions(fake_os, True)
- print_mock.assert_called_once_with('api_v1', 'volume_feature_enabled',
+ print_mock.assert_called_once_with('api_v1', 'volume-feature-enabled',
False, True)
def test_verify_glance_version_no_v2_with_v1_1(self):
@@ -170,7 +170,7 @@
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
- print_mock.assert_called_once_with('api_v2', 'image_feature_enabled',
+ print_mock.assert_called_once_with('api_v2', 'image-feature-enabled',
False, True)
def test_verify_glance_version_no_v2_with_v1_0(self):
@@ -181,7 +181,7 @@
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
- print_mock.assert_called_once_with('api_v2', 'image_feature_enabled',
+ print_mock.assert_called_once_with('api_v2', 'image-feature-enabled',
False, True)
def test_verify_glance_version_no_v1(self):
@@ -192,7 +192,7 @@
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
- print_mock.assert_called_once_with('api_v1', 'image_feature_enabled',
+ print_mock.assert_called_once_with('api_v1', 'image-feature-enabled',
False, True)
def test_verify_extensions_neutron(self):
@@ -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 8fc3745..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)
@@ -297,8 +297,9 @@
test_accounts_class = accounts.Accounts('v2', 'test_name')
with mock.patch('tempest.services.compute.json.networks_client.'
'NetworksClient.list_networks',
- return_value=[{'name': 'network-2', 'id': 'fake-id',
- 'label': 'network-2'}]):
+ return_value={'networks': [{'name': 'network-2',
+ 'id': 'fake-id',
+ 'label': 'network-2'}]}):
creds = test_accounts_class.get_creds_by_roles(['role-7'])
self.assertTrue(isinstance(creds, cred_provider.TestResources))
network = creds.network
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
index adc0785..d404660 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..31e576e 100644
--- a/tempest/tests/services/compute/test_agents_client.py
+++ b/tempest/tests/services/compute/test_agents_client.py
@@ -12,17 +12,38 @@
# 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_lib.tests import fake_auth_provider
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 +52,40 @@
'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)
+ self.check_service_client_function(
+ self.client.list_agents,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"agents": []},
+ bytes_body,
+ hypervisor="kvm")
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 eacc251..e92b76b 100644
--- a/tempest/tests/services/compute/test_aggregates_client.py
+++ b/tempest/tests/services/compute/test_aggregates_client.py
@@ -12,17 +12,56 @@
# 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_lib.tests import fake_auth_provider
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 +70,11 @@
fake_auth, 'compute', 'regionOne')
def _test_list_aggregates(self, bytes_body=False):
- body = '{"aggregates": []}'
- if bytes_body:
- body = body.encode('utf-8')
- expected = []
- 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 +83,12 @@
self._test_list_aggregates(bytes_body=True)
def _test_show_aggregate(self, bytes_body=False):
- expected = {"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({"aggregate": 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 +97,12 @@
self._test_show_aggregate(bytes_body=True)
def _test_create_aggregate(self, bytes_body=False):
- expected = {"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({"aggregate": 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 +111,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 = {"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({"aggregate": 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..e1d94bc
--- /dev/null
+++ b/tempest/tests/services/compute/test_availability_zone_client.py
@@ -0,0 +1,82 @@
+# 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_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import availability_zone_client
+from tempest.tests.services.compute import base
+
+
+class TestAvailabilityZoneClient(base.BaseComputeServiceTest):
+
+ FAKE_AZ_INFO = {
+ "availabilityZoneInfo":
+ [
+ {
+ "zoneState": {
+ "available": True
+ },
+ "hosts": None,
+ "zoneName": u'\xf4'
+ }
+ ]
+ }
+
+ FAKE_AZ_DETAILS = {
+ "testhost": {
+ "nova-compute": {
+ "available": True,
+ "active": True,
+ "updated_at": "2015-09-10T07:16:46.000000"
+ }
+ }
+ }
+
+ 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_availability_zones(self, to_utf=False):
+ self.check_service_client_function(
+ self.client.list_availability_zones,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_AZ_INFO,
+ to_utf)
+
+ def _test_availability_zones_with_details(self, to_utf=False):
+ fake_az_details = copy.deepcopy(self.FAKE_AZ_INFO)
+ fake_az_details['availabilityZoneInfo'][0]['hosts'] = \
+ self.FAKE_AZ_DETAILS
+ self.check_service_client_function(
+ self.client.list_availability_zones,
+ 'tempest.common.service_client.ServiceClient.get',
+ fake_az_details,
+ to_utf,
+ detail=True)
+
+ def test_list_availability_zones_with_str_body(self):
+ self._test_availability_zones()
+
+ def test_list_availability_zones_with_bytes_body(self):
+ self._test_availability_zones(True)
+
+ def test_list_availability_zones_with_str_body_and_details(self):
+ self._test_availability_zones_with_details()
+
+ def test_list_availability_zones_with_bytes_body_and_details(self):
+ self._test_availability_zones_with_details(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..86c035c
--- /dev/null
+++ b/tempest/tests/services/compute/test_baremetal_nodes_client.py
@@ -0,0 +1,75 @@
+# 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_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import baremetal_nodes_client
+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..2ba90d0
--- /dev/null
+++ b/tempest/tests/services/compute/test_certificates_client.py
@@ -0,0 +1,65 @@
+# 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_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import certificates_client
+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..21efc52 100644
--- a/tempest/tests/services/compute/test_extensions_client.py
+++ b/tempest/tests/services/compute/test_extensions_client.py
@@ -12,17 +12,25 @@
# 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_lib.tests import fake_auth_provider
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 +39,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 +52,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..5acb422
--- /dev/null
+++ b/tempest/tests/services/compute/test_fixedIPs_client.py
@@ -0,0 +1,46 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import fixed_ips_client
+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_flavors_client.py b/tempest/tests/services/compute/test_flavors_client.py
new file mode 100644
index 0000000..6c0edb8
--- /dev/null
+++ b/tempest/tests/services/compute/test_flavors_client.py
@@ -0,0 +1,255 @@
+# Copyright 2015 IBM Corp.
+#
+# 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
+import httplib2
+
+from oslo_serialization import jsonutils as json
+from oslotest import mockpatch
+
+from tempest.services.compute.json import flavors_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFlavorsClient(base.BaseComputeServiceTest):
+
+ FAKE_FLAVOR = {
+ "disk": 1,
+ "id": "1",
+ "links": [{
+ "href": "http://openstack.example.com/v2/openstack/flavors/1",
+ "rel": "self"}, {
+ "href": "http://openstack.example.com/openstack/flavors/1",
+ "rel": "bookmark"}],
+ "name": "m1.tiny",
+ "ram": 512,
+ "swap": 1,
+ "vcpus": 1
+ }
+
+ EXTRA_SPECS = {"extra_specs": {
+ "key1": "value1",
+ "key2": "value2"}
+ }
+
+ FAKE_FLAVOR_ACCESS = {
+ "flavor_id": "10",
+ "tenant_id": "1a951d988e264818afe520e78697dcbf"
+ }
+
+ def setUp(self):
+ super(TestFlavorsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = flavors_client.FlavorsClient(fake_auth,
+ 'compute', 'regionOne')
+
+ def _test_list_flavors(self, bytes_body=False):
+ flavor = copy.deepcopy(TestFlavorsClient.FAKE_FLAVOR)
+ # Remove extra attributes
+ for attribute in ('disk', 'vcpus', 'ram', 'swap'):
+ del flavor[attribute]
+ expected = {'flavors': [flavor]}
+ self.check_service_client_function(
+ self.client.list_flavors,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected,
+ bytes_body)
+
+ def test_list_flavors_str_body(self):
+ self._test_list_flavors(bytes_body=False)
+
+ def test_list_flavors_byte_body(self):
+ self._test_list_flavors(bytes_body=True)
+
+ def _test_show_flavor(self, bytes_body=False):
+ expected = {"flavor": TestFlavorsClient.FAKE_FLAVOR}
+ self.check_service_client_function(
+ self.client.show_flavor,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected,
+ bytes_body,
+ flavor_id='fake-id')
+
+ def test_show_flavor_str_body(self):
+ self._test_show_flavor(bytes_body=False)
+
+ def test_show_flavor_byte_body(self):
+ self._test_show_flavor(bytes_body=True)
+
+ def _test_create_flavor(self, bytes_body=False):
+ expected = {"flavor": TestFlavorsClient.FAKE_FLAVOR}
+ request = copy.deepcopy(TestFlavorsClient.FAKE_FLAVOR)
+ # The 'links' parameter should not be passed in
+ del request['links']
+ self.check_service_client_function(
+ self.client.create_flavor,
+ 'tempest.common.service_client.ServiceClient.post',
+ expected,
+ bytes_body,
+ **request)
+
+ def test_create_flavor_str_body(self):
+ self._test_create_flavor(bytes_body=False)
+
+ def test_create_flavor__byte_body(self):
+ self._test_create_flavor(bytes_body=True)
+
+ def test_delete_flavor(self):
+ self.check_service_client_function(
+ self.client.delete_flavor,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=202, flavor_id='c782b7a9-33cd-45f0-b795-7f87f456408b')
+
+ def _test_is_resource_deleted(self, flavor_id, is_deleted=True,
+ bytes_body=False):
+ body = json.dumps({'flavors': [TestFlavorsClient.FAKE_FLAVOR]})
+ if bytes_body:
+ body = body.encode('utf-8')
+ response = (httplib2.Response({'status': 200}), body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.get',
+ return_value=response))
+ self.assertEqual(is_deleted,
+ self.client.is_resource_deleted(flavor_id))
+
+ def test_is_resource_deleted_true_str_body(self):
+ self._test_is_resource_deleted('2', bytes_body=False)
+
+ def test_is_resource_deleted_true_byte_body(self):
+ self._test_is_resource_deleted('2', bytes_body=True)
+
+ def test_is_resource_deleted_false_str_body(self):
+ self._test_is_resource_deleted('1', is_deleted=False, bytes_body=False)
+
+ def test_is_resource_deleted_false_byte_body(self):
+ self._test_is_resource_deleted('1', is_deleted=False, bytes_body=True)
+
+ def _test_set_flavor_extra_spec(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.set_flavor_extra_spec,
+ 'tempest.common.service_client.ServiceClient.post',
+ TestFlavorsClient.EXTRA_SPECS,
+ bytes_body,
+ flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
+ **TestFlavorsClient.EXTRA_SPECS)
+
+ def test_set_flavor_extra_spec_str_body(self):
+ self._test_set_flavor_extra_spec(bytes_body=False)
+
+ def test_set_flavor_extra_spec_byte_body(self):
+ self._test_set_flavor_extra_spec(bytes_body=True)
+
+ def _test_list_flavor_extra_specs(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_flavor_extra_specs,
+ 'tempest.common.service_client.ServiceClient.get',
+ TestFlavorsClient.EXTRA_SPECS,
+ bytes_body,
+ flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6')
+
+ def test_list_flavor_extra_specs_str_body(self):
+ self._test_list_flavor_extra_specs(bytes_body=False)
+
+ def test_list_flavor_extra_specs__byte_body(self):
+ self._test_list_flavor_extra_specs(bytes_body=True)
+
+ def _test_show_flavor_extra_spec(self, bytes_body=False):
+ expected = {"key": "value"}
+ self.check_service_client_function(
+ self.client.show_flavor_extra_spec,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected,
+ bytes_body,
+ flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
+ key='key')
+
+ def test_show_flavor_extra_spec_str_body(self):
+ self._test_show_flavor_extra_spec(bytes_body=False)
+
+ def test_show_flavor_extra_spec__byte_body(self):
+ self._test_show_flavor_extra_spec(bytes_body=True)
+
+ def _test_update_flavor_extra_spec(self, bytes_body=False):
+ expected = {"key1": "value"}
+ self.check_service_client_function(
+ self.client.update_flavor_extra_spec,
+ 'tempest.common.service_client.ServiceClient.put',
+ expected,
+ bytes_body,
+ flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
+ key='key1', **expected)
+
+ def test_update_flavor_extra_spec_str_body(self):
+ self._test_update_flavor_extra_spec(bytes_body=False)
+
+ def test_update_flavor_extra_spec_byte_body(self):
+ self._test_update_flavor_extra_spec(bytes_body=True)
+
+ def test_unset_flavor_extra_spec(self):
+ self.check_service_client_function(
+ self.client.unset_flavor_extra_spec,
+ 'tempest.common.service_client.ServiceClient.delete', {},
+ flavor_id='c782b7a9-33cd-45f0-b795-7f87f456408b', key='key')
+
+ def _test_list_flavor_access(self, bytes_body=False):
+ expected = {'flavor_access': [TestFlavorsClient.FAKE_FLAVOR_ACCESS]}
+ self.check_service_client_function(
+ self.client.list_flavor_access,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected,
+ bytes_body,
+ flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6')
+
+ def test_list_flavor_access_str_body(self):
+ self._test_list_flavor_access(bytes_body=False)
+
+ def test_list_flavor_access_byte_body(self):
+ self._test_list_flavor_access(bytes_body=True)
+
+ def _test_add_flavor_access(self, bytes_body=False):
+ expected = {
+ "flavor_access": [TestFlavorsClient.FAKE_FLAVOR_ACCESS]
+ }
+ self.check_service_client_function(
+ self.client.add_flavor_access,
+ 'tempest.common.service_client.ServiceClient.post',
+ expected,
+ bytes_body,
+ flavor_id='8c7aae5a-d315-4216-875b-ed9b6a5bcfc6',
+ tenant_id='1a951d988e264818afe520e78697dcbf')
+
+ def test_add_flavor_access_str_body(self):
+ self._test_add_flavor_access(bytes_body=False)
+
+ def test_add_flavor_access_byte_body(self):
+ self._test_add_flavor_access(bytes_body=True)
+
+ def _test_remove_flavor_access(self, bytes_body=False):
+ expected = {
+ "flavor_access": [TestFlavorsClient.FAKE_FLAVOR_ACCESS]
+ }
+ self.check_service_client_function(
+ self.client.remove_flavor_access,
+ 'tempest.common.service_client.ServiceClient.post',
+ expected,
+ bytes_body,
+ flavor_id='10',
+ tenant_id='a6edd4d66ad04245b5d2d8716ecc91e3')
+
+ def test_remove_flavor_access_str_body(self):
+ self._test_remove_flavor_access(bytes_body=False)
+
+ def test_remove_flavor_access_byte_body(self):
+ self._test_remove_flavor_access(bytes_body=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..1cb4bf3
--- /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_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import floating_ip_pools_client
+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..600985b
--- /dev/null
+++ b/tempest/tests/services/compute/test_floating_ips_bulk_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_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import floating_ips_bulk_client
+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_floating_ips_client.py b/tempest/tests/services/compute/test_floating_ips_client.py
new file mode 100644
index 0000000..ee22004
--- /dev/null
+++ b/tempest/tests/services/compute/test_floating_ips_client.py
@@ -0,0 +1,113 @@
+# Copyright 2015 IBM Corp.
+#
+# 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 floating_ips_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestFloatingIpsClient(base.BaseComputeServiceTest):
+
+ floating_ip = {"fixed_ip": None,
+ "id": "46d61064-13ba-4bf0-9557-69de824c3d6f",
+ "instance_id": "a1daa443-a6bb-463e-aea2-104b7d912eb8",
+ "ip": "10.10.10.1",
+ "pool": "nova"}
+
+ def setUp(self):
+ super(TestFloatingIpsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = floating_ips_client.FloatingIPsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_floating_ips(self, bytes_body=False):
+ expected = {'floating_ips': [TestFloatingIpsClient.floating_ip]}
+ self.check_service_client_function(
+ self.client.list_floating_ips,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected,
+ bytes_body)
+
+ def test_list_floating_ips_str_body(self):
+ self._test_list_floating_ips(bytes_body=False)
+
+ def test_list_floating_ips_byte_body(self):
+ self._test_list_floating_ips(bytes_body=True)
+
+ def _test_show_floating_ip(self, bytes_body=False):
+ expected = {"floating_ip": TestFloatingIpsClient.floating_ip}
+ self.check_service_client_function(
+ self.client.show_floating_ip,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected,
+ bytes_body,
+ floating_ip_id='a1daa443-a6bb-463e-aea2-104b7d912eb8')
+
+ def test_show_floating_ip_str_body(self):
+ self._test_show_floating_ip(bytes_body=False)
+
+ def test_show_floating_ip_byte_body(self):
+ self._test_show_floating_ip(bytes_body=True)
+
+ def _test_create_floating_ip(self, bytes_body=False):
+ expected = {"floating_ip": TestFloatingIpsClient.floating_ip}
+ self.check_service_client_function(
+ self.client.create_floating_ip,
+ 'tempest.common.service_client.ServiceClient.post',
+ expected,
+ bytes_body,
+ pool_name='nova')
+
+ def test_create_floating_ip_str_body(self):
+ self._test_create_floating_ip(bytes_body=False)
+
+ def test_create_floating_ip_byte_body(self):
+ self._test_create_floating_ip(bytes_body=True)
+
+ def test_delete_floating_ip(self):
+ self.check_service_client_function(
+ self.client.delete_floating_ip,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=202, floating_ip_id='fake-id')
+
+ def test_associate_floating_ip_to_server(self):
+ self.check_service_client_function(
+ self.client.associate_floating_ip_to_server,
+ 'tempest.common.service_client.ServiceClient.post',
+ {}, status=202, floating_ip='10.10.10.1',
+ server_id='c782b7a9-33cd-45f0-b795-7f87f456408b')
+
+ def test_disassociate_floating_ip_from_server(self):
+ self.check_service_client_function(
+ self.client.disassociate_floating_ip_from_server,
+ 'tempest.common.service_client.ServiceClient.post',
+ {}, status=202, floating_ip='10.10.10.1',
+ server_id='c782b7a9-33cd-45f0-b795-7f87f456408b')
+
+ def test_is_resource_deleted_true(self):
+ self.useFixture(mockpatch.Patch(
+ 'tempest.services.compute.json.floating_ips_client.'
+ 'FloatingIPsClient.show_floating_ip',
+ side_effect=lib_exc.NotFound()))
+ self.assertTrue(self.client.is_resource_deleted('fake-id'))
+
+ def test_is_resource_deleted_false(self):
+ self.useFixture(mockpatch.Patch(
+ 'tempest.services.compute.json.floating_ips_client.'
+ 'FloatingIPsClient.show_floating_ip',
+ return_value={"floating_ip": TestFloatingIpsClient.floating_ip}))
+ self.assertFalse(self.client.is_resource_deleted('fake-id'))
diff --git a/tempest/tests/services/compute/test_hosts_client.py b/tempest/tests/services/compute/test_hosts_client.py
new file mode 100644
index 0000000..2b7fdb5
--- /dev/null
+++ b/tempest/tests/services/compute/test_hosts_client.py
@@ -0,0 +1,147 @@
+# 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 hosts_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestHostsClient(base.BaseComputeServiceTest):
+ FAKE_HOST_DATA = {
+ "host": {
+ "resource": {
+ "cpu": 1,
+ "disk_gb": 1028,
+ "host": "c1a7de0ac9d94e4baceae031d05caae3",
+ "memory_mb": 8192,
+ "project": "(total)"
+ }
+ },
+ "hosts": {
+ "host_name": "c1a7de0ac9d94e4baceae031d05caae3",
+ "service": "conductor",
+ "zone": "internal"
+ },
+ "enable_hosts": {
+ "host": "65c5d5b7e3bd44308e67fc50f362aee6",
+ "maintenance_mode": "off_maintenance",
+ "status": "enabled"
+ }
+ }
+
+ FAKE_CONTROL_DATA = {
+ "shutdown": {
+ "host": "c1a7de0ac9d94e4baceae031d05caae3",
+ "power_action": "shutdown"
+ },
+ "startup": {
+ "host": "c1a7de0ac9d94e4baceae031d05caae3",
+ "power_action": "startup"
+ },
+ "reboot": {
+ "host": "c1a7de0ac9d94e4baceae031d05caae3",
+ "power_action": "reboot"
+ }}
+
+ HOST_DATA = {'host': [FAKE_HOST_DATA['host']]}
+ HOSTS_DATA = {'hosts': [FAKE_HOST_DATA['hosts']]}
+ ENABLE_HOST_DATA = FAKE_HOST_DATA['enable_hosts']
+ HOST_ID = "c1a7de0ac9d94e4baceae031d05caae3"
+ TEST_HOST_DATA = {
+ "status": "enable",
+ "maintenance_mode": "disable"
+ }
+
+ def setUp(self):
+ super(TestHostsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = hosts_client.HostsClient(fake_auth, 'compute',
+ 'regionOne')
+ self.params = {'hostname': self.HOST_ID}
+ self.func2mock = {
+ 'get': 'tempest.common.service_client.ServiceClient.get',
+ 'put': 'tempest.common.service_client.ServiceClient.put'}
+
+ def _test_host_data(self, test_type='list', bytes_body=False):
+ expected_resp = self.HOST_DATA
+ if test_type != 'list':
+ function_call = self.client.show_host
+ else:
+ expected_resp = self.HOSTS_DATA
+ function_call = self.client.list_hosts
+ self.params = {'host_name': self.HOST_ID}
+
+ self.check_service_client_function(
+ function_call, self.func2mock['get'],
+ expected_resp, bytes_body,
+ 200, **self.params)
+
+ def _test_update_hosts(self, bytes_body=False):
+ expected_resp = self.ENABLE_HOST_DATA
+ self.check_service_client_function(
+ self.client.update_host, self.func2mock['put'],
+ expected_resp, bytes_body,
+ 200, **self.params)
+
+ def _test_control_host(self, control_op='reboot', bytes_body=False):
+ if control_op == 'start':
+ expected_resp = self.FAKE_CONTROL_DATA['startup']
+ function_call = self.client.startup_host
+ elif control_op == 'stop':
+ expected_resp = self.FAKE_CONTROL_DATA['shutdown']
+ function_call = self.client.shutdown_host
+ else:
+ expected_resp = self.FAKE_CONTROL_DATA['reboot']
+ function_call = self.client.reboot_host
+
+ self.check_service_client_function(
+ function_call, self.func2mock['get'],
+ expected_resp, bytes_body,
+ 200, **self.params)
+
+ def test_show_host_with_str_body(self):
+ self._test_host_data('show')
+
+ def test_show_host_with_bytes_body(self):
+ self._test_host_data('show', True)
+
+ def test_list_host_with_str_body(self):
+ self._test_host_data()
+
+ def test_list_host_with_bytes_body(self):
+ self._test_host_data(bytes_body=True)
+
+ def test_start_host_with_str_body(self):
+ self._test_control_host('start')
+
+ def test_start_host_with_bytes_body(self):
+ self._test_control_host('start', True)
+
+ def test_stop_host_with_str_body(self):
+ self._test_control_host('stop')
+
+ def test_stop_host_with_bytes_body(self):
+ self._test_control_host('stop', True)
+
+ def test_reboot_host_with_str_body(self):
+ self._test_control_host('reboot')
+
+ def test_reboot_host_with_bytes_body(self):
+ self._test_control_host('reboot', True)
+
+ def test_update_host_with_str_body(self):
+ self._test_update_hosts()
+
+ def test_update_host_with_bytes_body(self):
+ self._test_update_hosts(True)
diff --git a/tempest/tests/services/compute/test_hypervisor_client.py b/tempest/tests/services/compute/test_hypervisor_client.py
new file mode 100644
index 0000000..441e7e6
--- /dev/null
+++ b/tempest/tests/services/compute/test_hypervisor_client.py
@@ -0,0 +1,167 @@
+# Copyright 2015 IBM Corp.
+#
+# 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 hypervisor_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestHypervisorClient(base.BaseComputeServiceTest):
+
+ hypervisor_id = "1"
+ hypervisor_name = "hyper.hostname.com"
+
+ def setUp(self):
+ super(TestHypervisorClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = hypervisor_client.HypervisorClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def test_list_hypervisor_str_body(self):
+ self._test_list_hypervisor(bytes_body=False)
+
+ def test_list_hypervisor_byte_body(self):
+ self._test_list_hypervisor(bytes_body=True)
+
+ def _test_list_hypervisor(self, bytes_body=False):
+ expected = {"hypervisors": [{
+ "id": 1,
+ "hypervisor_hostname": "hypervisor1.hostname.com"},
+ {
+ "id": 2,
+ "hypervisor_hostname": "hypervisor2.hostname.com"}]}
+ self.check_service_client_function(
+ self.client.list_hypervisors,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body)
+
+ def test_show_hypervisor_str_body(self):
+ self._test_show_hypervisor(bytes_body=False)
+
+ def test_show_hypervisor_byte_body(self):
+ self._test_show_hypervisor(bytes_body=True)
+
+ def _test_show_hypervisor(self, bytes_body=False):
+ expected = {"hypervisor": {
+ "cpu_info": "?",
+ "current_workload": 0,
+ "disk_available_least": 1,
+ "host_ip": "10.10.10.10",
+ "free_disk_gb": 1028,
+ "free_ram_mb": 7680,
+ "hypervisor_hostname": "fake-mini",
+ "hypervisor_type": "fake",
+ "hypervisor_version": 1,
+ "id": 1,
+ "local_gb": 1028,
+ "local_gb_used": 0,
+ "memory_mb": 8192,
+ "memory_mb_used": 512,
+ "running_vms": 0,
+ "service": {
+ "host": "fake_host",
+ "id": 2},
+ "vcpus": 1,
+ "vcpus_used": 0}}
+ self.check_service_client_function(
+ self.client.show_hypervisor,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body,
+ hypervisor_id=self.hypervisor_id)
+
+ def test_list_servers_on_hypervisor_str_body(self):
+ self._test_list_servers_on_hypervisor(bytes_body=False)
+
+ def test_list_servers_on_hypervisor_byte_body(self):
+ self._test_list_servers_on_hypervisor(bytes_body=True)
+
+ def _test_list_servers_on_hypervisor(self, bytes_body=False):
+ expected = {"hypervisors": [{
+ "id": 1,
+ "hypervisor_hostname": "hyper.hostname.com",
+ "servers": [{
+ "uuid": "e1ae8fc4-b72d-4c2f-a427-30dd420b6277",
+ "name": "instance-00000001"},
+ {
+ "uuid": "e1ae8fc4-b72d-4c2f-a427-30dd42066666",
+ "name": "instance-00000002"}
+ ]}
+ ]}
+ self.check_service_client_function(
+ self.client.list_servers_on_hypervisor,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body,
+ hypervisor_name=self.hypervisor_name)
+
+ def test_show_hypervisor_statistics_str_body(self):
+ self._test_show_hypervisor_statistics(bytes_body=False)
+
+ def test_show_hypervisor_statistics_byte_body(self):
+ self._test_show_hypervisor_statistics(bytes_body=True)
+
+ def _test_show_hypervisor_statistics(self, bytes_body=False):
+ expected = {
+ "hypervisor_statistics": {
+ "count": 1,
+ "current_workload": 0,
+ "disk_available_least": 0,
+ "free_disk_gb": 1028,
+ "free_ram_mb": 7680,
+ "local_gb": 1028,
+ "local_gb_used": 0,
+ "memory_mb": 8192,
+ "memory_mb_used": 512,
+ "running_vms": 0,
+ "vcpus": 1,
+ "vcpus_used": 0}}
+ self.check_service_client_function(
+ self.client.show_hypervisor_statistics,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body)
+
+ def test_show_hypervisor_uptime_str_body(self):
+ self._test_show_hypervisor_uptime(bytes_body=False)
+
+ def test_show_hypervisor_uptime_byte_body(self):
+ self._test_show_hypervisor_uptime(bytes_body=True)
+
+ def _test_show_hypervisor_uptime(self, bytes_body=False):
+ expected = {
+ "hypervisor": {
+ "hypervisor_hostname": "fake-mini",
+ "id": 1,
+ "uptime": (" 08:32:11 up 93 days, 18:25, 12 users, "
+ " load average: 0.20, 0.12, 0.14")
+ }}
+ self.check_service_client_function(
+ self.client.show_hypervisor_uptime,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body,
+ hypervisor_id=self.hypervisor_id)
+
+ def test_search_hypervisor_str_body(self):
+ self._test_search_hypervisor(bytes_body=False)
+
+ def test_search_hypervisor_byte_body(self):
+ self._test_search_hypervisor(bytes_body=True)
+
+ def _test_search_hypervisor(self, bytes_body=False):
+ expected = {"hypervisors": [{
+ "id": 2,
+ "hypervisor_hostname": "hyper.hostname.com"}]}
+ self.check_service_client_function(
+ self.client.search_hypervisor,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body,
+ hypervisor_name=self.hypervisor_name)
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..b4af9d5
--- /dev/null
+++ b/tempest/tests/services/compute/test_instance_usage_audit_log_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 datetime
+
+from tempest_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import instance_usage_audit_log_client
+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_interfaces_client.py b/tempest/tests/services/compute/test_interfaces_client.py
new file mode 100644
index 0000000..235585a
--- /dev/null
+++ b/tempest/tests/services/compute/test_interfaces_client.py
@@ -0,0 +1,98 @@
+# 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 interfaces_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestInterfacesClient(base.BaseComputeServiceTest):
+ # Data Values to be used for testing #
+ FAKE_INTERFACE_DATA = {
+ "fixed_ips": [{
+ "ip_address": "192.168.1.1",
+ "subnet_id": "f8a6e8f8-c2ec-497c-9f23-da9616de54ef"
+ }],
+ "mac_addr": "fa:16:3e:4c:2c:30",
+ "net_id": "3cb9bc59-5699-4588-a4b1-b87f96708bc6",
+ "port_id": "ce531f90-199f-48c0-816c-13e38010b442",
+ "port_state": "ACTIVE"}
+
+ FAKE_SHOW_DATA = {
+ "interfaceAttachment": FAKE_INTERFACE_DATA}
+ FAKE_LIST_DATA = {
+ "interfaceAttachments": [FAKE_INTERFACE_DATA]}
+
+ FAKE_SERVER_ID = "ec14c864-096e-4e27-bb8a-2c2b4dc6f3f5"
+ FAKE_PORT_ID = FAKE_SHOW_DATA['interfaceAttachment']['port_id']
+ func2mock = {
+ 'delete': 'tempest.common.service_client.ServiceClient.delete',
+ 'get': 'tempest.common.service_client.ServiceClient.get',
+ 'post': 'tempest.common.service_client.ServiceClient.post'}
+
+ def setUp(self):
+ super(TestInterfacesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = interfaces_client.InterfacesClient(fake_auth,
+ "compute",
+ "regionOne")
+
+ def _test_interface_operation(self, operation="create", bytes_body=False):
+ response_code = 200
+ expected_op = self.FAKE_SHOW_DATA
+ mock_operation = self.func2mock['get']
+ params = {'server_id': self.FAKE_SERVER_ID,
+ 'port_id': self.FAKE_PORT_ID}
+ if operation == 'list':
+ expected_op = self.FAKE_LIST_DATA
+ function = self.client.list_interfaces
+ params = {'server_id': self.FAKE_SERVER_ID}
+ elif operation == 'show':
+ function = self.client.show_interface
+ elif operation == 'delete':
+ expected_op = {}
+ mock_operation = self.func2mock['delete']
+ function = self.client.delete_interface
+ response_code = 202
+ else:
+ function = self.client.create_interface
+ mock_operation = self.func2mock['post']
+
+ self.check_service_client_function(
+ function, mock_operation, expected_op,
+ bytes_body, response_code, **params)
+
+ def test_list_interfaces_with_str_body(self):
+ self._test_interface_operation('list')
+
+ def test_list_interfaces_with_bytes_body(self):
+ self._test_interface_operation('list', True)
+
+ def test_show_interface_with_str_body(self):
+ self._test_interface_operation('show')
+
+ def test_show_interface_with_bytes_body(self):
+ self._test_interface_operation('show', True)
+
+ def test_delete_interface_with_str_body(self):
+ self._test_interface_operation('delete')
+
+ def test_delete_interface_with_bytes_body(self):
+ self._test_interface_operation('delete', True)
+
+ def test_create_interface_with_str_body(self):
+ self._test_interface_operation()
+
+ def test_create_interface_with_bytes_body(self):
+ self._test_interface_operation(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..8b1a9a8 100644
--- a/tempest/tests/services/compute/test_keypairs_client.py
+++ b/tempest/tests/services/compute/test_keypairs_client.py
@@ -13,17 +13,14 @@
# under the License.
import copy
-import httplib2
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
+from tempest_lib.tests import fake_auth_provider
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 +36,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 +57,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 +74,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 +89,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..733d3d1 100644
--- a/tempest/tests/services/compute/test_limits_client.py
+++ b/tempest/tests/services/compute/test_limits_client.py
@@ -12,17 +12,13 @@
# 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_lib.tests import fake_auth_provider
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 +27,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..55f2ef2
--- /dev/null
+++ b/tempest/tests/services/compute/test_migrations_client.py
@@ -0,0 +1,53 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import migrations_client
+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 5e57dea..cec8262 100644
--- a/tempest/tests/services/compute/test_networks_client.py
+++ b/tempest/tests/services/compute/test_networks_client.py
@@ -12,17 +12,13 @@
# 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_lib.tests import fake_auth_provider
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,16 +66,12 @@
fake_auth, 'compute', 'regionOne')
def _test_list_networks(self, bytes_body=False):
- serialized_body = json.dumps({"networks": self.FAKE_NETWORKS})
- 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(self.FAKE_NETWORKS, resp)
+ fake_list,
+ bytes_body)
def test_list_networks_with_str_body(self):
self._test_list_networks()
@@ -88,16 +80,13 @@
self._test_list_networks(bytes_body=True)
def _test_show_network(self, bytes_body=False):
- serialized_body = json.dumps({"network": self.FAKE_NETWORK})
- 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(self.FAKE_NETWORK, 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..29800a2 100644
--- a/tempest/tests/services/compute/test_quota_classes_client.py
+++ b/tempest/tests/services/compute/test_quota_classes_client.py
@@ -13,17 +13,14 @@
# under the License.
import copy
-import httplib2
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
+from tempest_lib.tests import fake_auth_provider
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 +47,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 +64,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..9a9d8fe 100644
--- a/tempest/tests/services/compute/test_quotas_client.py
+++ b/tempest/tests/services/compute/test_quotas_client.py
@@ -13,33 +13,33 @@
# under the License.
import copy
-import httplib2
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
+from tempest_lib.tests import fake_auth_provider
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 +50,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 +64,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 +79,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..99ab305
--- /dev/null
+++ b/tempest/tests/services/compute/test_security_group_default_rules_client.py
@@ -0,0 +1,89 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import security_group_default_rules_client
+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_group_rules_client.py b/tempest/tests/services/compute/test_security_group_rules_client.py
new file mode 100644
index 0000000..c182742
--- /dev/null
+++ b/tempest/tests/services/compute/test_security_group_rules_client.py
@@ -0,0 +1,66 @@
+# 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_rules_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestSecurityGroupRulesClient(base.BaseComputeServiceTest):
+
+ FAKE_SECURITY_GROUP_RULE = {
+ "security_group_rule": {
+ "id": "2d021cf1-ce4b-4292-994f-7a785d62a144",
+ "ip_range": {
+ "cidr": "0.0.0.0/0"
+ },
+ "parent_group_id": "48700ff3-30b8-4e63-845f-a79c9633e9fb",
+ "to_port": 443,
+ "ip_protocol": "tcp",
+ "group": {},
+ "from_port": 443
+ }
+ }
+
+ def setUp(self):
+ super(TestSecurityGroupRulesClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = security_group_rules_client.SecurityGroupRulesClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_create_security_group_rule(self, bytes_body=False):
+ req_body = {
+ "from_port": "443",
+ "ip_protocol": "tcp",
+ "to_port": "443",
+ "cidr": "0.0.0.0/0",
+ "parent_group_id": "48700ff3-30b8-4e63-845f-a79c9633e9fb"
+ }
+ self.check_service_client_function(
+ self.client.create_security_group_rule,
+ 'tempest.common.service_client.ServiceClient.post',
+ self.FAKE_SECURITY_GROUP_RULE,
+ to_utf=bytes_body, **req_body)
+
+ def test_create_security_group_rule_with_str_body(self):
+ self._test_create_security_group_rule()
+
+ def test_create_security_group_rule_with_bytes_body(self):
+ self._test_create_security_group_rule(bytes_body=True)
+
+ def test_delete_security_group_rule(self):
+ self.check_service_client_function(
+ self.client.delete_security_group_rule,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=202, group_rule_id='group-id')
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..9e40b96
--- /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_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import security_groups_client
+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_server_groups_client.py b/tempest/tests/services/compute/test_server_groups_client.py
new file mode 100644
index 0000000..5e058d6
--- /dev/null
+++ b/tempest/tests/services/compute/test_server_groups_client.py
@@ -0,0 +1,84 @@
+# Copyright 2015 IBM Corp.
+#
+# 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 oslotest import mockpatch
+from tempest_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import server_groups_client
+from tempest.tests.services.compute import base
+
+
+class TestServerGroupsClient(base.BaseComputeServiceTest):
+
+ server_group = {
+ "id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
+ "name": "test",
+ "policies": ["anti-affinity"],
+ "members": [],
+ "metadata": {}}
+
+ def setUp(self):
+ super(TestServerGroupsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = server_groups_client.ServerGroupsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_create_server_group(self, bytes_body=False):
+ expected = {"server_group": TestServerGroupsClient.server_group}
+ self.check_service_client_function(
+ self.client.create_server_group,
+ 'tempest.common.service_client.ServiceClient.post', expected,
+ bytes_body, name='fake-group', policies=['affinity'])
+
+ def test_create_server_group_str_body(self):
+ self._test_create_server_group(bytes_body=False)
+
+ def test_create_server_group_byte_body(self):
+ self._test_create_server_group(bytes_body=True)
+
+ def test_delete_server_group(self):
+ response = (httplib2.Response({'status': 204}), None)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.delete',
+ return_value=response))
+ self.client.delete_server_group('fake-group')
+
+ def _test_list_server_groups(self, bytes_body=False):
+ expected = {"server_groups": [TestServerGroupsClient.server_group]}
+ self.check_service_client_function(
+ self.client.list_server_groups,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body)
+
+ def test_list_server_groups_str_body(self):
+ self._test_list_server_groups(bytes_body=False)
+
+ def test_list_server_groups_byte_body(self):
+ self._test_list_server_groups(bytes_body=True)
+
+ def _test_get_server_group(self, bytes_body=False):
+ expected = {"server_group": TestServerGroupsClient.server_group}
+ self.check_service_client_function(
+ self.client.get_server_group,
+ 'tempest.common.service_client.ServiceClient.get',
+ expected, bytes_body,
+ server_group_id='5bbcc3c4-1da2-4437-a48a-66f15b1b13f9')
+
+ def test_get_server_group_str_body(self):
+ self._test_get_server_group(bytes_body=False)
+
+ def test_get_server_group_byte_body(self):
+ self._test_get_server_group(bytes_body=True)
diff --git a/tempest/tests/services/compute/test_servers_client.py b/tempest/tests/services/compute/test_servers_client.py
new file mode 100644
index 0000000..5813318
--- /dev/null
+++ b/tempest/tests/services/compute/test_servers_client.py
@@ -0,0 +1,133 @@
+# Copyright 2015 IBM Corp.
+#
+# 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 servers_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestServersClient(base.BaseComputeServiceTest):
+
+ FAKE_SERVERS = {'servers': [{
+ "id": "616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "links": [
+ {
+ "href": "http://os.co/v2/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "self"
+ },
+ {
+ "href": "http://os.co/616fb98f-46ca-475e-917e-2563e5a8cd19",
+ "rel": "bookmark"
+ }
+ ],
+ "name": u"new\u1234-server-test"}]
+ }
+
+ FAKE_SERVER_GET = {'server': {
+ "accessIPv4": "",
+ "accessIPv6": "",
+ "addresses": {
+ "private": [
+ {
+ "addr": "192.168.0.3",
+ "version": 4
+ }
+ ]
+ },
+ "created": "2012-08-20T21:11:09Z",
+ "flavor": {
+ "id": "1",
+ "links": [
+ {
+ "href": "http://os.com/openstack/flavors/1",
+ "rel": "bookmark"
+ }
+ ]
+ },
+ "hostId": "65201c14a29663e06d0748e561207d998b343e1d164bfa0aafa9c45d",
+ "id": "893c7791-f1df-4c3d-8383-3caae9656c62",
+ "image": {
+ "id": "70a599e0-31e7-49b7-b260-868f441e862b",
+ "links": [
+ {
+ "href": "http://imgs/70a599e0-31e7-49b7-b260-868f441e862b",
+ "rel": "bookmark"
+ }
+ ]
+ },
+ "links": [
+ {
+ "href": "http://v2/srvs/893c7791-f1df-4c3d-8383-3caae9656c62",
+ "rel": "self"
+ },
+ {
+ "href": "http://srvs/893c7791-f1df-4c3d-8383-3caae9656c62",
+ "rel": "bookmark"
+ }
+ ],
+ "metadata": {
+ u"My Server Nu\1234me": u"Apau\1234che1"
+ },
+ "name": u"new\u1234-server-test",
+ "progress": 0,
+ "status": "ACTIVE",
+ "tenant_id": "openstack",
+ "updated": "2012-08-20T21:11:09Z",
+ "user_id": "fake"}
+ }
+
+ server_id = FAKE_SERVER_GET['server']['id']
+
+ def setUp(self):
+ super(TestServersClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = servers_client.ServersClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def test_list_servers_with_str_body(self):
+ self._test_list_servers()
+
+ def test_list_servers_with_bytes_body(self):
+ self._test_list_servers(bytes_body=True)
+
+ def _test_list_servers(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_servers,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_SERVERS,
+ bytes_body)
+
+ def test_show_server_with_str_body(self):
+ self._test_show_server()
+
+ def test_show_server_with_bytes_body(self):
+ self._test_show_server(bytes_body=True)
+
+ def _test_show_server(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_server,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_SERVER_GET,
+ bytes_body,
+ server_id=self.server_id
+ )
+
+ def test_delete_server(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.delete_server,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {},
+ status=204,
+ server_id=self.server_id
+ )
diff --git a/tempest/tests/services/compute/test_services_client.py b/tempest/tests/services/compute/test_services_client.py
index 61ca830..fce28e8 100644
--- a/tempest/tests/services/compute/test_services_client.py
+++ b/tempest/tests/services/compute/test_services_client.py
@@ -13,34 +13,37 @@
# under the License.
import copy
-import httplib2
-from oslo_serialization import jsonutils as json
-from oslotest import mockpatch
+from tempest_lib.tests import fake_auth_provider
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,35 +51,25 @@
self.client = services_client.ServicesClient(
fake_auth, 'compute', 'regionOne')
- def _test_list_services(self, bytes_body=False):
- serialized_body = json.dumps({"services": self.FAKE_SERVICES})
- 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(self.FAKE_SERVICES, 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):
- serialized_body = json.dumps({"service": self.FAKE_SERVICE})
- 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(self.FAKE_SERVICE, resp)
+ self.FAKE_SERVICE,
+ bytes_body,
+ host_name="nova-conductor", binary="controller")
def test_enable_service_with_str_body(self):
self._test_enable_service()
@@ -86,21 +79,17 @@
def _test_disable_service(self, bytes_body=False):
fake_service = copy.deepcopy(self.FAKE_SERVICE)
- fake_service["status"] = "disable"
+ fake_service["service"]["status"] = "disable"
- serialized_body = json.dumps({"service": self.FAKE_SERVICE})
- 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.disable_service,
'tempest.common.service_client.ServiceClient.put',
- return_value=mocked_resp))
- resp = self.client.disable_service("nova-conductor", "controller")
- self.assertEqual(self.FAKE_SERVICE, 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..691792a
--- /dev/null
+++ b/tempest/tests/services/compute/test_tenant_networks_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.
+
+from tempest_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import tenant_networks_client
+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..58e0b7a
--- /dev/null
+++ b/tempest/tests/services/compute/test_tenant_usages_client.py
@@ -0,0 +1,80 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest_lib.tests import fake_auth_provider
+
+from tempest.services.compute.json import tenant_usages_client
+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/services/compute/test_volumes_extensions_client.py b/tempest/tests/services/compute/test_volumes_extensions_client.py
new file mode 100644
index 0000000..2fe8497
--- /dev/null
+++ b/tempest/tests/services/compute/test_volumes_extensions_client.py
@@ -0,0 +1,114 @@
+# 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 oslotest import mockpatch
+from tempest_lib import exceptions as lib_exc
+
+from tempest.services.compute.json import volumes_extensions_client
+from tempest.tests import fake_auth_provider
+from tempest.tests.services.compute import base
+
+
+class TestVolumesExtensionsClient(base.BaseComputeServiceTest):
+
+ FAKE_VOLUME = {
+ "id": "521752a6-acf6-4b2d-bc7a-119f9148cd8c",
+ "displayName": u"v\u12345ol-001",
+ "displayDescription": u"Another \u1234volume.",
+ "size": 30,
+ "status": "Active",
+ "volumeType": "289da7f8-6440-407c-9fb4-7db01ec49164",
+ "metadata": {
+ "contents": "junk"
+ },
+ "availabilityZone": "us-east1",
+ "snapshotId": None,
+ "attachments": [],
+ "createdAt": "2012-02-14T20:53:07Z"
+ }
+
+ FAKE_VOLUMES = {"volumes": [FAKE_VOLUME]}
+
+ def setUp(self):
+ super(TestVolumesExtensionsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = volumes_extensions_client.VolumesExtensionsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_volumes(self, bytes_body=False, **params):
+ self.check_service_client_function(
+ self.client.list_volumes,
+ 'tempest.common.service_client.ServiceClient.get',
+ self.FAKE_VOLUMES, to_utf=bytes_body, **params)
+
+ def test_list_volumes_with_str_body(self):
+ self._test_list_volumes()
+
+ def test_list_volumes_with_byte_body(self):
+ self._test_list_volumes(bytes_body=True)
+
+ def test_list_volumes_with_params(self):
+ self._test_list_volumes(name='fake')
+
+ def _test_show_volume(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_volume,
+ 'tempest.common.service_client.ServiceClient.get',
+ {"volume": self.FAKE_VOLUME},
+ to_utf=bytes_body, volume_id=self.FAKE_VOLUME['id'])
+
+ def test_show_volume_with_str_body(self):
+ self._test_show_volume()
+
+ def test_show_volume_with_bytes_body(self):
+ self._test_show_volume(bytes_body=True)
+
+ def _test_create_volume(self, bytes_body=False):
+ post_body = copy.deepcopy(self.FAKE_VOLUME)
+ del post_body['id']
+ del post_body['createdAt']
+ del post_body['status']
+ self.check_service_client_function(
+ self.client.create_volume,
+ 'tempest.common.service_client.ServiceClient.post',
+ {"volume": self.FAKE_VOLUME},
+ to_utf=bytes_body, status=200, **post_body)
+
+ def test_create_volume_with_str_body(self):
+ self._test_create_volume()
+
+ def test_create_volume_with_bytes_body(self):
+ self._test_create_volume(bytes_body=True)
+
+ def test_delete_volume(self):
+ self.check_service_client_function(
+ self.client.delete_volume,
+ 'tempest.common.service_client.ServiceClient.delete',
+ {}, status=202, volume_id=self.FAKE_VOLUME['id'])
+
+ def test_is_resource_deleted_true(self):
+ module = ('tempest.services.compute.json.volumes_extensions_client.'
+ 'VolumesExtensionsClient.show_volume')
+ self.useFixture(mockpatch.Patch(
+ module, side_effect=lib_exc.NotFound))
+ self.assertTrue(self.client.is_resource_deleted('fake-id'))
+
+ def test_is_resource_deleted_false(self):
+ module = ('tempest.services.compute.json.volumes_extensions_client.'
+ 'VolumesExtensionsClient.show_volume')
+ self.useFixture(mockpatch.Patch(
+ module, return_value={}))
+ self.assertFalse(self.client.is_resource_deleted('fake-id'))
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..5aba2c7 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')
@@ -55,7 +55,7 @@
json_iden_client.IdentityClient,
'create_user',
return_value=(service_client.ResponseBody
- (200, {'id': id, 'name': name}))))
+ (200, {'user': {'id': id, 'name': name}}))))
return user_fix
def _mock_tenant_create(self, id, name):
@@ -63,28 +63,29 @@
json_iden_client.IdentityClient,
'create_tenant',
return_value=(service_client.ResponseBody
- (200, {'id': id, 'name': name}))))
+ (200, {'tenant': {'id': id, 'name': name}}))))
return tenant_fix
def _mock_list_roles(self, id, name):
roles_fix = self.useFixture(mockpatch.PatchObject(
json_iden_client.IdentityClient,
'list_roles',
- return_value=(service_client.ResponseBodyList
+ return_value=(service_client.ResponseBody
(200,
- [{'id': id, 'name': name},
- {'id': '1', 'name': 'FakeRole'}]))))
+ {'roles': [{'id': id, 'name': name},
+ {'id': '1', 'name': 'FakeRole'},
+ {'id': '2', 'name': 'Member'}]}))))
return roles_fix
def _mock_list_2_roles(self):
roles_fix = self.useFixture(mockpatch.PatchObject(
json_iden_client.IdentityClient,
'list_roles',
- return_value=(service_client.ResponseBodyList
+ return_value=(service_client.ResponseBody
(200,
- [{'id': '1234', 'name': 'role1'},
+ {'roles': [{'id': '1234', 'name': 'role1'},
{'id': '1', 'name': 'FakeRole'},
- {'id': '12345', 'name': 'role2'}]))))
+ {'id': '12345', 'name': 'role2'}]}))))
return roles_fix
def _mock_assign_user_role(self):
@@ -99,25 +100,27 @@
roles_fix = self.useFixture(mockpatch.PatchObject(
json_iden_client.IdentityClient,
'list_roles',
- return_value=(service_client.ResponseBodyList
- (200, [{'id': '1', 'name': 'FakeRole'}]))))
+ return_value=(service_client.ResponseBody
+ (200, {'roles': [{'id': '1',
+ 'name': 'FakeRole'}]}))))
return roles_fix
def _mock_list_ec2_credentials(self, user_id, tenant_id):
ec2_creds_fix = self.useFixture(mockpatch.PatchObject(
json_iden_client.IdentityClient,
'list_user_ec2_credentials',
- return_value=(service_client.ResponseBodyList
- (200, [{'access': 'fake_access',
- 'secret': 'fake_secret',
- 'tenant_id': tenant_id,
- 'user_id': user_id,
- 'trust_id': None}]))))
+ return_value=(service_client.ResponseBody
+ (200, {'credentials': [{
+ 'access': 'fake_access',
+ 'secret': 'fake_secret',
+ 'tenant_id': tenant_id,
+ 'user_id': user_id,
+ 'trust_id': None}]}))))
return ec2_creds_fix
def _mock_network_create(self, iso_creds, id, name):
net_fix = self.useFixture(mockpatch.PatchObject(
- iso_creds.network_admin_client,
+ iso_creds.networks_admin_client,
'create_network',
return_value={'network': {'id': id, 'name': name}}))
return net_fix
@@ -265,7 +268,7 @@
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
self._mock_tenant_create('1234', 'fake_prim_tenant')
- net = mock.patch.object(iso_creds.network_admin_client,
+ net = mock.patch.object(iso_creds.networks_admin_client,
'delete_network')
net_mock = net.start()
subnet = mock.patch.object(iso_creds.network_admin_client,
@@ -358,7 +361,7 @@
'IdentityClient.delete_user')
self.patch('tempest.services.identity.v2.json.identity_client.'
'IdentityClient.delete_tenant')
- net = mock.patch.object(iso_creds.network_admin_client,
+ net = mock.patch.object(iso_creds.networks_admin_client,
'delete_network')
net_mock = net.start()
subnet = mock.patch.object(iso_creds.network_admin_client,
@@ -491,7 +494,7 @@
self._mock_list_role()
self._mock_user_create('1234', 'fake_prim_user')
self._mock_tenant_create('1234', 'fake_prim_tenant')
- net = mock.patch.object(iso_creds.network_admin_client,
+ net = mock.patch.object(iso_creds.networks_admin_client,
'delete_network')
net_mock = net.start()
subnet = mock.patch.object(iso_creds.network_admin_client,
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index 9f119b4..1ced180 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -211,7 +211,7 @@
def resource_setup(cls):
super(BotoTestCase, cls).resource_setup()
cls.conclusion = decision_maker()
- # The trash contains cleanup functions and paramaters in tuples
+ # The trash contains cleanup functions and parameters in tuples
# (function, *args, **kwargs)
cls._resource_trash_bin = {}
cls._sequence = -1
@@ -303,7 +303,7 @@
@classmethod
def get_lfunction_gone(cls, obj):
"""If the object is instance of a well know type returns back with
- with the correspoding function otherwise it assumes the obj itself
+ with the corresponding function otherwise it assumes the obj itself
is the function.
"""
ec = cls.ec2_error_code
@@ -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
@@ -467,7 +467,7 @@
client.InvalidInstanceID.NotFound.match(exc) is None:
return "_GONE"
# NOTE(afazekas): incorrect code,
- # but the resource must be destoreyd
+ # but the resource must be destroyed
if exc.error_code == "InstanceNotFound":
return "_GONE"
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/tempest/thirdparty/boto/test_ec2_security_groups.py b/tempest/thirdparty/boto/test_ec2_security_groups.py
index 88ff154..594dc8b 100644
--- a/tempest/thirdparty/boto/test_ec2_security_groups.py
+++ b/tempest/thirdparty/boto/test_ec2_security_groups.py
@@ -68,5 +68,5 @@
group_get = self.client.get_all_security_groups(
groupnames=(group_name,))[0]
- # all rules shuld be removed now
+ # all rules should be removed now
self.assertEqual(0, len(group_get.rules))
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}