Merge "Add test for compute API List Security Groups By Server"
diff --git a/doc/source/library/clients.rst b/doc/source/library/clients.rst
index 086cfc9..0f4ba4c 100644
--- a/doc/source/library/clients.rst
+++ b/doc/source/library/clients.rst
@@ -16,9 +16,18 @@
The ``ServiceClients`` class provides a convenient way to get access to all
available service clients initialized with a provided set of credentials.
-------------------
-The clients module
-------------------
+-----------------------------
+The clients management module
+-----------------------------
.. automodule:: tempest.lib.services.clients
:members:
+
+------------------------------
+Compute service client modules
+------------------------------
+
+.. toctree::
+ :maxdepth: 2
+
+ service_clients/compute_clients
diff --git a/doc/source/library/service_clients/compute_clients.rst b/doc/source/library/service_clients/compute_clients.rst
new file mode 100644
index 0000000..4ca55d4
--- /dev/null
+++ b/doc/source/library/service_clients/compute_clients.rst
@@ -0,0 +1,7 @@
+.. _servers_client:
+
+Compute Client Usage
+====================
+
+.. automodule:: tempest.lib.services.compute.servers_client
+ :members:
diff --git a/releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml b/releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml
index 484d543..d07448a 100644
--- a/releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml
+++ b/releasenotes/notes/12.2.0-clients_module-16f3025f515bf9ec.yaml
@@ -4,7 +4,7 @@
plugins to declare and automatically register any service client defined
in the plugin.
- tempest.lib exposes a new stable interface, the clients module and
- ServiceClients class, which provides a convinient way for plugin tests to
+ ServiceClients class, which provides a convenient way for plugin tests to
access service clients defined in Tempest as well as service clients
defined in all loaded plugins.
The new ServiceClients class only exposes for now the service clients
diff --git a/releasenotes/notes/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml b/releasenotes/notes/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml
index 543cf7b..52c04af 100644
--- a/releasenotes/notes/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml
+++ b/releasenotes/notes/13.0.0-move-call-until-true-to-tempest-lib-c9ea70dd6fe9bd15.yaml
@@ -2,4 +2,4 @@
deprecations:
- The ``call_until_true`` function is moved from the ``tempest.test`` module
to the ``tempest.lib.common.utils.test_utils`` module. Backward
- compatibilty is preserved until Ocata.
+ compatibility is preserved until Ocata.
diff --git a/releasenotes/notes/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml b/releasenotes/notes/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml
index 20f310d..813e47f 100644
--- a/releasenotes/notes/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml
+++ b/releasenotes/notes/13.0.0-tempest-cleanup-nostandalone-39df2aafb2545d35.yaml
@@ -1,5 +1,5 @@
---
upgrade:
- - the already depreacted tempest-cleanup standalone command has been
+ - the already deprecated tempest-cleanup standalone command has been
removed. The corresponding functionalities can be accessed through
the unified `tempest` command (`tempest cleanup`).
diff --git a/releasenotes/notes/remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml b/releasenotes/notes/remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml
new file mode 100644
index 0000000..b1c0c62
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-compute-microversion-config-options-eaee6a7d2f8390a8.yaml
@@ -0,0 +1,9 @@
+---
+upgrade:
+ - The deprecated compute microversion config options from
+ 'compute-feature-enabled' group have been removed. Those config options
+ are available under 'compute' group to configure the min and max
+ microversion for compute service.
+
+ * CONF.compute.min_microversion
+ * CONF.compute.max_microversion
diff --git a/releasenotes/notes/remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml b/releasenotes/notes/remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml
new file mode 100644
index 0000000..8665b8b
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-compute-validation-config-options-e3d1b89ce074d71c.yaml
@@ -0,0 +1,14 @@
+---
+upgrade:
+ - |
+ Below deprecated config options from compute group have been removed.
+ Corresponding config options already been available in validation group.
+
+ - ``compute.use_floatingip_for_ssh`` (available as ``validation.connect_method``)
+ - ``compute.ssh_auth_method`` (available as ``validation.auth_method``)
+ - ``compute.image_ssh_password`` (available as ``validation.image_ssh_password``)
+ - ``compute.ssh_shell_prologue`` (available as ``validation.ssh_shell_prologue``)
+ - ``compute.ping_size `` (available as ``validation.ping_size``)
+ - ``compute.ping_count `` (available as ``validation.ping_count``)
+ - ``compute.floating_ip_range `` (available as ``validation.floating_ip_range``)
+
diff --git a/releasenotes/notes/remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml b/releasenotes/notes/remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml
new file mode 100644
index 0000000..371c061
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-input-scenario-config-options-414e0c5442e967e9.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+ - The deprecated input-scenario config options and group
+ have been removed.
+ The input scenarios functionality already being removed from tempest
+ and from this release, their corresponding config options too.
diff --git a/releasenotes/notes/remove-deprecated-network-config-options-f9ce276231578fe6.yaml b/releasenotes/notes/remove-deprecated-network-config-options-f9ce276231578fe6.yaml
new file mode 100644
index 0000000..e445fb3
--- /dev/null
+++ b/releasenotes/notes/remove-deprecated-network-config-options-f9ce276231578fe6.yaml
@@ -0,0 +1,11 @@
+---
+upgrade:
+ - |
+ Below deprecated network config options have been removed.
+ Those config options already been renamed to below meaningful names.
+
+ - ``tenant_network_cidr`` (removed) -> ``project_network_cidr``
+ - ``tenant_network_mask_bits`` (removed) -> ``project_network_mask_bits``
+ - ``tenant_network_v6_cidr`` (removed) -> ``project_network_v6_cidr``
+ - ``tenant_network_v6_mask_bits`` (removed) -> ``project_network_v6_mask_bits``
+ - ``tenant_networks_reachable`` (removed) -> ``project_networks_reachable``
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index 8eac1d0..cea76b4 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,8 @@
:maxdepth: 1
unreleased
+ v15.0.0
+ v14.0.0
v13.0.0
v12.0.0
v11.0.0
diff --git a/releasenotes/source/v14.0.0.rst b/releasenotes/source/v14.0.0.rst
new file mode 100644
index 0000000..440c85b
--- /dev/null
+++ b/releasenotes/source/v14.0.0.rst
@@ -0,0 +1,6 @@
+=====================
+v14.0.0 Release Notes
+=====================
+
+.. release-notes:: 14.0.0 Release Notes
+ :version: 14.0.0
diff --git a/releasenotes/source/v15.0.0.rst b/releasenotes/source/v15.0.0.rst
new file mode 100644
index 0000000..2ee1894
--- /dev/null
+++ b/releasenotes/source/v15.0.0.rst
@@ -0,0 +1,6 @@
+=====================
+v15.0.0 Release Notes
+=====================
+
+.. release-notes:: 15.0.0 Release Notes
+ :version: 15.0.0
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index deded73..00107cd 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -34,7 +34,6 @@
def resource_setup(cls):
super(AggregatesAdminNegativeTestJSON, cls).resource_setup()
cls.aggregate_name_prefix = 'test_aggregate'
- cls.az_name_prefix = 'test_az'
hosts_all = cls.os_adm.hosts_client.list_hosts()['hosts']
hosts = ([host['host_name']
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 3fd1612..0a9db46 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -33,12 +33,6 @@
raise cls.skipException(msg)
@classmethod
- def setup_clients(cls):
- super(FlavorsAdminTestJSON, cls).setup_clients()
- cls.client = cls.os_adm.flavors_client
- cls.user_client = cls.os.flavors_client
-
- @classmethod
def resource_setup(cls):
super(FlavorsAdminTestJSON, cls).resource_setup()
@@ -50,50 +44,22 @@
cls.swap = 1024
cls.rxtx = 2
- def flavor_clean_up(self, flavor_id):
- self.client.delete_flavor(flavor_id)
- self.client.wait_for_resource_deletion(flavor_id)
-
- def _create_flavor(self, flavor_id):
- # Create a flavor and ensure it is listed
- # This operation requires the user to have 'admin' role
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
-
- # Create the flavor
- flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- 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)
- self.assertEqual(flavor['disk'], self.disk)
- self.assertEqual(flavor['ram'], self.ram)
- self.assertEqual(flavor['swap'], self.swap)
- self.assertEqual(flavor['rxtx_factor'], self.rxtx)
- self.assertEqual(flavor['OS-FLV-EXT-DATA:ephemeral'],
- self.ephemeral)
- self.assertEqual(flavor['os-flavor-access:is_public'], True)
-
- # Verify flavor is retrieved
- flavor = self.client.show_flavor(flavor['id'])['flavor']
- self.assertEqual(flavor['name'], flavor_name)
-
- return flavor['id']
-
@decorators.idempotent_id('8b4330e1-12c4-4554-9390-e6639971f086')
def test_create_flavor_with_int_id(self):
flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor_id = self._create_flavor(flavor_id)
+ new_flavor_id = self.create_flavor(ram=self.ram,
+ vcpus=self.vcpus,
+ disk=self.disk,
+ id=flavor_id)['id']
self.assertEqual(new_flavor_id, str(flavor_id))
@decorators.idempotent_id('94c9bb4e-2c2a-4f3c-bb1f-5f0daf918e6d')
def test_create_flavor_with_uuid_id(self):
flavor_id = data_utils.rand_uuid()
- new_flavor_id = self._create_flavor(flavor_id)
+ new_flavor_id = self.create_flavor(ram=self.ram,
+ vcpus=self.vcpus,
+ disk=self.disk,
+ id=flavor_id)['id']
self.assertEqual(new_flavor_id, flavor_id)
@decorators.idempotent_id('f83fe669-6758-448a-a85e-32d351f36fe0')
@@ -101,7 +67,10 @@
# If nova receives a request with None as flavor_id,
# nova generates flavor_id of uuid.
flavor_id = None
- new_flavor_id = self._create_flavor(flavor_id)
+ new_flavor_id = self.create_flavor(ram=self.ram,
+ vcpus=self.vcpus,
+ disk=self.disk,
+ id=flavor_id)['id']
self.assertEqual(new_flavor_id, str(uuid.UUID(new_flavor_id)))
@decorators.idempotent_id('8261d7b0-be58-43ec-a2e5-300573c3f6c5')
@@ -109,24 +78,19 @@
# Create a flavor and ensure it's details are listed
# This operation requires the user to have 'admin' role
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
# Create the flavor
- flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- ephemeral=self.ephemeral,
- swap=self.swap,
- 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']
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertTrue(flag)
+ self.create_flavor(name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ ephemeral=self.ephemeral,
+ swap=self.swap,
+ rxtx_factor=self.rxtx)
+
+ # Check if flavor is present in list
+ flavors_list = self.admin_flavors_client.list_flavors(
+ detail=True)['flavors']
+ self.assertIn(flavor_name, [f['name'] for f in flavors_list])
@decorators.idempotent_id('63dc64e6-2e79-4fdf-868f-85500d308d66')
def test_create_list_flavor_without_extra_data(self):
@@ -144,11 +108,10 @@
new_flavor_id = data_utils.rand_int_id(start=1000)
# Create the flavor
- flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id)['flavor']
- self.addCleanup(self.flavor_clean_up, flavor['id'])
+ flavor = self.create_flavor(name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id)
self.assertEqual(flavor['name'], flavor_name)
self.assertEqual(flavor['ram'], self.ram)
self.assertEqual(flavor['vcpus'], self.vcpus)
@@ -157,18 +120,17 @@
verify_flavor_response_extension(flavor)
# Verify flavor is retrieved
- flavor = self.client.show_flavor(new_flavor_id)['flavor']
+ flavor = self.admin_flavors_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
- flag = False
- flavors = self.user_client.list_flavors(detail=True)['flavors']
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- verify_flavor_response_extension(flavor)
- flag = True
- self.assertTrue(flag)
+ flavors_list = [
+ f for f in self.flavors_client.list_flavors(detail=True)['flavors']
+ if f['name'] == flavor_name
+ ]
+ self.assertNotEmpty(flavors_list)
+ verify_flavor_response_extension(flavors_list[0])
@decorators.idempotent_id('be6cc18c-7c5d-48c0-ac16-17eaf03c54eb')
def test_list_non_public_flavor(self):
@@ -177,44 +139,27 @@
# tenant is not automatically added access list.
# This operation requires the user to have 'admin' role
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
# Create the flavor
- flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- 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']
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertFalse(flag)
+ self.create_flavor(name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ is_public="False")
+ # Verify flavor is not retrieved
+ flavors_list = self.admin_flavors_client.list_flavors(
+ detail=True)['flavors']
+ self.assertNotIn(flavor_name, [f['name'] for f in flavors_list])
# Verify flavor is not retrieved with other user
- flag = False
- flavors = self.user_client.list_flavors(detail=True)['flavors']
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertFalse(flag)
+ flavors_list = self.flavors_client.list_flavors(detail=True)['flavors']
+ self.assertNotIn(flavor_name, [f['name'] for f in flavors_list])
@decorators.idempotent_id('bcc418ef-799b-47cc-baa1-ce01368b8987')
def test_create_server_with_non_public_flavor(self):
# Create a flavor with os-flavor-access:is_public false
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
-
- # Create the flavor
- flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public="False")['flavor']
- self.addCleanup(self.flavor_clean_up, flavor['id'])
+ flavor = self.create_flavor(ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ is_public="False")
# Verify flavor is not used by other user
self.assertRaises(lib_exc.BadRequest,
@@ -227,60 +172,40 @@
# Create a Flavor with public access.
# Try to List/Get flavor with another user
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
- new_flavor_id = data_utils.rand_int_id(start=1000)
# Create the flavor
- flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public="True")['flavor']
- self.addCleanup(self.flavor_clean_up, flavor['id'])
- flag = False
- self.new_client = self.flavors_client
+ self.create_flavor(name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ is_public="True")
# Verify flavor is retrieved with new user
- flavors = self.new_client.list_flavors(detail=True)['flavors']
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- flag = True
- self.assertTrue(flag)
+ flavors_list = self.flavors_client.list_flavors(detail=True)['flavors']
+ self.assertIn(flavor_name, [f['name'] for f in flavors_list])
@decorators.idempotent_id('fb9cbde6-3a0e-41f2-a983-bdb0a823c44e')
def test_is_public_string_variations(self):
- flavor_id_not_public = data_utils.rand_int_id(start=1000)
flavor_name_not_public = data_utils.rand_name(self.flavor_name_prefix)
- flavor_id_public = data_utils.rand_int_id(start=1000)
flavor_name_public = data_utils.rand_name(self.flavor_name_prefix)
# Create a non public flavor
- flavor = self.client.create_flavor(name=flavor_name_not_public,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=flavor_id_not_public,
- is_public="False")['flavor']
- self.addCleanup(self.flavor_clean_up, flavor['id'])
+ self.create_flavor(name=flavor_name_not_public,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ is_public="False")
# Create a public flavor
- flavor = self.client.create_flavor(name=flavor_name_public,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=flavor_id_public,
- is_public="True")['flavor']
- self.addCleanup(self.flavor_clean_up, flavor['id'])
-
- def _flavor_lookup(flavors, flavor_name):
- for flavor in flavors:
- if flavor['name'] == flavor_name:
- return flavor
- return None
+ self.create_flavor(name=flavor_name_public,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ is_public="True")
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.admin_flavors_client.list_flavors(detail=True,
+ **params)
['flavors'])
- flavor = _flavor_lookup(flavors, flavor_name)
- self.assertIsNotNone(flavor)
+ self.assertIn(flavor_name, [f['name'] for f in flavors])
_test_string_variations(['f', 'false', 'no', '0'],
flavor_name_not_public)
@@ -290,17 +215,11 @@
@decorators.idempotent_id('3b541a2e-2ac2-4b42-8b8d-ba6e22fcd4da')
def test_create_flavor_using_string_ram(self):
- flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
ram = "1024"
- flavor = self.client.create_flavor(name=flavor_name,
- ram=ram, vcpus=self.vcpus,
- disk=self.disk,
- 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)
- self.assertEqual(flavor['disk'], self.disk)
+ flavor = self.create_flavor(ram=ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id)
self.assertEqual(flavor['ram'], int(ram))
self.assertEqual(int(flavor['id']), new_flavor_id)
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 38ff4c0..04b0c2d 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -33,11 +33,6 @@
raise cls.skipException(msg)
@classmethod
- def setup_clients(cls):
- super(FlavorsAccessTestJSON, cls).setup_clients()
- cls.client = cls.os_adm.flavors_client
-
- @classmethod
def resource_setup(cls):
super(FlavorsAccessTestJSON, cls).resource_setup()
@@ -54,14 +49,16 @@
# private flavor will return an empty access list
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- 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'])
+ new_flavor = self.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id,
+ is_public='False')['flavor']
+ self.addCleanup(self.admin_flavors_client.delete_flavor,
+ new_flavor['id'])
+ flavor_access = (self.admin_flavors_client.list_flavor_access(
+ new_flavor_id)['flavor_access'])
self.assertEqual(len(flavor_access), 0, str(flavor_access))
@decorators.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
@@ -69,20 +66,21 @@
# Test to add and remove flavor access to a given tenant.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public='False')['flavor']
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+ new_flavor = self.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id,
+ is_public='False')['flavor']
+ self.addCleanup(self.admin_flavors_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)
- ['flavor_access'])
+ add_body = (self.admin_flavors_client.add_flavor_access(
+ new_flavor['id'], self.tenant_id)['flavor_access'])
self.assertIn(resp_body, add_body)
# The flavor is present in list.
@@ -90,9 +88,8 @@
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)
- ['flavor_access'])
+ remove_body = (self.admin_flavors_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.
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index 2719cc4..bd72d13 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -34,11 +34,6 @@
raise cls.skipException(msg)
@classmethod
- def setup_clients(cls):
- super(FlavorsAccessNegativeTestJSON, cls).setup_clients()
- cls.client = cls.os_adm.flavors_client
-
- @classmethod
def resource_setup(cls):
super(FlavorsAccessNegativeTestJSON, cls).resource_setup()
@@ -54,14 +49,16 @@
# Test to list flavor access with exceptions by querying public flavor
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public='True')['flavor']
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+ new_flavor = self.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id,
+ is_public='True')['flavor']
+ self.addCleanup(self.admin_flavors_client.delete_flavor,
+ new_flavor['id'])
self.assertRaises(lib_exc.NotFound,
- self.client.list_flavor_access,
+ self.admin_flavors_client.list_flavor_access,
new_flavor_id)
@test.attr(type=['negative'])
@@ -70,12 +67,14 @@
# Test to add flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public='False')['flavor']
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+ new_flavor = self.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id,
+ is_public='False')['flavor']
+ self.addCleanup(self.admin_flavors_client.delete_flavor,
+ new_flavor['id'])
self.assertRaises(lib_exc.Forbidden,
self.flavors_client.add_flavor_access,
new_flavor['id'],
@@ -87,15 +86,18 @@
# Test to remove flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public='False')['flavor']
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+ new_flavor = self.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id,
+ is_public='False')['flavor']
+ self.addCleanup(self.admin_flavors_client.delete_flavor,
+ new_flavor['id'])
# Add flavor access to a tenant.
- self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
- self.addCleanup(self.client.remove_flavor_access,
+ self.admin_flavors_client.add_flavor_access(new_flavor['id'],
+ self.tenant_id)
+ self.addCleanup(self.admin_flavors_client.remove_flavor_access,
new_flavor['id'], self.tenant_id)
self.assertRaises(lib_exc.Forbidden,
self.flavors_client.remove_flavor_access,
@@ -108,22 +110,25 @@
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public='False')['flavor']
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+ new_flavor = self.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id,
+ is_public='False')['flavor']
+ self.addCleanup(self.admin_flavors_client.delete_flavor,
+ new_flavor['id'])
# Add flavor access to a tenant.
- self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
- self.addCleanup(self.client.remove_flavor_access,
+ self.admin_flavors_client.add_flavor_access(new_flavor['id'],
+ self.tenant_id)
+ self.addCleanup(self.admin_flavors_client.remove_flavor_access,
new_flavor['id'], self.tenant_id)
# An exception should be raised when adding flavor access to the same
# tenant
self.assertRaises(lib_exc.Conflict,
- self.client.add_flavor_access,
+ self.admin_flavors_client.add_flavor_access,
new_flavor['id'],
self.tenant_id)
@@ -133,15 +138,17 @@
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
new_flavor_id = data_utils.rand_int_id(start=1000)
- new_flavor = self.client.create_flavor(name=flavor_name,
- ram=self.ram, vcpus=self.vcpus,
- disk=self.disk,
- id=new_flavor_id,
- is_public='False')['flavor']
- self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+ new_flavor = self.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=self.ram, vcpus=self.vcpus,
+ disk=self.disk,
+ id=new_flavor_id,
+ is_public='False')['flavor']
+ self.addCleanup(self.admin_flavors_client.delete_flavor,
+ new_flavor['id'])
# An exception should be raised when flavor access is not found
self.assertRaises(lib_exc.NotFound,
- self.client.remove_flavor_access,
+ self.admin_flavors_client.remove_flavor_access,
new_flavor['id'],
data_utils.rand_uuid())
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 70e662c..ee1e3a0 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -34,11 +34,6 @@
raise cls.skipException(msg)
@classmethod
- def setup_clients(cls):
- super(FlavorsExtraSpecsTestJSON, cls).setup_clients()
- cls.client = cls.os_adm.flavors_client
-
- @classmethod
def resource_setup(cls):
super(FlavorsExtraSpecsTestJSON, cls).resource_setup()
flavor_name = data_utils.rand_name('test_flavor')
@@ -46,22 +41,23 @@
vcpus = 1
disk = 10
ephemeral = 10
- cls.new_flavor_id = data_utils.rand_int_id(start=1000)
+ new_flavor_id = data_utils.rand_int_id(start=1000)
swap = 1024
rxtx = 1
# Create a flavor so as to set/get/unset extra specs
- cls.flavor = cls.client.create_flavor(name=flavor_name,
- ram=ram, vcpus=vcpus,
- disk=disk,
- id=cls.new_flavor_id,
- ephemeral=ephemeral,
- swap=swap,
- rxtx_factor=rxtx)['flavor']
+ cls.flavor = cls.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=ram, vcpus=vcpus,
+ disk=disk,
+ id=new_flavor_id,
+ ephemeral=ephemeral,
+ swap=swap,
+ rxtx_factor=rxtx)['flavor']
@classmethod
def resource_cleanup(cls):
- cls.client.delete_flavor(cls.flavor['id'])
- cls.client.wait_for_resource_deletion(cls.flavor['id'])
+ cls.admin_flavors_client.delete_flavor(cls.flavor['id'])
+ cls.admin_flavors_client.wait_for_resource_deletion(cls.flavor['id'])
super(FlavorsExtraSpecsTestJSON, cls).resource_cleanup()
@decorators.idempotent_id('0b2f9d4b-1ca2-4b99-bb40-165d4bb94208')
@@ -71,46 +67,47 @@
# 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)['extra_specs']
+ set_body = self.admin_flavors_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'])
- ['extra_specs'])
+ get_body = (self.admin_flavors_client.list_flavor_extra_specs(
+ self.flavor['id'])['extra_specs'])
self.assertEqual(get_body, specs)
# UPDATE the value of the extra specs key1
update_body = \
- self.client.update_flavor_extra_spec(self.flavor['id'],
- "key1",
- key1="value")
+ self.admin_flavors_client.update_flavor_extra_spec(
+ self.flavor['id'], "key1", key1="value")
self.assertEqual({"key1": "value"}, update_body)
# 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'])
- ['extra_specs'])
+ get_body = (self.admin_flavors_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
- self.client.unset_flavor_extra_spec(self.flavor['id'], "key1")
- self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
+ self.admin_flavors_client.unset_flavor_extra_spec(self.flavor['id'],
+ "key1")
+ self.admin_flavors_client.unset_flavor_extra_spec(self.flavor['id'],
+ "key2")
@decorators.idempotent_id('a99dad88-ae1c-4fba-aeb4-32f898218bd0')
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'])
- ['extra_specs'])
+ self.admin_flavors_client.set_flavor_extra_spec(self.flavor['id'],
+ **specs)
+ body = (self.flavors_client.list_flavor_extra_specs(
+ self.flavor['id'])['extra_specs'])
for key in specs:
self.assertEqual(body[key], specs[key])
@decorators.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")['extra_specs']
+ body = self.admin_flavors_client.set_flavor_extra_spec(
+ self.flavor['id'], 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 767a1ca..dab83e5 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -35,11 +35,6 @@
raise cls.skipException(msg)
@classmethod
- def setup_clients(cls):
- super(FlavorsExtraSpecsNegativeTestJSON, cls).setup_clients()
- cls.client = cls.os_adm.flavors_client
-
- @classmethod
def resource_setup(cls):
super(FlavorsExtraSpecsNegativeTestJSON, cls).resource_setup()
@@ -48,22 +43,23 @@
vcpus = 1
disk = 10
ephemeral = 10
- cls.new_flavor_id = data_utils.rand_int_id(start=1000)
+ new_flavor_id = data_utils.rand_int_id(start=1000)
swap = 1024
rxtx = 1
# Create a flavor
- cls.flavor = cls.client.create_flavor(name=flavor_name,
- ram=ram, vcpus=vcpus,
- disk=disk,
- id=cls.new_flavor_id,
- ephemeral=ephemeral,
- swap=swap,
- rxtx_factor=rxtx)['flavor']
+ cls.flavor = cls.admin_flavors_client.create_flavor(
+ name=flavor_name,
+ ram=ram, vcpus=vcpus,
+ disk=disk,
+ id=new_flavor_id,
+ ephemeral=ephemeral,
+ swap=swap,
+ rxtx_factor=rxtx)['flavor']
@classmethod
def resource_cleanup(cls):
- cls.client.delete_flavor(cls.flavor['id'])
- cls.client.wait_for_resource_deletion(cls.flavor['id'])
+ cls.admin_flavors_client.delete_flavor(cls.flavor['id'])
+ cls.admin_flavors_client.wait_for_resource_deletion(cls.flavor['id'])
super(FlavorsExtraSpecsNegativeTestJSON, cls).resource_cleanup()
@test.attr(type=['negative'])
@@ -79,7 +75,7 @@
@decorators.idempotent_id('1ebf4ef8-759e-48fe-a801-d451d80476fb')
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(
+ body = self.admin_flavors_client.set_flavor_extra_spec(
self.flavor['id'], key1="value1", key2="value2")['extra_specs']
self.assertEqual(body['key1'], 'value1')
self.assertRaises(lib_exc.Forbidden,
@@ -92,8 +88,8 @@
@test.attr(type=['negative'])
@decorators.idempotent_id('28f12249-27c7-44c1-8810-1f382f316b11')
def test_flavor_non_admin_unset_keys(self):
- self.client.set_flavor_extra_spec(self.flavor['id'],
- key1="value1", key2="value2")
+ self.admin_flavors_client.set_flavor_extra_spec(
+ self.flavor['id'], key1="value1", key2="value2")
self.assertRaises(lib_exc.Forbidden,
self.flavors_client.unset_flavor_extra_spec,
@@ -104,7 +100,7 @@
@decorators.idempotent_id('440b9f3f-3c7f-4293-a106-0ceda350f8de')
def test_flavor_unset_nonexistent_key(self):
self.assertRaises(lib_exc.NotFound,
- self.client.unset_flavor_extra_spec,
+ self.admin_flavors_client.unset_flavor_extra_spec,
self.flavor['id'],
'nonexistent_key')
@@ -121,7 +117,7 @@
def test_flavor_update_mismatch_key(self):
# the key will be updated should be match the key in the body
self.assertRaises(lib_exc.BadRequest,
- self.client.update_flavor_extra_spec,
+ self.admin_flavors_client.update_flavor_extra_spec,
self.flavor['id'],
"key2",
key1="value")
@@ -131,7 +127,7 @@
def test_flavor_update_more_key(self):
# there should be just one item in the request body
self.assertRaises(lib_exc.BadRequest,
- self.client.update_flavor_extra_spec,
+ self.admin_flavors_client.update_flavor_extra_spec,
self.flavor['id'],
"key1",
key1="value",
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 1283629..b53ced9 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -42,9 +42,7 @@
super(ServersAdminNegativeTestJSON, cls).resource_setup()
cls.tenant_id = cls.client.tenant_id
- cls.s1_name = data_utils.rand_name(cls.__name__ + '-server')
- server = cls.create_test_server(name=cls.s1_name,
- wait_until='ACTIVE')
+ server = cls.create_test_server(wait_until='ACTIVE')
cls.s1_id = server['id']
def _get_unused_flavor_id(self):
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index c3c5460..c636894 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -467,3 +467,17 @@
super(BaseV2ComputeAdminTest, cls).setup_clients()
cls.availability_zone_admin_client = (
cls.os_adm.availability_zone_client)
+ cls.admin_flavors_client = cls.os_adm.flavors_client
+
+ def create_flavor(self, ram, vcpus, disk, name=None,
+ is_public='True', **kwargs):
+ if name is None:
+ name = data_utils.rand_name(self.__class__.__name__ + "-flavor")
+ id = kwargs.pop('id', data_utils.rand_int_id(start=1000))
+ client = self.admin_flavors_client
+ flavor = client.create_flavor(
+ ram=ram, vcpus=vcpus, disk=disk, name=name,
+ id=id, is_public=is_public, **kwargs)['flavor']
+ self.addCleanup(client.wait_for_resource_deletion, flavor['id'])
+ self.addCleanup(client.delete_flavor, flavor['id'])
+ return flavor
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 546667f..89051c1 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -22,17 +22,12 @@
_min_disk = 'minDisk'
_min_ram = 'minRam'
- @classmethod
- def setup_clients(cls):
- super(FlavorsV2TestJSON, cls).setup_clients()
- cls.client = cls.flavors_client
-
@test.attr(type='smoke')
@decorators.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()['flavors']
- flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+ flavors = self.flavors_client.list_flavors()['flavors']
+ flavor = self.flavors_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)
@@ -40,89 +35,93 @@
@decorators.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)['flavors']
- flavor = self.client.show_flavor(self.flavor_ref)['flavor']
+ flavors = self.flavors_client.list_flavors(detail=True)['flavors']
+ flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
self.assertIn(flavor, flavors)
@test.attr(type='smoke')
@decorators.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']
+ flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
self.assertEqual(self.flavor_ref, flavor['id'])
@decorators.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']
+ flavors = self.flavors_client.list_flavors(**params)['flavors']
self.assertEqual(1, len(flavors))
@decorators.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']
+ flavors = self.flavors_client.list_flavors(detail=True,
+ **params)['flavors']
self.assertEqual(1, len(flavors))
@decorators.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']
+ flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {'marker': flavor_id}
- flavors = self.client.list_flavors(**params)['flavors']
+ flavors = self.flavors_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.')
@decorators.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']
+ flavor = self.flavors_client.show_flavor(self.flavor_ref)['flavor']
flavor_id = flavor['id']
params = {'marker': flavor_id}
- flavors = self.client.list_flavors(detail=True, **params)['flavors']
+ flavors = self.flavors_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.')
@decorators.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']
+ flavor = self.flavors_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']
+ flavors = self.flavors_client.list_flavors(detail=True,
+ **params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
@decorators.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']
+ flavor = self.flavors_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']
+ flavors = self.flavors_client.list_flavors(detail=True,
+ **params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
@decorators.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']
+ flavor = self.flavors_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']
+ flavors = self.flavors_client.list_flavors(**params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
@decorators.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']
+ flavor = self.flavors_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']
+ flavors = self.flavors_client.list_flavors(**params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
new file mode 100644
index 0000000..a70c0a9
--- /dev/null
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -0,0 +1,89 @@
+# Copyright 2017 Red Hat, Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import random
+
+import six
+
+from tempest.api.compute import base
+from tempest.common import image as common_image
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest.lib import exceptions as lib_exc
+from tempest import test
+
+CONF = config.CONF
+
+
+class FlavorsV2NegativeTest(base.BaseV2ComputeTest):
+
+ @classmethod
+ def setup_clients(cls):
+ super(FlavorsV2NegativeTest, cls).setup_clients()
+ if CONF.image_feature_enabled.api_v1:
+ cls.images_client = cls.os.image_client
+ elif CONF.image_feature_enabled.api_v2:
+ cls.images_client = cls.os.image_client_v2
+ else:
+ raise lib_exc.InvalidConfiguration(
+ 'Either api_v1 or api_v2 must be True in '
+ '[image-feature-enabled].')
+
+ @test.attr(type=['negative'])
+ @test.services('image')
+ @test.idempotent_id('90f0d93a-91c1-450c-91e6-07d18172cefe')
+ def test_boot_with_low_ram(self):
+ """Try boot a vm with lower than min ram
+
+ Create an image with min_ram value
+ Try to create server with flavor of insufficient ram size from
+ that image
+ """
+ flavor = self.flavors_client.show_flavor(
+ CONF.compute.flavor_ref)['flavor']
+ min_img_ram = flavor['ram'] + 1
+ size = random.randint(1024, 4096)
+ image_file = six.BytesIO(data_utils.random_bytes(size))
+ params = {
+ 'name': data_utils.rand_name('image'),
+ 'container_format': CONF.image.container_formats[0],
+ 'disk_format': CONF.image.disk_formats[0],
+ 'min_ram': min_img_ram
+ }
+
+ if CONF.image_feature_enabled.api_v1:
+ params.update({'is_public': False})
+ params = {'headers': common_image.image_meta_to_headers(**params)}
+ else:
+ params.update({'visibility': 'private'})
+
+ image = self.images_client.create_image(**params)
+ image = image['image'] if 'image' in image else image
+ self.addCleanup(self.images_client.delete_image, image['id'])
+
+ if CONF.image_feature_enabled.api_v1:
+ self.images_client.update_image(image['id'], data=image_file)
+ else:
+ self.images_client.store_image_file(image['id'], data=image_file)
+
+ self.assertEqual(min_img_ram, image['min_ram'])
+
+ # Try to create server with flavor of insufficient ram size
+ self.assertRaisesRegexp(lib_exc.BadRequest,
+ "Flavor's memory is too small for "
+ "requested image",
+ self.create_test_server,
+ image_id=image['id'],
+ flavor=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 4d8416f..2769245 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from tempest.api.compute.floating_ips import base
from tempest import config
from tempest.lib.common.utils import test_utils
@@ -86,6 +88,8 @@
@decorators.idempotent_id('307efa27-dc6f-48a0-8cd2-162ce3ef0b52')
@test.services('network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_associate_disassociate_floating_ip(self):
# Positive test:Associate and disassociate the provided floating IP
# to a specific server should be successful
@@ -107,6 +111,8 @@
@decorators.idempotent_id('6edef4b2-aaf1-4abc-bbe3-993e2561e0fe')
@test.services('network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_associate_already_associated_floating_ip(self):
# positive test:Association of an already associated floating IP
# to specific server should change the association of the Floating IP
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 7658848..b82fa3b 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -31,7 +31,6 @@
@classmethod
def resource_setup(cls):
super(SecurityGroupRulesTestJSON, cls).resource_setup()
- cls.neutron_available = CONF.service_available.neutron
cls.ip_protocol = 'tcp'
cls.from_port = 22
cls.to_port = 22
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 ad18861..48bb1b6 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -32,11 +32,6 @@
super(SecurityGroupsNegativeTestJSON, cls).setup_clients()
cls.client = cls.security_groups_client
- @classmethod
- def resource_setup(cls):
- super(SecurityGroupsNegativeTestJSON, cls).resource_setup()
- cls.neutron_available = CONF.service_available.neutron
-
@test.attr(type=['negative'])
@decorators.idempotent_id('673eaec1-9b3e-48ed-bdf1-2786c1b9661c')
@test.services('network')
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 5ddae5e..a94c20b 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -51,7 +51,7 @@
cls.name = data_utils.rand_name(cls.__name__ + '-server')
cls.password = data_utils.rand_password()
disk_config = cls.disk_config
- cls.server_initial = cls.create_test_server(
+ server_initial = cls.create_test_server(
validatable=True,
wait_until='ACTIVE',
name=cls.name,
@@ -60,7 +60,7 @@
accessIPv6=cls.accessIPv6,
disk_config=disk_config,
adminPass=cls.password)
- cls.server = (cls.client.show_server(cls.server_initial['id'])
+ cls.server = (cls.client.show_server(server_initial['id'])
['server'])
def _create_net_subnet_ret_net_from_cidr(self, cidr):
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index d9e83a6..5bcbdac 100644
--- a/tempest/api/compute/servers/test_device_tagging.py
+++ b/tempest/api/compute/servers/test_device_tagging.py
@@ -20,6 +20,7 @@
from tempest.common.utils import data_utils
from tempest.common.utils.linux import remote_client
from tempest import config
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions
from tempest import test
@@ -249,9 +250,9 @@
self.verify_device_metadata(md_json)
return True
- if not test.call_until_true(get_and_verify_metadata,
- CONF.compute.build_timeout,
- CONF.compute.build_interval):
+ if not test_utils.call_until_true(get_and_verify_metadata,
+ CONF.compute.build_timeout,
+ CONF.compute.build_interval):
raise exceptions.TimeoutException('Timeout while verifying '
'metadata on server.')
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 594c5c9..3010caf 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -35,11 +35,9 @@
# by the test methods in this class. These
# servers are cleaned up automatically in the
# tearDownClass method of the super-class.
- cls.existing_fixtures = []
cls.deleted_fixtures = []
for _ in range(2):
srv = cls.create_test_server(wait_until='ACTIVE')
- cls.existing_fixtures.append(srv)
srv = cls.create_test_server(wait_until='ACTIVE')
cls.client.delete_server(srv['id'])
diff --git a/tempest/api/compute/servers/test_novnc.py b/tempest/api/compute/servers/test_novnc.py
index d10f370..3f6abab 100644
--- a/tempest/api/compute/servers/test_novnc.py
+++ b/tempest/api/compute/servers/test_novnc.py
@@ -1,4 +1,4 @@
-# Copyright 2016 OpenStack Foundation
+# Copyright 2016-2017 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -22,10 +22,15 @@
from tempest.api.compute import base
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
+if six.PY2:
+ ord_func = ord
+else:
+ ord_func = int
+
class NoVNCConsoleTestJSON(base.BaseV2ComputeTest):
@@ -60,14 +65,19 @@
resp = urllib3.PoolManager().request('GET', vnc_url)
# Make sure that the GET request was accepted by the novncproxy
self.assertEqual(resp.status, 200, 'Got a Bad HTTP Response on the '
- 'initial call: ' + str(resp.status))
+ 'initial call: ' + six.text_type(resp.status))
# Do some basic validation to make sure it is an expected HTML document
- self.assertTrue('<html>' in resp.data and '</html>' in resp.data,
- 'Not a valid html document in the response.')
+ resp_data = resp.data.decode()
+ self.assertIn('<html>', resp_data,
+ 'Not a valid html document in the response.')
+ self.assertIn('</html>', resp_data,
+ 'Not a valid html document in the response.')
# Just try to make sure we got JavaScript back for noVNC, since we
# won't actually use it since not inside of a browser
- self.assertTrue('noVNC' in resp.data and '<script' in resp.data,
- 'Not a valid noVNC javascript html document.')
+ self.assertIn('noVNC', resp_data,
+ 'Not a valid noVNC javascript html document.')
+ self.assertIn('<script', resp_data,
+ 'Not a valid noVNC javascript html document.')
def _validate_rfb_negotiation(self):
"""Verify we can connect to novnc and do the websocket connection."""
@@ -82,14 +92,14 @@
int(data[8:11], base=10)))
self.assertTrue(version >= 3.3, 'Bad RFB Version: ' + str(version))
# Send our RFB version to the server, which we will just go with 3.3
- self._websocket.send_frame(str(data))
+ self._websocket.send_frame(data)
# Get the sever authentication type and make sure None is supported
data = self._websocket.receive_frame()
self.assertIsNotNone(data, 'Expected authentication type None.')
self.assertGreaterEqual(
len(data), 2, 'Expected authentication type None.')
self.assertIn(
- 1, [ord(data[i + 1]) for i in range(ord(data[0]))],
+ 1, [ord_func(data[i + 1]) for i in range(ord_func(data[0]))],
'Expected authentication type None.')
# Send to the server that we only support authentication type None
self._websocket.send_frame(six.int2byte(1))
@@ -98,7 +108,7 @@
self.assertEqual(
len(data), 4, 'Server did not think security was successful.')
self.assertEqual(
- [ord(i) for i in data], [0, 0, 0, 0],
+ [ord_func(i) for i in data], [0, 0, 0, 0],
'Server did not think security was successful.')
# Say to leave the desktop as shared as part of client initialization
self._websocket.send_frame(six.int2byte(1))
@@ -121,12 +131,12 @@
def _validate_websocket_upgrade(self):
self.assertTrue(
- self._websocket.response.startswith('HTTP/1.1 101 Switching '
- 'Protocols\r\n'),
+ self._websocket.response.startswith(b'HTTP/1.1 101 Switching '
+ b'Protocols\r\n'),
'Did not get the expected 101 on the websockify call: '
- + str(len(self._websocket.response)))
+ + six.text_type(self._websocket.response))
self.assertTrue(
- self._websocket.response.find('Server: WebSockify') > 0,
+ self._websocket.response.find(b'Server: WebSockify') > 0,
'Did not get the expected WebSocket HTTP Response.')
def _create_websocket(self, url):
@@ -137,7 +147,7 @@
# Turn the Socket into a WebSocket to do the communication
return _WebSocket(client_socket, url)
- @test.idempotent_id('c640fdff-8ab4-45a4-a5d8-7e6146cbd0dc')
+ @decorators.idempotent_id('c640fdff-8ab4-45a4-a5d8-7e6146cbd0dc')
def test_novnc(self):
body = self.client.get_vnc_console(self.server['id'],
type='novnc')['console']
@@ -151,7 +161,7 @@
# Validate the RFB Negotiation to determine if a valid VNC session
self._validate_rfb_negotiation()
- @test.idempotent_id('f9c79937-addc-4aaa-9e0e-841eef02aeb7')
+ @decorators.idempotent_id('f9c79937-addc-4aaa-9e0e-841eef02aeb7')
def test_novnc_bad_token(self):
body = self.client.get_vnc_console(self.server['id'],
type='novnc')['console']
@@ -187,8 +197,8 @@
# frames less than 125 bytes here (for the negotiation) and
# that only the 2nd byte contains the length, and since the
# server doesn't do masking, we can just read the data length
- if ord(header[1]) & 127 > 0:
- return self._socket.recv(ord(header[1]) & 127)
+ if ord_func(header[1]) & 127 > 0:
+ return self._socket.recv(ord_func(header[1]) & 127)
def send_frame(self, data):
"""Wrapper for sending data to add in the WebSocket frame format."""
@@ -205,7 +215,7 @@
frame_bytes.append(mask[i])
# Mask each of the actual data bytes that we are going to send
for i in range(len(data)):
- frame_bytes.append(ord(data[i]) ^ mask[i % 4])
+ frame_bytes.append(ord_func(data[i]) ^ mask[i % 4])
# Convert our integer list to a binary array of bytes
frame_bytes = struct.pack('!%iB' % len(frame_bytes), * frame_bytes)
self._socket.sendall(frame_bytes)
@@ -233,9 +243,9 @@
# We are choosing to use binary even though browser may do Base64
reqdata += 'Sec-WebSocket-Protocol: binary\r\n\r\n'
# Send the HTTP GET request and get the response back
- self._socket.sendall(reqdata)
+ self._socket.sendall(reqdata.encode('utf8'))
self.response = data = self._socket.recv(4096)
# Loop through & concatenate all of the data in the response body
- while len(data) > 0 and self.response.find('\r\n\r\n') < 0:
+ while len(data) > 0 and self.response.find(b'\r\n\r\n') < 0:
data = self._socket.recv(4096)
self.response += data
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 5db7f4f..209ab38 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest.common import waiters
@@ -48,9 +50,9 @@
# Security group creation
cls.sg_name = data_utils.rand_name('sg')
- cls.sg_desc = data_utils.rand_name('sg-desc')
+ 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)['security_group']
+ name=cls.sg_name, description=sg_desc)['security_group']
cls.sg_id = cls.sg['id']
cls.password = data_utils.rand_password()
@@ -85,6 +87,8 @@
'ACTIVE')
@decorators.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_rescued_vm_associate_dissociate_floating_ip(self):
# Rescue the server
self.servers_client.rescue_server(
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index dd9d408..0d8214f 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -44,13 +44,11 @@
super(VolumesTestJSON, cls).resource_setup()
# Create 3 Volumes
cls.volume_list = []
- cls.volume_id_list = []
for _ in range(3):
metadata = {'Type': 'work'}
volume = cls.create_volume(metadata=metadata)
volume = cls.client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
- cls.volume_id_list.append(volume['id'])
@decorators.idempotent_id('bc2dd1a0-15af-48e5-9990-f2e75a48325d')
def test_volume_list(self):
diff --git a/tempest/api/identity/admin/v3/test_domains_negative.py b/tempest/api/identity/admin/v3/test_domains_negative.py
index 280a5a8..4555a6a 100644
--- a/tempest/api/identity/admin/v3/test_domains_negative.py
+++ b/tempest/api/identity/admin/v3/test_domains_negative.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.identity import base
-from tempest.lib.common.utils import data_utils
+from tempest.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index e89be4b..445d928 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -15,7 +15,9 @@
from tempest.api.identity import base
from tempest.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -195,3 +197,112 @@
body = self.roles_client.list_roles()['roles']
found = [role for role in body if role in self.roles]
self.assertEqual(len(found), len(self.roles))
+
+ def _create_implied_role(self, prior_role_id, implies_role_id,
+ ignore_not_found=False):
+ self.roles_client.create_role_inference_rule(
+ prior_role_id, implies_role_id)
+ if ignore_not_found:
+ self.addCleanup(
+ test_utils.call_and_ignore_notfound_exc,
+ self.roles_client.delete_role_inference_rule,
+ prior_role_id,
+ implies_role_id)
+ else:
+ self.addCleanup(
+ self.roles_client.delete_role_inference_rule,
+ prior_role_id,
+ implies_role_id)
+
+ @decorators.idempotent_id('c90c316c-d706-4728-bcba-eb1912081b69')
+ def test_implied_roles_create_delete(self):
+ prior_role_id = self.roles[0]['id']
+ implies_role_id = self.roles[1]['id']
+
+ # Create an inference rule from prior_role to implies_role
+ self._create_implied_role(prior_role_id, implies_role_id,
+ ignore_not_found=True)
+
+ # Check if the inference rule exists
+ self.roles_client.show_role_inference_rule(
+ prior_role_id, implies_role_id)
+
+ # Delete the inference rule
+ self.roles_client.delete_role_inference_rule(
+ prior_role_id, implies_role_id)
+ # Check if the inference rule no longer exists
+ self.assertRaises(
+ lib_exc.NotFound,
+ self.roles_client.show_role_inference_rule,
+ prior_role_id,
+ implies_role_id)
+
+ @decorators.idempotent_id('dc6f5959-b74d-4e30-a9e5-a8255494ff00')
+ def test_roles_hierarchy(self):
+ # Create inference rule from "roles[0]" to "role[1]"
+ self._create_implied_role(
+ self.roles[0]['id'], self.roles[1]['id'])
+
+ # Create inference rule from "roles[0]" to "role[2]"
+ self._create_implied_role(
+ self.roles[0]['id'], self.roles[2]['id'])
+
+ # Create inference rule from "roles[2]" to "role"
+ self._create_implied_role(
+ self.roles[2]['id'], self.role['id'])
+
+ # Listing inferences rules from "roles[2]" should only return "role"
+ rules = self.roles_client.list_role_inferences_rules(
+ self.roles[2]['id'])['role_inference']
+ self.assertEqual(1, len(rules['implies']))
+ self.assertEqual(self.role['id'], rules['implies'][0]['id'])
+
+ # Listing inferences rules from "roles[0]" should return "roles[1]" and
+ # "roles[2]" (only direct rules are listed)
+ rules = self.roles_client.list_role_inferences_rules(
+ self.roles[0]['id'])['role_inference']
+ implies_ids = [role['id'] for role in rules['implies']]
+ self.assertEqual(2, len(implies_ids))
+ self.assertIn(self.roles[1]['id'], implies_ids)
+ self.assertIn(self.roles[2]['id'], implies_ids)
+
+ @decorators.idempotent_id('c8828027-df48-4021-95df-b65b92c7429e')
+ def test_assignments_for_implied_roles_create_delete(self):
+ # Create a grant using "roles[0]"
+ self.roles_client.create_user_role_on_project(
+ self.project['id'], self.user_body['id'], self.roles[0]['id'])
+ self.addCleanup(
+ self.roles_client.delete_role_from_user_on_project,
+ self.project['id'], self.user_body['id'], self.roles[0]['id'])
+
+ # Create an inference rule from "roles[0]" to "roles[1]"
+ self._create_implied_role(self.roles[0]['id'], self.roles[1]['id'],
+ ignore_not_found=True)
+
+ # In the effective list of role assignments, both prior role and
+ # implied role should be present. This means that a user can
+ # authenticate using both roles (both roles will be present
+ # in the token).
+ params = {'scope.project.id': self.project['id'],
+ 'user.id': self.user_body['id']}
+ role_assignments = self.role_assignments.list_role_assignments(
+ effective=True, **params)['role_assignments']
+ self.assertEqual(2, len(role_assignments))
+
+ roles_ids = [assignment['role']['id']
+ for assignment in role_assignments]
+ self.assertIn(self.roles[0]['id'], roles_ids)
+ self.assertIn(self.roles[1]['id'], roles_ids)
+
+ # After deleting the implied role, only the assignment with "roles[0]"
+ # should be present.
+ self.roles_client.delete_role_inference_rule(
+ self.roles[0]['id'], self.roles[1]['id'])
+
+ role_assignments = self.role_assignments.list_role_assignments(
+ effective=True, **params)['role_assignments']
+ self.assertEqual(1, len(role_assignments))
+
+ roles_ids = [assignment['role']['id']
+ for assignment in role_assignments]
+ self.assertIn(self.roles[0]['id'], roles_ids)
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 9515788..3bbe47a 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -67,7 +67,7 @@
return role[0]
def _create_test_user(self, **kwargs):
- if kwargs['password'] is None:
+ if kwargs.get('password', None) is None:
user_password = data_utils.rand_password()
kwargs['password'] = user_password
user = self.users_client.create_user(**kwargs)['user']
diff --git a/tempest/api/identity/v3/test_api_discovery.py b/tempest/api/identity/v3/test_api_discovery.py
index 74e9ec1..2eed3c8 100644
--- a/tempest/api/identity/v3/test_api_discovery.py
+++ b/tempest/api/identity/v3/test_api_discovery.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.identity import base
+from tempest.lib import decorators
from tempest import test
@@ -21,7 +22,7 @@
"""Tests for API discovery features."""
@test.attr(type='smoke')
- @test.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
+ @decorators.idempotent_id('b9232f5e-d9e5-4d97-b96c-28d3db4de1bd')
def test_api_version_resources(self):
descr = self.non_admin_client.show_api_description()['version']
expected_resources = ('id', 'links', 'media-types', 'status',
@@ -32,7 +33,7 @@
self.assertIn(res, keys)
@test.attr(type='smoke')
- @test.idempotent_id('657c1970-4722-4189-8831-7325f3bc4265')
+ @decorators.idempotent_id('657c1970-4722-4189-8831-7325f3bc4265')
def test_api_media_types(self):
descr = self.non_admin_client.show_api_description()['version']
# Get MIME type bases and descriptions
@@ -47,7 +48,7 @@
self.assertIn(s_type, media_types)
@test.attr(type='smoke')
- @test.idempotent_id('8879a470-abfb-47bb-bb8d-5a7fd279ad1e')
+ @decorators.idempotent_id('8879a470-abfb-47bb-bb8d-5a7fd279ad1e')
def test_api_version_statuses(self):
descr = self.non_admin_client.show_api_description()['version']
status = descr['status'].lower()
diff --git a/tempest/api/identity/v3/test_projects.py b/tempest/api/identity/v3/test_projects.py
index 26cb90b..570be99 100644
--- a/tempest/api/identity/v3/test_projects.py
+++ b/tempest/api/identity/v3/test_projects.py
@@ -14,15 +14,15 @@
# under the License.
from tempest.api.identity import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
-from tempest import test
class IdentityV3ProjectsTest(base.BaseIdentityV3Test):
credentials = ['primary', 'alt']
- @test.idempotent_id('86128d46-e170-4644-866a-cc487f699e1d')
+ @decorators.idempotent_id('86128d46-e170-4644-866a-cc487f699e1d')
def test_list_projects_returns_only_authorized_projects(self):
alt_project_name =\
self.alt_manager.credentials.project_name
diff --git a/tempest/api/identity/v3/test_tokens.py b/tempest/api/identity/v3/test_tokens.py
index b410da6..1dc1df6 100644
--- a/tempest/api/identity/v3/test_tokens.py
+++ b/tempest/api/identity/v3/test_tokens.py
@@ -16,12 +16,12 @@
from oslo_utils import timeutils
import six
from tempest.api.identity import base
-from tempest import test
+from tempest.lib import decorators
class TokensV3Test(base.BaseIdentityV3Test):
- @test.idempotent_id('6f8e4436-fc96-4282-8122-e41df57197a9')
+ @decorators.idempotent_id('6f8e4436-fc96-4282-8122-e41df57197a9')
def test_create_token(self):
creds = self.os.credentials
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index 9592cb9..f263258 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -20,8 +20,8 @@
from tempest.api.identity import base
from tempest import config
from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions
-from tempest import test
CONF = config.CONF
@@ -78,7 +78,7 @@
time.sleep(1)
self.non_admin_users_client.auth_provider.set_auth()
- @test.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
+ @decorators.idempotent_id('ad71bd23-12ad-426b-bb8b-195d2b635f27')
def test_user_update_own_password(self):
old_pass = self.creds.password
old_token = self.non_admin_client.token
@@ -103,7 +103,7 @@
@testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
'Security compliance not available.')
- @test.idempotent_id('941784ee-5342-4571-959b-b80dd2cea516')
+ @decorators.idempotent_id('941784ee-5342-4571-959b-b80dd2cea516')
def test_password_history_check_self_service_api(self):
old_pass = self.creds.password
new_pass1 = data_utils.rand_password()
@@ -133,7 +133,7 @@
@testtools.skipUnless(CONF.identity_feature_enabled.security_compliance,
'Security compliance not available.')
- @test.idempotent_id('a7ad8bbf-2cff-4520-8c1d-96332e151658')
+ @decorators.idempotent_id('a7ad8bbf-2cff-4520-8c1d-96332e151658')
def test_user_account_lockout(self):
password = self.creds.password
diff --git a/tempest/api/image/admin/v2/test_images.py b/tempest/api/image/admin/v2/test_images.py
index fc5ed79..11b595a 100644
--- a/tempest/api/image/admin/v2/test_images.py
+++ b/tempest/api/image/admin/v2/test_images.py
@@ -17,8 +17,8 @@
import testtools
from tempest.api.image import base
+from tempest.common.utils import data_utils
from tempest import config
-from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index a79c18c..756c78c 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -145,24 +145,24 @@
a_formats = ['ami', 'ari', 'aki']
(cls.container_format,
- cls.container_format_alt) = CONF.image.container_formats[:2]
+ container_format_alt) = CONF.image.container_formats[:2]
cls.disk_format, cls.disk_format_alt = CONF.image.disk_formats[:2]
if cls.container_format in a_formats:
cls.disk_format = cls.container_format
- if cls.container_format_alt in a_formats:
- cls.disk_format_alt = cls.container_format_alt
+ if container_format_alt in a_formats:
+ cls.disk_format_alt = container_format_alt
img1 = cls._create_remote_image('one', cls.container_format,
cls.disk_format)
- img2 = cls._create_remote_image('two', cls.container_format_alt,
+ img2 = cls._create_remote_image('two', container_format_alt,
cls.disk_format_alt)
img3 = cls._create_remote_image('dup', cls.container_format,
cls.disk_format)
img4 = cls._create_remote_image('dup', cls.container_format,
cls.disk_format)
- img5 = cls._create_standard_image('1', cls.container_format_alt,
+ img5 = cls._create_standard_image('1', container_format_alt,
cls.disk_format_alt, 42)
- img6 = cls._create_standard_image('2', cls.container_format_alt,
+ img6 = cls._create_standard_image('2', container_format_alt,
cls.disk_format_alt, 142)
img7 = cls._create_standard_image('33', cls.container_format,
cls.disk_format, 142)
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 868771f..485c8f5 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -32,7 +32,7 @@
# Create a network and make sure it will be hosted by a
# dhcp agent: this is done by creating a regular port
cls.network = cls.create_network()
- cls.subnet = cls.create_subnet(cls.network)
+ cls.create_subnet(cls.network)
cls.port = cls.create_port(cls.network)
@decorators.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
diff --git a/tempest/api/network/admin/test_external_networks_negative.py b/tempest/api/network/admin/test_external_networks_negative.py
index 743089a..770d91f 100644
--- a/tempest/api/network/admin/test_external_networks_negative.py
+++ b/tempest/api/network/admin/test_external_networks_negative.py
@@ -12,6 +12,7 @@
# 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 testtools
from tempest.api.network import base
from tempest import config
@@ -27,6 +28,8 @@
@test.attr(type=['negative'])
@decorators.idempotent_id('d402ae6c-0be0-4d8e-833b-a738895d98d0')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_create_port_with_precreated_floatingip_as_fixed_ip(self):
# NOTE: External networks can be used to create both floating-ip as
# well as instance-ip. So, creating an instance-ip with a value of a
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index c36323a..9a17817 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -31,6 +31,9 @@
if not test.is_extension_enabled('router', 'network'):
msg = "router extension not enabled."
raise cls.skipException(msg)
+ if not CONF.network.public_network_id:
+ msg = "The public_network_id option must be specified."
+ raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
@@ -43,9 +46,9 @@
cls.ext_net_id = CONF.network.public_network_id
cls.floating_ip = cls.create_floatingip(cls.ext_net_id)
cls.network = cls.create_network()
- cls.subnet = cls.create_subnet(cls.network)
- cls.router = cls.create_router(external_network_id=cls.ext_net_id)
- cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+ subnet = cls.create_subnet(cls.network)
+ router = cls.create_router(external_network_id=cls.ext_net_id)
+ cls.create_router_interface(router['id'], subnet['id'])
cls.port = cls.create_port(cls.network)
@decorators.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index 5a54ae0..e1970b9 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -79,7 +79,7 @@
cls.router['id'])['router'].get('distributed', False)
if cls.is_dvr_router:
cls.network = cls.create_network()
- cls.subnet = cls.create_subnet(cls.network)
+ cls.create_subnet(cls.network)
cls.port = cls.create_port(cls.network)
cls.routers_client.add_router_interface(
cls.router['id'], port_id=cls.port['id'])
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index 5fb5232..f6fd871 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -38,10 +38,8 @@
client.delete_router(router_id)
# Asserting that the router is not found in the list
# after deletion
- list_body = self.routers_client.list_routers()
- routers_list = list()
- for router in list_body['routers']:
- routers_list.append(router['id'])
+ list_body = client.list_routers()
+ routers_list = [router['id'] for router in list_body['routers']]
self.assertNotIn(router_id, routers_list)
def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index fa4010d..136f9e6 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -13,9 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import netaddr
import random
+import netaddr
+
from tempest.api.network import base
from tempest.common.utils import data_utils
from tempest.common.utils import net_info
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 52507f9..1156275 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -43,16 +43,16 @@
def resource_setup(cls):
super(ExtraDHCPOptionsTestJSON, cls).resource_setup()
cls.network = cls.create_network()
- cls.subnet = cls.create_subnet(cls.network)
+ cls.create_subnet(cls.network)
cls.port = cls.create_port(cls.network)
- cls.ip_tftp = ('123.123.123.123' if cls._ip_version == 4
- else '2015::dead')
- cls.ip_server = ('123.123.123.45' if cls._ip_version == 4
- else '2015::badd')
+ ip_tftp = ('123.123.123.123' if cls._ip_version == 4
+ else '2015::dead')
+ ip_server = ('123.123.123.45' if cls._ip_version == 4
+ else '2015::badd')
cls.extra_dhcp_opts = [
{'opt_value': 'pxelinux.0', 'opt_name': 'bootfile-name'},
- {'opt_value': cls.ip_tftp, 'opt_name': 'tftp-server'},
- {'opt_value': cls.ip_server, 'opt_name': 'server-ip-address'}
+ {'opt_value': ip_tftp, 'opt_name': 'tftp-server'},
+ {'opt_value': ip_server, 'opt_name': 'server-ip-address'}
]
@decorators.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 23614d6..1dc574b 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -46,6 +46,9 @@
if not test.is_extension_enabled('router', 'network'):
msg = "router extension not enabled."
raise cls.skipException(msg)
+ if not CONF.network.public_network_id:
+ msg = "The public_network_id option must be specified."
+ raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 9ccda05..cb29d3d 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -37,6 +37,9 @@
if not test.is_extension_enabled('router', 'network'):
msg = "router extension not enabled."
raise cls.skipException(msg)
+ if not CONF.network.public_network_id:
+ msg = "The public_network_id option must be specified."
+ raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
@@ -44,9 +47,9 @@
cls.ext_net_id = CONF.network.public_network_id
# Create a network with a subnet connected to a router.
cls.network = cls.create_network()
- cls.subnet = cls.create_subnet(cls.network)
- cls.router = cls.create_router()
- cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+ subnet = cls.create_subnet(cls.network)
+ router = cls.create_router()
+ cls.create_router_interface(router['id'], subnet['id'])
cls.port = cls.create_port(cls.network)
@test.attr(type=['negative'])
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 1426798..69d4ebe 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -34,7 +34,6 @@
def resource_setup(cls):
super(BaseNetworkTestResources, 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._subnet_data = {6: {'gateway':
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 524ab9e..694b86b 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -14,6 +14,7 @@
# under the License.
import netaddr
+import testtools
from tempest.api.network import base_routers as base
from tempest.common.utils import data_utils
@@ -42,6 +43,8 @@
@test.attr(type='smoke')
@decorators.idempotent_id('f64403e2-8483-4b34-8ccd-b09a87bcc68c')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_create_show_list_update_delete_router(self):
# Create a router
router = self._create_router(
@@ -89,6 +92,8 @@
@decorators.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
@test.requires_ext(extension='ext-gw-mode', service='network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_create_router_with_default_snat_value(self):
# Create a router with default snat rule
router = self._create_router(
@@ -99,6 +104,8 @@
@decorators.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
@test.requires_ext(extension='ext-gw-mode', service='network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_create_router_with_snat_explicit(self):
name = data_utils.rand_name('snat-router')
# Create a router enabling snat attributes
@@ -184,6 +191,8 @@
self.assertIn(subnet_id, public_subnet_ids)
@decorators.idempotent_id('6cc285d8-46bf-4f36-9b1a-783e3008ba79')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_update_router_set_gateway(self):
router = self._create_router()
self.routers_client.update_router(
@@ -198,6 +207,8 @@
@decorators.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
@test.requires_ext(extension='ext-gw-mode', service='network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_update_router_set_gateway_with_snat_explicit(self):
router = self._create_router()
self.admin_routers_client.update_router(
@@ -213,6 +224,8 @@
@decorators.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
@test.requires_ext(extension='ext-gw-mode', service='network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_update_router_set_gateway_without_snat(self):
router = self._create_router()
self.admin_routers_client.update_router(
@@ -227,6 +240,8 @@
self._verify_gateway_port(router['id'])
@decorators.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_update_router_unset_gateway(self):
router = self._create_router(
external_network_id=CONF.network.public_network_id)
@@ -241,6 +256,8 @@
@decorators.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
@test.requires_ext(extension='ext-gw-mode', service='network')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
def test_update_router_reset_gateway_without_snat(self):
router = self._create_router(
external_network_id=CONF.network.public_network_id)
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index e0216fd..642c1ac 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -16,8 +16,8 @@
import time
from tempest.common import custom_matchers
+from tempest.common.utils import data_utils
from tempest import config
-from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions as lib_exc
import tempest.test
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index d779d42..cf7dbe8 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -253,6 +253,18 @@
self.assertEqual(True, container.decode(
'utf-8').startswith(prefix))
+ @decorators.idempotent_id('b1811cff-d1ed-4c15-a52e-efd8de41cf34')
+ def test_list_containers_reverse_order(self):
+ # list containers in reverse order
+ _, orig_container_list = self.account_client.list_account_containers()
+
+ params = {'reverse': True}
+ resp, container_list = self.account_client.list_account_containers(
+ params=params)
+ self.assertHeaders(resp, 'Account', 'GET')
+ self.assertEqual(sorted(orig_container_list, reverse=True),
+ container_list)
+
@test.attr(type='smoke')
@decorators.idempotent_id('4894c312-6056-4587-8d6f-86ffbf861f80')
def test_list_account_metadata(self):
@@ -291,7 +303,7 @@
self.account_client.delete_account_metadata(metadata)
@decorators.idempotent_id('9f60348d-c46f-4465-ae06-d51dbd470953')
- def test_update_account_metadata_with_delete_matadata(self):
+ def test_update_account_metadata_with_delete_metadata(self):
# delete metadata from account
metadata = {'test-account-meta1': 'Meta1'}
self.account_client.create_account_metadata(metadata)
@@ -302,7 +314,7 @@
self.assertNotIn('x-account-meta-test-account-meta1', resp)
@decorators.idempotent_id('64fd53f3-adbd-4639-af54-436e4982dbfb')
- def test_update_account_metadata_with_create_matadata_key(self):
+ def test_update_account_metadata_with_create_metadata_key(self):
# if the value of metadata is not set, the metadata is not
# registered at a server
metadata = {'test-account-meta1': ''}
@@ -313,7 +325,7 @@
self.assertNotIn('x-account-meta-test-account-meta1', resp)
@decorators.idempotent_id('d4d884d3-4696-4b85-bc98-4f57c4dd2bf1')
- def test_update_account_metadata_with_delete_matadata_key(self):
+ def test_update_account_metadata_with_delete_metadata_key(self):
# Although the value of metadata is not set, the feature of
# deleting metadata is valid
metadata_1 = {'test-account-meta1': 'Meta1'}
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index 4b65584..2e617f3 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.object_storage import base
-from tempest.lib.common.utils import data_utils
+from tempest.common.utils import data_utils
from tempest.lib import decorators
from tempest import test
@@ -166,7 +166,7 @@
container_name = self.create_container()
object_name, _ = self.create_object(container_name)
- params = {'end_marker': 'ZzzzObject1234567890'}
+ params = {'end_marker': object_name + 'zzzz'}
resp, object_list = self.container_client.list_container_contents(
container_name,
params=params)
@@ -246,7 +246,8 @@
def test_list_container_contents_with_path(self):
# get container contents list using path param
container_name = self.create_container()
- object_name = data_utils.rand_name(name='Swift/TestObject')
+ object_name = data_utils.rand_name(name='TestObject')
+ object_name = 'Swift/' + object_name
self.create_object(container_name, object_name)
params = {'path': 'Swift'}
diff --git a/tempest/api/object_storage/test_container_services_negative.py b/tempest/api/object_storage/test_container_services_negative.py
index be066ba..ebbb84e 100644
--- a/tempest/api/object_storage/test_container_services_negative.py
+++ b/tempest/api/object_storage/test_container_services_negative.py
@@ -16,8 +16,8 @@
import testtools
from tempest.api.object_storage import base
+from tempest.common.utils import data_utils
from tempest import config
-from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
from tempest import test
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 72d71c7..1b97e4a 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -34,19 +34,18 @@
super(VolumeMultiBackendV2Test, cls).resource_setup()
# read backend name from a list .
- cls.backend_names = set(CONF.volume.backend_names)
+ backend_names = set(CONF.volume.backend_names)
cls.name_field = cls.special_fields['name_field']
- cls.volume_type_id_list = []
cls.volume_id_list_with_prefix = []
cls.volume_id_list_without_prefix = []
# Volume/Type creation (uses volume_backend_name)
# It is not allowed to create the same backend name twice
- if len(cls.backend_names) < 2:
+ if len(backend_names) < 2:
raise cls.skipException("Requires at least two different "
"backend names")
- for backend_name in cls.backend_names:
+ for backend_name in backend_names:
# Volume/Type creation (uses backend_name)
cls._create_type_and_volume(backend_name, False)
# Volume/Type creation (uses capabilities:volume_backend_name)
@@ -63,8 +62,8 @@
extra_specs = {spec_key_with_prefix: backend_name_key}
else:
extra_specs = {spec_key_without_prefix: backend_name_key}
- cls.type = cls.create_volume_type(name=type_name,
- extra_specs=extra_specs)
+ cls.create_volume_type(name=type_name,
+ extra_specs=extra_specs)
params = {cls.name_field: vol_name, 'volume_type': type_name,
'size': CONF.volume.volume_size}
diff --git a/tempest/api/volume/admin/test_volume_retype_with_migration.py b/tempest/api/volume/admin/test_volume_retype_with_migration.py
index dc509de..4d32fdd 100644
--- a/tempest/api/volume/admin/test_volume_retype_with_migration.py
+++ b/tempest/api/volume/admin/test_volume_retype_with_migration.py
@@ -40,16 +40,16 @@
def resource_setup(cls):
super(VolumeRetypeWithMigrationV2Test, cls).resource_setup()
# read backend name from a list.
- cls.backend_src = CONF.volume.backend_names[0]
- cls.backend_dst = CONF.volume.backend_names[1]
+ backend_src = CONF.volume.backend_names[0]
+ backend_dst = CONF.volume.backend_names[1]
- extra_specs_src = {"volume_backend_name": cls.backend_src}
- extra_specs_dst = {"volume_backend_name": cls.backend_dst}
+ extra_specs_src = {"volume_backend_name": backend_src}
+ extra_specs_dst = {"volume_backend_name": backend_dst}
- cls.src_vol_type = cls.create_volume_type(extra_specs=extra_specs_src)
+ src_vol_type = cls.create_volume_type(extra_specs=extra_specs_src)
cls.dst_vol_type = cls.create_volume_type(extra_specs=extra_specs_dst)
- cls.src_vol = cls.create_volume(volume_type=cls.src_vol_type['name'])
+ cls.src_vol = cls.create_volume(volume_type=src_vol_type['name'])
@classmethod
def resource_cleanup(cls):
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 7938604..213723c 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -36,7 +36,7 @@
# Create/update/get/delete volume with volume_type and extra spec.
volume_types = list()
vol_name = data_utils.rand_name(self.__class__.__name__ + '-volume')
- self.name_field = self.special_fields['name_field']
+ name_field = self.special_fields['name_field']
proto = CONF.volume.storage_protocol
vendor = CONF.volume.vendor_name
extra_specs = {"storage_protocol": proto,
@@ -46,14 +46,14 @@
vol_type = self.create_volume_type(
extra_specs=extra_specs)
volume_types.append(vol_type)
- params = {self.name_field: vol_name,
+ params = {name_field: vol_name,
'volume_type': volume_types[0]['id'],
'size': CONF.volume.volume_size}
# Create volume
volume = self.create_volume(**params)
self.assertEqual(volume_types[0]['name'], volume["volume_type"])
- self.assertEqual(volume[self.name_field], vol_name,
+ self.assertEqual(volume[name_field], vol_name,
"The created volume name is not equal "
"to the requested name")
self.assertIsNotNone(volume['id'],
@@ -74,7 +74,7 @@
fetched_volume['volume_type'],
'The fetched Volume type is different '
'from updated volume type')
- self.assertEqual(vol_name, fetched_volume[self.name_field],
+ self.assertEqual(vol_name, fetched_volume[name_field],
'The fetched Volume is different '
'from the created Volume')
self.assertEqual(volume['id'], fetched_volume['id'],
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index 933b6ad..1dce7e0 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -24,8 +24,8 @@
@classmethod
def resource_setup(cls):
super(ExtraSpecsNegativeV2Test, cls).resource_setup()
- cls.extra_specs = {"spec1": "val1"}
- cls.volume_type = cls.create_volume_type(extra_specs=cls.extra_specs)
+ extra_specs = {"spec1": "val1"}
+ cls.volume_type = cls.create_volume_type(extra_specs=extra_specs)
@decorators.idempotent_id('08961d20-5cbb-4910-ac0f-89ad6dbb2da1')
def test_update_no_body(self):
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index b278127..e8694b2 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -24,8 +24,8 @@
@decorators.idempotent_id('b48c98f2-e662-4885-9b71-032256906314')
def test_create_with_nonexistent_volume_type(self):
# Should not be able to create volume with nonexistent volume_type.
- self.name_field = self.special_fields['name_field']
- params = {self.name_field: data_utils.rand_uuid(),
+ name_field = self.special_fields['name_field']
+ params = {name_field: data_utils.rand_uuid(),
'volume_type': data_utils.rand_uuid()}
self.assertRaises(lib_exc.NotFound,
self.volumes_client.create_volume, **params)
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 8d94cd2..5477770 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -30,7 +30,6 @@
cls.client = cls.volumes_client
cls.alt_client = cls.os_alt.volumes_client
- cls.alt_tenant_id = cls.alt_client.tenant_id
cls.adm_client = cls.os_adm.volumes_client
@decorators.idempotent_id('4d75b645-a478-48b1-97c8-503f64242f1a')
diff --git a/tempest/api/volume/test_volumes_clone.py b/tempest/api/volume/test_volumes_clone.py
index 79a1a0a..d653808 100644
--- a/tempest/api/volume/test_volumes_clone.py
+++ b/tempest/api/volume/test_volumes_clone.py
@@ -43,7 +43,7 @@
volume = self.volumes_client.show_volume(dst_vol['id'])['volume']
# Should allow
self.assertEqual(volume['source_volid'], src_vol['id'])
- self.assertEqual(int(volume['size']), src_size + 1)
+ self.assertEqual(volume['size'], src_size + 1)
@decorators.idempotent_id('cbbcd7c6-5a6c-481a-97ac-ca55ab715d16')
def test_create_from_bootable_volume(self):
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
index 20118df..2378790 100644
--- a/tempest/api/volume/test_volumes_extend.py
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -23,14 +23,14 @@
@decorators.idempotent_id('9a36df71-a257-43a5-9555-dc7c88e66e0e')
def test_volume_extend(self):
# Extend Volume Test.
- self.volume = self.create_volume()
- extend_size = int(self.volume['size']) + 1
- self.volumes_client.extend_volume(self.volume['id'],
+ volume = self.create_volume()
+ extend_size = volume['size'] + 1
+ self.volumes_client.extend_volume(volume['id'],
new_size=extend_size)
waiters.wait_for_volume_status(self.volumes_client,
- self.volume['id'], 'available')
- volume = self.volumes_client.show_volume(self.volume['id'])['volume']
- self.assertEqual(int(volume['size']), extend_size)
+ volume['id'], 'available')
+ volume = self.volumes_client.show_volume(volume['id'])['volume']
+ self.assertEqual(volume['size'], extend_size)
class VolumesV1ExtendTest(VolumesV2ExtendTest):
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 0a095a9..28e65ed 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -221,7 +221,7 @@
@decorators.idempotent_id('8f05a943-013c-4063-ac71-7baf561e82eb')
def test_volume_extend_with_nonexistent_volume_id(self):
# Extend volume size when volume is nonexistent.
- extend_size = int(self.volume['size']) + 1
+ extend_size = self.volume['size'] + 1
self.assertRaises(lib_exc.NotFound, self.volumes_client.extend_volume,
data_utils.rand_uuid(), new_size=extend_size)
@@ -229,7 +229,7 @@
@decorators.idempotent_id('aff8ba64-6d6f-4f2e-bc33-41a08ee9f115')
def test_volume_extend_without_passing_volume_id(self):
# Extend volume size when passing volume id is None.
- extend_size = int(self.volume['size']) + 1
+ extend_size = self.volume['size'] + 1
self.assertRaises(lib_exc.NotFound, self.volumes_client.extend_volume,
None, new_size=extend_size)
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index f1ca722..9f4ce95 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -153,7 +153,7 @@
volume = self.volumes_client.show_volume(dst_vol['id'])['volume']
# Should allow
self.assertEqual(volume['snapshot_id'], src_snap['id'])
- self.assertEqual(int(volume['size']), src_size + 1)
+ self.assertEqual(volume['size'], src_size + 1)
class VolumesV1SnapshotTestJSON(VolumesV2SnapshotTestJSON):
diff --git a/tempest/api/volume/test_volumes_snapshots_list.py b/tempest/api/volume/test_volumes_snapshots_list.py
index ff390ea..a0eaa00 100644
--- a/tempest/api/volume/test_volumes_snapshots_list.py
+++ b/tempest/api/volume/test_volumes_snapshots_list.py
@@ -28,11 +28,11 @@
@classmethod
def resource_setup(cls):
super(VolumesV2SnapshotListTestJSON, cls).resource_setup()
- cls.volume_origin = cls.create_volume()
+ volume_origin = cls.create_volume()
cls.name_field = cls.special_fields['name_field']
# Create snapshots with params
for _ in range(2):
- cls.snapshot = cls.create_snapshot(cls.volume_origin['id'])
+ cls.snapshot = cls.create_snapshot(volume_origin['id'])
def _list_by_param_values_and_assert(self, with_detail=False, **params):
"""list or list_details with given params and validates result."""
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 9b17515..8b51e64 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -15,6 +15,7 @@
# under the License.
import random
+
from six.moves.urllib import parse
from tempest.api.volume import base
@@ -36,13 +37,13 @@
super(VolumesV2ListTestJSON, cls).resource_setup()
# Create 3 test volumes
- cls.metadata = {'Type': 'work'}
+ metadata = {'Type': 'work'}
# NOTE(zhufl): When using pre-provisioned credentials, the project
# may have volumes other than those created below.
existing_volumes = cls.volumes_client.list_volumes()['volumes']
cls.volume_id_list = [vol['id'] for vol in existing_volumes]
for _ in range(3):
- volume = cls.create_volume(metadata=cls.metadata)
+ volume = cls.create_volume(metadata=metadata)
cls.volume_id_list.append(volume['id'])
@decorators.idempotent_id('2a7064eb-b9c3-429b-b888-33928fc5edd3')
diff --git a/tempest/api/volume/v2/test_volumes_snapshots_list.py b/tempest/api/volume/v2/test_volumes_snapshots_list.py
index f389b59..d385f65 100644
--- a/tempest/api/volume/v2/test_volumes_snapshots_list.py
+++ b/tempest/api/volume/v2/test_volumes_snapshots_list.py
@@ -15,7 +15,7 @@
from tempest.api.volume import base
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -33,11 +33,10 @@
super(VolumesV2SnapshotListTestJSON, cls).resource_setup()
cls.snapshot_id_list = []
# Create a volume
- cls.volume_origin = cls.create_volume()
- cls.name_field = cls.special_fields['name_field']
+ volume_origin = cls.create_volume()
# Create 3 snapshots
for _ in range(3):
- snapshot = cls.create_snapshot(cls.volume_origin['id'])
+ snapshot = cls.create_snapshot(volume_origin['id'])
cls.snapshot_id_list.append(snapshot['id'])
def _list_snapshots_param_sort(self, sort_key, sort_dir):
@@ -56,33 +55,33 @@
self.assertEqual(sorted(sorted_list, reverse=(sort_dir == 'desc')),
sorted_list, msg)
- @test.idempotent_id('c5513ada-64c1-4d28-83b9-af3307ec1388')
+ @decorators.idempotent_id('c5513ada-64c1-4d28-83b9-af3307ec1388')
def test_snapshot_list_param_sort_id_asc(self):
self._list_snapshots_param_sort(sort_key='id', sort_dir='asc')
- @test.idempotent_id('8a7fe058-0b41-402a-8afd-2dbc5a4a718b')
+ @decorators.idempotent_id('8a7fe058-0b41-402a-8afd-2dbc5a4a718b')
def test_snapshot_list_param_sort_id_desc(self):
self._list_snapshots_param_sort(sort_key='id', sort_dir='desc')
- @test.idempotent_id('4052c3a0-2415-440a-a8cc-305a875331b0')
+ @decorators.idempotent_id('4052c3a0-2415-440a-a8cc-305a875331b0')
def test_snapshot_list_param_sort_created_at_asc(self):
self._list_snapshots_param_sort(sort_key='created_at', sort_dir='asc')
- @test.idempotent_id('dcbbe24a-f3c0-4ec8-9274-55d48db8d1cf')
+ @decorators.idempotent_id('dcbbe24a-f3c0-4ec8-9274-55d48db8d1cf')
def test_snapshot_list_param_sort_created_at_desc(self):
self._list_snapshots_param_sort(sort_key='created_at', sort_dir='desc')
- @test.idempotent_id('d58b5fed-0c37-42d3-8c5d-39014ac13c00')
+ @decorators.idempotent_id('d58b5fed-0c37-42d3-8c5d-39014ac13c00')
def test_snapshot_list_param_sort_name_asc(self):
self._list_snapshots_param_sort(sort_key='display_name',
sort_dir='asc')
- @test.idempotent_id('96ba6f4d-1f18-47e1-b4bc-76edc6c21250')
+ @decorators.idempotent_id('96ba6f4d-1f18-47e1-b4bc-76edc6c21250')
def test_snapshot_list_param_sort_name_desc(self):
self._list_snapshots_param_sort(sort_key='display_name',
sort_dir='desc')
- @test.idempotent_id('05489dde-44bc-4961-a1f5-3ce7ee7824f7')
+ @decorators.idempotent_id('05489dde-44bc-4961-a1f5-3ce7ee7824f7')
def test_snapshot_list_param_marker(self):
# The list of snapshots should end before the provided marker
params = {'marker': self.snapshot_id_list[1]}
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 01de704..55bc93e 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -17,10 +17,10 @@
from oslo_utils import excutils
from tempest.common import fixed_network
+from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
from tempest.lib.common import rest_client
-from tempest.lib.common.utils import data_utils
CONF = config.CONF
diff --git a/tempest/common/dynamic_creds.py b/tempest/common/dynamic_creds.py
index 632a876..88fe26c 100644
--- a/tempest/common/dynamic_creds.py
+++ b/tempest/common/dynamic_creds.py
@@ -293,12 +293,12 @@
return resp_body['subnet']
def _create_router(self, router_name, tenant_id):
- external_net_id = dict(
- network_id=self.public_network_id)
- resp_body = self.routers_admin_client.create_router(
- name=router_name,
- external_gateway_info=external_net_id,
- tenant_id=tenant_id)
+ kwargs = {'name': router_name,
+ 'tenant_id': tenant_id}
+ if self.public_network_id:
+ kwargs['external_gateway_info'] = dict(
+ network_id=self.public_network_id)
+ resp_body = self.routers_admin_client.create_router(**kwargs)
return resp_body['router']
def _add_router_interface(self, router_id, subnet_id):
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
index f50edbd..4032c90 100644
--- a/tempest/common/fixed_network.py
+++ b/tempest/common/fixed_network.py
@@ -11,6 +11,7 @@
# under the License.
import copy
+
from oslo_log import log as logging
from tempest import exceptions
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 009812e..1487c1d 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -10,12 +10,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-import netaddr
import re
-import six
import sys
import time
+import netaddr
+import six
+
from oslo_log import log as logging
from tempest import config
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 865db39..15619f4 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -121,7 +121,7 @@
'/'.join((server_status, str(task_state))),
time.time() - start_time)
if server_status == 'ERROR' and not ignore_error:
- raise exceptions.BuildErrorException(server_id=server_id)
+ raise lib_exc.DeleteErrorException(resource_id=server_id)
if int(time.time()) - start_time >= client.build_timeout:
raise lib_exc.TimeoutException
@@ -218,7 +218,7 @@
'within the required time (%s s).' %
(volume_id, new_volume_type, current_volume_type,
client.build_timeout))
- raise exceptions.TimeoutException(message)
+ raise lib_exc.TimeoutException(message)
def wait_for_snapshot_status(client, snapshot_id, status):
diff --git a/tempest/config.py b/tempest/config.py
index fe8c175..b4d88c5 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -15,14 +15,12 @@
from __future__ import print_function
-import functools
import os
import tempfile
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslo_log import log as logging
-import testtools
from tempest.lib import exceptions
from tempest.lib.services import clients
@@ -310,8 +308,7 @@
"min_microversion and max_microversion. "
"If both values are not specified, Tempest avoids tests "
"which require a microversion. Valid values are string "
- "with format 'X.Y' or string 'latest'",
- deprecated_group='compute-feature-enabled'),
+ "with format 'X.Y' or string 'latest'"),
cfg.StrOpt('max_microversion',
default=None,
help="Upper version of the test target microversion range. "
@@ -320,8 +317,7 @@
"min_microversion and max_microversion. "
"If both values are not specified, Tempest avoids tests "
"which require a microversion. Valid values are string "
- "with format 'X.Y' or string 'latest'",
- deprecated_group='compute-feature-enabled'),
+ "with format 'X.Y' or string 'latest'"),
]
compute_features_group = cfg.OptGroup(name='compute-feature-enabled',
@@ -537,23 +533,18 @@
'publicURL', 'adminURL', 'internalURL'],
help="The endpoint type to use for the network service."),
cfg.StrOpt('project_network_cidr',
- deprecated_name='tenant_network_cidr',
default="10.100.0.0/16",
help="The cidr block to allocate project ipv4 subnets from"),
cfg.IntOpt('project_network_mask_bits',
- deprecated_name='tenant_network_mask_bits',
default=28,
help="The mask bits for project ipv4 subnets"),
cfg.StrOpt('project_network_v6_cidr',
- deprecated_name='tenant_network_v6_cidr',
default="2003::/48",
help="The cidr block to allocate project ipv6 subnets from"),
cfg.IntOpt('project_network_v6_mask_bits',
- deprecated_name='tenant_network_v6_mask_bits',
default=64,
help="The mask bits for project ipv6 subnets"),
cfg.BoolOpt('project_networks_reachable',
- deprecated_name='tenant_networks_reachable',
default=False,
help="Whether project networks can be reached directly from "
"the test client. This must be set to True when the "
@@ -655,17 +646,13 @@
choices=['fixed', 'floating'],
help='Default IP type used for validation: '
'-fixed: uses the first IP belonging to the fixed network '
- '-floating: creates and uses a floating IP',
- deprecated_opts=[cfg.DeprecatedOpt('use_floatingip_for_ssh',
- group='compute')]),
+ '-floating: creates and uses a floating IP'),
cfg.StrOpt('auth_method',
default='keypair',
choices=['keypair'],
help='Default authentication method to the instance. '
'Only ssh via keypair is supported for now. '
- 'Additional methods will be handled in a separate spec.',
- deprecated_opts=[cfg.DeprecatedOpt('ssh_auth_method',
- group='compute')]),
+ 'Additional methods will be handled in a separate spec.'),
cfg.IntOpt('ip_version_for_ssh',
default=4,
help='Default IP version for ssh connections.'),
@@ -692,35 +679,25 @@
group='scenario')]),
cfg.StrOpt('image_ssh_password',
default="password",
- help="Password used to authenticate to an instance.",
- deprecated_opts=[cfg.DeprecatedOpt('image_ssh_password',
- group='compute')]),
+ help="Password used to authenticate to an instance."),
cfg.StrOpt('ssh_shell_prologue',
default="set -eu -o pipefail; PATH=$$PATH:/sbin;",
help="Shell fragments to use before executing a command "
- "when sshing to a guest.",
- deprecated_opts=[cfg.DeprecatedOpt('ssh_shell_prologue',
- group='compute')]),
+ "when sshing to a guest."),
cfg.IntOpt('ping_size',
default=56,
help="The packet size for ping packets originating "
- "from remote linux hosts",
- deprecated_opts=[cfg.DeprecatedOpt('ping_size',
- group='compute')]),
+ "from remote linux hosts"),
cfg.IntOpt('ping_count',
default=1,
help="The number of ping packets originating from remote "
- "linux hosts",
- deprecated_opts=[cfg.DeprecatedOpt('ping_count',
- group='compute')]),
+ "linux hosts"),
cfg.StrOpt('floating_ip_range',
default='10.0.0.0/29',
help='Unallocated floating IP range, which will be used to '
'test the floating IP bulk feature for CRUD operation. '
'This block must not overlap an existing floating IP '
- 'pool.',
- deprecated_opts=[cfg.DeprecatedOpt('floating_ip_range',
- group='compute')]),
+ 'pool.'),
cfg.StrOpt('network_for_ssh',
default='public',
help="Network used for SSH connections. Ignored if "
@@ -1035,32 +1012,6 @@
""")
]
-input_scenario_group = cfg.OptGroup(name="input-scenario",
- title="Filters and values for"
- " input scenarios[DEPRECATED]")
-
-
-InputScenarioGroup = [
- cfg.StrOpt('image_regex',
- default='^cirros-0.3.1-x86_64-uec$',
- help="Matching images become parameters for scenario tests",
- deprecated_for_removal=True),
- cfg.StrOpt('flavor_regex',
- default='^m1.nano$',
- help="Matching flavors become parameters for scenario tests",
- deprecated_for_removal=True),
- cfg.StrOpt('non_ssh_image_regex',
- default='^.*[Ww]in.*$',
- help="SSH verification in tests is skipped"
- "for matching images",
- deprecated_for_removal=True),
- cfg.StrOpt('ssh_user_regex',
- default="[[\"^.*[Cc]irros.*$\", \"cirros\"]]",
- help="List of user mapped to regex "
- "to matching image names.",
- deprecated_for_removal=True),
-]
-
DefaultGroup = [
cfg.StrOpt('resources_prefix',
default='tempest',
@@ -1090,7 +1041,6 @@
(scenario_group, ScenarioGroup),
(service_available_group, ServiceAvailableGroup),
(debug_group, DebugGroup),
- (input_scenario_group, InputScenarioGroup),
(None, DefaultGroup)
]
@@ -1152,7 +1102,6 @@
self.scenario = _CONF.scenario
self.service_available = _CONF.service_available
self.debug = _CONF.debug
- self.input_scenario = _CONF['input-scenario']
logging.tempest_set_log_file('tempest.log')
def __init__(self, parse_conf=True, config_path=None):
@@ -1240,75 +1189,6 @@
CONF = TempestConfigProxy()
-def skip_unless_config(*args):
- """Decorator to raise a skip if a config opt doesn't exist or is False
-
- :param str group: The first arg, the option group to check
- :param str name: The second arg, the option name to check
- :param str msg: Optional third arg, the skip msg to use if a skip is raised
- :raises testtools.TestCaseskipException: If the specified config option
- doesn't exist or it exists and evaluates to False
- """
- def decorator(f):
- group = args[0]
- name = args[1]
-
- @functools.wraps(f)
- def wrapper(self, *func_args, **func_kwargs):
- if not hasattr(CONF, group):
- msg = "Config group %s doesn't exist" % group
- raise testtools.TestCase.skipException(msg)
-
- conf_group = getattr(CONF, group)
- if not hasattr(conf_group, name):
- msg = "Config option %s.%s doesn't exist" % (group,
- name)
- raise testtools.TestCase.skipException(msg)
-
- value = getattr(conf_group, name)
- if not value:
- if len(args) == 3:
- msg = args[2]
- else:
- msg = "Config option %s.%s is false" % (group,
- name)
- raise testtools.TestCase.skipException(msg)
- return f(self, *func_args, **func_kwargs)
- return wrapper
- return decorator
-
-
-def skip_if_config(*args):
- """Raise a skipException if a config exists and is True
-
- :param str group: The first arg, the option group to check
- :param str name: The second arg, the option name to check
- :param str msg: Optional third arg, the skip msg to use if a skip is raised
- :raises testtools.TestCase.skipException: If the specified config option
- exists and evaluates to True
- """
- def decorator(f):
- group = args[0]
- name = args[1]
-
- @functools.wraps(f)
- def wrapper(self, *func_args, **func_kwargs):
- if hasattr(CONF, group):
- conf_group = getattr(CONF, group)
- if hasattr(conf_group, name):
- value = getattr(conf_group, name)
- if value:
- if len(args) == 3:
- msg = args[2]
- else:
- msg = "Config option %s.%s is false" % (group,
- name)
- raise testtools.TestCase.skipException(msg)
- return f(self, *func_args, **func_kwargs)
- return wrapper
- return decorator
-
-
def service_client_config(service_client_name=None):
"""Return a dict with the parameters to init service clients
diff --git a/tempest/lib/api_schema/response/compute/v2_1/availability_zone.py b/tempest/lib/api_schema/response/compute/v2_1/availability_zone.py
index f7b77a1..0dc28c3 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/availability_zone.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/availability_zone.py
@@ -51,7 +51,7 @@
}
detail = {
- 'type': 'object',
+ 'type': ['object', 'null'],
'patternProperties': {
# NOTE: Here is for a hostname
'^[a-zA-Z0-9-_.]+$': {
diff --git a/tempest/lib/cmd/check_uuid.py b/tempest/lib/cmd/check_uuid.py
index 2fe957b..283b10f 100755
--- a/tempest/lib/cmd/check_uuid.py
+++ b/tempest/lib/cmd/check_uuid.py
@@ -27,6 +27,7 @@
import six.moves.urllib.parse as urlparse
# TODO(oomichi): Need to remove this after switching all modules to decorators
+# on all OpenStack projects because they runs check-uuid on their own gates.
OLD_DECORATOR_MODULE = 'test'
DECORATOR_MODULE = 'decorators'
@@ -120,7 +121,7 @@
@staticmethod
def _get_idempotent_id(test_node):
- """Return key-value dict with all metadata from @test.idempotent_id"""
+ "Return key-value dict with metadata from @decorators.idempotent_id"
idempotent_id = None
for decorator in test_node.decorator_list:
if (hasattr(decorator, 'func') and
@@ -308,7 +309,8 @@
Returns true if untagged tests exist.
"""
def report(module_name, test_name, tests):
- error_str = "%s:%s\nmissing @test.idempotent_id('...')\n%s\n" % (
+ error_str = ("%s:%s\nmissing @decorators.idempotent_id"
+ "('...')\n%s\n") % (
tests[module_name]['source_path'],
tests[module_name]['tests'][test_name].lineno,
test_name
@@ -356,7 +358,8 @@
else:
errors = checker.report_untagged(untagged) or errors
if errors:
- sys.exit("@test.idempotent_id existence and uniqueness checks failed\n"
+ sys.exit("@decorators.idempotent_id existence and uniqueness checks "
+ "failed\n"
"Run 'tox -v -euuidgen' to automatically fix tests with\n"
"missing @test.idempotent_id decorators.")
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index d0e21ff..f5bff20 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -617,6 +617,7 @@
:raises BadRequest: If a 400 response code is received
:raises Gone: If a 410 response code is received
:raises Conflict: If a 409 response code is received
+ :raises PreconditionFailed: If a 412 response code is received
:raises OverLimit: If a 413 response code is received and over_limit is
not in the response body
:raises RateLimitExceeded: If a 413 response code is received and
@@ -775,6 +776,11 @@
resp_body = self._parse_resp(resp_body)
raise exceptions.Conflict(resp_body, resp=resp)
+ if resp.status == 412:
+ if parse_resp:
+ resp_body = self._parse_resp(resp_body)
+ raise exceptions.PreconditionFailed(resp_body, resp=resp)
+
if resp.status == 413:
if parse_resp:
resp_body = self._parse_resp(resp_body)
diff --git a/tempest/lib/common/utils/data_utils.py b/tempest/lib/common/utils/data_utils.py
index 75c2e51..642514b 100644
--- a/tempest/lib/common/utils/data_utils.py
+++ b/tempest/lib/common/utils/data_utils.py
@@ -14,12 +14,12 @@
# under the License.
import itertools
-import netaddr
import random
import string
import uuid
from debtcollector import removals
+import netaddr
from oslo_utils import netutils
from oslo_utils import uuidutils
import six.moves
diff --git a/tempest/lib/exceptions.py b/tempest/lib/exceptions.py
index 108ba70..dea3289 100644
--- a/tempest/lib/exceptions.py
+++ b/tempest/lib/exceptions.py
@@ -101,6 +101,11 @@
message = "The requested resource is no longer available"
+class PreconditionFailed(ClientRestClientException):
+ status_code = 412
+ message = "Precondition Failed"
+
+
class RateLimitExceeded(ClientRestClientException):
status_code = 413
message = "Rate limit exceeded"
@@ -259,3 +264,8 @@
class VolumeBackupException(TempestException):
message = "Volume backup %(backup_id)s failed and is in ERROR status"
+
+
+class DeleteErrorException(TempestException):
+ message = ("Resource %(resource_id)s failed to delete "
+ "and is in ERROR status")
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index 775d311..adff244 100644
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -32,6 +32,8 @@
class ServersClient(base_compute_client.BaseComputeClient):
+ """Service client for the resource /servers"""
+
schema_versions_info = [
{'min': None, 'max': '2.2', 'schema': schema},
{'min': '2.3', 'max': '2.8', 'schema': schemav23},
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 5422e16..6014c8c 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -117,7 +117,7 @@
return body['keypair']
def create_server(self, name=None, image_id=None, flavor=None,
- validatable=False, wait_until=None,
+ validatable=False, wait_until='ACTIVE',
clients=None, **kwargs):
"""Wrapper utility that returns a test server.
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 50fe9c8..95c2d32 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -36,9 +36,8 @@
def setup_clients(cls):
super(TestAggregatesBasicOps, cls).setup_clients()
# Use admin client by default
- cls.manager = cls.admin_manager
- cls.aggregates_client = cls.manager.aggregates_client
- cls.hosts_client = cls.manager.hosts_client
+ cls.aggregates_client = cls.admin_manager.aggregates_client
+ cls.hosts_client = cls.admin_manager.hosts_client
def _create_aggregate(self, **kwargs):
aggregate = (self.aggregates_client.create_aggregate(**kwargs)
diff --git a/tempest/scenario/test_encrypted_cinder_volumes.py b/tempest/scenario/test_encrypted_cinder_volumes.py
index 77bd10f..da29485 100644
--- a/tempest/scenario/test_encrypted_cinder_volumes.py
+++ b/tempest/scenario/test_encrypted_cinder_volumes.py
@@ -46,9 +46,7 @@
image = self.glance_image_create()
keypair = self.create_keypair()
- return self.create_server(image_id=image,
- key_name=keypair['name'],
- wait_until='ACTIVE')
+ return self.create_server(image_id=image, key_name=keypair['name'])
def create_encrypted_volume(self, encryption_provider, volume_type):
volume_type = self.create_volume_type(name=volume_type)
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 4b1c362..27c45cb 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from tempest.common import custom_matchers
from tempest.common import waiters
from tempest import config
@@ -99,14 +101,14 @@
return address
@decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
@test.services('compute', 'volume', 'image', 'network')
def test_minimum_basic_scenario(self):
image = self.glance_image_create()
keypair = self.create_keypair()
- server = self.create_server(image_id=image,
- key_name=keypair['name'],
- wait_until='ACTIVE')
+ server = self.create_server(image_id=image, key_name=keypair['name'])
servers = self.servers_client.list_servers()['servers']
self.assertIn(server['id'], [x['id'] for x in servers])
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 7843531..1196659 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -39,7 +39,6 @@
def setup_clients(cls):
super(TestNetworkAdvancedServerOps, cls).setup_clients()
cls.admin_servers_client = cls.os_adm.servers_client
- cls.admin_hosts_client = cls.os_adm.hosts_client
@classmethod
def skip_checks(cls):
@@ -65,8 +64,7 @@
server = self.create_server(
networks=[{'uuid': network['id']}],
key_name=keypair['name'],
- security_groups=security_groups,
- wait_until='ACTIVE')
+ security_groups=security_groups)
return server
def _setup_network(self, server, keypair):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index c324261..4dae564 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -109,13 +109,13 @@
self.check_networks()
self.ports = []
- self.port_id = None
+ 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})
+ port_id = self._create_port(self.network['id'])['id']
+ self.ports.append({'port': port_id})
- server = self._create_server(self.network, self.port_id)
+ server = self._create_server(self.network, port_id)
self._check_tenant_network_connectivity()
floating_ip = self.create_floating_ip(server)
@@ -160,8 +160,7 @@
server = self.create_server(
networks=[network],
key_name=keypair['name'],
- security_groups=security_groups,
- wait_until='ACTIVE')
+ security_groups=security_groups)
self.servers.append(server)
return server
@@ -321,11 +320,8 @@
# We ping the external IP from the instance using its floating IP
# which is always IPv4, so we must only test connectivity to
# external IPv4 IPs if the external network is dualstack.
- ext_ips = self.router['external_gateway_info']['external_fixed_ips']
- subnet_ids = [sub['subnet_id'] for sub in ext_ips]
v4_subnets = [s for s in self._list_subnets(
- network_id=CONF.network.public_network_id)
- if s['ip_version'] == 4 and s['id'] in subnet_ids]
+ network_id=CONF.network.public_network_id) if s['ip_version'] == 4]
self.assertEqual(1, len(v4_subnets),
"Found %d IPv4 subnets" % len(v4_subnets))
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index f235934..2d6ea75 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -126,8 +126,7 @@
srv = self.create_server(
key_name=self.keypair['name'],
security_groups=[{'name': self.sec_grp['name']}],
- networks=[{'uuid': n['id']} for n in networks],
- wait_until='ACTIVE')
+ networks=[{'uuid': n['id']} for n in networks])
fip = self.create_floating_ip(thing=srv)
ips = self.define_server_ips(srv=srv)
ssh = self.get_remote_client(
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 07f9d0f..5565cb8 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -241,9 +241,11 @@
self.assertIn(tenant.router['id'], seen_router_ids)
myport = (tenant.router['id'], tenant.subnet['id'])
- router_ports = [(i['device_id'], i['fixed_ips'][0]['subnet_id']) for i
- in self._list_ports()
- if net_info.is_router_interface_port(i)]
+ router_ports = [
+ (i['device_id'], f['subnet_id'])
+ for i in self._list_ports(device_id=tenant.router['id'])
+ if net_info.is_router_interface_port(i)
+ for f in i['fixed_ips']]
self.assertIn(myport, router_ports)
@@ -263,7 +265,6 @@
networks=[{'uuid': tenant.network["id"]}],
key_name=tenant.keypair['name'],
security_groups=security_groups_names,
- wait_until='ACTIVE',
clients=tenant.manager,
**kwargs)
if 'security_groups' in server:
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 6cc5cd3..4d9e59c 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -54,7 +54,7 @@
@test.services('compute', 'volume')
def test_resize_volume_backed_server_confirm(self):
# We create an instance for use in this test
- instance = self.create_server(wait_until='ACTIVE', volume_backed=True)
+ instance = self.create_server(volume_backed=True)
instance_id = instance['id']
resize_flavor = CONF.compute.flavor_ref_alt
LOG.debug("Resizing instance %s from flavor %s to flavor %s",
@@ -75,7 +75,7 @@
@test.services('compute')
def test_server_sequence_suspend_resume(self):
# We create an instance for use in this test
- instance = self.create_server(wait_until='ACTIVE')
+ instance = self.create_server()
instance_id = instance['id']
LOG.debug("Suspending instance %s. Current status: %s",
instance_id, instance['status'])
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 1af68ff..ddbaf5a 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -45,8 +45,6 @@
def setUp(self):
super(TestServerBasicOps, self).setUp()
- self.image_ref = CONF.compute.image_ref
- self.flavor_ref = CONF.compute.flavor_ref
self.run_ssh = CONF.validation.run_validation
self.ssh_user = CONF.validation.image_ssh_user
@@ -133,13 +131,10 @@
security_group = self._create_security_group()
self.md = {'meta1': 'data1', 'meta2': 'data2', 'metaN': 'dataN'}
self.instance = self.create_server(
- image_id=self.image_ref,
- flavor=self.flavor_ref,
key_name=keypair['name'],
security_groups=[{'name': security_group['name']}],
config_drive=CONF.compute_feature_enabled.config_drive,
- metadata=self.md,
- wait_until='ACTIVE')
+ metadata=self.md)
self.verify_ssh(keypair)
self.verify_metadata()
self.verify_metadata_on_config_drive()
diff --git a/tempest/scenario/test_server_multinode.py b/tempest/scenario/test_server_multinode.py
index df83063..db91a21 100644
--- a/tempest/scenario/test_server_multinode.py
+++ b/tempest/scenario/test_server_multinode.py
@@ -75,9 +75,10 @@
# by getting to active state here, this means this has
# landed on the host in question.
inst = self.create_server(
- availability_zone='%(zone)s:%(host_name)s' % host,
- wait_until='ACTIVE')
+ availability_zone='%(zone)s:%(host_name)s' % host)
server = self.servers_client.show_server(inst['id'])['server']
+ # ensure server is located on the requested host
+ self.assertEqual(host['host_name'], server['OS-EXT-SRV-ATTR:host'])
servers.append(server)
# make sure we really have the number of servers we think we should
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index 2264a98..75cef88 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from tempest.common import compute
from tempest.common import waiters
from tempest import config
@@ -55,10 +57,8 @@
security_groups = [{'name': security_group['name']}]
server = self.create_server(
- image_id=CONF.compute.image_ref,
key_name=keypair['name'],
security_groups=security_groups,
- wait_until='ACTIVE',
volume_backed=boot_from_volume)
instance_ip = self.get_server_ip(server)
@@ -75,11 +75,15 @@
self.assertEqual(timestamp, timestamp2)
@decorators.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
@test.services('compute', 'network', 'image')
def test_shelve_instance(self):
self._create_server_then_shelve_and_unshelve()
@decorators.idempotent_id('c1b6318c-b9da-490b-9c67-9339b627271f')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
@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 374cdba..6dedd1d 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from tempest import config
from tempest.lib import decorators
from tempest.scenario import manager
@@ -39,6 +41,8 @@
raise cls.skipException("Snapshotting is not available.")
@decorators.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
@test.services('compute', 'network', 'image')
def test_snapshot_pattern(self):
# prepare for booting an instance
@@ -47,10 +51,8 @@
# boot an instance and create a timestamp file in it
server = self.create_server(
- image_id=CONF.compute.image_ref,
key_name=keypair['name'],
- security_groups=[{'name': security_group['name']}],
- wait_until='ACTIVE')
+ security_groups=[{'name': security_group['name']}])
instance_ip = self.get_server_ip(server)
timestamp = self.create_timestamp(instance_ip,
@@ -63,8 +65,7 @@
server_from_snapshot = self.create_server(
image_id=snapshot_image['id'],
key_name=keypair['name'],
- security_groups=[{'name': security_group['name']}],
- wait_until='ACTIVE')
+ security_groups=[{'name': security_group['name']}])
# check the existence of the timestamp file in the second instance
server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index a302b1c..8661217 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-import time
-
from oslo_log import log as logging
import testtools
@@ -63,21 +61,17 @@
snapshot_name = data_utils.rand_name('scenario-snapshot')
snapshot = self.snapshots_client.create_snapshot(
volume_id=volume['id'], display_name=snapshot_name)['snapshot']
-
- def cleaner():
- self.snapshots_client.delete_snapshot(snapshot['id'])
- try:
- while self.snapshots_client.show_snapshot(
- snapshot['id'])['snapshot']:
- time.sleep(1)
- except lib_exc.NotFound:
- pass
- self.addCleanup(cleaner)
+ self.addCleanup(self.snapshots_client.wait_for_resource_deletion,
+ snapshot['id'])
+ self.addCleanup(self.snapshots_client.delete_snapshot, snapshot['id'])
waiters.wait_for_volume_status(self.volumes_client,
volume['id'], 'available')
waiters.wait_for_snapshot_status(self.snapshots_client,
snapshot['id'], 'available')
- self.assertEqual(snapshot_name, snapshot['display_name'])
+ if 'display_name' in snapshot:
+ self.assertEqual(snapshot_name, snapshot['display_name'])
+ else:
+ self.assertEqual(snapshot_name, snapshot['name'])
return snapshot
def _wait_for_volume_available_on_the_system(self, ip_address,
@@ -94,10 +88,11 @@
CONF.compute.build_interval):
raise lib_exc.TimeoutException
- @decorators.skip_because(bug="1205344")
@decorators.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
@test.services('compute', 'network', 'volume', 'image')
def test_stamp_pattern(self):
# prepare for booting an instance
@@ -107,10 +102,8 @@
# boot an instance and create a timestamp file in it
volume = self.create_volume()
server = self.create_server(
- image_id=CONF.compute.image_ref,
key_name=keypair['name'],
- security_groups=security_group,
- wait_until='ACTIVE')
+ security_groups=[{'name': security_group['name']}])
# create and add floating IP to server1
ip_for_server = self.get_server_ip(server)
@@ -137,7 +130,7 @@
server_from_snapshot = self.create_server(
image_id=snapshot_image['id'],
key_name=keypair['name'],
- security_groups=security_group)
+ security_groups=[{'name': security_group['name']}])
# create and add floating IP to server_from_snapshot
ip_for_snapshot = self.get_server_ip(server_from_snapshot)
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index e34efca..43dcf96 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 as logging
+import testtools
from tempest.common.utils import data_utils
from tempest.common import waiters
@@ -69,10 +70,7 @@
source_type,
delete_on_termination=delete_on_termination))
- return self.create_server(
- image_id='',
- wait_until='ACTIVE',
- **create_kwargs)
+ return self.create_server(image_id='', **create_kwargs)
def _create_snapshot_from_volume(self, vol_id):
snap_name = data_utils.rand_name(
@@ -101,6 +99,8 @@
@decorators.idempotent_id('557cd2c2-4eb8-4dce-98be-f86765ff311b')
@test.attr(type='smoke')
+ @testtools.skipUnless(CONF.network.public_network_id,
+ 'The public_network_id option must be specified.')
@test.services('compute', 'volume', 'image')
def test_volume_boot_pattern(self):
@@ -199,6 +199,8 @@
# The created volume when creating a server from a snapshot
created_volume = server_info['os-extended-volumes:volumes_attached']
+ self.assertNotEmpty(created_volume, "No volume attachment found.")
+
created_volume_info = self.volumes_client.show_volume(
created_volume[0]['id'])['volume']
@@ -229,8 +231,7 @@
self._delete_server(instance)
# boot instance from EBS image
- instance = self.create_server(
- image_id=image['id'])
+ instance = self.create_server(image_id=image['id'])
# just ensure that instance booted
# delete instance
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
index 161e6f2..891e22d 100644
--- a/tempest/scenario/test_volume_migrate_attached.py
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -62,7 +62,7 @@
block_device_mapping = [{'device_name': 'vda', 'volume_id': vol_id,
'delete_on_termination': False}]
- return self.create_server(image_id='', wait_until='ACTIVE',
+ return self.create_server(image_id='',
key_name=key_name,
security_groups=security_groups,
block_device_mapping=block_device_mapping)
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index 9932b4a..4859e75 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -128,6 +128,13 @@
than the specified marker.
DEFAULT: No Marker
+ prefix=[string value Y]
+ Given string value Y, return object names starting with that prefix
+
+ reverse=[boolean value Z]
+ Reverse the result order based on the boolean value Z
+ DEFAULT: False
+
format=[string value, either 'json' or 'xml']
Specify either json or xml to return the respective serialized
response.
diff --git a/tempest/test.py b/tempest/test.py
index 039afa1..06de520 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -39,7 +39,11 @@
CONF = config.CONF
-idempotent_id = decorators.idempotent_id
+# TODO(oomichi): This test.idempotent_id should be removed after all projects
+# switch to use decorators.idempotent_id.
+idempotent_id = debtcollector.moves.moved_function(
+ decorators.idempotent_id, 'idempotent_id', __name__,
+ version='Mitaka', removal_version='?')
def attr(**kwargs):
diff --git a/tempest/tests/common/test_preprov_creds.py b/tempest/tests/common/test_preprov_creds.py
index 1c9982c..2fd375d 100644
--- a/tempest/tests/common/test_preprov_creds.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -14,14 +14,15 @@
import hashlib
import os
-import testtools
+import shutil
import mock
+import six
+import testtools
+
from oslo_concurrency.fixture import lockutils as lockutils_fixtures
from oslo_config import cfg
from oslotest import mockpatch
-import shutil
-import six
from tempest.common import preprov_creds
from tempest import config
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index e4f4c04..5be6229 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import fixtures
import time
+import fixtures
from oslo_config import cfg
from oslotest import mockpatch
diff --git a/tempest/tests/lib/cli/test_execute.py b/tempest/tests/lib/cli/test_execute.py
index aaeb6f4..0130454 100644
--- a/tempest/tests/lib/cli/test_execute.py
+++ b/tempest/tests/lib/cli/test_execute.py
@@ -11,9 +11,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import mock
import subprocess
+import mock
+
from tempest.lib.cli import base as cli_base
from tempest.lib import exceptions
from tempest.tests import base
diff --git a/tempest/tests/lib/services/compute/test_versions_client.py b/tempest/tests/lib/services/compute/test_versions_client.py
index 06ecdc3..255a0a3 100644
--- a/tempest/tests/lib/services/compute/test_versions_client.py
+++ b/tempest/tests/lib/services/compute/test_versions_client.py
@@ -13,6 +13,7 @@
# under the License.
import copy
+
from oslotest import mockpatch
from tempest.lib.services.compute import versions_client
diff --git a/tempest/tests/lib/services/test_clients.py b/tempest/tests/lib/services/test_clients.py
index 5db932c..a3b390e 100644
--- a/tempest/tests/lib/services/test_clients.py
+++ b/tempest/tests/lib/services/test_clients.py
@@ -12,10 +12,11 @@
# License for the specific language governing permissions and limitations under
# the License.
+import types
+
import fixtures
import mock
import testtools
-import types
from tempest.lib import auth
from tempest.lib import exceptions
diff --git a/tempest/tests/lib/test_auth.py b/tempest/tests/lib/test_auth.py
index 2f975d2..ac13a13 100644
--- a/tempest/tests/lib/test_auth.py
+++ b/tempest/tests/lib/test_auth.py
@@ -15,9 +15,9 @@
import copy
import datetime
-import testtools
from oslotest import mockpatch
+import testtools
from tempest.lib import auth
from tempest.lib import exceptions
diff --git a/tempest/tests/lib/test_rest_client.py b/tempest/tests/lib/test_rest_client.py
index e6cf047..4a83631 100644
--- a/tempest/tests/lib/test_rest_client.py
+++ b/tempest/tests/lib/test_rest_client.py
@@ -337,6 +337,10 @@
def test_response_410(self):
self._test_error_checker(exceptions.Gone, self.set_data("410"))
+ def test_response_412(self):
+ self._test_error_checker(exceptions.PreconditionFailed,
+ self.set_data("412"))
+
def test_response_413(self):
self._test_error_checker(exceptions.OverLimit, self.set_data("413"))
@@ -460,7 +464,7 @@
def test_response_bigger_than_400(self):
# Any response code, that bigger than 400, and not in
- # (401, 403, 404, 409, 413, 422, 500, 501)
+ # (401, 403, 404, 409, 412, 413, 422, 500, 501)
self._test_error_checker(exceptions.UnexpectedResponseCode,
self.set_data("402"))
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index ae2f2a3..a069a81 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -199,96 +199,3 @@
self._test_requires_ext_helper,
extension='enabled_ext',
service='bad_service')
-
-
-class TestConfigDecorators(BaseDecoratorsTest):
- def setUp(self):
- super(TestConfigDecorators, self).setUp()
- cfg.CONF.set_default('nova', True, 'service_available')
- cfg.CONF.set_default('glance', False, 'service_available')
-
- def _assert_skip_message(self, func, skip_msg):
- try:
- func()
- self.fail()
- except testtools.TestCase.skipException as skip_exc:
- self.assertEqual(skip_exc.args[0], skip_msg)
-
- def _test_skip_unless_config(self, expected_to_skip=True, *decorator_args):
-
- class TestFoo(test.BaseTestCase):
- @config.skip_unless_config(*decorator_args)
- def test_bar(self):
- return 0
-
- t = TestFoo('test_bar')
- if expected_to_skip:
- self.assertRaises(testtools.TestCase.skipException, t.test_bar)
- if (len(decorator_args) >= 3):
- # decorator_args[2]: skip message specified
- self._assert_skip_message(t.test_bar, decorator_args[2])
- else:
- try:
- self.assertEqual(t.test_bar(), 0)
- except testtools.TestCase.skipException:
- # We caught a skipException but we didn't expect to skip
- # this test so raise a hard test failure instead.
- raise testtools.TestCase.failureException(
- "Not supposed to skip")
-
- def _test_skip_if_config(self, expected_to_skip=True,
- *decorator_args):
-
- class TestFoo(test.BaseTestCase):
- @config.skip_if_config(*decorator_args)
- def test_bar(self):
- return 0
-
- t = TestFoo('test_bar')
- if expected_to_skip:
- self.assertRaises(testtools.TestCase.skipException, t.test_bar)
- if (len(decorator_args) >= 3):
- # decorator_args[2]: skip message specified
- self._assert_skip_message(t.test_bar, decorator_args[2])
- else:
- try:
- self.assertEqual(t.test_bar(), 0)
- except testtools.TestCase.skipException:
- # We caught a skipException but we didn't expect to skip
- # this test so raise a hard test failure instead.
- raise testtools.TestCase.failureException(
- "Not supposed to skip")
-
- def test_skip_unless_no_group(self):
- self._test_skip_unless_config(True, 'fake_group', 'an_option')
-
- def test_skip_unless_no_option(self):
- self._test_skip_unless_config(True, 'service_available',
- 'not_an_option')
-
- def test_skip_unless_false_option(self):
- self._test_skip_unless_config(True, 'service_available', 'glance')
-
- def test_skip_unless_false_option_msg(self):
- self._test_skip_unless_config(True, 'service_available', 'glance',
- 'skip message')
-
- def test_skip_unless_true_option(self):
- self._test_skip_unless_config(False,
- 'service_available', 'nova')
-
- def test_skip_if_no_group(self):
- self._test_skip_if_config(False, 'fake_group', 'an_option')
-
- def test_skip_if_no_option(self):
- self._test_skip_if_config(False, 'service_available', 'not_an_option')
-
- def test_skip_if_false_option(self):
- self._test_skip_if_config(False, 'service_available', 'glance')
-
- def test_skip_if_true_option(self):
- self._test_skip_if_config(True, 'service_available', 'nova')
-
- def test_skip_if_true_option_msg(self):
- self._test_skip_if_config(True, 'service_available', 'nova',
- 'skip message')
diff --git a/tempest/tests/test_list_tests.py b/tempest/tests/test_list_tests.py
index 38d4c5c..a238879 100644
--- a/tempest/tests/test_list_tests.py
+++ b/tempest/tests/test_list_tests.py
@@ -14,9 +14,10 @@
import os
import re
-import six
import subprocess
+import six
+
from tempest.tests import base
diff --git a/test-requirements.txt b/test-requirements.txt
index 475fb16..f7d63a8 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -9,3 +9,4 @@
mock>=2.0 # BSD
coverage>=4.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
+flake8-import-order==0.11 # LGPLv3
diff --git a/tools/check_logs.py b/tools/check_logs.py
index caad85c..f82b387 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -19,10 +19,10 @@
import gzip
import os
import re
-import six
-import six.moves.urllib.request as urlreq
import sys
+import six
+import six.moves.urllib.request as urlreq
import yaml
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index f2da27a..2ba8b16 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -18,9 +18,10 @@
import gzip
import pprint
import re
+import sys
+
import six
import six.moves.urllib.request as urlreq
-import sys
pp = pprint.PrettyPrinter()
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index 03e838e..acb29af 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -25,6 +25,7 @@
import json
import re
+
import requests
url = 'https://review.openstack.org/projects/'
diff --git a/tox.ini b/tox.ini
index 46823d8..d8d390e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -147,6 +147,7 @@
show-source = True
exclude = .git,.venv,.tox,dist,doc,*egg
enable-extensions = H106,H203,H904
+import-order-style = pep8
[testenv:releasenotes]
commands = sphinx-build -a -E -W -d releasenotes/build/doctrees -b html releasenotes/source releasenotes/build/html