Merge "Add tempest test to test NoVNC support"
diff --git a/releasenotes/notes/add-image-clients-tests-49dbc0a0a4281a77.yaml b/releasenotes/notes/add-image-clients-tests-49dbc0a0a4281a77.yaml
index 9d1a003..eaab1f0 100644
--- a/releasenotes/notes/add-image-clients-tests-49dbc0a0a4281a77.yaml
+++ b/releasenotes/notes/add-image-clients-tests-49dbc0a0a4281a77.yaml
@@ -6,4 +6,5 @@
there are some apis are not included, add them.
* namespace_objects_client(v2)
+ * namespace_tags_client(v2)
diff --git a/releasenotes/notes/add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml b/releasenotes/notes/add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml
new file mode 100644
index 0000000..9a4e6b1
--- /dev/null
+++ b/releasenotes/notes/add-snapshot-manage-client-as-library-a76ffdba9d8d01cb.yaml
@@ -0,0 +1,8 @@
+---
+features:
+ - |
+ Define v2 snapshot_manage_client client for the volume service as
+ library interfaces, allowing other projects to use this module as
+ stable libraries without maintenance changes.
+
+ * snapshot_manage_client(v2)
diff --git a/releasenotes/notes/deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml b/releasenotes/notes/deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml
new file mode 100644
index 0000000..4acdc6d
--- /dev/null
+++ b/releasenotes/notes/deprecate-allow_port_security_disabled-option-2d3d87f6bd11d03a.yaml
@@ -0,0 +1,8 @@
+---
+upgrade:
+ - The default value for the ``allow_port_security_disabled`` option in the
+ ``compute-feature-enabled`` section has been changed from ``False``
+ to ``True``.
+deprecations:
+ - The ``allow_port_security_disabled`` option in the
+ ``compute-feature-enabled`` section is now deprecated.
diff --git a/releasenotes/notes/jsonschema-validator-2377ba131e12d3c7.yaml b/releasenotes/notes/jsonschema-validator-2377ba131e12d3c7.yaml
new file mode 100644
index 0000000..8817ed4
--- /dev/null
+++ b/releasenotes/notes/jsonschema-validator-2377ba131e12d3c7.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - Added customized JSON schema format checker for 'date-time' format.
+ Compute response schema will be validated against customized format
+ checker.
diff --git a/releasenotes/source/conf.py b/releasenotes/source/conf.py
index 140263c..eec42cd 100644
--- a/releasenotes/source/conf.py
+++ b/releasenotes/source/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
diff --git a/tempest/api/compute/admin/test_agents.py b/tempest/api/compute/admin/test_agents.py
index 1c37cad..118ad60 100644
--- a/tempest/api/compute/admin/test_agents.py
+++ b/tempest/api/compute/admin/test_agents.py
@@ -14,7 +14,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
class AgentsAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -44,7 +44,7 @@
kwargs[rand_key] = data_utils.rand_name(kwargs[rand_key])
return kwargs
- @test.idempotent_id('1fc6bdc8-0b6d-4cc7-9f30-9b04fabe5b90')
+ @decorators.idempotent_id('1fc6bdc8-0b6d-4cc7-9f30-9b04fabe5b90')
def test_create_agent(self):
# Create an agent.
params = self._param_helper(
@@ -56,7 +56,7 @@
for expected_item, value in params.items():
self.assertEqual(value, body[expected_item])
- @test.idempotent_id('dc9ffd51-1c50-4f0e-a820-ae6d2a568a9e')
+ @decorators.idempotent_id('dc9ffd51-1c50-4f0e-a820-ae6d2a568a9e')
def test_update_agent(self):
# Create and update an agent.
body = self.client.create_agent(**self.params_agent)['agent']
@@ -69,7 +69,7 @@
for expected_item, value in params.items():
self.assertEqual(value, body[expected_item])
- @test.idempotent_id('470e0b89-386f-407b-91fd-819737d0b335')
+ @decorators.idempotent_id('470e0b89-386f-407b-91fd-819737d0b335')
def test_delete_agent(self):
# Create an agent and delete it.
body = self.client.create_agent(**self.params_agent)['agent']
@@ -80,7 +80,7 @@
self.assertNotIn(body['agent_id'], map(lambda x: x['agent_id'],
agents))
- @test.idempotent_id('6a326c69-654b-438a-80a3-34bcc454e138')
+ @decorators.idempotent_id('6a326c69-654b-438a-80a3-34bcc454e138')
def test_list_agents(self):
# Create an agent and list all agents.
body = self.client.create_agent(**self.params_agent)['agent']
@@ -90,7 +90,7 @@
'Cannot get any agents.(%s)' % agents)
self.assertIn(body['agent_id'], map(lambda x: x['agent_id'], agents))
- @test.idempotent_id('eabadde4-3cd7-4ec4-a4b5-5a936d2d4408')
+ @decorators.idempotent_id('eabadde4-3cd7-4ec4-a4b5-5a936d2d4408')
def test_list_agents_with_filter(self):
# Create agents and list the agent builds by the filter.
body = self.client.create_agent(**self.params_agent)['agent']
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 1233a2b..36ce975 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -20,7 +20,7 @@
from tempest.common.utils import data_utils
from tempest import config
from tempest.lib.common.utils import test_utils
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -59,7 +59,7 @@
msg += " for hypervisor_type %s" % CONF.compute.hypervisor_type
raise testtools.TestCase.failureException(msg)
- @test.idempotent_id('0d148aa3-d54c-4317-aa8d-42040a475e20')
+ @decorators.idempotent_id('0d148aa3-d54c-4317-aa8d-42040a475e20')
def test_aggregate_create_delete(self):
# Create and delete an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -73,7 +73,7 @@
self.client.delete_aggregate(aggregate['id'])
self.client.wait_for_resource_deletion(aggregate['id'])
- @test.idempotent_id('5873a6f8-671a-43ff-8838-7ce430bb6d0b')
+ @decorators.idempotent_id('5873a6f8-671a-43ff-8838-7ce430bb6d0b')
def test_aggregate_create_delete_with_az(self):
# Create and delete an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -88,7 +88,7 @@
self.client.delete_aggregate(aggregate['id'])
self.client.wait_for_resource_deletion(aggregate['id'])
- @test.idempotent_id('68089c38-04b1-4758-bdf0-cf0daec4defd')
+ @decorators.idempotent_id('68089c38-04b1-4758-bdf0-cf0daec4defd')
def test_aggregate_create_verify_entry_in_list(self):
# Create an aggregate and ensure it is listed.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -101,7 +101,7 @@
map(lambda x: (x['id'], x['availability_zone']),
aggregates))
- @test.idempotent_id('36ec92ca-7a73-43bc-b920-7531809e8540')
+ @decorators.idempotent_id('36ec92ca-7a73-43bc-b920-7531809e8540')
def test_aggregate_create_update_metadata_get_details(self):
# Create an aggregate and ensure its details are returned.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -124,7 +124,7 @@
body = self.client.show_aggregate(aggregate['id'])['aggregate']
self.assertEqual(meta, body["metadata"])
- @test.idempotent_id('4d2b2004-40fa-40a1-aab2-66f4dab81beb')
+ @decorators.idempotent_id('4d2b2004-40fa-40a1-aab2-66f4dab81beb')
def test_aggregate_create_update_with_az(self):
# Update an aggregate and ensure properties are updated correctly
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -154,7 +154,7 @@
(x['id'], x['name'], x['availability_zone']),
aggregates))
- @test.idempotent_id('c8e85064-e79b-4906-9931-c11c24294d02')
+ @decorators.idempotent_id('c8e85064-e79b-4906-9931-c11c24294d02')
def test_aggregate_add_remove_host(self):
# Add a host to the given aggregate and remove.
self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -177,7 +177,7 @@
body['availability_zone'])
self.assertNotIn(self.host, body['hosts'])
- @test.idempotent_id('7f6a1cc5-2446-4cdb-9baa-b6ae0a919b72')
+ @decorators.idempotent_id('7f6a1cc5-2446-4cdb-9baa-b6ae0a919b72')
def test_aggregate_add_host_list(self):
# Add a host to the given aggregate and list.
self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -197,7 +197,7 @@
self.assertIsNone(agg['availability_zone'])
self.assertIn(self.host, agg['hosts'])
- @test.idempotent_id('eeef473c-7c52-494d-9f09-2ed7fc8fc036')
+ @decorators.idempotent_id('eeef473c-7c52-494d-9f09-2ed7fc8fc036')
def test_aggregate_add_host_get_details(self):
# Add a host to the given aggregate and get details.
self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -214,7 +214,7 @@
self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
- @test.idempotent_id('96be03c7-570d-409c-90f8-e4db3c646996')
+ @decorators.idempotent_id('96be03c7-570d-409c-90f8-e4db3c646996')
def test_aggregate_add_host_create_server_with_az(self):
# Add a host to the given aggregate and create a server.
self.useFixture(fixtures.LockFixture('availability_zone'))
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index 85aa301..deded73 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -16,6 +16,7 @@
from tempest.api.compute import base
from tempest.common import tempest_fixtures as fixtures
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -48,7 +49,7 @@
return aggregate
@test.attr(type=['negative'])
- @test.idempotent_id('86a1cb14-da37-4a70-b056-903fd56dfe29')
+ @decorators.idempotent_id('86a1cb14-da37-4a70-b056-903fd56dfe29')
def test_aggregate_create_as_user(self):
# Regular user is not allowed to create an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
@@ -57,7 +58,7 @@
name=aggregate_name)
@test.attr(type=['negative'])
- @test.idempotent_id('3b8a1929-3793-4e92-bcb4-dfa572ee6c1d')
+ @decorators.idempotent_id('3b8a1929-3793-4e92-bcb4-dfa572ee6c1d')
def test_aggregate_create_aggregate_name_length_less_than_1(self):
# the length of aggregate name should >= 1 and <=255
self.assertRaises(lib_exc.BadRequest,
@@ -65,7 +66,7 @@
name='')
@test.attr(type=['negative'])
- @test.idempotent_id('4c194563-543b-4e70-a719-557bbe947fac')
+ @decorators.idempotent_id('4c194563-543b-4e70-a719-557bbe947fac')
def test_aggregate_create_aggregate_name_length_exceeds_255(self):
# the length of aggregate name should >= 1 and <=255
aggregate_name = 'a' * 256
@@ -74,7 +75,7 @@
name=aggregate_name)
@test.attr(type=['negative'])
- @test.idempotent_id('9c23a291-b0b1-487b-b464-132e061151b3')
+ @decorators.idempotent_id('9c23a291-b0b1-487b-b464-132e061151b3')
def test_aggregate_create_with_existent_aggregate_name(self):
# creating an aggregate with existent aggregate name is forbidden
aggregate = self._create_test_aggregate()
@@ -83,7 +84,7 @@
name=aggregate['name'])
@test.attr(type=['negative'])
- @test.idempotent_id('cd6de795-c15d-45f1-8d9e-813c6bb72a3d')
+ @decorators.idempotent_id('cd6de795-c15d-45f1-8d9e-813c6bb72a3d')
def test_aggregate_delete_as_user(self):
# Regular user is not allowed to delete an aggregate.
aggregate = self._create_test_aggregate()
@@ -92,14 +93,14 @@
aggregate['id'])
@test.attr(type=['negative'])
- @test.idempotent_id('b7d475a6-5dcd-4ff4-b70a-cd9de66a6672')
+ @decorators.idempotent_id('b7d475a6-5dcd-4ff4-b70a-cd9de66a6672')
def test_aggregate_list_as_user(self):
# Regular user is not allowed to list aggregates.
self.assertRaises(lib_exc.Forbidden,
self.user_client.list_aggregates)
@test.attr(type=['negative'])
- @test.idempotent_id('557cad12-34c9-4ff4-95f0-22f0dfbaf7dc')
+ @decorators.idempotent_id('557cad12-34c9-4ff4-95f0-22f0dfbaf7dc')
def test_aggregate_get_details_as_user(self):
# Regular user is not allowed to get aggregate details.
aggregate = self._create_test_aggregate()
@@ -108,21 +109,21 @@
aggregate['id'])
@test.attr(type=['negative'])
- @test.idempotent_id('c74f4bf1-4708-4ff2-95a0-f49eaca951bd')
+ @decorators.idempotent_id('c74f4bf1-4708-4ff2-95a0-f49eaca951bd')
def test_aggregate_delete_with_invalid_id(self):
# Delete an aggregate with invalid id should raise exceptions.
self.assertRaises(lib_exc.NotFound,
self.client.delete_aggregate, -1)
@test.attr(type=['negative'])
- @test.idempotent_id('3c916244-2c46-49a4-9b55-b20bb0ae512c')
+ @decorators.idempotent_id('3c916244-2c46-49a4-9b55-b20bb0ae512c')
def test_aggregate_get_details_with_invalid_id(self):
# Get aggregate details with invalid id should raise exceptions.
self.assertRaises(lib_exc.NotFound,
self.client.show_aggregate, -1)
@test.attr(type=['negative'])
- @test.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
+ @decorators.idempotent_id('0ef07828-12b4-45ba-87cc-41425faf5711')
def test_aggregate_add_non_exist_host(self):
# Adding a non-exist host to an aggregate should raise exceptions.
hosts_all = self.os_adm.hosts_client.list_hosts()['hosts']
@@ -136,7 +137,7 @@
aggregate['id'], host=non_exist_host)
@test.attr(type=['negative'])
- @test.idempotent_id('7324c334-bd13-4c93-8521-5877322c3d51')
+ @decorators.idempotent_id('7324c334-bd13-4c93-8521-5877322c3d51')
def test_aggregate_add_host_as_user(self):
# Regular user is not allowed to add a host to an aggregate.
aggregate = self._create_test_aggregate()
@@ -145,7 +146,7 @@
aggregate['id'], host=self.host)
@test.attr(type=['negative'])
- @test.idempotent_id('19dd44e1-c435-4ee1-a402-88c4f90b5950')
+ @decorators.idempotent_id('19dd44e1-c435-4ee1-a402-88c4f90b5950')
def test_aggregate_add_existent_host(self):
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate = self._create_test_aggregate()
@@ -158,7 +159,7 @@
aggregate['id'], host=self.host)
@test.attr(type=['negative'])
- @test.idempotent_id('7a53af20-137a-4e44-a4ae-e19260e626d9')
+ @decorators.idempotent_id('7a53af20-137a-4e44-a4ae-e19260e626d9')
def test_aggregate_remove_host_as_user(self):
# Regular user is not allowed to remove a host from an aggregate.
self.useFixture(fixtures.LockFixture('availability_zone'))
@@ -173,7 +174,7 @@
aggregate['id'], host=self.host)
@test.attr(type=['negative'])
- @test.idempotent_id('95d6a6fa-8da9-4426-84d0-eec0329f2e4d')
+ @decorators.idempotent_id('95d6a6fa-8da9-4426-84d0-eec0329f2e4d')
def test_aggregate_remove_nonexistent_host(self):
aggregate = self._create_test_aggregate()
diff --git a/tempest/api/compute/admin/test_auto_allocate_network.py b/tempest/api/compute/admin/test_auto_allocate_network.py
index 08e4072..7fda732 100644
--- a/tempest/api/compute/admin/test_auto_allocate_network.py
+++ b/tempest/api/compute/admin/test_auto_allocate_network.py
@@ -19,6 +19,7 @@
from tempest.common import credentials_factory as credentials
from tempest import config
from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_excs
from tempest import test
@@ -145,7 +146,7 @@
test_utils.call_and_ignore_notfound_exc(
cls.networks_client.delete_network, network['id'])
- @test.idempotent_id('5eb7b8fa-9c23-47a2-9d7d-02ed5809dd34')
+ @decorators.idempotent_id('5eb7b8fa-9c23-47a2-9d7d-02ed5809dd34')
def test_server_create_no_allocate(self):
"""Tests that no networking is allocated for the server."""
# create the server with no networking
@@ -158,7 +159,7 @@
# assert that there is no networking
self.assertEqual({}, addresses)
- @test.idempotent_id('2e6cf129-9e28-4e8a-aaaa-045ea826b2a6')
+ @decorators.idempotent_id('2e6cf129-9e28-4e8a-aaaa-045ea826b2a6')
def test_server_multi_create_auto_allocate(self):
"""Tests that networking is auto-allocated for multiple servers."""
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index 3470602..50dec28 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class AZAdminV2TestJSON(base.BaseV2ComputeAdminTest):
@@ -25,13 +25,13 @@
super(AZAdminV2TestJSON, cls).setup_clients()
cls.client = cls.availability_zone_admin_client
- @test.idempotent_id('d3431479-8a09-4f76-aa2d-26dc580cb27c')
+ @decorators.idempotent_id('d3431479-8a09-4f76-aa2d-26dc580cb27c')
def test_get_availability_zone_list(self):
# List of availability zone
availability_zone = self.client.list_availability_zones()
self.assertGreater(len(availability_zone['availabilityZoneInfo']), 0)
- @test.idempotent_id('ef726c58-530f-44c2-968c-c7bed22d5b8c')
+ @decorators.idempotent_id('ef726c58-530f-44c2-968c-c7bed22d5b8c')
def test_get_availability_zone_list_detail(self):
# List of availability zones and available services
availability_zone = self.client.list_availability_zones(detail=True)
diff --git a/tempest/api/compute/admin/test_availability_zone_negative.py b/tempest/api/compute/admin/test_availability_zone_negative.py
index c60de1e..faeb811 100644
--- a/tempest/api/compute/admin/test_availability_zone_negative.py
+++ b/tempest/api/compute/admin/test_availability_zone_negative.py
@@ -13,6 +13,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -26,7 +27,7 @@
cls.non_adm_client = cls.availability_zone_client
@test.attr(type=['negative'])
- @test.idempotent_id('bf34dca2-fdc3-4073-9c02-7648d9eae0d7')
+ @decorators.idempotent_id('bf34dca2-fdc3-4073-9c02-7648d9eae0d7')
def test_get_availability_zone_list_detail_with_non_admin_user(self):
# List of availability zones and available services with
# non-administrator user
diff --git a/tempest/api/compute/admin/test_baremetal_nodes.py b/tempest/api/compute/admin/test_baremetal_nodes.py
index 722d9a6..7726ed4 100644
--- a/tempest/api/compute/admin/test_baremetal_nodes.py
+++ b/tempest/api/compute/admin/test_baremetal_nodes.py
@@ -14,6 +14,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -32,11 +33,11 @@
cls.ironic_client = cls.os_adm.baremetal_client
@test.attr(type=['baremetal'])
- @test.idempotent_id('e475aa6e-416d-4fa4-b3af-28d5e84250fb')
+ @decorators.idempotent_id('e475aa6e-416d-4fa4-b3af-28d5e84250fb')
def test_list_get_baremetal_nodes(self):
# Create some test nodes in Ironic directly
test_nodes = []
- for i in range(0, 3):
+ for _ in range(0, 3):
_, node = self.ironic_client.create_node()
test_nodes.append(node)
self.addCleanup(self.ironic_client.delete_node, node['uuid'])
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index 9cda0cd..10ed519 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -47,18 +48,18 @@
if cls.ip:
break
- @test.idempotent_id('16b7d848-2f7c-4709-85a3-2dfb4576cc52')
+ @decorators.idempotent_id('16b7d848-2f7c-4709-85a3-2dfb4576cc52')
@test.services('network')
def test_list_fixed_ip_details(self):
fixed_ip = self.client.show_fixed_ip(self.ip)
self.assertEqual(fixed_ip['fixed_ip']['address'], self.ip)
- @test.idempotent_id('5485077b-7e46-4cec-b402-91dc3173433b')
+ @decorators.idempotent_id('5485077b-7e46-4cec-b402-91dc3173433b')
@test.services('network')
def test_set_reserve(self):
self.client.reserve_fixed_ip(self.ip, reserve="None")
- @test.idempotent_id('7476e322-b9ff-4710-bf82-49d51bac6e2e')
+ @decorators.idempotent_id('7476e322-b9ff-4710-bf82-49d51bac6e2e')
@test.services('network')
def test_set_unreserve(self):
self.client.reserve_fixed_ip(self.ip, unreserve="None")
diff --git a/tempest/api/compute/admin/test_fixed_ips_negative.py b/tempest/api/compute/admin/test_fixed_ips_negative.py
index 05bba21..073f152 100644
--- a/tempest/api/compute/admin/test_fixed_ips_negative.py
+++ b/tempest/api/compute/admin/test_fixed_ips_negative.py
@@ -14,6 +14,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -49,14 +50,14 @@
break
@test.attr(type=['negative'])
- @test.idempotent_id('9f17f47d-daad-4adc-986e-12370c93e407')
+ @decorators.idempotent_id('9f17f47d-daad-4adc-986e-12370c93e407')
@test.services('network')
def test_list_fixed_ip_details_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.show_fixed_ip, self.ip)
@test.attr(type=['negative'])
- @test.idempotent_id('ce60042c-fa60-4836-8d43-1c8e3359dc47')
+ @decorators.idempotent_id('ce60042c-fa60-4836-8d43-1c8e3359dc47')
@test.services('network')
def test_set_reserve_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
@@ -64,7 +65,7 @@
self.ip, reserve="None")
@test.attr(type=['negative'])
- @test.idempotent_id('f1f7a35b-0390-48c5-9803-5f27461439db')
+ @decorators.idempotent_id('f1f7a35b-0390-48c5-9803-5f27461439db')
@test.services('network')
def test_set_unreserve_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
@@ -72,7 +73,7 @@
self.ip, unreserve="None")
@test.attr(type=['negative'])
- @test.idempotent_id('f51cf464-7fc5-4352-bc3e-e75cfa2cb717')
+ @decorators.idempotent_id('f51cf464-7fc5-4352-bc3e-e75cfa2cb717')
@test.services('network')
def test_set_reserve_with_invalid_ip(self):
# NOTE(maurosr): since this exercises the same code snippet, we do it
@@ -85,7 +86,7 @@
"my.invalid.ip", reserve="None")
@test.attr(type=['negative'])
- @test.idempotent_id('fd26ef50-f135-4232-9d32-281aab3f9176')
+ @decorators.idempotent_id('fd26ef50-f135-4232-9d32-281aab3f9176')
@test.services('network')
def test_fixed_ip_with_invalid_action(self):
self.assertRaises(lib_exc.BadRequest,
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index fde5622..3fd1612 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -17,6 +17,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -83,19 +84,19 @@
return flavor['id']
- @test.idempotent_id('8b4330e1-12c4-4554-9390-e6639971f086')
+ @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)
self.assertEqual(new_flavor_id, str(flavor_id))
- @test.idempotent_id('94c9bb4e-2c2a-4f3c-bb1f-5f0daf918e6d')
+ @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)
self.assertEqual(new_flavor_id, flavor_id)
- @test.idempotent_id('f83fe669-6758-448a-a85e-32d351f36fe0')
+ @decorators.idempotent_id('f83fe669-6758-448a-a85e-32d351f36fe0')
def test_create_flavor_with_none_id(self):
# If nova receives a request with None as flavor_id,
# nova generates flavor_id of uuid.
@@ -103,7 +104,7 @@
new_flavor_id = self._create_flavor(flavor_id)
self.assertEqual(new_flavor_id, str(uuid.UUID(new_flavor_id)))
- @test.idempotent_id('8261d7b0-be58-43ec-a2e5-300573c3f6c5')
+ @decorators.idempotent_id('8261d7b0-be58-43ec-a2e5-300573c3f6c5')
def test_create_flavor_verify_entry_in_list_details(self):
# Create a flavor and ensure it's details are listed
# This operation requires the user to have 'admin' role
@@ -127,7 +128,7 @@
flag = True
self.assertTrue(flag)
- @test.idempotent_id('63dc64e6-2e79-4fdf-868f-85500d308d66')
+ @decorators.idempotent_id('63dc64e6-2e79-4fdf-868f-85500d308d66')
def test_create_list_flavor_without_extra_data(self):
# Create a flavor and ensure it is listed
# This operation requires the user to have 'admin' role
@@ -169,7 +170,7 @@
flag = True
self.assertTrue(flag)
- @test.idempotent_id('be6cc18c-7c5d-48c0-ac16-17eaf03c54eb')
+ @decorators.idempotent_id('be6cc18c-7c5d-48c0-ac16-17eaf03c54eb')
def test_list_non_public_flavor(self):
# Create a flavor with os-flavor-access:is_public false.
# The flavor should not be present in list_details as the
@@ -201,7 +202,7 @@
flag = True
self.assertFalse(flag)
- @test.idempotent_id('bcc418ef-799b-47cc-baa1-ce01368b8987')
+ @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)
@@ -221,7 +222,7 @@
name='test', imageRef=self.image_ref,
flavorRef=flavor['id'])
- @test.idempotent_id('b345b196-bfbd-4231-8ac1-6d7fe15ff3a3')
+ @decorators.idempotent_id('b345b196-bfbd-4231-8ac1-6d7fe15ff3a3')
def test_list_public_flavor_with_other_user(self):
# Create a Flavor with public access.
# Try to List/Get flavor with another user
@@ -244,7 +245,7 @@
flag = True
self.assertTrue(flag)
- @test.idempotent_id('fb9cbde6-3a0e-41f2-a983-bdb0a823c44e')
+ @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)
@@ -287,7 +288,7 @@
_test_string_variations(['t', 'true', 'yes', '1'],
flavor_name_public)
- @test.idempotent_id('3b541a2e-2ac2-4b42-8b8d-ba6e22fcd4da')
+ @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)
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 2063267..38ff4c0 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest import test
@@ -47,7 +48,7 @@
cls.vcpus = 1
cls.disk = 10
- @test.idempotent_id('ea2c2211-29fa-4db9-97c3-906d36fad3e0')
+ @decorators.idempotent_id('ea2c2211-29fa-4db9-97c3-906d36fad3e0')
def test_flavor_access_list_with_private_flavor(self):
# Test to make sure that list flavor access on a newly created
# private flavor will return an empty access list
@@ -63,7 +64,7 @@
['flavor_access'])
self.assertEqual(len(flavor_access), 0, str(flavor_access))
- @test.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
+ @decorators.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
def test_flavor_access_add_remove(self):
# Test to add and remove flavor access to a given tenant.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index 1b7eb12..2719cc4 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -48,7 +49,7 @@
cls.disk = 10
@test.attr(type=['negative'])
- @test.idempotent_id('0621c53e-d45d-40e7-951d-43e5e257b272')
+ @decorators.idempotent_id('0621c53e-d45d-40e7-951d-43e5e257b272')
def test_flavor_access_list_with_public_flavor(self):
# Test to list flavor access with exceptions by querying public flavor
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -64,7 +65,7 @@
new_flavor_id)
@test.attr(type=['negative'])
- @test.idempotent_id('41eaaade-6d37-4f28-9c74-f21b46ca67bd')
+ @decorators.idempotent_id('41eaaade-6d37-4f28-9c74-f21b46ca67bd')
def test_flavor_non_admin_add(self):
# Test to add flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -81,7 +82,7 @@
self.tenant_id)
@test.attr(type=['negative'])
- @test.idempotent_id('073e79a6-c311-4525-82dc-6083d919cb3a')
+ @decorators.idempotent_id('073e79a6-c311-4525-82dc-6083d919cb3a')
def test_flavor_non_admin_remove(self):
# Test to remove flavor access as a user without admin privileges.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -102,7 +103,7 @@
self.tenant_id)
@test.attr(type=['negative'])
- @test.idempotent_id('f3592cc0-0306-483c-b210-9a7b5346eddc')
+ @decorators.idempotent_id('f3592cc0-0306-483c-b210-9a7b5346eddc')
def test_add_flavor_access_duplicate(self):
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
@@ -127,7 +128,7 @@
self.tenant_id)
@test.attr(type=['negative'])
- @test.idempotent_id('1f710927-3bc7-4381-9f82-0ca6e42644b7')
+ @decorators.idempotent_id('1f710927-3bc7-4381-9f82-0ca6e42644b7')
def test_remove_flavor_access_not_found(self):
# Create a new flavor.
flavor_name = data_utils.rand_name(self.flavor_name_prefix)
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index 661cd18..70e662c 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest import test
@@ -63,7 +64,7 @@
cls.client.wait_for_resource_deletion(cls.flavor['id'])
super(FlavorsExtraSpecsTestJSON, cls).resource_cleanup()
- @test.idempotent_id('0b2f9d4b-1ca2-4b99-bb40-165d4bb94208')
+ @decorators.idempotent_id('0b2f9d4b-1ca2-4b99-bb40-165d4bb94208')
def test_flavor_set_get_update_show_unset_keys(self):
# Test to SET, GET, UPDATE, SHOW, UNSET flavor extra
# spec as a user with admin privileges.
@@ -95,7 +96,7 @@
self.client.unset_flavor_extra_spec(self.flavor['id'], "key1")
self.client.unset_flavor_extra_spec(self.flavor['id'], "key2")
- @test.idempotent_id('a99dad88-ae1c-4fba-aeb4-32f898218bd0')
+ @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)
@@ -105,7 +106,7 @@
for key in specs:
self.assertEqual(body[key], specs[key])
- @test.idempotent_id('12805a7f-39a3-4042-b989-701d5cad9c90')
+ @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",
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 7eb4bbf..767a1ca 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs_negative.py
@@ -16,6 +16,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -66,7 +67,7 @@
super(FlavorsExtraSpecsNegativeTestJSON, cls).resource_cleanup()
@test.attr(type=['negative'])
- @test.idempotent_id('a00a3b81-5641-45a8-ab2b-4a8ec41e1d7d')
+ @decorators.idempotent_id('a00a3b81-5641-45a8-ab2b-4a8ec41e1d7d')
def test_flavor_non_admin_set_keys(self):
# Test to SET flavor extra spec as a user without admin privileges.
self.assertRaises(lib_exc.Forbidden,
@@ -75,7 +76,7 @@
key1="value1", key2="value2")
@test.attr(type=['negative'])
- @test.idempotent_id('1ebf4ef8-759e-48fe-a801-d451d80476fb')
+ @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(
@@ -89,7 +90,7 @@
key1='value1_new')
@test.attr(type=['negative'])
- @test.idempotent_id('28f12249-27c7-44c1-8810-1f382f316b11')
+ @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")
@@ -100,7 +101,7 @@
'key1')
@test.attr(type=['negative'])
- @test.idempotent_id('440b9f3f-3c7f-4293-a106-0ceda350f8de')
+ @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,
@@ -108,7 +109,7 @@
'nonexistent_key')
@test.attr(type=['negative'])
- @test.idempotent_id('329a7be3-54b2-48be-8052-bf2ce4afd898')
+ @decorators.idempotent_id('329a7be3-54b2-48be-8052-bf2ce4afd898')
def test_flavor_get_nonexistent_key(self):
self.assertRaises(lib_exc.NotFound,
self.flavors_client.show_flavor_extra_spec,
@@ -116,7 +117,7 @@
"nonexistent_key")
@test.attr(type=['negative'])
- @test.idempotent_id('25b822b8-9f49-44f6-80de-d99f0482e5cb')
+ @decorators.idempotent_id('25b822b8-9f49-44f6-80de-d99f0482e5cb')
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,
@@ -126,7 +127,7 @@
key1="value")
@test.attr(type=['negative'])
- @test.idempotent_id('f5889590-bf66-41cc-b4b1-6e6370cfd93f')
+ @decorators.idempotent_id('f5889590-bf66-41cc-b4b1-6e6370cfd93f')
def test_flavor_update_more_key(self):
# there should be just one item in the request body
self.assertRaises(lib_exc.BadRequest,
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index a4695b0..f38af56 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -18,6 +18,7 @@
from tempest.api.compute import base
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
@@ -55,7 +56,7 @@
raise exceptions.InvalidConfiguration(msg)
return
- @test.idempotent_id('2c8f145f-8012-4cb8-ac7e-95a587f0e4ab')
+ @decorators.idempotent_id('2c8f145f-8012-4cb8-ac7e-95a587f0e4ab')
@test.services('network')
def test_create_list_delete_floating_ips_bulk(self):
# Create, List and delete the Floating IPs Bulk
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index 3797b29..b664955 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -14,7 +14,7 @@
from tempest.api.compute import base
from tempest.common import tempest_fixtures as fixtures
-from tempest import test
+from tempest.lib import decorators
class HostsAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -25,12 +25,12 @@
super(HostsAdminTestJSON, cls).setup_clients()
cls.client = cls.os_adm.hosts_client
- @test.idempotent_id('9bfaf98d-e2cb-44b0-a07e-2558b2821e4f')
+ @decorators.idempotent_id('9bfaf98d-e2cb-44b0-a07e-2558b2821e4f')
def test_list_hosts(self):
hosts = self.client.list_hosts()['hosts']
self.assertGreaterEqual(len(hosts), 2, str(hosts))
- @test.idempotent_id('5dc06f5b-d887-47a2-bb2a-67762ef3c6de')
+ @decorators.idempotent_id('5dc06f5b-d887-47a2-bb2a-67762ef3c6de')
def test_list_hosts_with_zone(self):
self.useFixture(fixtures.LockFixture('availability_zone'))
hosts = self.client.list_hosts()['hosts']
@@ -39,21 +39,21 @@
self.assertGreaterEqual(len(hosts), 1)
self.assertIn(host, hosts)
- @test.idempotent_id('9af3c171-fbf4-4150-a624-22109733c2a6')
+ @decorators.idempotent_id('9af3c171-fbf4-4150-a624-22109733c2a6')
def test_list_hosts_with_a_blank_zone(self):
# If send the request with a blank zone, the request will be successful
# and it will return all the hosts list
hosts = self.client.list_hosts(zone='')['hosts']
self.assertNotEqual(0, len(hosts))
- @test.idempotent_id('c6ddbadb-c94e-4500-b12f-8ffc43843ff8')
+ @decorators.idempotent_id('c6ddbadb-c94e-4500-b12f-8ffc43843ff8')
def test_list_hosts_with_nonexistent_zone(self):
# If send the request with a nonexistent zone, the request will be
# successful and no hosts will be returned
hosts = self.client.list_hosts(zone='xxx')['hosts']
self.assertEqual(0, len(hosts))
- @test.idempotent_id('38adbb12-aee2-4498-8aec-329c72423aa4')
+ @decorators.idempotent_id('38adbb12-aee2-4498-8aec-329c72423aa4')
def test_show_host_detail(self):
hosts = self.client.list_hosts()['hosts']
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index 3821b22..07ab8c5 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -13,6 +13,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -35,26 +36,26 @@
cls.hostname = hosts[0]['host_name']
@test.attr(type=['negative'])
- @test.idempotent_id('dd032027-0210-4d9c-860e-69b1b8deed5f')
+ @decorators.idempotent_id('dd032027-0210-4d9c-860e-69b1b8deed5f')
def test_list_hosts_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.list_hosts)
@test.attr(type=['negative'])
- @test.idempotent_id('e75b0a1a-041f-47a1-8b4a-b72a6ff36d3f')
+ @decorators.idempotent_id('e75b0a1a-041f-47a1-8b4a-b72a6ff36d3f')
def test_show_host_detail_with_nonexistent_hostname(self):
self.assertRaises(lib_exc.NotFound,
self.client.show_host, 'nonexistent_hostname')
@test.attr(type=['negative'])
- @test.idempotent_id('19ebe09c-bfd4-4b7c-81a2-e2e0710f59cc')
+ @decorators.idempotent_id('19ebe09c-bfd4-4b7c-81a2-e2e0710f59cc')
def test_show_host_detail_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.show_host,
self.hostname)
@test.attr(type=['negative'])
- @test.idempotent_id('e40c72b1-0239-4ed6-ba21-81a184df1f7c')
+ @decorators.idempotent_id('e40c72b1-0239-4ed6-ba21-81a184df1f7c')
def test_update_host_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.update_host,
@@ -63,7 +64,7 @@
maintenance_mode='enable')
@test.attr(type=['negative'])
- @test.idempotent_id('fbe2bf3e-3246-4a95-a59f-94e4e298ec77')
+ @decorators.idempotent_id('fbe2bf3e-3246-4a95-a59f-94e4e298ec77')
def test_update_host_with_invalid_status(self):
# 'status' can only be 'enable' or 'disable'
self.assertRaises(lib_exc.BadRequest,
@@ -73,7 +74,7 @@
maintenance_mode='enable')
@test.attr(type=['negative'])
- @test.idempotent_id('ab1e230e-5e22-41a9-8699-82b9947915d4')
+ @decorators.idempotent_id('ab1e230e-5e22-41a9-8699-82b9947915d4')
def test_update_host_with_invalid_maintenance_mode(self):
# 'maintenance_mode' can only be 'enable' or 'disable'
self.assertRaises(lib_exc.BadRequest,
@@ -83,7 +84,7 @@
maintenance_mode='invalid')
@test.attr(type=['negative'])
- @test.idempotent_id('0cd85f75-6992-4a4a-b1bd-d11e37fd0eee')
+ @decorators.idempotent_id('0cd85f75-6992-4a4a-b1bd-d11e37fd0eee')
def test_update_host_without_param(self):
# 'status' or 'maintenance_mode' needed for host update
self.assertRaises(lib_exc.BadRequest,
@@ -91,7 +92,7 @@
self.hostname)
@test.attr(type=['negative'])
- @test.idempotent_id('23c92146-2100-4d68-b2d6-c7ade970c9c1')
+ @decorators.idempotent_id('23c92146-2100-4d68-b2d6-c7ade970c9c1')
def test_update_nonexistent_host(self):
self.assertRaises(lib_exc.NotFound,
self.client.update_host,
@@ -100,42 +101,42 @@
maintenance_mode='enable')
@test.attr(type=['negative'])
- @test.idempotent_id('0d981ac3-4320-4898-b674-82b61fbb60e4')
+ @decorators.idempotent_id('0d981ac3-4320-4898-b674-82b61fbb60e4')
def test_startup_nonexistent_host(self):
self.assertRaises(lib_exc.NotFound,
self.client.startup_host,
'nonexistent_hostname')
@test.attr(type=['negative'])
- @test.idempotent_id('9f4ebb7e-b2ae-4e5b-a38f-0fd1bb0ddfca')
+ @decorators.idempotent_id('9f4ebb7e-b2ae-4e5b-a38f-0fd1bb0ddfca')
def test_startup_host_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.startup_host,
self.hostname)
@test.attr(type=['negative'])
- @test.idempotent_id('9e637444-29cf-4244-88c8-831ae82c31b6')
+ @decorators.idempotent_id('9e637444-29cf-4244-88c8-831ae82c31b6')
def test_shutdown_nonexistent_host(self):
self.assertRaises(lib_exc.NotFound,
self.client.shutdown_host,
'nonexistent_hostname')
@test.attr(type=['negative'])
- @test.idempotent_id('a803529c-7e3f-4d3c-a7d6-8e1c203d27f6')
+ @decorators.idempotent_id('a803529c-7e3f-4d3c-a7d6-8e1c203d27f6')
def test_shutdown_host_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.shutdown_host,
self.hostname)
@test.attr(type=['negative'])
- @test.idempotent_id('f86bfd7b-0b13-4849-ae29-0322e83ee58b')
+ @decorators.idempotent_id('f86bfd7b-0b13-4849-ae29-0322e83ee58b')
def test_reboot_nonexistent_host(self):
self.assertRaises(lib_exc.NotFound,
self.client.reboot_host,
'nonexistent_hostname')
@test.attr(type=['negative'])
- @test.idempotent_id('02d79bb9-eb57-4612-abf6-2cb38897d2f8')
+ @decorators.idempotent_id('02d79bb9-eb57-4612-abf6-2cb38897d2f8')
def test_reboot_host_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.reboot_host,
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 1f043dc..4637024 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class HypervisorAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -33,19 +33,19 @@
def assertHypervisors(self, hypers):
self.assertGreater(len(hypers), 0, "No hypervisors found: %s" % hypers)
- @test.idempotent_id('7f0ceacd-c64d-4e96-b8ee-d02943142cc5')
+ @decorators.idempotent_id('7f0ceacd-c64d-4e96-b8ee-d02943142cc5')
def test_get_hypervisor_list(self):
# List of hypervisor and available hypervisors hostname
hypers = self._list_hypervisors()
self.assertHypervisors(hypers)
- @test.idempotent_id('1e7fdac2-b672-4ad1-97a4-bad0e3030118')
+ @decorators.idempotent_id('1e7fdac2-b672-4ad1-97a4-bad0e3030118')
def test_get_hypervisor_list_details(self):
# Display the details of the all hypervisor
hypers = self.client.list_hypervisors(detail=True)['hypervisors']
self.assertHypervisors(hypers)
- @test.idempotent_id('94ff9eae-a183-428e-9cdb-79fde71211cc')
+ @decorators.idempotent_id('94ff9eae-a183-428e-9cdb-79fde71211cc')
def test_get_hypervisor_show_details(self):
# Display the details of the specified hypervisor
hypers = self._list_hypervisors()
@@ -56,7 +56,7 @@
self.assertEqual(details['hypervisor_hostname'],
hypers[0]['hypervisor_hostname'])
- @test.idempotent_id('e81bba3f-6215-4e39-a286-d52d2f906862')
+ @decorators.idempotent_id('e81bba3f-6215-4e39-a286-d52d2f906862')
def test_get_hypervisor_show_servers(self):
# Show instances about the specific hypervisors
hypers = self._list_hypervisors()
@@ -67,14 +67,14 @@
['hypervisors'])
self.assertGreater(len(hypervisors), 0)
- @test.idempotent_id('797e4f28-b6e0-454d-a548-80cc77c00816')
+ @decorators.idempotent_id('797e4f28-b6e0-454d-a548-80cc77c00816')
def test_get_hypervisor_stats(self):
# Verify the stats of the all hypervisor
stats = (self.client.show_hypervisor_statistics()
['hypervisor_statistics'])
self.assertGreater(len(stats), 0)
- @test.idempotent_id('91a50d7d-1c2b-4f24-b55a-a1fe20efca70')
+ @decorators.idempotent_id('91a50d7d-1c2b-4f24-b55a-a1fe20efca70')
def test_get_hypervisor_uptime(self):
# Verify that GET shows the specified hypervisor uptime
hypers = self._list_hypervisors()
@@ -113,7 +113,7 @@
has_valid_uptime,
"None of the hypervisors had a valid uptime: %s" % hypers)
- @test.idempotent_id('d7e1805b-3b14-4a3b-b6fd-50ec6d9f361f')
+ @decorators.idempotent_id('d7e1805b-3b14-4a3b-b6fd-50ec6d9f361f')
def test_search_hypervisor(self):
hypers = self._list_hypervisors()
self.assertHypervisors(hypers)
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index 0f35e14..1a37312 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -34,7 +35,7 @@
return hypers
@test.attr(type=['negative'])
- @test.idempotent_id('c136086a-0f67-4b2b-bc61-8482bd68989f')
+ @decorators.idempotent_id('c136086a-0f67-4b2b-bc61-8482bd68989f')
def test_show_nonexistent_hypervisor(self):
nonexistent_hypervisor_id = data_utils.rand_uuid()
@@ -44,7 +45,7 @@
nonexistent_hypervisor_id)
@test.attr(type=['negative'])
- @test.idempotent_id('51e663d0-6b89-4817-a465-20aca0667d03')
+ @decorators.idempotent_id('51e663d0-6b89-4817-a465-20aca0667d03')
def test_show_hypervisor_with_non_admin_user(self):
hypers = self._list_hypervisors()
self.assertGreater(len(hypers), 0)
@@ -55,7 +56,7 @@
hypers[0]['id'])
@test.attr(type=['negative'])
- @test.idempotent_id('2a0a3938-832e-4859-95bf-1c57c236b924')
+ @decorators.idempotent_id('2a0a3938-832e-4859-95bf-1c57c236b924')
def test_show_servers_with_non_admin_user(self):
hypers = self._list_hypervisors()
self.assertGreater(len(hypers), 0)
@@ -66,7 +67,7 @@
hypers[0]['id'])
@test.attr(type=['negative'])
- @test.idempotent_id('02463d69-0ace-4d33-a4a8-93d7883a2bba')
+ @decorators.idempotent_id('02463d69-0ace-4d33-a4a8-93d7883a2bba')
def test_show_servers_with_nonexistent_hypervisor(self):
nonexistent_hypervisor_id = data_utils.rand_uuid()
@@ -76,14 +77,14 @@
nonexistent_hypervisor_id)
@test.attr(type=['negative'])
- @test.idempotent_id('e2b061bb-13f9-40d8-9d6e-d5bf17595849')
+ @decorators.idempotent_id('e2b061bb-13f9-40d8-9d6e-d5bf17595849')
def test_get_hypervisor_stats_with_non_admin_user(self):
self.assertRaises(
lib_exc.Forbidden,
self.non_adm_client.show_hypervisor_statistics)
@test.attr(type=['negative'])
- @test.idempotent_id('f60aa680-9a3a-4c7d-90e1-fae3a4891303')
+ @decorators.idempotent_id('f60aa680-9a3a-4c7d-90e1-fae3a4891303')
def test_get_nonexistent_hypervisor_uptime(self):
nonexistent_hypervisor_id = data_utils.rand_uuid()
@@ -93,7 +94,7 @@
nonexistent_hypervisor_id)
@test.attr(type=['negative'])
- @test.idempotent_id('6c3461f9-c04c-4e2a-bebb-71dc9cb47df2')
+ @decorators.idempotent_id('6c3461f9-c04c-4e2a-bebb-71dc9cb47df2')
def test_get_hypervisor_uptime_with_non_admin_user(self):
hypers = self._list_hypervisors()
self.assertGreater(len(hypers), 0)
@@ -104,7 +105,7 @@
hypers[0]['id'])
@test.attr(type=['negative'])
- @test.idempotent_id('51b3d536-9b14-409c-9bce-c6f7c794994e')
+ @decorators.idempotent_id('51b3d536-9b14-409c-9bce-c6f7c794994e')
def test_get_hypervisor_list_with_non_admin_user(self):
# List of hypervisor and available services with non admin user
self.assertRaises(
@@ -112,7 +113,7 @@
self.non_adm_client.list_hypervisors)
@test.attr(type=['negative'])
- @test.idempotent_id('dc02db05-e801-4c5f-bc8e-d915290ab345')
+ @decorators.idempotent_id('dc02db05-e801-4c5f-bc8e-d915290ab345')
def test_get_hypervisor_list_details_with_non_admin_user(self):
# List of hypervisor details and available services with non admin user
self.assertRaises(
@@ -120,7 +121,7 @@
self.non_adm_client.list_hypervisors, detail=True)
@test.attr(type=['negative'])
- @test.idempotent_id('19a45cc1-1000-4055-b6d2-28e8b2ec4faa')
+ @decorators.idempotent_id('19a45cc1-1000-4055-b6d2-28e8b2ec4faa')
def test_search_nonexistent_hypervisor(self):
self.assertRaises(
lib_exc.NotFound,
@@ -128,7 +129,7 @@
'nonexistent_hypervisor_name')
@test.attr(type=['negative'])
- @test.idempotent_id('5b6a6c79-5dc1-4fa5-9c58-9c8085948e74')
+ @decorators.idempotent_id('5b6a6c79-5dc1-4fa5-9c58-9c8085948e74')
def test_search_hypervisor_with_non_admin_user(self):
hypers = self._list_hypervisors()
self.assertGreater(len(hypers), 0)
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log.py b/tempest/api/compute/admin/test_instance_usage_audit_log.py
index 6976783..b613a26 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log.py
@@ -18,7 +18,7 @@
from six.moves.urllib import parse as urllib
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class InstanceUsageAuditLogTestJSON(base.BaseV2ComputeAdminTest):
@@ -28,7 +28,7 @@
super(InstanceUsageAuditLogTestJSON, cls).setup_clients()
cls.adm_client = cls.os_adm.instance_usages_audit_log_client
- @test.idempotent_id('25319919-33d9-424f-9f99-2c203ee48b9d')
+ @decorators.idempotent_id('25319919-33d9-424f-9f99-2c203ee48b9d')
def test_list_instance_usage_audit_logs(self):
# list instance usage audit logs
body = (self.adm_client.list_instance_usage_audit_logs()
@@ -41,7 +41,7 @@
for item in expected_items:
self.assertIn(item, body)
- @test.idempotent_id('6e40459d-7c5f-400b-9e83-449fbc8e7feb')
+ @decorators.idempotent_id('6e40459d-7c5f-400b-9e83-449fbc8e7feb')
def test_get_instance_usage_audit_log(self):
# Get instance usage audit log before specified time
now = datetime.datetime.now()
diff --git a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
index b908502..16c39c4 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log_negative.py
@@ -18,6 +18,7 @@
from six.moves.urllib import parse as urllib
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -30,7 +31,7 @@
cls.adm_client = cls.os_adm.instance_usages_audit_log_client
@test.attr(type=['negative'])
- @test.idempotent_id('a9d33178-d2c9-4131-ad3b-f4ca8d0308a2')
+ @decorators.idempotent_id('a9d33178-d2c9-4131-ad3b-f4ca8d0308a2')
def test_instance_usage_audit_logs_with_nonadmin_user(self):
# the instance_usage_audit_logs API just can be accessed by admin user
self.assertRaises(lib_exc.Forbidden,
@@ -43,7 +44,7 @@
urllib.quote(now.strftime("%Y-%m-%d %H:%M:%S")))
@test.attr(type=['negative'])
- @test.idempotent_id('9b952047-3641-41c7-ba91-a809fc5974c8')
+ @decorators.idempotent_id('9b952047-3641-41c7-ba91-a809fc5974c8')
def test_get_instance_usage_audit_logs_with_invalid_time(self):
self.assertRaises(lib_exc.BadRequest,
self.adm_client.show_instance_usage_audit_log,
diff --git a/tempest/api/compute/admin/test_keypairs_v210.py b/tempest/api/compute/admin/test_keypairs_v210.py
index dfa7c39..82d3bae 100644
--- a/tempest/api/compute/admin/test_keypairs_v210.py
+++ b/tempest/api/compute/admin/test_keypairs_v210.py
@@ -15,7 +15,7 @@
from tempest.api.compute.keypairs import base
from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
class KeyPairsV210TestJSON(base.BaseKeypairTest):
@@ -30,11 +30,11 @@
def _create_and_check_keypairs(self, user_id):
key_list = list()
- for i in range(2):
+ for _ in range(2):
k_name = data_utils.rand_name('keypair')
- keypair = self._create_keypair(k_name,
- keypair_type='ssh',
- user_id=user_id)
+ keypair = self.create_keypair(k_name,
+ keypair_type='ssh',
+ user_id=user_id)
self.assertEqual(k_name, keypair['name'],
"The created keypair name is not equal "
"to the requested name!")
@@ -45,7 +45,7 @@
key_list.append(keypair)
return key_list
- @test.idempotent_id('3c8484af-cfb3-48f6-b8ba-d5d58bbf3eac')
+ @decorators.idempotent_id('3c8484af-cfb3-48f6-b8ba-d5d58bbf3eac')
def test_admin_manage_keypairs_for_other_users(self):
user_id = self.non_admin_client.user_id
key_list = self._create_and_check_keypairs(user_id)
@@ -56,8 +56,7 @@
self.assertEqual(user_id, keypair_detail['user_id'],
"The fetched keypair is not for requested user!")
# Create a admin keypair
- admin_k_name = data_utils.rand_name('keypair')
- admin_keypair = self._create_keypair(admin_k_name, keypair_type='ssh')
+ admin_keypair = self.create_keypair(keypair_type='ssh')
admin_keypair.pop('private_key', None)
admin_keypair.pop('user_id')
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index ff84945..39797f7 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -117,23 +117,23 @@
self.assertEqual(target_host, self._get_host_for_server(server_id),
msg)
- @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
+ @decorators.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
def test_live_block_migration(self):
self._test_live_migration()
- @test.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
+ @decorators.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
def test_live_block_migration_paused(self):
self._test_live_migration(state='PAUSED')
@decorators.skip_because(bug="1524898")
- @test.idempotent_id('5071cf17-3004-4257-ae61-73a84e28badd')
+ @decorators.idempotent_id('5071cf17-3004-4257-ae61-73a84e28badd')
@test.services('volume')
def test_volume_backed_live_migration(self):
self._test_live_migration(volume_backed=True)
- @test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
+ @decorators.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
@testtools.skipIf(not CONF.compute_feature_enabled.
block_migration_for_live_migration,
'Block Live migration not available')
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index 2dd2e89..21f5c68 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -18,8 +18,8 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions
-from tempest import test
CONF = config.CONF
@@ -33,12 +33,12 @@
cls.flavors_admin_client = cls.os_adm.flavors_client
cls.admin_servers_client = cls.os_adm.servers_client
- @test.idempotent_id('75c0b83d-72a0-4cf8-a153-631e83e7d53f')
+ @decorators.idempotent_id('75c0b83d-72a0-4cf8-a153-631e83e7d53f')
def test_list_migrations(self):
# Admin can get the migrations list
self.client.list_migrations()
- @test.idempotent_id('1b512062-8093-438e-b47a-37d2f597cd64')
+ @decorators.idempotent_id('1b512062-8093-438e-b47a-37d2f597cd64')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_list_migrations_in_flavor_resize_situation(self):
@@ -60,7 +60,7 @@
except exceptions.NotFound:
pass
- @test.idempotent_id('33f1fec3-ba18-4470-8e4e-1d888e7c3593')
+ @decorators.idempotent_id('33f1fec3-ba18-4470-8e4e-1d888e7c3593')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_resize_server_revert_deleted_flavor(self):
@@ -127,13 +127,13 @@
server['id'])['server']['OS-EXT-SRV-ATTR:host']
assert_func(src_host, dst_host)
- @test.idempotent_id('4bf0be52-3b6f-4746-9a27-3143636fe30d')
+ @decorators.idempotent_id('4bf0be52-3b6f-4746-9a27-3143636fe30d')
@testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
'Cold migration not available.')
def test_cold_migration(self):
self._test_cold_migrate_server(revert=False)
- @test.idempotent_id('caa1aa8b-f4ef-4374-be0d-95f001c2ac2d')
+ @decorators.idempotent_id('caa1aa8b-f4ef-4374-be0d-95f001c2ac2d')
@testtools.skipUnless(CONF.compute_feature_enabled.cold_migration,
'Cold migration not available.')
def test_revert_cold_migration(self):
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 8504840..12ae864 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -15,7 +15,7 @@
from tempest.api.compute import base
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -32,7 +32,7 @@
super(NetworksTest, cls).setup_clients()
cls.client = cls.os_adm.compute_networks_client
- @test.idempotent_id('d206d211-8912-486f-86e2-a9d090d1f416')
+ @decorators.idempotent_id('d206d211-8912-486f-86e2-a9d090d1f416')
def test_get_network(self):
networks = self.client.list_networks()['networks']
if CONF.compute.fixed_network_name:
@@ -53,7 +53,7 @@
['network'])
self.assertEqual(configured_network['label'], network['label'])
- @test.idempotent_id('df3d1046-6fa5-4b2c-ad0c-cfa46a351cb9')
+ @decorators.idempotent_id('df3d1046-6fa5-4b2c-ad0c-cfa46a351cb9')
def test_list_all_networks(self):
networks = self.client.list_networks()['networks']
# Check the configured network is in the list
@@ -61,5 +61,5 @@
configured_network = CONF.compute.fixed_network_name
self.assertIn(configured_network, [x['label'] for x in networks])
else:
- network_name = map(lambda x: x['label'], networks)
- self.assertGreaterEqual(len(network_name), 1)
+ network_labels = [x['label'] for x in networks]
+ self.assertGreaterEqual(len(network_labels), 1)
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 33b9bef..3e9dc79 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -19,7 +19,7 @@
from tempest.api.compute import base
from tempest.common import tempest_fixtures as fixtures
from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
LOG = logging.getLogger(__name__)
@@ -53,7 +53,7 @@
'instances', 'security_group_rules',
'cores', 'security_groups'))
- @test.idempotent_id('3b0a7c8f-cf58-46b8-a60c-715a32a8ba7d')
+ @decorators.idempotent_id('3b0a7c8f-cf58-46b8-a60c-715a32a8ba7d')
def test_get_default_quotas(self):
# Admin can get the default resource quota set for a tenant
expected_quota_set = self.default_quota_set | set(['id'])
@@ -63,7 +63,7 @@
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
- @test.idempotent_id('55fbe2bf-21a9-435b-bbd2-4162b0ed799a')
+ @decorators.idempotent_id('55fbe2bf-21a9-435b-bbd2-4162b0ed799a')
def test_update_all_quota_resources_for_tenant(self):
# Admin can update all the resource quota limits for a tenant
default_quota_set = self.adm_client.show_default_quota_set(
@@ -88,7 +88,7 @@
self.assertIn(quota, quota_set.keys())
# TODO(afazekas): merge these test cases
- @test.idempotent_id('ce9e0815-8091-4abd-8345-7fe5b85faa1d')
+ @decorators.idempotent_id('ce9e0815-8091-4abd-8345-7fe5b85faa1d')
def test_get_updated_quotas(self):
# Verify that GET shows the updated quota set of project
project_name = data_utils.rand_name('cpu_quota_project')
@@ -120,7 +120,7 @@
project_id, user_id=user_id)['quota_set']
self.assertEqual(2048, quota_set['ram'])
- @test.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
+ @decorators.idempotent_id('389d04f0-3a41-405f-9317-e5f86e3c44f0')
def test_delete_quota(self):
# Admin can delete the resource quota set for a project
project_name = data_utils.rand_name('ram_quota_project')
@@ -164,7 +164,7 @@
# global state, and possibly needs to be part of a set of
# tests that get run all by themselves at the end under a
# 'danger' flag.
- @test.idempotent_id('7932ab0f-5136-4075-b201-c0e2338df51a')
+ @decorators.idempotent_id('7932ab0f-5136-4075-b201-c0e2338df51a')
def test_update_default_quotas(self):
LOG.debug("get the current 'default' quota class values")
body = (self.adm_client.show_quota_class_set('default')
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index 015e14d..0850205 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -52,7 +52,7 @@
**{quota_item: default_quota_value})
@test.attr(type=['negative'])
- @test.idempotent_id('733abfe8-166e-47bb-8363-23dbd7ff3476')
+ @decorators.idempotent_id('733abfe8-166e-47bb-8363-23dbd7ff3476')
def test_update_quota_normal_user(self):
self.assertRaises(lib_exc.Forbidden,
self.client.update_quota_set,
@@ -62,7 +62,7 @@
# TODO(afazekas): Add dedicated tenant to the skipped quota tests.
# It can be moved into the setUpClass as well.
@test.attr(type=['negative'])
- @test.idempotent_id('91058876-9947-4807-9f22-f6eb17140d9b')
+ @decorators.idempotent_id('91058876-9947-4807-9f22-f6eb17140d9b')
def test_create_server_when_cpu_quota_is_full(self):
# Disallow server creation when tenant's vcpu quota is full
self._update_quota('cores', 0)
@@ -70,7 +70,7 @@
self.create_test_server)
@test.attr(type=['negative'])
- @test.idempotent_id('6fdd7012-584d-4327-a61c-49122e0d5864')
+ @decorators.idempotent_id('6fdd7012-584d-4327-a61c-49122e0d5864')
def test_create_server_when_memory_quota_is_full(self):
# Disallow server creation when tenant's memory quota is full
self._update_quota('ram', 0)
@@ -78,7 +78,7 @@
self.create_test_server)
@test.attr(type=['negative'])
- @test.idempotent_id('7c6be468-0274-449a-81c3-ac1c32ee0161')
+ @decorators.idempotent_id('7c6be468-0274-449a-81c3-ac1c32ee0161')
def test_create_server_when_instances_quota_is_full(self):
# Once instances quota limit is reached, disallow server creation
self._update_quota('instances', 0)
@@ -87,7 +87,7 @@
@decorators.skip_because(bug="1186354",
condition=CONF.service_available.neutron)
- @test.idempotent_id('7c6c8f3b-2bf6-4918-b240-57b136a66aa0')
+ @decorators.idempotent_id('7c6c8f3b-2bf6-4918-b240-57b136a66aa0')
@test.services('network')
def test_security_groups_exceed_limit(self):
# Negative test: Creation Security Groups over limit should FAIL
@@ -106,7 +106,7 @@
@decorators.skip_because(bug="1186354",
condition=CONF.service_available.neutron)
@test.attr(type=['negative'])
- @test.idempotent_id('6e9f436d-f1ed-4f8e-a493-7275dfaa4b4d')
+ @decorators.idempotent_id('6e9f436d-f1ed-4f8e-a493-7275dfaa4b4d')
@test.services('network')
def test_security_groups_rules_exceed_limit(self):
# Negative test: Creation of Security Group Rules should FAIL
diff --git a/tempest/api/compute/admin/test_security_group_default_rules.py b/tempest/api/compute/admin/test_security_group_default_rules.py
index ce350b6..ab97bd4 100644
--- a/tempest/api/compute/admin/test_security_group_default_rules.py
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -16,8 +16,8 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
-from tempest import test
CONF = config.CONF
@@ -55,7 +55,7 @@
self.assertEqual(cidr, rule['ip_range']['cidr'])
return rule
- @test.idempotent_id('6d880615-eec3-4d29-97c5-7a074dde239d')
+ @decorators.idempotent_id('6d880615-eec3-4d29-97c5-7a074dde239d')
def test_create_delete_security_group_default_rules(self):
# Create and delete Security Group default rule
ip_protocols = ['tcp', 'udp', 'icmp']
@@ -67,7 +67,7 @@
self.adm_client.show_security_group_default_rule,
rule['id'])
- @test.idempotent_id('4d752e0a-33a1-4c3a-b498-ff8667ca22e5')
+ @decorators.idempotent_id('4d752e0a-33a1-4c3a-b498-ff8667ca22e5')
def test_create_security_group_default_rule_without_cidr(self):
ip_protocol = 'udp'
from_port = 80
@@ -81,7 +81,7 @@
self.assertNotEqual(0, rule['id'])
self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
- @test.idempotent_id('29f2d218-69b0-4a95-8f3d-6bd0ef732b3a')
+ @decorators.idempotent_id('29f2d218-69b0-4a95-8f3d-6bd0ef732b3a')
def test_create_security_group_default_rule_with_blank_cidr(self):
ip_protocol = 'icmp'
from_port = 10
@@ -97,7 +97,7 @@
self.assertNotEqual(0, rule['id'])
self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
- @test.idempotent_id('6e6de55e-9146-4ae0-89f2-3569586e0b9b')
+ @decorators.idempotent_id('6e6de55e-9146-4ae0-89f2-3569586e0b9b')
def test_security_group_default_rules_list(self):
ip_protocol = 'tcp'
from_port = 22
@@ -114,7 +114,7 @@
self.assertNotEqual(0, len(rules))
self.assertIn(rule, rules)
- @test.idempotent_id('15cbb349-86b4-4f71-a048-04b7ef3f150b')
+ @decorators.idempotent_id('15cbb349-86b4-4f71-a048-04b7ef3f150b')
def test_default_security_group_default_rule_show(self):
ip_protocol = 'tcp'
from_port = 22
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index e329869..2efe755 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest import test
@@ -32,14 +33,14 @@
else:
self.client.delete_security_group(securitygroup_id)
- @test.idempotent_id('49667619-5af9-4c63-ab5d-2cfdd1c8f7f1')
+ @decorators.idempotent_id('49667619-5af9-4c63-ab5d-2cfdd1c8f7f1')
@test.services('network')
def test_list_security_groups_list_all_tenants_filter(self):
# Admin can list security groups of all tenants
# List of all security groups created
security_group_list = []
# Create two security groups for a non-admin tenant
- for i in range(2):
+ for _ in range(2):
name = data_utils.rand_name('securitygroup')
description = data_utils.rand_name('description')
securitygroup = self.client.create_security_group(
@@ -50,7 +51,7 @@
client_tenant_id = securitygroup['tenant_id']
# Create two security groups for admin tenant
- for i in range(2):
+ for _ in range(2):
name = data_utils.rand_name('securitygroup')
description = data_utils.rand_name('description')
adm_securitygroup = self.adm_client.create_security_group(
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index a8a8b83..85c7fba 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -18,7 +18,6 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest.lib import decorators
-from tempest import test
class ServersAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -44,7 +43,7 @@
wait_until='ACTIVE')
cls.s2_id = server['id']
- @test.idempotent_id('06f960bb-15bb-48dc-873d-f96e89be7870')
+ @decorators.idempotent_id('06f960bb-15bb-48dc-873d-f96e89be7870')
def test_list_servers_filter_by_error_status(self):
# Filter the list of servers by server error status
params = {'status': 'error'}
@@ -60,14 +59,14 @@
self.assertIn(self.s1_id, map(lambda x: x['id'], servers))
self.assertNotIn(self.s2_id, map(lambda x: x['id'], servers))
- @test.idempotent_id('d56e9540-73ed-45e0-9b88-98fc419087eb')
+ @decorators.idempotent_id('d56e9540-73ed-45e0-9b88-98fc419087eb')
def test_list_servers_detailed_filter_by_invalid_status(self):
params = {'status': 'invalid_status'}
body = self.client.list_servers(detail=True, **params)
servers = body['servers']
self.assertEqual([], servers)
- @test.idempotent_id('51717b38-bdc1-458b-b636-1cf82d99f62f')
+ @decorators.idempotent_id('51717b38-bdc1-458b-b636-1cf82d99f62f')
def test_list_servers_by_admin(self):
# Listing servers by admin user returns a list which doesn't
# contain the other tenants' server by default
@@ -80,7 +79,7 @@
self.assertNotIn(self.s1_name, servers_name)
self.assertNotIn(self.s2_name, servers_name)
- @test.idempotent_id('9f5579ae-19b4-4985-a091-2a5d56106580')
+ @decorators.idempotent_id('9f5579ae-19b4-4985-a091-2a5d56106580')
def test_list_servers_by_admin_with_all_tenants(self):
# Listing servers by admin user with all tenants parameter
# Here should be listed all servers
@@ -92,7 +91,7 @@
self.assertIn(self.s1_name, servers_name)
self.assertIn(self.s2_name, servers_name)
- @test.idempotent_id('7e5d6b8f-454a-4ba1-8ae2-da857af8338b')
+ @decorators.idempotent_id('7e5d6b8f-454a-4ba1-8ae2-da857af8338b')
def test_list_servers_by_admin_with_specified_tenant(self):
# In nova v2, tenant_id is ignored unless all_tenants is specified
@@ -101,7 +100,7 @@
params = {'tenant_id': tenant_id}
body = self.client.list_servers(detail=True, **params)
servers = body['servers']
- servers_name = map(lambda x: x['name'], servers)
+ servers_name = [x['name'] for x in servers]
self.assertNotIn(self.s1_name, servers_name)
self.assertNotIn(self.s2_name, servers_name)
@@ -109,7 +108,7 @@
params = {'all_tenants': '', 'tenant_id': tenant_id}
body = self.client.list_servers(detail=True, **params)
servers = body['servers']
- servers_name = map(lambda x: x['name'], servers)
+ servers_name = [x['name'] for x in servers]
self.assertIn(self.s1_name, servers_name)
self.assertIn(self.s2_name, servers_name)
@@ -118,11 +117,11 @@
params = {'all_tenants': '', 'tenant_id': admin_tenant_id}
body = self.client.list_servers(detail=True, **params)
servers = body['servers']
- servers_name = map(lambda x: x['name'], servers)
+ servers_name = [x['name'] for x in servers]
self.assertNotIn(self.s1_name, servers_name)
self.assertNotIn(self.s2_name, servers_name)
- @test.idempotent_id('86c7a8f7-50cf-43a9-9bac-5b985317134f')
+ @decorators.idempotent_id('86c7a8f7-50cf-43a9-9bac-5b985317134f')
def test_list_servers_filter_by_exist_host(self):
# Filter the list of servers by existent host
name = data_utils.rand_name(self.__class__.__name__ + '-server')
@@ -147,7 +146,7 @@
self.assertNotIn(test_server['id'],
map(lambda x: x['id'], nonexistent_servers))
- @test.idempotent_id('ee8ae470-db70-474d-b752-690b7892cab1')
+ @decorators.idempotent_id('ee8ae470-db70-474d-b752-690b7892cab1')
def test_reset_state_server(self):
# Reset server's state to 'error'
self.client.reset_state(self.s1_id, state='error')
@@ -164,7 +163,7 @@
self.assertEqual(server['status'], 'ACTIVE')
@decorators.skip_because(bug="1240043")
- @test.idempotent_id('31ff3486-b8a0-4f56-a6c0-aab460531db3')
+ @decorators.idempotent_id('31ff3486-b8a0-4f56-a6c0-aab460531db3')
def test_get_server_diagnostics_by_admin(self):
# Retrieve server diagnostics by admin user
diagnostic = self.client.show_server_diagnostics(self.s1_id)
@@ -174,7 +173,7 @@
for key in basic_attrs:
self.assertIn(key, str(diagnostic.keys()))
- @test.idempotent_id('682cb127-e5bb-4f53-87ce-cb9003604442')
+ @decorators.idempotent_id('682cb127-e5bb-4f53-87ce-cb9003604442')
def test_rebuild_server_in_error_state(self):
# The server in error state should be rebuilt using the provided
# image and changed to ACTIVE state
@@ -202,7 +201,7 @@
rebuilt_image_id = server['image']['id']
self.assertEqual(self.image_ref_alt, rebuilt_image_id)
- @test.idempotent_id('7a1323b4-a6a2-497a-96cb-76c07b945c71')
+ @decorators.idempotent_id('7a1323b4-a6a2-497a-96cb-76c07b945c71')
def test_reset_network_inject_network_info(self):
# Reset Network of a Server
server = self.create_test_server(wait_until='ACTIVE')
@@ -210,7 +209,7 @@
# Inject the Network Info into Server
self.client.inject_network_info(server['id'])
- @test.idempotent_id('fdcd9b33-0903-4e00-a1f7-b5f6543068d6')
+ @decorators.idempotent_id('fdcd9b33-0903-4e00-a1f7-b5f6543068d6')
def test_create_server_with_scheduling_hint(self):
# Create a server with scheduler hints.
hints = {
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 206260f..1283629 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -19,6 +19,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -56,7 +57,7 @@
flavor_id = data_utils.rand_int_id(start=1000)
return flavor_id
- @test.idempotent_id('28dcec23-f807-49da-822c-56a92ea3c687')
+ @decorators.idempotent_id('28dcec23-f807-49da-822c-56a92ea3c687')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
@test.attr(type=['negative'])
@@ -84,7 +85,7 @@
self.servers[0]['id'],
flavor_ref['id'])
- @test.idempotent_id('7368a427-2f26-4ad9-9ba9-911a0ec2b0db')
+ @decorators.idempotent_id('7368a427-2f26-4ad9-9ba9-911a0ec2b0db')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
@test.attr(type=['negative'])
@@ -113,27 +114,27 @@
flavor_ref['id'])
@test.attr(type=['negative'])
- @test.idempotent_id('b0b4d8af-1256-41ef-9ee7-25f1c19dde80')
+ @decorators.idempotent_id('b0b4d8af-1256-41ef-9ee7-25f1c19dde80')
def test_reset_state_server_invalid_state(self):
self.assertRaises(lib_exc.BadRequest,
self.client.reset_state, self.s1_id,
state='invalid')
@test.attr(type=['negative'])
- @test.idempotent_id('4cdcc984-fab0-4577-9a9d-6d558527ee9d')
+ @decorators.idempotent_id('4cdcc984-fab0-4577-9a9d-6d558527ee9d')
def test_reset_state_server_invalid_type(self):
self.assertRaises(lib_exc.BadRequest,
self.client.reset_state, self.s1_id,
state=1)
@test.attr(type=['negative'])
- @test.idempotent_id('e741298b-8df2-46f0-81cb-8f814ff2504c')
+ @decorators.idempotent_id('e741298b-8df2-46f0-81cb-8f814ff2504c')
def test_reset_state_server_nonexistent_server(self):
self.assertRaises(lib_exc.NotFound,
self.client.reset_state, '999', state='error')
@test.attr(type=['negative'])
- @test.idempotent_id('e84e2234-60d2-42fa-8b30-e2d3049724ac')
+ @decorators.idempotent_id('e84e2234-60d2-42fa-8b30-e2d3049724ac')
def test_get_server_diagnostics_by_non_admin(self):
# Non-admin user can not view server diagnostics according to policy
self.assertRaises(lib_exc.Forbidden,
@@ -141,14 +142,14 @@
self.s1_id)
@test.attr(type=['negative'])
- @test.idempotent_id('46a4e1ca-87ae-4d28-987a-1b6b136a0221')
+ @decorators.idempotent_id('46a4e1ca-87ae-4d28-987a-1b6b136a0221')
def test_migrate_non_existent_server(self):
# migrate a non existent server
self.assertRaises(lib_exc.NotFound,
self.client.migrate_server,
data_utils.rand_uuid())
- @test.idempotent_id('b0b17f83-d14e-4fc4-8f31-bcc9f3cfa629')
+ @decorators.idempotent_id('b0b17f83-d14e-4fc4-8f31-bcc9f3cfa629')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
index 1bbde98..6b92273 100644
--- a/tempest/api/compute/admin/test_servers_on_multinodes.py
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -16,6 +16,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -35,7 +36,7 @@
return self.os_adm.servers_client.show_server(
server_id)['server']['OS-EXT-SRV-ATTR:host']
- @test.idempotent_id('26a9d5df-6890-45f2-abc4-a659290cb130')
+ @decorators.idempotent_id('26a9d5df-6890-45f2-abc4-a659290cb130')
@testtools.skipUnless(
test.is_scheduler_filter_enabled("SameHostFilter"),
'SameHostFilter is not available.')
@@ -49,7 +50,7 @@
host02 = self._get_host(server02)
self.assertEqual(host01, host02)
- @test.idempotent_id('cc7ca884-6e3e-42a3-a92f-c522fcf25e8e')
+ @decorators.idempotent_id('cc7ca884-6e3e-42a3-a92f-c522fcf25e8e')
@testtools.skipUnless(
test.is_scheduler_filter_enabled("DifferentHostFilter"),
'DifferentHostFilter is not available.')
@@ -63,7 +64,7 @@
host02 = self._get_host(server02)
self.assertNotEqual(host01, host02)
- @test.idempotent_id('7869cc84-d661-4e14-9f00-c18cdc89cf57')
+ @decorators.idempotent_id('7869cc84-d661-4e14-9f00-c18cdc89cf57')
@testtools.skipUnless(
test.is_scheduler_filter_enabled("DifferentHostFilter"),
'DifferentHostFilter is not available.')
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index 8648b9f..c1c1c82 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -15,7 +15,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class ServicesAdminTestJSON(base.BaseV2ComputeAdminTest):
@@ -26,12 +26,12 @@
super(ServicesAdminTestJSON, cls).setup_clients()
cls.client = cls.os_adm.services_client
- @test.idempotent_id('5be41ef4-53d1-41cc-8839-5c2a48a1b283')
+ @decorators.idempotent_id('5be41ef4-53d1-41cc-8839-5c2a48a1b283')
def test_list_services(self):
services = self.client.list_services()['services']
self.assertNotEqual(0, len(services))
- @test.idempotent_id('f345b1ec-bc6e-4c38-a527-3ca2bc00bef5')
+ @decorators.idempotent_id('f345b1ec-bc6e-4c38-a527-3ca2bc00bef5')
def test_get_service_by_service_binary_name(self):
binary_name = 'nova-compute'
services = self.client.list_services(binary=binary_name)['services']
@@ -39,7 +39,7 @@
for service in services:
self.assertEqual(binary_name, service['binary'])
- @test.idempotent_id('affb42d5-5b4b-43c8-8b0b-6dca054abcca')
+ @decorators.idempotent_id('affb42d5-5b4b-43c8-8b0b-6dca054abcca')
def test_get_service_by_host_name(self):
services = self.client.list_services()['services']
host_name = services[0]['host']
@@ -57,7 +57,7 @@
# on order.
self.assertEqual(sorted(s1), sorted(s2))
- @test.idempotent_id('39397f6f-37b8-4234-8671-281e44c74025')
+ @decorators.idempotent_id('39397f6f-37b8-4234-8671-281e44c74025')
def test_get_service_by_service_and_host_name(self):
services = self.client.list_services()['services']
host_name = services[0]['host']
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index 710cac4..9447a09 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -13,6 +13,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -27,13 +28,13 @@
cls.non_admin_client = cls.services_client
@test.attr(type=['negative'])
- @test.idempotent_id('1126d1f8-266e-485f-a687-adc547492646')
+ @decorators.idempotent_id('1126d1f8-266e-485f-a687-adc547492646')
def test_list_services_with_non_admin_user(self):
self.assertRaises(lib_exc.Forbidden,
self.non_admin_client.list_services)
@test.attr(type=['negative'])
- @test.idempotent_id('d0884a69-f693-4e79-a9af-232d15643bf7')
+ @decorators.idempotent_id('d0884a69-f693-4e79-a9af-232d15643bf7')
def test_get_service_by_invalid_params(self):
# return all services if send the request with invalid parameter
services = self.client.list_services()['services']
@@ -42,7 +43,7 @@
self.assertEqual(len(services), len(services_xxx))
@test.attr(type=['negative'])
- @test.idempotent_id('1e966d4a-226e-47c7-b601-0b18a27add54')
+ @decorators.idempotent_id('1e966d4a-226e-47c7-b601-0b18a27add54')
def test_get_service_by_invalid_service_and_valid_host(self):
services = self.client.list_services()['services']
host_name = services[0]['host']
@@ -51,7 +52,7 @@
self.assertEqual(0, len(services))
@test.attr(type=['negative'])
- @test.idempotent_id('64e7e7fb-69e8-4cb6-a71d-8d5eb0c98655')
+ @decorators.idempotent_id('64e7e7fb-69e8-4cb6-a71d-8d5eb0c98655')
def test_get_service_with_valid_service_and_invalid_host(self):
services = self.client.list_services()['services']
binary_name = services[0]['binary']
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage.py b/tempest/api/compute/admin/test_simple_tenant_usage.py
index dbc22e0..ef55584 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage.py
@@ -17,8 +17,8 @@
from tempest.api.compute import base
from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as e
-from tempest import test
# Time that waits for until returning valid response
# TODO(takmatsu): Ideally this value would come from configuration.
@@ -65,7 +65,7 @@
func.__name__, duration))
return self.resp
- @test.idempotent_id('062c8ae9-9912-4249-8b51-e38d664e926e')
+ @decorators.idempotent_id('062c8ae9-9912-4249-8b51-e38d664e926e')
def test_list_usage_all_tenants(self):
# Get usage for all tenants
tenant_usage = self.call_until_valid(
@@ -73,7 +73,7 @@
start=self.start, end=self.end, detailed="1")['tenant_usages'][0]
self.assertEqual(len(tenant_usage), 8)
- @test.idempotent_id('94135049-a4c5-4934-ad39-08fa7da4f22e')
+ @decorators.idempotent_id('94135049-a4c5-4934-ad39-08fa7da4f22e')
def test_get_usage_tenant(self):
# Get usage for a specific tenant
tenant_usage = self.call_until_valid(
@@ -82,7 +82,7 @@
self.assertEqual(len(tenant_usage), 8)
- @test.idempotent_id('9d00a412-b40e-4fd9-8eba-97b496316116')
+ @decorators.idempotent_id('9d00a412-b40e-4fd9-8eba-97b496316116')
def test_get_usage_tenant_with_non_admin_user(self):
# Get usage for a specific tenant with non admin user
tenant_usage = self.call_until_valid(
diff --git a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
index 315116e..35762d6 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
@@ -16,6 +16,7 @@
import datetime
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -41,7 +42,7 @@
return at.strftime('%Y-%m-%dT%H:%M:%S.%f')
@test.attr(type=['negative'])
- @test.idempotent_id('8b21e135-d94b-4991-b6e9-87059609c8ed')
+ @decorators.idempotent_id('8b21e135-d94b-4991-b6e9-87059609c8ed')
def test_get_usage_tenant_with_empty_tenant_id(self):
# Get usage for a specific tenant empty
params = {'start': self.start,
@@ -51,7 +52,7 @@
'', **params)
@test.attr(type=['negative'])
- @test.idempotent_id('4079dd2a-9e8d-479f-869d-6fa985ce45b6')
+ @decorators.idempotent_id('4079dd2a-9e8d-479f-869d-6fa985ce45b6')
def test_get_usage_tenant_with_invalid_date(self):
# Get usage for tenant with invalid date
params = {'start': self.end,
@@ -61,7 +62,7 @@
self.client.tenant_id, **params)
@test.attr(type=['negative'])
- @test.idempotent_id('bbe6fe2c-15d8-404c-a0a2-44fad0ad5cc7')
+ @decorators.idempotent_id('bbe6fe2c-15d8-404c-a0a2-44fad0ad5cc7')
def test_list_usage_all_tenants_with_non_admin_user(self):
# Get usage for all tenants with non admin user
params = {'start': self.start,
diff --git a/tempest/api/compute/admin/test_volume_swap.py b/tempest/api/compute/admin/test_volume_swap.py
index f603abd..5f2444a 100644
--- a/tempest/api/compute/admin/test_volume_swap.py
+++ b/tempest/api/compute/admin/test_volume_swap.py
@@ -13,6 +13,7 @@
from tempest.api.compute import base
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -43,7 +44,7 @@
# We need the admin client for performing the update (swap) volume call
cls.servers_admin_client = cls.os_adm.servers_client
- @test.idempotent_id('1769f00d-a693-4d67-a631-6a3496773813')
+ @decorators.idempotent_id('1769f00d-a693-4d67-a631-6a3496773813')
@test.services('volume')
def test_volume_swap(self):
# Create two volumes.
diff --git a/tempest/api/compute/admin/test_volumes_negative.py b/tempest/api/compute/admin/test_volumes_negative.py
index 26b8742..1f85c18 100644
--- a/tempest/api/compute/admin/test_volumes_negative.py
+++ b/tempest/api/compute/admin/test_volumes_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -40,7 +41,7 @@
super(VolumesAdminNegativeTest, cls).resource_setup()
cls.server = cls.create_test_server(wait_until='ACTIVE')
- @test.idempotent_id('309b5ecd-0585-4a7e-a36f-d2b2bf55259d')
+ @decorators.idempotent_id('309b5ecd-0585-4a7e-a36f-d2b2bf55259d')
def test_update_attached_volume_with_nonexistent_volume_in_uri(self):
volume = self.create_volume()
nonexistent_volume = data_utils.rand_uuid()
@@ -50,7 +51,7 @@
volumeId=volume['id'])
@test.related_bug('1629110', status_code=400)
- @test.idempotent_id('7dcac15a-b107-46d3-a5f6-cb863f4e454a')
+ @decorators.idempotent_id('7dcac15a-b107-46d3-a5f6-cb863f4e454a')
def test_update_attached_volume_with_nonexistent_volume_in_body(self):
volume = self.create_volume()
self.attach_volume(self.server, volume)
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index d5c7302..a39fec9 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -15,7 +15,7 @@
from tempest.api.compute import base
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -28,14 +28,14 @@
if not CONF.compute_feature_enabled.nova_cert:
raise cls.skipException("Nova cert is not available")
- @test.idempotent_id('c070a441-b08e-447e-a733-905909535b1b')
+ @decorators.idempotent_id('c070a441-b08e-447e-a733-905909535b1b')
def test_create_root_certificate(self):
# create certificates
body = self.certificates_client.create_certificate()['certificate']
self.assertIn('data', body)
self.assertIn('private_key', body)
- @test.idempotent_id('3ac273d0-92d2-4632-bdfc-afbc21d4606c')
+ @decorators.idempotent_id('3ac273d0-92d2-4632-bdfc-afbc21d4606c')
def test_get_root_certificate(self):
# get the root certificate
body = (self.certificates_client.show_certificate('root')
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 7e01296..546667f 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest import test
@@ -27,7 +28,7 @@
cls.client = cls.flavors_client
@test.attr(type='smoke')
- @test.idempotent_id('e36c0eaa-dff5-4082-ad1f-3f9a80aa3f59')
+ @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']
@@ -36,7 +37,7 @@
'name': flavor['name']}
self.assertIn(flavor_min_detail, flavors)
- @test.idempotent_id('6e85fde4-b3cd-4137-ab72-ed5f418e8c24')
+ @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']
@@ -44,27 +45,27 @@
self.assertIn(flavor, flavors)
@test.attr(type='smoke')
- @test.idempotent_id('1f12046b-753d-40d2-abb6-d8eb8b30cb2f')
+ @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']
self.assertEqual(self.flavor_ref, flavor['id'])
- @test.idempotent_id('8d7691b3-6ed4-411a-abc9-2839a765adab')
+ @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']
self.assertEqual(1, len(flavors))
- @test.idempotent_id('b26f6327-2886-467a-82be-cef7a27709cb')
+ @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']
self.assertEqual(1, len(flavors))
- @test.idempotent_id('e800f879-9828-4bd0-8eae-4f17189951fb')
+ @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']
@@ -75,7 +76,7 @@
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
'The list of flavors did not start after the marker.')
- @test.idempotent_id('6db2f0c0-ddee-4162-9c84-0703d3dd1107')
+ @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']
@@ -86,7 +87,7 @@
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]),
'The list of flavors did not start after the marker.')
- @test.idempotent_id('3df2743e-3034-4e57-a4cb-b6527f6eac79')
+ @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']
@@ -96,7 +97,7 @@
flavors = self.client.list_flavors(detail=True, **params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
- @test.idempotent_id('09fe7509-b4ee-4b34-bf8b-39532dc47292')
+ @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']
@@ -106,7 +107,7 @@
flavors = self.client.list_flavors(detail=True, **params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
- @test.idempotent_id('10645a4d-96f5-443f-831b-730711e11dd4')
+ @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']
@@ -116,7 +117,7 @@
flavors = self.client.list_flavors(**params)['flavors']
self.assertFalse(any([i for i in flavors if i['id'] == flavor_id]))
- @test.idempotent_id('935cf550-e7c8-4da6-8002-00f92d5edfaa')
+ @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']
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 dcb2d2c..4d8416f 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -16,6 +16,7 @@
from tempest.api.compute.floating_ips import base
from tempest import config
from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -52,7 +53,7 @@
cls.client.delete_floating_ip(cls.floating_ip_id)
super(FloatingIPsTestJSON, cls).resource_cleanup()
- @test.idempotent_id('f7bfb946-297e-41b8-9e8c-aba8e9bb5194')
+ @decorators.idempotent_id('f7bfb946-297e-41b8-9e8c-aba8e9bb5194')
@test.services('network')
def test_allocate_floating_ip(self):
# Positive test:Allocation of a new floating IP to a project
@@ -68,7 +69,7 @@
body = self.client.list_floating_ips()['floating_ips']
self.assertIn(floating_ip_details, body)
- @test.idempotent_id('de45e989-b5ca-4a9b-916b-04a52e7bbb8b')
+ @decorators.idempotent_id('de45e989-b5ca-4a9b-916b-04a52e7bbb8b')
@test.services('network')
def test_delete_floating_ip(self):
# Positive test:Deletion of valid floating IP from project
@@ -83,7 +84,7 @@
# Check it was really deleted.
self.client.wait_for_resource_deletion(floating_ip_body['id'])
- @test.idempotent_id('307efa27-dc6f-48a0-8cd2-162ce3ef0b52')
+ @decorators.idempotent_id('307efa27-dc6f-48a0-8cd2-162ce3ef0b52')
@test.services('network')
def test_associate_disassociate_floating_ip(self):
# Positive test:Associate and disassociate the provided floating IP
@@ -104,7 +105,7 @@
self.floating_ip,
self.server_id)
- @test.idempotent_id('6edef4b2-aaf1-4abc-bbe3-993e2561e0fe')
+ @decorators.idempotent_id('6edef4b2-aaf1-4abc-bbe3-993e2561e0fe')
@test.services('network')
def test_associate_already_associated_floating_ip(self):
# positive test:Association of an already associated floating IP
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index 31cf39c..5e47d18 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -16,6 +16,7 @@
from tempest.api.compute.floating_ips import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -48,7 +49,7 @@
break
@test.attr(type=['negative'])
- @test.idempotent_id('6e0f059b-e4dd-48fb-8207-06e3bba5b074')
+ @decorators.idempotent_id('6e0f059b-e4dd-48fb-8207-06e3bba5b074')
@test.services('network')
def test_allocate_floating_ip_from_nonexistent_pool(self):
# Negative test:Allocation of a new floating IP from a nonexistent_pool
@@ -58,7 +59,7 @@
pool="non_exist_pool")
@test.attr(type=['negative'])
- @test.idempotent_id('ae1c55a8-552b-44d4-bfb6-2a115a15d0ba')
+ @decorators.idempotent_id('ae1c55a8-552b-44d4-bfb6-2a115a15d0ba')
@test.services('network')
def test_delete_nonexistent_floating_ip(self):
# Negative test:Deletion of a nonexistent floating IP
@@ -69,7 +70,7 @@
self.non_exist_id)
@test.attr(type=['negative'])
- @test.idempotent_id('595fa616-1a71-4670-9614-46564ac49a4c')
+ @decorators.idempotent_id('595fa616-1a71-4670-9614-46564ac49a4c')
@test.services('network')
def test_associate_nonexistent_floating_ip(self):
# Negative test:Association of a non existent floating IP
@@ -80,7 +81,7 @@
"0.0.0.0", self.server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('0a081a66-e568-4e6b-aa62-9587a876dca8')
+ @decorators.idempotent_id('0a081a66-e568-4e6b-aa62-9587a876dca8')
@test.services('network')
def test_dissociate_nonexistent_floating_ip(self):
# Negative test:Dissociation of a non existent floating IP should fail
@@ -90,7 +91,7 @@
"0.0.0.0", self.server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('804b4fcb-bbf5-412f-925d-896672b61eb3')
+ @decorators.idempotent_id('804b4fcb-bbf5-412f-925d-896672b61eb3')
@test.services('network')
def test_associate_ip_to_server_without_passing_floating_ip(self):
# Negative test:Association of empty floating IP to specific server
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 222bf18..71f5f13 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -33,7 +34,7 @@
super(FloatingIPDetailsTestJSON, cls).resource_setup()
cls.floating_ip = []
cls.floating_ip_id = []
- for i in range(3):
+ for _ in range(3):
body = cls.client.create_floating_ip(
pool=CONF.network.floating_network_name)['floating_ip']
cls.floating_ip.append(body)
@@ -45,7 +46,7 @@
cls.client.delete_floating_ip(f_id)
super(FloatingIPDetailsTestJSON, cls).resource_cleanup()
- @test.idempotent_id('16db31c3-fb85-40c9-bbe2-8cf7b67ff99f')
+ @decorators.idempotent_id('16db31c3-fb85-40c9-bbe2-8cf7b67ff99f')
@test.services('network')
def test_list_floating_ips(self):
# Positive test:Should return the list of floating IPs
@@ -56,7 +57,7 @@
for i in range(3):
self.assertIn(self.floating_ip[i], floating_ips)
- @test.idempotent_id('eef497e0-8ff7-43c8-85ef-558440574f84')
+ @decorators.idempotent_id('eef497e0-8ff7-43c8-85ef-558440574f84')
@test.services('network')
def test_get_floating_ip_details(self):
# Positive test:Should be able to GET the details of floatingIP
@@ -78,7 +79,7 @@
body['fixed_ip'])
self.assertEqual(floating_ip_id, body['id'])
- @test.idempotent_id('df389fc8-56f5-43cc-b290-20eda39854d3')
+ @decorators.idempotent_id('df389fc8-56f5-43cc-b290-20eda39854d3')
@test.services('network')
def test_list_floating_ip_pools(self):
# Positive test:Should return the list of floating IP Pools
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index ea56ae9..00a4075 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -16,6 +16,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -30,7 +31,7 @@
cls.client = cls.floating_ips_client
@test.attr(type=['negative'])
- @test.idempotent_id('7ab18834-4a4b-4f28-a2c5-440579866695')
+ @decorators.idempotent_id('7ab18834-4a4b-4f28-a2c5-440579866695')
@test.services('network')
def test_get_nonexistent_floating_ip_details(self):
# Negative test:Should not be able to GET the details
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 26d4efe..f131007 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -20,8 +20,8 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions
-from tempest import test
CONF = config.CONF
@@ -83,7 +83,7 @@
meta = {'os_version': 'value1', 'os_distro': 'value2'}
self.client.set_image_metadata(self.image_id, meta)
- @test.idempotent_id('37ec6edd-cf30-4c53-bd45-ae74db6b0531')
+ @decorators.idempotent_id('37ec6edd-cf30-4c53-bd45-ae74db6b0531')
def test_list_image_metadata(self):
# All metadata key/value pairs for an image should be returned
resp_metadata = self.client.list_image_metadata(self.image_id)
@@ -91,7 +91,7 @@
'os_version': 'value1', 'os_distro': 'value2'}}
self.assertEqual(expected, resp_metadata)
- @test.idempotent_id('ece7befc-d3ce-42a4-b4be-c3067a418c29')
+ @decorators.idempotent_id('ece7befc-d3ce-42a4-b4be-c3067a418c29')
def test_set_image_metadata(self):
# The metadata for the image should match the new values
req_metadata = {'os_version': 'value2', 'architecture': 'value3'}
@@ -102,7 +102,7 @@
['metadata'])
self.assertEqual(req_metadata, resp_metadata)
- @test.idempotent_id('7b491c11-a9d5-40fe-a696-7f7e03d3fea2')
+ @decorators.idempotent_id('7b491c11-a9d5-40fe-a696-7f7e03d3fea2')
def test_update_image_metadata(self):
# The metadata for the image should match the updated values
req_metadata = {'os_version': 'alt1', 'architecture': 'value3'}
@@ -116,14 +116,14 @@
'architecture': 'value3'}}
self.assertEqual(expected, resp_metadata)
- @test.idempotent_id('4f5db52f-6685-4c75-b848-f4bb363f9aa6')
+ @decorators.idempotent_id('4f5db52f-6685-4c75-b848-f4bb363f9aa6')
def test_get_image_metadata_item(self):
# The value for a specific metadata key should be returned
meta = self.client.show_image_metadata_item(self.image_id,
'os_distro')['meta']
self.assertEqual('value2', meta['os_distro'])
- @test.idempotent_id('f2de776a-4778-4d90-a5da-aae63aee64ae')
+ @decorators.idempotent_id('f2de776a-4778-4d90-a5da-aae63aee64ae')
def test_set_image_metadata_item(self):
# The value provided for the given meta item should be set for
# the image
@@ -134,7 +134,7 @@
expected = {'metadata': {'os_version': 'alt', 'os_distro': 'value2'}}
self.assertEqual(expected, resp_metadata)
- @test.idempotent_id('a013796c-ba37-4bb5-8602-d944511def14')
+ @decorators.idempotent_id('a013796c-ba37-4bb5-8602-d944511def14')
def test_delete_image_metadata_item(self):
# The metadata value/key pair should be deleted from the image
self.client.delete_image_metadata_item(self.image_id,
diff --git a/tempest/api/compute/images/test_image_metadata_negative.py b/tempest/api/compute/images/test_image_metadata_negative.py
index 489bfbc..0f5b9d8 100644
--- a/tempest/api/compute/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/images/test_image_metadata_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -27,7 +28,7 @@
cls.client = cls.compute_images_client
@test.attr(type=['negative'])
- @test.idempotent_id('94069db2-792f-4fa8-8bd3-2271a6e0c095')
+ @decorators.idempotent_id('94069db2-792f-4fa8-8bd3-2271a6e0c095')
def test_list_nonexistent_image_metadata(self):
# Negative test: List on nonexistent image
# metadata should not happen
@@ -35,7 +36,7 @@
data_utils.rand_uuid())
@test.attr(type=['negative'])
- @test.idempotent_id('a403ef9e-9f95-427c-b70a-3ce3388796f1')
+ @decorators.idempotent_id('a403ef9e-9f95-427c-b70a-3ce3388796f1')
def test_update_nonexistent_image_metadata(self):
# Negative test:An update should not happen for a non-existent image
meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
@@ -44,7 +45,7 @@
data_utils.rand_uuid(), meta)
@test.attr(type=['negative'])
- @test.idempotent_id('41ae052c-6ee6-405c-985e-5712393a620d')
+ @decorators.idempotent_id('41ae052c-6ee6-405c-985e-5712393a620d')
def test_get_nonexistent_image_metadata_item(self):
# Negative test: Get on non-existent image should not happen
self.assertRaises(lib_exc.NotFound,
@@ -52,7 +53,7 @@
data_utils.rand_uuid(), 'os_version')
@test.attr(type=['negative'])
- @test.idempotent_id('dc64f2ce-77e8-45b0-88c8-e15041d08eaf')
+ @decorators.idempotent_id('dc64f2ce-77e8-45b0-88c8-e15041d08eaf')
def test_set_nonexistent_image_metadata(self):
# Negative test: Metadata should not be set to a non-existent image
meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
@@ -60,7 +61,7 @@
data_utils.rand_uuid(), meta)
@test.attr(type=['negative'])
- @test.idempotent_id('2154fd03-ab54-457c-8874-e6e3eb56e9cf')
+ @decorators.idempotent_id('2154fd03-ab54-457c-8874-e6e3eb56e9cf')
def test_set_nonexistent_image_metadata_item(self):
# Negative test: Metadata item should not be set to a
# nonexistent image
@@ -71,7 +72,7 @@
meta)
@test.attr(type=['negative'])
- @test.idempotent_id('848e157f-6bcf-4b2e-a5dd-5124025a8518')
+ @decorators.idempotent_id('848e157f-6bcf-4b2e-a5dd-5124025a8518')
def test_delete_nonexistent_image_metadata_item(self):
# Negative test: Shouldn't be able to delete metadata
# item from non-existent image
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index a06f4a7..a0c860a 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -16,7 +16,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -39,7 +39,7 @@
super(ImagesTestJSON, cls).setup_clients()
cls.client = cls.compute_images_client
- @test.idempotent_id('aa06b52b-2db5-4807-b218-9441f75d74e3')
+ @decorators.idempotent_id('aa06b52b-2db5-4807-b218-9441f75d74e3')
def test_delete_saving_image(self):
server = self.create_test_server(wait_until='ACTIVE')
self.addCleanup(self.servers_client.delete_server, server['id'])
@@ -50,7 +50,7 @@
.format(image_id=image['id']))
self.assertTrue(self.client.is_resource_deleted(image['id']), msg)
- @test.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
+ @decorators.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
def test_create_image_from_stopped_server(self):
server = self.create_test_server(wait_until='ACTIVE')
self.servers_client.stop_server(server['id'])
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 549262e..10f3c70 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -16,6 +16,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -41,7 +42,7 @@
cls.client = cls.compute_images_client
@test.attr(type=['negative'])
- @test.idempotent_id('6cd5a89d-5b47-46a7-93bc-3916f0d84973')
+ @decorators.idempotent_id('6cd5a89d-5b47-46a7-93bc-3916f0d84973')
def test_create_image_from_deleted_server(self):
# An image should not be created if the server instance is removed
server = self.create_test_server(wait_until='ACTIVE')
@@ -50,24 +51,22 @@
self.servers_client.delete_server(server['id'])
waiters.wait_for_server_termination(self.servers_client, server['id'])
# Create a new image after server is deleted
- name = data_utils.rand_name('image')
meta = {'image_type': 'test'}
self.assertRaises(lib_exc.NotFound,
self.create_image_from_server,
- server['id'], name=name, meta=meta)
+ server['id'], meta=meta)
@test.attr(type=['negative'])
- @test.idempotent_id('82c5b0c4-9dbd-463c-872b-20c4755aae7f')
+ @decorators.idempotent_id('82c5b0c4-9dbd-463c-872b-20c4755aae7f')
def test_create_image_from_invalid_server(self):
# An image should not be created with invalid server id
# Create a new image with invalid server id
- name = data_utils.rand_name('image')
meta = {'image_type': 'test'}
self.assertRaises(lib_exc.NotFound, self.create_image_from_server,
- '!@$^&*()', name=name, meta=meta)
+ data_utils.rand_name('invalid'), meta=meta)
@test.attr(type=['negative'])
- @test.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
+ @decorators.idempotent_id('ec176029-73dc-4037-8d72-2e4ff60cf538')
def test_create_image_specify_uuid_35_characters_or_less(self):
# Return an error if Image ID passed is 35 characters or less
snapshot_name = data_utils.rand_name('test-snap')
@@ -76,7 +75,7 @@
test_uuid, name=snapshot_name)
@test.attr(type=['negative'])
- @test.idempotent_id('36741560-510e-4cc2-8641-55fe4dfb2437')
+ @decorators.idempotent_id('36741560-510e-4cc2-8641-55fe4dfb2437')
def test_create_image_specify_uuid_37_characters_or_more(self):
# Return an error if Image ID passed is 37 characters or more
snapshot_name = data_utils.rand_name('test-snap')
@@ -85,14 +84,14 @@
test_uuid, name=snapshot_name)
@test.attr(type=['negative'])
- @test.idempotent_id('381acb65-785a-4942-94ce-d8f8c84f1f0f')
+ @decorators.idempotent_id('381acb65-785a-4942-94ce-d8f8c84f1f0f')
def test_delete_image_with_invalid_image_id(self):
# An image should not be deleted with invalid image id
self.assertRaises(lib_exc.NotFound, self.client.delete_image,
- '!@$^&*()')
+ data_utils.rand_name('invalid'))
@test.attr(type=['negative'])
- @test.idempotent_id('137aef61-39f7-44a1-8ddf-0adf82511701')
+ @decorators.idempotent_id('137aef61-39f7-44a1-8ddf-0adf82511701')
def test_delete_non_existent_image(self):
# Return an error while trying to delete a non-existent image
@@ -101,13 +100,13 @@
non_existent_image_id)
@test.attr(type=['negative'])
- @test.idempotent_id('e6e41425-af5c-4fe6-a4b5-7b7b963ffda5')
+ @decorators.idempotent_id('e6e41425-af5c-4fe6-a4b5-7b7b963ffda5')
def test_delete_image_blank_id(self):
# Return an error while trying to delete an image with blank Id
self.assertRaises(lib_exc.NotFound, self.client.delete_image, '')
@test.attr(type=['negative'])
- @test.idempotent_id('924540c3-f1f1-444c-8f58-718958b6724e')
+ @decorators.idempotent_id('924540c3-f1f1-444c-8f58-718958b6724e')
def test_delete_image_non_hex_string_id(self):
# Return an error while trying to delete an image with non hex id
invalid_image_id = data_utils.rand_uuid()[:-1] + "j"
@@ -115,13 +114,13 @@
invalid_image_id)
@test.attr(type=['negative'])
- @test.idempotent_id('68e2c175-bd26-4407-ac0f-4ea9ce2139ea')
+ @decorators.idempotent_id('68e2c175-bd26-4407-ac0f-4ea9ce2139ea')
def test_delete_image_negative_image_id(self):
# Return an error while trying to delete an image with negative id
self.assertRaises(lib_exc.NotFound, self.client.delete_image, -1)
@test.attr(type=['negative'])
- @test.idempotent_id('b340030d-82cd-4066-a314-c72fb7c59277')
+ @decorators.idempotent_id('b340030d-82cd-4066-a314-c72fb7c59277')
def test_delete_image_with_id_over_character_limit(self):
# Return an error while trying to delete image with id over limit
invalid_image_id = data_utils.rand_uuid() + "1"
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 0b4a2a8..7fff555 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -18,7 +18,7 @@
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import test_utils
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -46,7 +46,7 @@
flavor = self.flavors_client.show_flavor(flavor_id)['flavor']
return flavor['disk']
- @test.idempotent_id('3731d080-d4c5-4872-b41a-64d0d0021314')
+ @decorators.idempotent_id('3731d080-d4c5-4872-b41a-64d0d0021314')
def test_create_delete_image(self):
server_id = self.create_test_server(wait_until='ACTIVE')['id']
@@ -79,7 +79,7 @@
self.client.delete_image(image_id)
self.client.wait_for_resource_deletion(image_id)
- @test.idempotent_id('3b7c6fe4-dfe7-477c-9243-b06359db51e6')
+ @decorators.idempotent_id('3b7c6fe4-dfe7-477c-9243-b06359db51e6')
def test_create_image_specify_multibyte_character_image_name(self):
server_id = self.create_test_server(wait_until='ACTIVE')['id']
@@ -89,7 +89,7 @@
# We use a string with 3 byte utf-8 character due to bug
# #1370954 in glance which will 500 if mysql is used as the
# backend and it attempts to store a 4 byte utf-8 character
- utf8_name = data_utils.rand_name('\xe2\x82\xa1')
+ utf8_name = data_utils.rand_name(b'\xe2\x82\xa1'.decode('utf-8'))
body = self.client.create_image(server_id, name=utf8_name)
image_id = data_utils.parse_image_id(body.response['location'])
self.addCleanup(self.client.delete_image, image_id)
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index cd71de7..09bbfbe 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -20,6 +20,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -82,7 +83,7 @@
cls.image_ids = []
@test.attr(type=['negative'])
- @test.idempotent_id('55d1d38c-dd66-4933-9c8e-7d92aeb60ddc')
+ @decorators.idempotent_id('55d1d38c-dd66-4933-9c8e-7d92aeb60ddc')
def test_create_image_specify_invalid_metadata(self):
# Return an error when creating image with invalid metadata
snapshot_name = data_utils.rand_name('test-snap')
@@ -91,7 +92,7 @@
self.server_id, name=snapshot_name, metadata=meta)
@test.attr(type=['negative'])
- @test.idempotent_id('3d24d11f-5366-4536-bd28-cff32b748eca')
+ @decorators.idempotent_id('3d24d11f-5366-4536-bd28-cff32b748eca')
def test_create_image_specify_metadata_over_limits(self):
# Return an error when creating image with meta data over 255 chars
snapshot_name = data_utils.rand_name('test-snap')
@@ -100,7 +101,7 @@
self.server_id, name=snapshot_name, metadata=meta)
@test.attr(type=['negative'])
- @test.idempotent_id('0460efcf-ee88-4f94-acef-1bf658695456')
+ @decorators.idempotent_id('0460efcf-ee88-4f94-acef-1bf658695456')
def test_create_second_image_when_first_image_is_being_saved(self):
# Disallow creating another image when first image is being saved
@@ -117,7 +118,7 @@
self.server_id, name=alt_snapshot_name)
@test.attr(type=['negative'])
- @test.idempotent_id('084f0cbc-500a-4963-8a4e-312905862581')
+ @decorators.idempotent_id('084f0cbc-500a-4963-8a4e-312905862581')
def test_create_image_specify_name_over_character_limit(self):
# Return an error if snapshot name over 255 characters is passed
@@ -126,7 +127,7 @@
self.server_id, name=snapshot_name)
@test.attr(type=['negative'])
- @test.idempotent_id('0894954d-2db2-4195-a45b-ffec0bc0187e')
+ @decorators.idempotent_id('0894954d-2db2-4195-a45b-ffec0bc0187e')
def test_delete_image_that_is_not_yet_active(self):
# Return an error while trying to delete an image what is creating
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index a9c2f7a..9c9b8a1 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -23,8 +23,8 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions
-from tempest import test
CONF = config.CONF
@@ -122,7 +122,7 @@
cls.server1['id'], wait_until='ACTIVE')
cls.snapshot2_id = cls.snapshot2['id']
- @test.idempotent_id('a3f5b513-aeb3-42a9-b18e-f091ef73254d')
+ @decorators.idempotent_id('a3f5b513-aeb3-42a9-b18e-f091ef73254d')
def test_list_images_filter_by_status(self):
# The list of images should contain only images with the
# provided status
@@ -133,7 +133,7 @@
self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
- @test.idempotent_id('33163b73-79f5-4d07-a7ea-9213bcc468ff')
+ @decorators.idempotent_id('33163b73-79f5-4d07-a7ea-9213bcc468ff')
def test_list_images_filter_by_name(self):
# List of all images should contain the expected images filtered
# by name
@@ -144,7 +144,7 @@
self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
self.assertFalse(any([i for i in images if i['id'] == self.image3_id]))
- @test.idempotent_id('9f238683-c763-45aa-b848-232ec3ce3105')
+ @decorators.idempotent_id('9f238683-c763-45aa-b848-232ec3ce3105')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
def test_list_images_filter_by_server_id(self):
@@ -161,7 +161,7 @@
self.assertFalse(any([i for i in images
if i['id'] == self.snapshot3_id]))
- @test.idempotent_id('05a377b8-28cf-4734-a1e6-2ab5c38bf606')
+ @decorators.idempotent_id('05a377b8-28cf-4734-a1e6-2ab5c38bf606')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
def test_list_images_filter_by_server_ref(self):
@@ -180,7 +180,7 @@
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot3_id]))
- @test.idempotent_id('e3356918-4d3e-4756-81d5-abc4524ba29f')
+ @decorators.idempotent_id('e3356918-4d3e-4756-81d5-abc4524ba29f')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
def test_list_images_filter_by_type(self):
@@ -197,14 +197,14 @@
self.assertFalse(any([i for i in images
if i['id'] == self.image_ref]))
- @test.idempotent_id('3a484ca9-67ba-451e-b494-7fcf28d32d62')
+ @decorators.idempotent_id('3a484ca9-67ba-451e-b494-7fcf28d32d62')
def test_list_images_limit_results(self):
# Verify only the expected number of results are returned
params = {'limit': '1'}
images = self.client.list_images(**params)['images']
self.assertEqual(1, len([x for x in images if 'id' in x]))
- @test.idempotent_id('18bac3ae-da27-436c-92a9-b22474d13aab')
+ @decorators.idempotent_id('18bac3ae-da27-436c-92a9-b22474d13aab')
def test_list_images_filter_by_changes_since(self):
# Verify only updated images are returned in the detailed list
@@ -215,7 +215,7 @@
found = any([i for i in images if i['id'] == self.image3_id])
self.assertTrue(found)
- @test.idempotent_id('9b0ea018-6185-4f71-948a-a123a107988e')
+ @decorators.idempotent_id('9b0ea018-6185-4f71-948a-a123a107988e')
def test_list_images_with_detail_filter_by_status(self):
# Detailed list of all images should only contain images
# with the provided status
@@ -226,7 +226,7 @@
self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
- @test.idempotent_id('644ea267-9bd9-4f3b-af9f-dffa02396a17')
+ @decorators.idempotent_id('644ea267-9bd9-4f3b-af9f-dffa02396a17')
def test_list_images_with_detail_filter_by_name(self):
# Detailed list of all images should contain the expected
# images filtered by name
@@ -237,7 +237,7 @@
self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
self.assertFalse(any([i for i in images if i['id'] == self.image3_id]))
- @test.idempotent_id('ba2fa9a9-b672-47cc-b354-3b4c0600e2cb')
+ @decorators.idempotent_id('ba2fa9a9-b672-47cc-b354-3b4c0600e2cb')
def test_list_images_with_detail_limit_results(self):
# Verify only the expected number of results (with full details)
# are returned
@@ -245,7 +245,7 @@
images = self.client.list_images(detail=True, **params)['images']
self.assertEqual(1, len(images))
- @test.idempotent_id('8c78f822-203b-4bf6-8bba-56ebd551cf84')
+ @decorators.idempotent_id('8c78f822-203b-4bf6-8bba-56ebd551cf84')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
def test_list_images_with_detail_filter_by_server_ref(self):
@@ -264,7 +264,7 @@
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot3_id]))
- @test.idempotent_id('888c0cc0-7223-43c5-9db0-b125fd0a393b')
+ @decorators.idempotent_id('888c0cc0-7223-43c5-9db0-b125fd0a393b')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting is not available.')
def test_list_images_with_detail_filter_by_type(self):
@@ -282,7 +282,7 @@
self.assertFalse(any([i for i in images
if i['id'] == self.image_ref]))
- @test.idempotent_id('7d439e18-ac2e-4827-b049-7e18004712c4')
+ @decorators.idempotent_id('7d439e18-ac2e-4827-b049-7e18004712c4')
def test_list_images_with_detail_filter_by_changes_since(self):
# Verify an update image is returned
diff --git a/tempest/api/compute/images/test_list_image_filters_negative.py b/tempest/api/compute/images/test_list_image_filters_negative.py
index 2689f88..e04a57a 100644
--- a/tempest/api/compute/images/test_list_image_filters_negative.py
+++ b/tempest/api/compute/images/test_list_image_filters_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -36,7 +37,7 @@
cls.client = cls.compute_images_client
@test.attr(type=['negative'])
- @test.idempotent_id('391b0440-432c-4d4b-b5da-c5096aa247eb')
+ @decorators.idempotent_id('391b0440-432c-4d4b-b5da-c5096aa247eb')
def test_get_nonexistent_image(self):
# Check raises a NotFound
nonexistent_image = data_utils.rand_uuid()
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index ae3667d..5d3cbf3 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -15,7 +15,7 @@
from tempest.api.compute import base
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -34,20 +34,20 @@
super(ListImagesTestJSON, cls).setup_clients()
cls.client = cls.compute_images_client
- @test.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
+ @decorators.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
def test_get_image(self):
# Returns the correct details for a single image
image = self.client.show_image(self.image_ref)['image']
self.assertEqual(self.image_ref, image['id'])
- @test.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
+ @decorators.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
def test_list_images(self):
# The list of all images should contain the image
images = self.client.list_images()['images']
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
- @test.idempotent_id('9f94cb6b-7f10-48c5-b911-a0b84d7d4cd6')
+ @decorators.idempotent_id('9f94cb6b-7f10-48c5-b911-a0b84d7d4cd6')
def test_list_images_with_detail(self):
# Detailed list of all images should contain the expected images
images = self.client.list_images(detail=True)['images']
diff --git a/tempest/api/compute/keypairs/base.py b/tempest/api/compute/keypairs/base.py
index ad7f958..21f504b 100644
--- a/tempest/api/compute/keypairs/base.py
+++ b/tempest/api/compute/keypairs/base.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.common.utils import data_utils
class BaseKeypairTest(base.BaseV2ComputeTest):
@@ -27,9 +28,12 @@
def _delete_keypair(self, keypair_name, **params):
self.client.delete_keypair(keypair_name, **params)
- def _create_keypair(self, keypair_name,
- pub_key=None, keypair_type=None,
- user_id=None):
+ def create_keypair(self, keypair_name=None,
+ pub_key=None, keypair_type=None,
+ user_id=None):
+ if keypair_name is None:
+ keypair_name = data_utils.rand_name(
+ self.__class__.__name__ + '-keypair')
kwargs = {'name': keypair_name}
delete_params = {}
if pub_key:
diff --git a/tempest/api/compute/keypairs/test_keypairs.py b/tempest/api/compute/keypairs/test_keypairs.py
index 562a508..11e84e8 100644
--- a/tempest/api/compute/keypairs/test_keypairs.py
+++ b/tempest/api/compute/keypairs/test_keypairs.py
@@ -15,20 +15,19 @@
from tempest.api.compute.keypairs import base
from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
class KeyPairsV2TestJSON(base.BaseKeypairTest):
max_microversion = '2.1'
- @test.idempotent_id('1d1dbedb-d7a0-432a-9d09-83f543c3c19b')
+ @decorators.idempotent_id('1d1dbedb-d7a0-432a-9d09-83f543c3c19b')
def test_keypairs_create_list_delete(self):
# Keypairs created should be available in the response list
# Create 3 keypairs
key_list = list()
- for i in range(3):
- k_name = data_utils.rand_name('keypair')
- keypair = self._create_keypair(k_name)
+ for _ in range(3):
+ keypair = self.create_keypair()
# Need to pop these keys so that our compare doesn't fail later,
# as the keypair dicts from list API doesn't have them.
keypair.pop('private_key')
@@ -47,11 +46,11 @@
"Failed to find keypairs %s in fetched list"
% ', '.join(m_key['name'] for m_key in missing_kps))
- @test.idempotent_id('6c1d3123-4519-4742-9194-622cb1714b7d')
+ @decorators.idempotent_id('6c1d3123-4519-4742-9194-622cb1714b7d')
def test_keypair_create_delete(self):
# Keypair should be created, verified and deleted
k_name = data_utils.rand_name('keypair')
- keypair = self._create_keypair(k_name)
+ keypair = self.create_keypair(k_name)
private_key = keypair['private_key']
key_name = keypair['name']
self.assertEqual(key_name, k_name,
@@ -60,11 +59,11 @@
self.assertIsNotNone(private_key,
"Field private_key is empty or not found.")
- @test.idempotent_id('a4233d5d-52d8-47cc-9a25-e1864527e3df')
+ @decorators.idempotent_id('a4233d5d-52d8-47cc-9a25-e1864527e3df')
def test_get_keypair_detail(self):
# Keypair should be created, Got details by name and deleted
k_name = data_utils.rand_name('keypair')
- self._create_keypair(k_name)
+ self.create_keypair(k_name)
keypair_detail = self.client.show_keypair(k_name)['keypair']
self.assertIn('name', keypair_detail)
self.assertIn('public_key', keypair_detail)
@@ -75,7 +74,7 @@
self.assertIsNotNone(public_key,
"Field public_key is empty or not found.")
- @test.idempotent_id('39c90c6a-304a-49dd-95ec-2366129def05')
+ @decorators.idempotent_id('39c90c6a-304a-49dd-95ec-2366129def05')
def test_keypair_create_with_pub_key(self):
# Keypair should be created with a given public key
k_name = data_utils.rand_name('keypair')
@@ -88,7 +87,7 @@
"LOeB1kYMOBaiUPLQTWXR3JpckqFIQwhIH0zoHlJvZE8hh90"
"XcPojYN56tI0OlrGqojbediJYD0rUsJu4weZpbn8vilb3JuDY+jws"
"snSA8wzBx3A/8y9Pp1B nova@ubuntu")
- keypair = self._create_keypair(k_name, pub_key)
+ keypair = self.create_keypair(k_name, pub_key)
self.assertNotIn('private_key', keypair,
"Field private_key is not empty!")
key_name = keypair['name']
diff --git a/tempest/api/compute/keypairs/test_keypairs_negative.py b/tempest/api/compute/keypairs/test_keypairs_negative.py
index 2a6139b..863ce0d 100644
--- a/tempest/api/compute/keypairs/test_keypairs_negative.py
+++ b/tempest/api/compute/keypairs/test_keypairs_negative.py
@@ -16,22 +16,22 @@
from tempest.api.compute.keypairs import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
class KeyPairsNegativeTestJSON(base.BaseKeypairTest):
@test.attr(type=['negative'])
- @test.idempotent_id('29cca892-46ae-4d48-bc32-8fe7e731eb81')
+ @decorators.idempotent_id('29cca892-46ae-4d48-bc32-8fe7e731eb81')
def test_keypair_create_with_invalid_pub_key(self):
# Keypair should not be created with a non RSA public key
- k_name = data_utils.rand_name('keypair')
pub_key = "ssh-rsa JUNK nova@ubuntu"
self.assertRaises(lib_exc.BadRequest,
- self._create_keypair, k_name, pub_key)
+ self.create_keypair, pub_key=pub_key)
@test.attr(type=['negative'])
- @test.idempotent_id('7cc32e47-4c42-489d-9623-c5e2cb5a2fa5')
+ @decorators.idempotent_id('7cc32e47-4c42-489d-9623-c5e2cb5a2fa5')
def test_keypair_delete_nonexistent_key(self):
# Non-existent key deletion should throw a proper error
k_name = data_utils.rand_name("keypair-non-existent")
@@ -39,53 +39,51 @@
k_name)
@test.attr(type=['negative'])
- @test.idempotent_id('dade320e-69ca-42a9-ba4a-345300f127e0')
+ @decorators.idempotent_id('dade320e-69ca-42a9-ba4a-345300f127e0')
def test_create_keypair_with_empty_public_key(self):
# Keypair should not be created with an empty public key
- k_name = data_utils.rand_name("keypair")
pub_key = ' '
- self.assertRaises(lib_exc.BadRequest, self._create_keypair,
- k_name, pub_key)
+ self.assertRaises(lib_exc.BadRequest, self.create_keypair,
+ pub_key=pub_key)
@test.attr(type=['negative'])
- @test.idempotent_id('fc100c19-2926-4b9c-8fdc-d0589ee2f9ff')
+ @decorators.idempotent_id('fc100c19-2926-4b9c-8fdc-d0589ee2f9ff')
def test_create_keypair_when_public_key_bits_exceeds_maximum(self):
# Keypair should not be created when public key bits are too long
- k_name = data_utils.rand_name("keypair")
pub_key = 'ssh-rsa ' + 'A' * 2048 + ' openstack@ubuntu'
- self.assertRaises(lib_exc.BadRequest, self._create_keypair,
- k_name, pub_key)
+ self.assertRaises(lib_exc.BadRequest, self.create_keypair,
+ pub_key=pub_key)
@test.attr(type=['negative'])
- @test.idempotent_id('0359a7f1-f002-4682-8073-0c91e4011b7c')
+ @decorators.idempotent_id('0359a7f1-f002-4682-8073-0c91e4011b7c')
def test_create_keypair_with_duplicate_name(self):
# Keypairs with duplicate names should not be created
k_name = data_utils.rand_name('keypair')
self.client.create_keypair(name=k_name)
# Now try the same keyname to create another key
- self.assertRaises(lib_exc.Conflict, self._create_keypair,
+ self.assertRaises(lib_exc.Conflict, self.create_keypair,
k_name)
self.client.delete_keypair(k_name)
@test.attr(type=['negative'])
- @test.idempotent_id('1398abe1-4a84-45fb-9294-89f514daff00')
+ @decorators.idempotent_id('1398abe1-4a84-45fb-9294-89f514daff00')
def test_create_keypair_with_empty_name_string(self):
# Keypairs with name being an empty string should not be created
- self.assertRaises(lib_exc.BadRequest, self._create_keypair,
+ self.assertRaises(lib_exc.BadRequest, self.create_keypair,
'')
@test.attr(type=['negative'])
- @test.idempotent_id('3faa916f-779f-4103-aca7-dc3538eee1b7')
+ @decorators.idempotent_id('3faa916f-779f-4103-aca7-dc3538eee1b7')
def test_create_keypair_with_long_keynames(self):
# Keypairs with name longer than 255 chars should not be created
k_name = 'keypair-'.ljust(260, '0')
- self.assertRaises(lib_exc.BadRequest, self._create_keypair,
+ self.assertRaises(lib_exc.BadRequest, self.create_keypair,
k_name)
@test.attr(type=['negative'])
- @test.idempotent_id('45fbe5e0-acb5-49aa-837a-ff8d0719db91')
+ @decorators.idempotent_id('45fbe5e0-acb5-49aa-837a-ff8d0719db91')
def test_create_keypair_invalid_name(self):
# Keypairs with name being an invalid name should not be created
k_name = 'key_/.\@:'
- self.assertRaises(lib_exc.BadRequest, self._create_keypair,
+ self.assertRaises(lib_exc.BadRequest, self.create_keypair,
k_name)
diff --git a/tempest/api/compute/keypairs/test_keypairs_v22.py b/tempest/api/compute/keypairs/test_keypairs_v22.py
index 997ef9b..c893a4f 100644
--- a/tempest/api/compute/keypairs/test_keypairs_v22.py
+++ b/tempest/api/compute/keypairs/test_keypairs_v22.py
@@ -14,7 +14,7 @@
from tempest.api.compute.keypairs import test_keypairs
from tempest.common.utils import data_utils
-from tempest import test
+from tempest.lib import decorators
class KeyPairsV22TestJSON(test_keypairs.KeyPairsV2TestJSON):
@@ -28,7 +28,7 @@
def _test_keypairs_create_list_show(self, keypair_type=None):
k_name = data_utils.rand_name('keypair')
- keypair = self._create_keypair(k_name, keypair_type=keypair_type)
+ keypair = self.create_keypair(k_name, keypair_type=keypair_type)
# Verify whether 'type' is present in keypair create response of
# version 2.2 and it is with default value 'ssh'.
self._check_keypair_type(keypair, keypair_type)
@@ -41,11 +41,11 @@
if keypair['keypair']['name'] == k_name:
self._check_keypair_type(keypair['keypair'], keypair_type)
- @test.idempotent_id('8726fa85-7f98-4b20-af9e-f710a4f3391c')
+ @decorators.idempotent_id('8726fa85-7f98-4b20-af9e-f710a4f3391c')
def test_keypairsv22_create_list_show(self):
self._test_keypairs_create_list_show()
- @test.idempotent_id('89d59d43-f735-441a-abcf-0601727f47b6')
+ @decorators.idempotent_id('89d59d43-f735-441a-abcf-0601727f47b6')
def test_keypairsv22_create_list_show_with_type(self):
keypair_type = 'x509'
self._test_keypairs_create_list_show(keypair_type=keypair_type)
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 6cc722c..58352bd 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class AbsoluteLimitsTestJSON(base.BaseV2ComputeTest):
@@ -24,7 +24,7 @@
super(AbsoluteLimitsTestJSON, cls).setup_clients()
cls.client = cls.limits_client
- @test.idempotent_id('b54c66af-6ab6-4cf0-a9e5-a0cb58d75e0b')
+ @decorators.idempotent_id('b54c66af-6ab6-4cf0-a9e5-a0cb58d75e0b')
def test_absLimits_get(self):
# To check if all limits are present in the response
limits = self.client.show_limits()['limits']
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index 66bc241..b9ae0c6 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common import tempest_fixtures as fixtures
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -32,7 +33,7 @@
cls.client = cls.limits_client
@test.attr(type=['negative'])
- @test.idempotent_id('215cd465-d8ae-49c9-bf33-9c911913a5c8')
+ @decorators.idempotent_id('215cd465-d8ae-49c9-bf33-9c911913a5c8')
def test_max_image_meta_exceed_limit(self):
# We should not create vm with image meta over maxImageMeta limit
# Get max limit value
diff --git a/tempest/api/compute/security_groups/base.py b/tempest/api/compute/security_groups/base.py
index f70f6d3..cb18775 100644
--- a/tempest/api/compute/security_groups/base.py
+++ b/tempest/api/compute/security_groups/base.py
@@ -14,6 +14,11 @@
# under the License.
from tempest.api.compute import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
class BaseSecurityGroupsTest(base.BaseV2ComputeTest):
@@ -23,3 +28,11 @@
# A network and a subnet will be created for these tests
cls.set_network_resources(network=True, subnet=True)
super(BaseSecurityGroupsTest, cls).setup_credentials()
+
+ @staticmethod
+ def generate_random_security_group_id():
+ if (CONF.service_available.neutron and
+ test.is_extension_enabled('security-group', 'network')):
+ return data_utils.rand_uuid()
+ else:
+ return data_utils.rand_int_id(start=999)
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 60caa19..7658848 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -15,6 +15,7 @@
from tempest.api.compute.security_groups import base
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -57,7 +58,7 @@
"Miss-matched key is %s" % key)
@test.attr(type='smoke')
- @test.idempotent_id('850795d7-d4d3-4e55-b527-a774c0123d3a')
+ @decorators.idempotent_id('850795d7-d4d3-4e55-b527-a774c0123d3a')
@test.services('network')
def test_security_group_rules_create(self):
# Positive test: Creation of Security Group rule
@@ -75,7 +76,7 @@
self.expected['ip_range'] = {'cidr': '0.0.0.0/0'}
self._check_expected_response(rule)
- @test.idempotent_id('7a01873e-3c38-4f30-80be-31a043cfe2fd')
+ @decorators.idempotent_id('7a01873e-3c38-4f30-80be-31a043cfe2fd')
@test.services('network')
def test_security_group_rules_create_with_optional_cidr(self):
# Positive test: Creation of Security Group rule
@@ -98,7 +99,7 @@
self.expected['ip_range'] = {'cidr': cidr}
self._check_expected_response(rule)
- @test.idempotent_id('7f5d2899-7705-4d4b-8458-4505188ffab6')
+ @decorators.idempotent_id('7f5d2899-7705-4d4b-8458-4505188ffab6')
@test.services('network')
def test_security_group_rules_create_with_optional_group_id(self):
# Positive test: Creation of Security Group rule
@@ -127,7 +128,7 @@
self._check_expected_response(rule)
@test.attr(type='smoke')
- @test.idempotent_id('a6154130-5a55-4850-8be4-5e9e796dbf17')
+ @decorators.idempotent_id('a6154130-5a55-4850-8be4-5e9e796dbf17')
@test.services('network')
def test_security_group_rules_list(self):
# Positive test: Created Security Group rules should be
@@ -165,7 +166,7 @@
self.assertTrue(any([i for i in rules if i['id'] == rule1_id]))
self.assertTrue(any([i for i in rules if i['id'] == rule2_id]))
- @test.idempotent_id('fc5c5acf-2091-43a6-a6ae-e42760e9ffaf')
+ @decorators.idempotent_id('fc5c5acf-2091-43a6-a6ae-e42760e9ffaf')
@test.services('network')
def test_security_group_rules_delete_when_peer_group_deleted(self):
# Positive test:rule will delete when peer group deleting
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index 32b3ea3..0312736 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -15,20 +15,10 @@
from tempest.api.compute.security_groups import base
from tempest.common.utils import data_utils
-from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
-CONF = config.CONF
-
-
-def not_existing_id():
- if (CONF.service_available.neutron and
- test.is_extension_enabled('security-group', 'network')):
- return data_utils.rand_uuid()
- else:
- return data_utils.rand_int_id(start=999)
-
class SecurityGroupRulesNegativeTestJSON(base.BaseSecurityGroupsTest):
@@ -38,13 +28,13 @@
cls.rules_client = cls.security_group_rules_client
@test.attr(type=['negative'])
- @test.idempotent_id('1d507e98-7951-469b-82c3-23f1e6b8c254')
+ @decorators.idempotent_id('1d507e98-7951-469b-82c3-23f1e6b8c254')
@test.services('network')
def test_create_security_group_rule_with_non_existent_id(self):
# Negative test: Creation of Security Group rule should FAIL
# with non existent Parent group id
# Adding rules to the non existent Security Group id
- parent_group_id = not_existing_id()
+ parent_group_id = self.generate_random_security_group_id()
ip_protocol = 'tcp'
from_port = 22
to_port = 22
@@ -55,7 +45,7 @@
to_port=to_port)
@test.attr(type=['negative'])
- @test.idempotent_id('2244d7e4-adb7-4ecb-9930-2d77e123ce4f')
+ @decorators.idempotent_id('2244d7e4-adb7-4ecb-9930-2d77e123ce4f')
@test.services('network')
def test_create_security_group_rule_with_invalid_id(self):
# Negative test: Creation of Security Group rule should FAIL
@@ -72,7 +62,7 @@
to_port=to_port)
@test.attr(type=['negative'])
- @test.idempotent_id('8bd56d02-3ffa-4d67-9933-b6b9a01d6089')
+ @decorators.idempotent_id('8bd56d02-3ffa-4d67-9933-b6b9a01d6089')
@test.services('network')
def test_create_security_group_rule_duplicate(self):
# Negative test: Create Security Group rule duplicate should fail
@@ -97,7 +87,7 @@
to_port=to_port)
@test.attr(type=['negative'])
- @test.idempotent_id('84c81249-9f6e-439c-9bbf-cbb0d2cddbdf')
+ @decorators.idempotent_id('84c81249-9f6e-439c-9bbf-cbb0d2cddbdf')
@test.services('network')
def test_create_security_group_rule_with_invalid_ip_protocol(self):
# Negative test: Creation of Security Group rule should FAIL
@@ -117,7 +107,7 @@
to_port=to_port)
@test.attr(type=['negative'])
- @test.idempotent_id('12bbc875-1045-4f7a-be46-751277baedb9')
+ @decorators.idempotent_id('12bbc875-1045-4f7a-be46-751277baedb9')
@test.services('network')
def test_create_security_group_rule_with_invalid_from_port(self):
# Negative test: Creation of Security Group rule should FAIL
@@ -136,7 +126,7 @@
to_port=to_port)
@test.attr(type=['negative'])
- @test.idempotent_id('ff88804d-144f-45d1-bf59-dd155838a43a')
+ @decorators.idempotent_id('ff88804d-144f-45d1-bf59-dd155838a43a')
@test.services('network')
def test_create_security_group_rule_with_invalid_to_port(self):
# Negative test: Creation of Security Group rule should FAIL
@@ -155,7 +145,7 @@
to_port=to_port)
@test.attr(type=['negative'])
- @test.idempotent_id('00296fa9-0576-496a-ae15-fbab843189e0')
+ @decorators.idempotent_id('00296fa9-0576-496a-ae15-fbab843189e0')
@test.services('network')
def test_create_security_group_rule_with_invalid_port_range(self):
# Negative test: Creation of Security Group rule should FAIL
@@ -174,12 +164,12 @@
to_port=to_port)
@test.attr(type=['negative'])
- @test.idempotent_id('56fddcca-dbb8-4494-a0db-96e9f869527c')
+ @decorators.idempotent_id('56fddcca-dbb8-4494-a0db-96e9f869527c')
@test.services('network')
def test_delete_security_group_rule_with_non_existent_id(self):
# Negative test: Deletion of Security Group rule should be FAIL
# with non existent id
- non_existent_rule_id = not_existing_id()
+ non_existent_rule_id = self.generate_random_security_group_id()
self.assertRaises(lib_exc.NotFound,
self.rules_client.delete_security_group_rule,
non_existent_rule_id)
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 4184afa..e070336 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -16,6 +16,7 @@
from tempest.api.compute.security_groups import base
from tempest.common.utils import data_utils
from tempest.common import waiters
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -28,13 +29,13 @@
cls.client = cls.security_groups_client
@test.attr(type='smoke')
- @test.idempotent_id('eb2b087d-633d-4d0d-a7bd-9e6ba35b32de')
+ @decorators.idempotent_id('eb2b087d-633d-4d0d-a7bd-9e6ba35b32de')
@test.services('network')
def test_security_groups_create_list_delete(self):
# Positive test:Should return the list of Security Groups
# Create 3 Security Groups
security_group_list = []
- for i in range(3):
+ for _ in range(3):
body = self.create_security_group()
security_group_list.append(body)
# Fetch all Security Groups and verify the list
@@ -60,7 +61,7 @@
"list" % ', '.join(m_group['name']
for m_group in deleted_sgs))
- @test.idempotent_id('ecc0da4a-2117-48af-91af-993cca39a615')
+ @decorators.idempotent_id('ecc0da4a-2117-48af-91af-993cca39a615')
@test.services('network')
def test_security_group_create_get_delete(self):
# Security Group should be created, fetched and deleted
@@ -82,7 +83,7 @@
self.client.delete_security_group(securitygroup['id'])
self.client.wait_for_resource_deletion(securitygroup['id'])
- @test.idempotent_id('fe4abc0d-83f5-4c50-ad11-57a1127297a2')
+ @decorators.idempotent_id('fe4abc0d-83f5-4c50-ad11-57a1127297a2')
@test.services('network')
def test_server_security_groups(self):
# Checks that security groups may be added and linked to a server
@@ -124,7 +125,7 @@
self.client.delete_security_group(sg['id'])
self.client.delete_security_group(sg2['id'])
- @test.idempotent_id('7d4e1d3c-3209-4d6d-b020-986304ebad1f')
+ @decorators.idempotent_id('7d4e1d3c-3209-4d6d-b020-986304ebad1f')
@test.services('network')
def test_update_security_groups(self):
# Update security group name and description
diff --git a/tempest/api/compute/security_groups/test_security_groups_negative.py b/tempest/api/compute/security_groups/test_security_groups_negative.py
index e6abf28..ad18861 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -37,36 +37,20 @@
super(SecurityGroupsNegativeTestJSON, cls).resource_setup()
cls.neutron_available = CONF.service_available.neutron
- def _generate_a_non_existent_security_group_id(self):
- security_group_id = []
- body = self.client.list_security_groups()['security_groups']
- for i in range(len(body)):
- security_group_id.append(body[i]['id'])
- # Generate a non-existent security group id
- while True:
- if (self.neutron_available and
- test.is_extension_enabled('security-group', 'network')):
- non_exist_id = data_utils.rand_uuid()
- else:
- non_exist_id = data_utils.rand_int_id(start=999)
- if non_exist_id not in security_group_id:
- break
- return non_exist_id
-
@test.attr(type=['negative'])
- @test.idempotent_id('673eaec1-9b3e-48ed-bdf1-2786c1b9661c')
+ @decorators.idempotent_id('673eaec1-9b3e-48ed-bdf1-2786c1b9661c')
@test.services('network')
def test_security_group_get_nonexistent_group(self):
# Negative test:Should not be able to GET the details
# of non-existent Security Group
- non_exist_id = self._generate_a_non_existent_security_group_id()
+ non_exist_id = self.generate_random_security_group_id()
self.assertRaises(lib_exc.NotFound, self.client.show_security_group,
non_exist_id)
@decorators.skip_because(bug="1161411",
condition=CONF.service_available.neutron)
@test.attr(type=['negative'])
- @test.idempotent_id('1759c3cb-b0fc-44b7-86ce-c99236be911d')
+ @decorators.idempotent_id('1759c3cb-b0fc-44b7-86ce-c99236be911d')
@test.services('network')
def test_security_group_create_with_invalid_group_name(self):
# Negative test: Security Group should not be created with group name
@@ -89,7 +73,7 @@
@decorators.skip_because(bug="1161411",
condition=CONF.service_available.neutron)
@test.attr(type=['negative'])
- @test.idempotent_id('777b6f14-aca9-4758-9e84-38783cfa58bc')
+ @decorators.idempotent_id('777b6f14-aca9-4758-9e84-38783cfa58bc')
@test.services('network')
def test_security_group_create_with_invalid_group_description(self):
# Negative test: Security Group should not be created with description
@@ -102,7 +86,7 @@
self.client.create_security_group,
name=s_name, description=s_description)
- @test.idempotent_id('9fdb4abc-6b66-4b27-b89c-eb215a956168')
+ @decorators.idempotent_id('9fdb4abc-6b66-4b27-b89c-eb215a956168')
@testtools.skipIf(CONF.service_available.neutron,
"Neutron allows duplicate names for security groups")
@test.attr(type=['negative'])
@@ -119,7 +103,7 @@
name=s_name, description=s_description)
@test.attr(type=['negative'])
- @test.idempotent_id('36a1629f-c6da-4a26-b8b8-55e7e5d5cd58')
+ @decorators.idempotent_id('36a1629f-c6da-4a26-b8b8-55e7e5d5cd58')
@test.services('network')
def test_delete_the_default_security_group(self):
# Negative test:Deletion of the "default" Security Group should Fail
@@ -135,16 +119,16 @@
default_security_group_id)
@test.attr(type=['negative'])
- @test.idempotent_id('6727c00b-214c-4f9e-9a52-017ac3e98411')
+ @decorators.idempotent_id('6727c00b-214c-4f9e-9a52-017ac3e98411')
@test.services('network')
def test_delete_nonexistent_security_group(self):
# Negative test:Deletion of a non-existent Security Group should fail
- non_exist_id = self._generate_a_non_existent_security_group_id()
+ non_exist_id = self.generate_random_security_group_id()
self.assertRaises(lib_exc.NotFound,
self.client.delete_security_group, non_exist_id)
@test.attr(type=['negative'])
- @test.idempotent_id('1438f330-8fa4-4aeb-8a94-37c250106d7f')
+ @decorators.idempotent_id('1438f330-8fa4-4aeb-8a94-37c250106d7f')
@test.services('network')
def test_delete_security_group_without_passing_id(self):
# Negative test:Deletion of a Security Group with out passing ID
@@ -152,7 +136,7 @@
self.assertRaises(lib_exc.NotFound,
self.client.delete_security_group, '')
- @test.idempotent_id('00579617-fe04-4e1c-9d08-ca7467d2e34b')
+ @decorators.idempotent_id('00579617-fe04-4e1c-9d08-ca7467d2e34b')
@testtools.skipIf(CONF.service_available.neutron,
"Neutron does not check the security group ID")
@test.attr(type=['negative'])
@@ -167,7 +151,7 @@
self.client.update_security_group, sg_id_invalid,
name=s_name, description=s_description)
- @test.idempotent_id('cda8d8b4-59f8-4087-821d-20cf5a03b3b1')
+ @decorators.idempotent_id('cda8d8b4-59f8-4087-821d-20cf5a03b3b1')
@testtools.skipIf(CONF.service_available.neutron,
"Neutron does not check the security group name")
@test.attr(type=['negative'])
@@ -183,7 +167,7 @@
self.client.update_security_group,
securitygroup_id, name=s_new_name)
- @test.idempotent_id('97d12b1c-a610-4194-93f1-ba859e718b45')
+ @decorators.idempotent_id('97d12b1c-a610-4194-93f1-ba859e718b45')
@testtools.skipIf(CONF.service_available.neutron,
"Neutron does not check the security group description")
@test.attr(type=['negative'])
@@ -200,11 +184,11 @@
securitygroup_id, description=s_new_des)
@test.attr(type=['negative'])
- @test.idempotent_id('27edee9c-873d-4da6-a68a-3c256efebe8f')
+ @decorators.idempotent_id('27edee9c-873d-4da6-a68a-3c256efebe8f')
@test.services('network')
def test_update_non_existent_security_group(self):
# Update a non-existent Security Group should Fail
- non_exist_id = self._generate_a_non_existent_security_group_id()
+ non_exist_id = self.generate_random_security_group_id()
s_name = data_utils.rand_name('sg')
s_description = data_utils.rand_name('description')
self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 1731bf3..9bba733 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -184,7 +184,7 @@
self.assertEqual(sorted(list1), sorted(list2))
- @test.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
+ @decorators.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
@test.services('network')
def test_create_list_show_delete_interfaces(self):
server, ifs = self._create_server_get_interfaces()
@@ -221,7 +221,7 @@
self.assertEqual(len(ifs) - 1, len(_ifs))
@test.attr(type='smoke')
- @test.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
+ @decorators.idempotent_id('c7e0e60b-ee45-43d0-abeb-8596fd42a2f9')
@test.services('network')
def test_add_remove_fixed_ip(self):
# Add and Remove the fixed IP to server.
@@ -246,7 +246,7 @@
self.servers_client.remove_fixed_ip(server['id'], address=fixed_ip)
@decorators.skip_because(bug='1607714')
- @test.idempotent_id('2f3a0127-95c7-4977-92d2-bc5aec602fb4')
+ @decorators.idempotent_id('2f3a0127-95c7-4977-92d2-bc5aec602fb4')
def test_reassign_port_between_servers(self):
"""Tests the following:
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 00df86b..82e74ed 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class AZV2TestJSON(base.BaseV2ComputeTest):
@@ -25,7 +25,7 @@
super(AZV2TestJSON, cls).setup_clients()
cls.client = cls.availability_zone_client
- @test.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
+ @decorators.idempotent_id('a8333aa2-205c-449f-a828-d38c2489bf25')
def test_get_availability_zone_list_with_non_admin_user(self):
# List of availability zone with non-administrator user
availability_zone = self.client.list_availability_zones()
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 2dcacb7..5ddae5e 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.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 import decorators
from tempest import test
CONF = config.CONF
@@ -77,7 +78,7 @@
return net
@test.attr(type='smoke')
- @test.idempotent_id('5de47127-9977-400a-936f-abcfbec1218f')
+ @decorators.idempotent_id('5de47127-9977-400a-936f-abcfbec1218f')
def test_verify_server_details(self):
# Verify the specified server attributes are set correctly
self.assertEqual(self.accessIPv4, self.server['accessIPv4'])
@@ -91,7 +92,7 @@
self.assertEqual(self.meta, self.server['metadata'])
@test.attr(type='smoke')
- @test.idempotent_id('9a438d88-10c6-4bcd-8b5b-5b6e25e1346f')
+ @decorators.idempotent_id('9a438d88-10c6-4bcd-8b5b-5b6e25e1346f')
def test_list_servers(self):
# The created server should be in the list of all servers
body = self.client.list_servers()
@@ -99,7 +100,7 @@
found = any([i for i in servers if i['id'] == self.server['id']])
self.assertTrue(found)
- @test.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
+ @decorators.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
def test_list_servers_with_detail(self):
# The created server should be in the detailed list of all servers
body = self.client.list_servers(detail=True)
@@ -107,7 +108,7 @@
found = any([i for i in servers if i['id'] == self.server['id']])
self.assertTrue(found)
- @test.idempotent_id('cbc0f52f-05aa-492b-bdc1-84b575ca294b')
+ @decorators.idempotent_id('cbc0f52f-05aa-492b-bdc1-84b575ca294b')
@testtools.skipUnless(CONF.validation.run_validation,
'Instance validation tests are disabled.')
def test_verify_created_server_vcpus(self):
@@ -123,7 +124,7 @@
servers_client=self.client)
self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
- @test.idempotent_id('ac1ad47f-984b-4441-9274-c9079b7a0666')
+ @decorators.idempotent_id('ac1ad47f-984b-4441-9274-c9079b7a0666')
@testtools.skipUnless(CONF.validation.run_validation,
'Instance validation tests are disabled.')
def test_host_name_is_same_as_server_name(self):
@@ -140,7 +141,7 @@
'hostname "%s" but got "%s".' % (self.name, hostname))
self.assertEqual(self.name.lower(), hostname, msg)
- @test.idempotent_id('ed20d3fb-9d1f-4329-b160-543fbd5d9811')
+ @decorators.idempotent_id('ed20d3fb-9d1f-4329-b160-543fbd5d9811')
@testtools.skipUnless(
test.is_scheduler_filter_enabled("ServerGroupAffinityFilter"),
'ServerGroupAffinityFilter is not available.')
@@ -156,7 +157,7 @@
['server_group'])
self.assertIn(server['id'], server_group['members'])
- @test.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2')
+ @decorators.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2')
@testtools.skipUnless(CONF.service_available.neutron,
'Neutron service must be available.')
def test_verify_multiple_nics_order(self):
@@ -194,7 +195,7 @@
for address, network in zip(addr, networks):
self.assertIn(address, network)
- @test.idempotent_id('1678d144-ed74-43f8-8e57-ab10dbf9b3c2')
+ @decorators.idempotent_id('1678d144-ed74-43f8-8e57-ab10dbf9b3c2')
@testtools.skipUnless(CONF.service_available.neutron,
'Neutron service must be available.')
def test_verify_duplicate_network_nics(self):
@@ -244,7 +245,7 @@
super(ServersWithSpecificFlavorTestJSON, cls).resource_setup()
- @test.idempotent_id('b3c7bcfc-bb5b-4e22-b517-c7f686b802ca')
+ @decorators.idempotent_id('b3c7bcfc-bb5b-4e22-b517-c7f686b802ca')
@testtools.skipUnless(CONF.validation.run_validation,
'Instance validation tests are disabled.')
def test_verify_created_server_ephemeral_disk(self):
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index 07f46c5..83b2e1b 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -19,6 +19,7 @@
from tempest.common import compute
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -34,21 +35,21 @@
super(DeleteServersTestJSON, cls).setup_clients()
cls.client = cls.servers_client
- @test.idempotent_id('9e6e0c87-3352-42f7-9faf-5d6210dbd159')
+ @decorators.idempotent_id('9e6e0c87-3352-42f7-9faf-5d6210dbd159')
def test_delete_server_while_in_building_state(self):
# Delete a server while it's VM state is Building
server = self.create_test_server(wait_until='BUILD')
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
- @test.idempotent_id('925fdfb4-5b13-47ea-ac8a-c36ae6fddb05')
+ @decorators.idempotent_id('925fdfb4-5b13-47ea-ac8a-c36ae6fddb05')
def test_delete_active_server(self):
# Delete a server while it's VM state is Active
server = self.create_test_server(wait_until='ACTIVE')
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
- @test.idempotent_id('546d368c-bb6c-4645-979a-83ed16f3a6be')
+ @decorators.idempotent_id('546d368c-bb6c-4645-979a-83ed16f3a6be')
def test_delete_server_while_in_shutoff_state(self):
# Delete a server while it's VM state is Shutoff
server = self.create_test_server(wait_until='ACTIVE')
@@ -57,7 +58,7 @@
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
- @test.idempotent_id('943bd6e8-4d7a-4904-be83-7a6cc2d4213b')
+ @decorators.idempotent_id('943bd6e8-4d7a-4904-be83-7a6cc2d4213b')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
def test_delete_server_while_in_pause_state(self):
@@ -68,7 +69,7 @@
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
- @test.idempotent_id('1f82ebd3-8253-4f4e-b93f-de9b7df56d8b')
+ @decorators.idempotent_id('1f82ebd3-8253-4f4e-b93f-de9b7df56d8b')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
def test_delete_server_while_in_suspended_state(self):
@@ -79,7 +80,7 @@
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
- @test.idempotent_id('bb0cb402-09dd-4947-b6e5-5e7e1cfa61ad')
+ @decorators.idempotent_id('bb0cb402-09dd-4947-b6e5-5e7e1cfa61ad')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
def test_delete_server_while_in_shelved_state(self):
@@ -90,7 +91,7 @@
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
- @test.idempotent_id('ab0c38b4-cdd8-49d3-9b92-0cb898723c01')
+ @decorators.idempotent_id('ab0c38b4-cdd8-49d3-9b92-0cb898723c01')
@testtools.skipIf(not CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_delete_server_while_in_verify_resize_state(self):
@@ -102,7 +103,7 @@
self.client.delete_server(server['id'])
waiters.wait_for_server_termination(self.client, server['id'])
- @test.idempotent_id('d0f3f0d6-d9b6-4a32-8da4-23015dcab23c')
+ @decorators.idempotent_id('d0f3f0d6-d9b6-4a32-8da4-23015dcab23c')
@test.services('volume')
def test_delete_server_while_in_attached_volume(self):
# Delete a server while a volume is attached to it
@@ -128,7 +129,7 @@
cls.non_admin_client = cls.servers_client
cls.admin_client = cls.os_adm.servers_client
- @test.idempotent_id('99774678-e072-49d1-9d2a-49a59bc56063')
+ @decorators.idempotent_id('99774678-e072-49d1-9d2a-49a59bc56063')
def test_delete_server_while_in_error_state(self):
# Delete a server while it's VM state is error
server = self.create_test_server(wait_until='ACTIVE')
@@ -141,7 +142,7 @@
server['id'],
ignore_error=True)
- @test.idempotent_id('73177903-6737-4f27-a60c-379e8ae8cf48')
+ @decorators.idempotent_id('73177903-6737-4f27-a60c-379e8ae8cf48')
def test_admin_delete_servers_of_others(self):
# Administrator can delete servers of others
server = self.create_test_server(wait_until='ACTIVE')
diff --git a/tempest/api/compute/servers/test_device_tagging.py b/tempest/api/compute/servers/test_device_tagging.py
index 1d502be..ae8f47d 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 import decorators
from tempest.lib import exceptions
from tempest import test
@@ -83,7 +84,7 @@
'net-2-100', 'net-2-200',
'boot', 'other'])
- @test.idempotent_id('a2e65a6c-66f1-4442-aaa8-498c31778d96')
+ @decorators.idempotent_id('a2e65a6c-66f1-4442-aaa8-498c31778d96')
@test.services('network', 'volume', 'image')
def test_device_tagging(self):
# Create volumes
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index ff8ea6e..4709180 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -18,7 +18,7 @@
from tempest.api.compute import base
from tempest.common import waiters
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -46,7 +46,7 @@
server = self.client.show_server(server['id'])['server']
self.assertEqual(disk_config, server['OS-DCF:diskConfig'])
- @test.idempotent_id('bef56b09-2e8c-4883-a370-4950812f430e')
+ @decorators.idempotent_id('bef56b09-2e8c-4883-a370-4950812f430e')
def test_rebuild_server_with_manual_disk_config(self):
# A server should be rebuilt using the manual disk config option
server = self.create_test_server(wait_until='ACTIVE')
@@ -65,7 +65,7 @@
server = self.client.show_server(server['id'])['server']
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
- @test.idempotent_id('9c9fae77-4feb-402f-8450-bf1c8b609713')
+ @decorators.idempotent_id('9c9fae77-4feb-402f-8450-bf1c8b609713')
def test_rebuild_server_with_auto_disk_config(self):
# A server should be rebuilt using the auto disk config option
server = self.create_test_server(wait_until='ACTIVE')
@@ -84,7 +84,7 @@
server = self.client.show_server(server['id'])['server']
self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
- @test.idempotent_id('414e7e93-45b5-44bc-8e03-55159c6bfc97')
+ @decorators.idempotent_id('414e7e93-45b5-44bc-8e03-55159c6bfc97')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_resize_server_from_manual_to_auto(self):
@@ -100,7 +100,7 @@
server = self.client.show_server(server['id'])['server']
self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
- @test.idempotent_id('693d16f3-556c-489a-8bac-3d0ca2490bad')
+ @decorators.idempotent_id('693d16f3-556c-489a-8bac-3d0ca2490bad')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_resize_server_from_auto_to_manual(self):
@@ -116,7 +116,7 @@
server = self.client.show_server(server['id'])['server']
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
- @test.idempotent_id('5ef18867-358d-4de9-b3c9-94d4ba35742f')
+ @decorators.idempotent_id('5ef18867-358d-4de9-b3c9-94d4ba35742f')
def test_update_server_from_auto_to_manual(self):
# A server should be updated from auto to manual disk config
server = self.create_test_server(wait_until='ACTIVE')
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index e50881f..b916a42 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -15,7 +15,7 @@
from tempest.api.compute import base
from tempest.common import waiters
-from tempest import test
+from tempest.lib import decorators
class InstanceActionsTestJSON(base.BaseV2ComputeTest):
@@ -31,7 +31,7 @@
cls.server = cls.create_test_server(wait_until='ACTIVE')
cls.request_id = cls.server.response['x-compute-request-id']
- @test.idempotent_id('77ca5cc5-9990-45e0-ab98-1de8fead201a')
+ @decorators.idempotent_id('77ca5cc5-9990-45e0-ab98-1de8fead201a')
def test_list_instance_actions(self):
# List actions of the provided server
self.client.reboot_server(self.server['id'], type='HARD')
@@ -44,7 +44,7 @@
self.assertEqual(sorted([i['action'] for i in body]),
['create', 'reboot'])
- @test.idempotent_id('aacc71ca-1d70-4aa5-bbf6-0ff71470e43c')
+ @decorators.idempotent_id('aacc71ca-1d70-4aa5-bbf6-0ff71470e43c')
def test_get_instance_action(self):
# Get the action details of the provided server
body = self.client.show_instance_action(
@@ -63,7 +63,7 @@
super(InstanceActionsV221TestJSON, cls).setup_clients()
cls.client = cls.servers_client
- @test.idempotent_id('0a0f85d4-10fa-41f6-bf80-a54fb4aa2ae1')
+ @decorators.idempotent_id('0a0f85d4-10fa-41f6-bf80-a54fb4aa2ae1')
def test_get_list_deleted_instance_actions(self):
# List actions of the deleted server
diff --git a/tempest/api/compute/servers/test_instance_actions_negative.py b/tempest/api/compute/servers/test_instance_actions_negative.py
index 33fed08..85e3281 100644
--- a/tempest/api/compute/servers/test_instance_actions_negative.py
+++ b/tempest/api/compute/servers/test_instance_actions_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -32,7 +33,7 @@
cls.server = cls.create_test_server(wait_until='ACTIVE')
@test.attr(type=['negative'])
- @test.idempotent_id('67e1fce6-7ec2-45c6-92d4-0a8f1a632910')
+ @decorators.idempotent_id('67e1fce6-7ec2-45c6-92d4-0a8f1a632910')
def test_list_instance_actions_non_existent_server(self):
# List actions of the non-existent server id
non_existent_server_id = data_utils.rand_uuid()
@@ -41,7 +42,7 @@
non_existent_server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('0269f40a-6f18-456c-b336-c03623c897f1')
+ @decorators.idempotent_id('0269f40a-6f18-456c-b336-c03623c897f1')
def test_get_instance_action_invalid_request(self):
# Get the action details of the provided server with invalid request
self.assertRaises(lib_exc.NotFound, self.client.show_instance_action,
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 611d5a2..c0a8eae 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -19,7 +19,6 @@
from tempest.common import waiters
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
-from tempest import test
class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
@@ -84,7 +83,7 @@
flavor=cls.flavor_ref_alt,
wait_until='ACTIVE')
- @test.idempotent_id('05e8a8e7-9659-459a-989d-92c2f501f4ba')
+ @decorators.idempotent_id('05e8a8e7-9659-459a-989d-92c2f501f4ba')
@decorators.skip_unless_attr('multiple_images', 'Only one image found')
def test_list_servers_filter_by_image(self):
# Filter the list of servers by image
@@ -96,7 +95,7 @@
self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
- @test.idempotent_id('573637f5-7325-47bb-9144-3476d0416908')
+ @decorators.idempotent_id('573637f5-7325-47bb-9144-3476d0416908')
def test_list_servers_filter_by_flavor(self):
# Filter the list of servers by flavor
params = {'flavor': self.flavor_ref_alt}
@@ -107,7 +106,7 @@
self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
- @test.idempotent_id('9b067a7b-7fee-4f6a-b29c-be43fe18fc5a')
+ @decorators.idempotent_id('9b067a7b-7fee-4f6a-b29c-be43fe18fc5a')
def test_list_servers_filter_by_server_name(self):
# Filter the list of servers by server name
params = {'name': self.s1_name}
@@ -118,7 +117,7 @@
self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
- @test.idempotent_id('ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e')
+ @decorators.idempotent_id('ca78e20e-fddb-4ce6-b7f7-bcbf8605e66e')
def test_list_servers_filter_by_active_status(self):
# Filter the list of servers by server active status
params = {'status': 'active'}
@@ -129,7 +128,7 @@
self.assertIn(self.s2['id'], map(lambda x: x['id'], servers))
self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
- @test.idempotent_id('451dbbb2-f330-4a9f-b0e1-5f5d2cb0f34c')
+ @decorators.idempotent_id('451dbbb2-f330-4a9f-b0e1-5f5d2cb0f34c')
def test_list_servers_filter_by_shutoff_status(self):
# Filter the list of servers by server shutoff status
params = {'status': 'shutoff'}
@@ -146,21 +145,21 @@
self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
self.assertNotIn(self.s3['id'], map(lambda x: x['id'], servers))
- @test.idempotent_id('614cdfc1-d557-4bac-915b-3e67b48eee76')
+ @decorators.idempotent_id('614cdfc1-d557-4bac-915b-3e67b48eee76')
def test_list_servers_filter_by_limit(self):
# Verify only the expected number of servers are returned
params = {'limit': 1}
servers = self.client.list_servers(**params)
self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
- @test.idempotent_id('b1495414-2d93-414c-8019-849afe8d319e')
+ @decorators.idempotent_id('b1495414-2d93-414c-8019-849afe8d319e')
def test_list_servers_filter_by_zero_limit(self):
# Verify only the expected number of servers are returned
params = {'limit': 0}
servers = self.client.list_servers(**params)
self.assertEqual(0, len(servers['servers']))
- @test.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
+ @decorators.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
def test_list_servers_filter_by_exceed_limit(self):
# Verify only the expected number of servers are returned
params = {'limit': 100000}
@@ -169,7 +168,7 @@
self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
len([x for x in servers['servers'] if 'id' in x]))
- @test.idempotent_id('b3304c3b-97df-46d2-8cd3-e2b6659724e7')
+ @decorators.idempotent_id('b3304c3b-97df-46d2-8cd3-e2b6659724e7')
@decorators.skip_unless_attr('multiple_images', 'Only one image found')
def test_list_servers_detailed_filter_by_image(self):
# Filter the detailed list of servers by image
@@ -181,7 +180,7 @@
self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
- @test.idempotent_id('80c574cc-0925-44ba-8602-299028357dd9')
+ @decorators.idempotent_id('80c574cc-0925-44ba-8602-299028357dd9')
def test_list_servers_detailed_filter_by_flavor(self):
# Filter the detailed list of servers by flavor
params = {'flavor': self.flavor_ref_alt}
@@ -192,7 +191,7 @@
self.assertNotIn(self.s2['id'], map(lambda x: x['id'], servers))
self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
- @test.idempotent_id('f9eb2b70-735f-416c-b260-9914ac6181e4')
+ @decorators.idempotent_id('f9eb2b70-735f-416c-b260-9914ac6181e4')
def test_list_servers_detailed_filter_by_server_name(self):
# Filter the detailed list of servers by server name
params = {'name': self.s1_name}
@@ -203,7 +202,7 @@
self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
- @test.idempotent_id('de2612ab-b7dd-4044-b0b1-d2539601911f')
+ @decorators.idempotent_id('de2612ab-b7dd-4044-b0b1-d2539601911f')
def test_list_servers_detailed_filter_by_server_status(self):
# Filter the detailed list of servers by server status
params = {'status': 'active'}
@@ -217,7 +216,7 @@
self.assertEqual(['ACTIVE'] * 3, [x['status'] for x in servers
if x['id'] in test_ids])
- @test.idempotent_id('e9f624ee-92af-4562-8bec-437945a18dcb')
+ @decorators.idempotent_id('e9f624ee-92af-4562-8bec-437945a18dcb')
def test_list_servers_filtered_by_name_wildcard(self):
# List all servers that contains '-instance' in name
params = {'name': '-instance'}
@@ -239,7 +238,7 @@
self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
- @test.idempotent_id('24a89b0c-0d55-4a28-847f-45075f19b27b')
+ @decorators.idempotent_id('24a89b0c-0d55-4a28-847f-45075f19b27b')
def test_list_servers_filtered_by_name_regex(self):
# list of regex that should match s1, s2 and s3
regexes = ['^.*\-instance\-[0-9]+$', '^.*\-instance\-.*$']
@@ -263,7 +262,7 @@
self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
- @test.idempotent_id('43a1242e-7b31-48d1-88f2-3f72aa9f2077')
+ @decorators.idempotent_id('43a1242e-7b31-48d1-88f2-3f72aa9f2077')
def test_list_servers_filtered_by_ip(self):
# Filter servers by ip
# Here should be listed 1 server
@@ -282,7 +281,7 @@
self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
@decorators.skip_because(bug="1540645")
- @test.idempotent_id('a905e287-c35e-42f2-b132-d02b09f3654a')
+ @decorators.idempotent_id('a905e287-c35e-42f2-b132-d02b09f3654a')
def test_list_servers_filtered_by_ip_regex(self):
# Filter servers by regex ip
# List all servers filtered by part of ip address.
@@ -312,7 +311,7 @@
"%s not found in %s, all servers %s" %
(self.s3_name, servers, all_servers))
- @test.idempotent_id('67aec2d0-35fe-4503-9f92-f13272b867ed')
+ @decorators.idempotent_id('67aec2d0-35fe-4503-9f92-f13272b867ed')
def test_list_servers_detailed_limit_results(self):
# Verify only the expected number of detailed results are returned
params = {'limit': 1}
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 3e408d2..594c5c9 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common import waiters
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -36,7 +37,7 @@
# tearDownClass method of the super-class.
cls.existing_fixtures = []
cls.deleted_fixtures = []
- for x in range(2):
+ for _ in range(2):
srv = cls.create_test_server(wait_until='ACTIVE')
cls.existing_fixtures.append(srv)
@@ -46,7 +47,7 @@
cls.deleted_fixtures.append(srv)
@test.attr(type=['negative'])
- @test.idempotent_id('24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f')
+ @decorators.idempotent_id('24a26f1a-1ddc-4eea-b0d7-a90cc874ad8f')
def test_list_servers_with_a_deleted_server(self):
# Verify deleted servers do not show by default in list servers
# List servers and verify server not returned
@@ -58,7 +59,7 @@
self.assertEqual([], actual)
@test.attr(type=['negative'])
- @test.idempotent_id('ff01387d-c7ad-47b4-ae9e-64fa214638fe')
+ @decorators.idempotent_id('ff01387d-c7ad-47b4-ae9e-64fa214638fe')
def test_list_servers_by_non_existing_image(self):
# Listing servers for a non existing image returns empty list
body = self.client.list_servers(image='non_existing_image')
@@ -66,7 +67,7 @@
self.assertEqual([], servers)
@test.attr(type=['negative'])
- @test.idempotent_id('5913660b-223b-44d4-a651-a0fbfd44ca75')
+ @decorators.idempotent_id('5913660b-223b-44d4-a651-a0fbfd44ca75')
def test_list_servers_by_non_existing_flavor(self):
# Listing servers by non existing flavor returns empty list
body = self.client.list_servers(flavor='non_existing_flavor')
@@ -74,7 +75,7 @@
self.assertEqual([], servers)
@test.attr(type=['negative'])
- @test.idempotent_id('e2c77c4a-000a-4af3-a0bd-629a328bde7c')
+ @decorators.idempotent_id('e2c77c4a-000a-4af3-a0bd-629a328bde7c')
def test_list_servers_by_non_existing_server_name(self):
# Listing servers for a non existent server name returns empty list
body = self.client.list_servers(name='non_existing_server_name')
@@ -82,21 +83,21 @@
self.assertEqual([], servers)
@test.attr(type=['negative'])
- @test.idempotent_id('fcdf192d-0f74-4d89-911f-1ec002b822c4')
+ @decorators.idempotent_id('fcdf192d-0f74-4d89-911f-1ec002b822c4')
def test_list_servers_status_non_existing(self):
# Return an empty list when invalid status is specified
body = self.client.list_servers(status='non_existing_status')
servers = body['servers']
self.assertEqual([], servers)
- @test.idempotent_id('12c80a9f-2dec-480e-882b-98ba15757659')
+ @decorators.idempotent_id('12c80a9f-2dec-480e-882b-98ba15757659')
def test_list_servers_by_limits(self):
# List servers by specifying limits
body = self.client.list_servers(limit=1)
self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
@test.attr(type=['negative'])
- @test.idempotent_id('d47c17fb-eebd-4287-8e95-f20a7e627b18')
+ @decorators.idempotent_id('d47c17fb-eebd-4287-8e95-f20a7e627b18')
def test_list_servers_by_limits_greater_than_actual_count(self):
# Gather the complete list of servers in the project for reference
full_list = self.client.list_servers()['servers']
@@ -106,21 +107,21 @@
self.assertEqual(len(full_list), len(body['servers']))
@test.attr(type=['negative'])
- @test.idempotent_id('679bc053-5e70-4514-9800-3dfab1a380a6')
+ @decorators.idempotent_id('679bc053-5e70-4514-9800-3dfab1a380a6')
def test_list_servers_by_limits_pass_string(self):
# Return an error if a string value is passed for limit
self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
limit='testing')
@test.attr(type=['negative'])
- @test.idempotent_id('62610dd9-4713-4ee0-8beb-fd2c1aa7f950')
+ @decorators.idempotent_id('62610dd9-4713-4ee0-8beb-fd2c1aa7f950')
def test_list_servers_by_limits_pass_negative_value(self):
# Return an error if a negative value for limit is passed
self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
limit=-1)
@test.attr(type=['negative'])
- @test.idempotent_id('87d12517-e20a-4c9c-97b6-dd1628d6d6c9')
+ @decorators.idempotent_id('87d12517-e20a-4c9c-97b6-dd1628d6d6c9')
def test_list_servers_by_changes_since_invalid_date(self):
# Return an error when invalid date format is passed
params = {'changes-since': '2011/01/01'}
@@ -128,7 +129,7 @@
**params)
@test.attr(type=['negative'])
- @test.idempotent_id('74745ad8-b346-45b5-b9b8-509d7447fc1f')
+ @decorators.idempotent_id('74745ad8-b346-45b5-b9b8-509d7447fc1f')
def test_list_servers_by_changes_since_future_date(self):
# Return an empty list when a date in the future is passed
changes_since = {'changes-since': '2051-01-01T12:34:00Z'}
@@ -136,7 +137,7 @@
self.assertEqual(0, len(body['servers']))
@test.attr(type=['negative'])
- @test.idempotent_id('93055106-2d34-46fe-af68-d9ddbf7ee570')
+ @decorators.idempotent_id('93055106-2d34-46fe-af68-d9ddbf7ee570')
def test_list_servers_detail_server_is_deleted(self):
# Server details are not listed for a deleted server
deleted_ids = [s['id'] for s in self.deleted_fixtures]
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index 9fc30f9..7e55b12 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -14,12 +14,12 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class MultipleCreateTestJSON(base.BaseV2ComputeTest):
- @test.idempotent_id('61e03386-89c3-449c-9bb1-a06f423fd9d1')
+ @decorators.idempotent_id('61e03386-89c3-449c-9bb1-a06f423fd9d1')
def test_multiple_create(self):
body = self.create_test_server(wait_until='ACTIVE',
min_count=1,
@@ -29,7 +29,7 @@
# contains return_reservation_id=False
self.assertNotIn('reservation_id', body)
- @test.idempotent_id('864777fb-2f1e-44e3-b5b9-3eb6fa84f2f7')
+ @decorators.idempotent_id('864777fb-2f1e-44e3-b5b9-3eb6fa84f2f7')
def test_multiple_create_with_reservation_return(self):
body = self.create_test_server(wait_until='ACTIVE',
min_count=1,
diff --git a/tempest/api/compute/servers/test_multiple_create_negative.py b/tempest/api/compute/servers/test_multiple_create_negative.py
index d9fb4ca..675cbee 100644
--- a/tempest/api/compute/servers/test_multiple_create_negative.py
+++ b/tempest/api/compute/servers/test_multiple_create_negative.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -21,35 +22,35 @@
class MultipleCreateNegativeTestJSON(base.BaseV2ComputeTest):
@test.attr(type=['negative'])
- @test.idempotent_id('daf29d8d-e928-4a01-9a8c-b129603f3fc0')
+ @decorators.idempotent_id('daf29d8d-e928-4a01-9a8c-b129603f3fc0')
def test_min_count_less_than_one(self):
invalid_min_count = 0
self.assertRaises(lib_exc.BadRequest, self.create_test_server,
min_count=invalid_min_count)
@test.attr(type=['negative'])
- @test.idempotent_id('999aa722-d624-4423-b813-0d1ac9884d7a')
+ @decorators.idempotent_id('999aa722-d624-4423-b813-0d1ac9884d7a')
def test_min_count_non_integer(self):
invalid_min_count = 2.5
self.assertRaises(lib_exc.BadRequest, self.create_test_server,
min_count=invalid_min_count)
@test.attr(type=['negative'])
- @test.idempotent_id('a6f9c2ab-e060-4b82-b23c-4532cb9390ff')
+ @decorators.idempotent_id('a6f9c2ab-e060-4b82-b23c-4532cb9390ff')
def test_max_count_less_than_one(self):
invalid_max_count = 0
self.assertRaises(lib_exc.BadRequest, self.create_test_server,
max_count=invalid_max_count)
@test.attr(type=['negative'])
- @test.idempotent_id('9c5698d1-d7af-4c80-b971-9d403135eea2')
+ @decorators.idempotent_id('9c5698d1-d7af-4c80-b971-9d403135eea2')
def test_max_count_non_integer(self):
invalid_max_count = 2.5
self.assertRaises(lib_exc.BadRequest, self.create_test_server,
max_count=invalid_max_count)
@test.attr(type=['negative'])
- @test.idempotent_id('476da616-f1ef-4271-a9b1-b9fc87727cdf')
+ @decorators.idempotent_id('476da616-f1ef-4271-a9b1-b9fc87727cdf')
def test_max_count_less_than_min_count(self):
min_count = 3
max_count = 2
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 0334eff..6160024 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -75,7 +75,7 @@
super(ServerActionsTestJSON, cls).resource_setup()
cls.server_id = cls.rebuild_server(None, validatable=True)
- @test.idempotent_id('6158df09-4b82-4ab3-af6d-29cf36af858d')
+ @decorators.idempotent_id('6158df09-4b82-4ab3-af6d-29cf36af858d')
@testtools.skipUnless(CONF.compute_feature_enabled.change_password,
'Change password not available.')
def test_change_server_password(self):
@@ -134,13 +134,13 @@
'%s > %s' % (new_boot_time, boot_time))
@test.attr(type='smoke')
- @test.idempotent_id('2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32')
+ @decorators.idempotent_id('2cb1baf6-ac8d-4429-bf0d-ba8a0ba53e32')
def test_reboot_server_hard(self):
# The server should be power cycled
self._test_reboot_server('HARD')
@decorators.skip_because(bug="1014647")
- @test.idempotent_id('4640e3ef-a5df-482e-95a1-ceeeb0faa84d')
+ @decorators.idempotent_id('4640e3ef-a5df-482e-95a1-ceeeb0faa84d')
def test_reboot_server_soft(self):
# The server should be signaled to reboot gracefully
self._test_reboot_server('SOFT')
@@ -154,7 +154,7 @@
.format(image_ref, rebuilt_server['image']['id']))
self.assertEqual(image_ref, rebuilt_server['image']['id'], msg)
- @test.idempotent_id('aaa6cdf3-55a7-461a-add9-1c8596b9a07c')
+ @decorators.idempotent_id('aaa6cdf3-55a7-461a-add9-1c8596b9a07c')
def test_rebuild_server(self):
# The server should be rebuilt using the provided image and data
meta = {'rebuild': 'server'}
@@ -202,7 +202,7 @@
servers_client=self.client)
linux_client.validate_authentication()
- @test.idempotent_id('30449a88-5aff-4f9b-9866-6ee9b17f906d')
+ @decorators.idempotent_id('30449a88-5aff-4f9b-9866-6ee9b17f906d')
def test_rebuild_server_in_stop_state(self):
# The server in stop state should be rebuilt using the provided
# image and remain in SHUTOFF state
@@ -234,7 +234,7 @@
self.client.start_server(self.server_id)
- @test.idempotent_id('b68bd8d6-855d-4212-b59b-2e704044dace')
+ @decorators.idempotent_id('b68bd8d6-855d-4212-b59b-2e704044dace')
@test.services('volume')
def test_rebuild_server_with_volume_attached(self):
# create a new volume and attach it to the server
@@ -281,19 +281,19 @@
# NOTE(mriedem): tearDown requires the server to be started.
self.client.start_server(self.server_id)
- @test.idempotent_id('1499262a-9328-4eda-9068-db1ac57498d2')
+ @decorators.idempotent_id('1499262a-9328-4eda-9068-db1ac57498d2')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_resize_server_confirm(self):
self._test_resize_server_confirm(stop=False)
- @test.idempotent_id('138b131d-66df-48c9-a171-64f45eb92962')
+ @decorators.idempotent_id('138b131d-66df-48c9-a171-64f45eb92962')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_resize_server_confirm_from_stopped(self):
self._test_resize_server_confirm(stop=True)
- @test.idempotent_id('c03aab19-adb1-44f5-917d-c419577e9e68')
+ @decorators.idempotent_id('c03aab19-adb1-44f5-917d-c419577e9e68')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
def test_resize_server_revert(self):
@@ -313,7 +313,7 @@
server = self.client.show_server(self.server_id)['server']
self.assertEqual(self.flavor_ref, server['flavor']['id'])
- @test.idempotent_id('b963d4f1-94b3-4c40-9e97-7b583f46e470')
+ @decorators.idempotent_id('b963d4f1-94b3-4c40-9e97-7b583f46e470')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
'Snapshotting not available, backup not possible.')
@test.services('image')
@@ -428,7 +428,7 @@
lines = len(output.split('\n'))
self.assertEqual(lines, 10)
- @test.idempotent_id('4b8867e6-fffa-4d54-b1d1-6fdda57be2f3')
+ @decorators.idempotent_id('4b8867e6-fffa-4d54-b1d1-6fdda57be2f3')
@testtools.skipUnless(CONF.compute_feature_enabled.console_output,
'Console output not supported.')
def test_get_console_output(self):
@@ -444,7 +444,7 @@
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
self.wait_for(self._get_output)
- @test.idempotent_id('89104062-69d8-4b19-a71b-f47b7af093d7')
+ @decorators.idempotent_id('89104062-69d8-4b19-a71b-f47b7af093d7')
@testtools.skipUnless(CONF.compute_feature_enabled.console_output,
'Console output not supported.')
def test_get_console_output_with_unlimited_size(self):
@@ -462,7 +462,7 @@
self.wait_for(_check_full_length_console_log)
- @test.idempotent_id('5b65d4e7-4ecd-437c-83c0-d6b79d927568')
+ @decorators.idempotent_id('5b65d4e7-4ecd-437c-83c0-d6b79d927568')
@testtools.skipUnless(CONF.compute_feature_enabled.console_output,
'Console output not supported.')
def test_get_console_output_server_id_in_shutoff_status(self):
@@ -479,7 +479,7 @@
waiters.wait_for_server_status(self.client, temp_server_id, 'SHUTOFF')
self.wait_for(self._get_output)
- @test.idempotent_id('bd61a9fd-062f-4670-972b-2d6c3e3b9e73')
+ @decorators.idempotent_id('bd61a9fd-062f-4670-972b-2d6c3e3b9e73')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
def test_pause_unpause_server(self):
@@ -488,7 +488,7 @@
self.client.unpause_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
- @test.idempotent_id('0d8ee21e-b749-462d-83da-b85b41c86c7f')
+ @decorators.idempotent_id('0d8ee21e-b749-462d-83da-b85b41c86c7f')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
def test_suspend_resume_server(self):
@@ -498,7 +498,7 @@
self.client.resume_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
- @test.idempotent_id('77eba8e0-036e-4635-944b-f7a8f3b78dc9')
+ @decorators.idempotent_id('77eba8e0-036e-4635-944b-f7a8f3b78dc9')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
def test_shelve_unshelve_server(self):
@@ -515,14 +515,14 @@
self.client.unshelve_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
- @test.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
+ @decorators.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
def test_stop_start_server(self):
self.client.stop_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
self.client.start_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
- @test.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
+ @decorators.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
def test_lock_unlock_server(self):
# Lock the server,try server stop(exceptions throw),unlock it and retry
self.client.lock_server(self.server_id)
@@ -545,7 +545,7 @@
self.assertNotEqual('None', parsed_url.hostname)
self.assertIn(parsed_url.scheme, valid_scheme)
- @test.idempotent_id('c6bc11bf-592e-4015-9319-1c98dc64daf5')
+ @decorators.idempotent_id('c6bc11bf-592e-4015-9319-1c98dc64daf5')
@testtools.skipUnless(CONF.compute_feature_enabled.vnc_console,
'VNC Console feature is disabled.')
def test_get_vnc_console(self):
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 549ba03..dfda51b 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest import test
@@ -37,7 +38,7 @@
cls.server = cls.create_test_server(wait_until='ACTIVE')
@test.attr(type='smoke')
- @test.idempotent_id('6eb718c0-02d9-4d5e-acd1-4e0c269cef39')
+ @decorators.idempotent_id('6eb718c0-02d9-4d5e-acd1-4e0c269cef39')
@test.services('network')
def test_list_server_addresses(self):
# All public and private addresses for
@@ -55,7 +56,7 @@
self.assertTrue(address['version'])
@test.attr(type='smoke')
- @test.idempotent_id('87bbc374-5538-4f64-b673-2b0e4443cc30')
+ @decorators.idempotent_id('87bbc374-5538-4f64-b673-2b0e4443cc30')
@test.services('network')
def test_list_server_addresses_by_network(self):
# Providing a network type should filter
diff --git a/tempest/api/compute/servers/test_server_addresses_negative.py b/tempest/api/compute/servers/test_server_addresses_negative.py
index b4753e1..1884e4f 100644
--- a/tempest/api/compute/servers/test_server_addresses_negative.py
+++ b/tempest/api/compute/servers/test_server_addresses_negative.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -36,7 +37,7 @@
cls.server = cls.create_test_server(wait_until='ACTIVE')
@test.attr(type=['negative'])
- @test.idempotent_id('02c3f645-2d2e-4417-8525-68c0407d001b')
+ @decorators.idempotent_id('02c3f645-2d2e-4417-8525-68c0407d001b')
@test.services('network')
def test_list_server_addresses_invalid_server_id(self):
# List addresses request should fail if server id not in system
@@ -44,7 +45,7 @@
'999')
@test.attr(type=['negative'])
- @test.idempotent_id('a2ab5144-78c0-4942-a0ed-cc8edccfd9ba')
+ @decorators.idempotent_id('a2ab5144-78c0-4942-a0ed-cc8edccfd9ba')
@test.services('network')
def test_list_server_addresses_by_network_neg(self):
# List addresses by network should fail if network name not valid
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index bc49e7b..6679b58 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest import test
@@ -67,23 +68,23 @@
server_group = self._create_server_group(name, policy)
self._delete_server_group(server_group)
- @test.idempotent_id('5dc57eda-35b7-4af7-9e5f-3c2be3d2d68b')
+ @decorators.idempotent_id('5dc57eda-35b7-4af7-9e5f-3c2be3d2d68b')
def test_create_delete_server_group_with_affinity_policy(self):
# Create and Delete the server-group with affinity policy
self._create_delete_server_group(self.policy)
- @test.idempotent_id('3645a102-372f-4140-afad-13698d850d23')
+ @decorators.idempotent_id('3645a102-372f-4140-afad-13698d850d23')
def test_create_delete_server_group_with_anti_affinity_policy(self):
# Create and Delete the server-group with anti-affinity policy
policy = ['anti-affinity']
self._create_delete_server_group(policy)
- @test.idempotent_id('154dc5a4-a2fe-44b5-b99e-f15806a4a113')
+ @decorators.idempotent_id('154dc5a4-a2fe-44b5-b99e-f15806a4a113')
def test_create_delete_multiple_server_groups_with_same_name_policy(self):
# Create and Delete the server-groups with same name and same policy
server_groups = []
server_group_name = data_utils.rand_name('server-group')
- for i in range(0, 2):
+ for _ in range(0, 2):
server_groups.append(self._create_server_group(server_group_name,
self.policy))
for key in ['name', 'policies']:
@@ -93,14 +94,14 @@
for i in range(0, 2):
self._delete_server_group(server_groups[i])
- @test.idempotent_id('b3545034-dd78-48f0-bdc2-a4adfa6d0ead')
+ @decorators.idempotent_id('b3545034-dd78-48f0-bdc2-a4adfa6d0ead')
def test_show_server_group(self):
# Get the server-group
body = self.client.show_server_group(
self.created_server_group['id'])['server_group']
self.assertEqual(self.created_server_group, body)
- @test.idempotent_id('d4874179-27b4-4d7d-80e4-6c560cdfe321')
+ @decorators.idempotent_id('d4874179-27b4-4d7d-80e4-6c560cdfe321')
def test_list_server_groups(self):
# List the server-group
body = self.client.list_server_groups()['server_groups']
diff --git a/tempest/api/compute/servers/test_server_metadata.py b/tempest/api/compute/servers/test_server_metadata.py
index 847b7a1..f77e7d3 100644
--- a/tempest/api/compute/servers/test_server_metadata.py
+++ b/tempest/api/compute/servers/test_server_metadata.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class ServerMetadataTestJSON(base.BaseV2ComputeTest):
@@ -34,7 +34,7 @@
meta = {'key1': 'value1', 'key2': 'value2'}
self.client.set_server_metadata(self.server['id'], meta)['metadata']
- @test.idempotent_id('479da087-92b3-4dcf-aeb3-fd293b2d14ce')
+ @decorators.idempotent_id('479da087-92b3-4dcf-aeb3-fd293b2d14ce')
def test_list_server_metadata(self):
# All metadata key/value pairs for a server should be returned
resp_metadata = (self.client.list_server_metadata(self.server['id'])
@@ -44,7 +44,7 @@
expected = {'key1': 'value1', 'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
- @test.idempotent_id('211021f6-21de-4657-a68f-908878cfe251')
+ @decorators.idempotent_id('211021f6-21de-4657-a68f-908878cfe251')
def test_set_server_metadata(self):
# The server's metadata should be replaced with the provided values
# Create a new set of metadata for the server
@@ -58,7 +58,7 @@
['metadata'])
self.assertEqual(resp_metadata, req_metadata)
- @test.idempotent_id('344d981e-0c33-4997-8a5d-6c1d803e4134')
+ @decorators.idempotent_id('344d981e-0c33-4997-8a5d-6c1d803e4134')
def test_update_server_metadata(self):
# The server's metadata values should be updated to the
# provided values
@@ -71,7 +71,7 @@
expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
self.assertEqual(expected, resp_metadata)
- @test.idempotent_id('0f58d402-e34a-481d-8af8-b392b17426d9')
+ @decorators.idempotent_id('0f58d402-e34a-481d-8af8-b392b17426d9')
def test_update_metadata_empty_body(self):
# The original metadata should not be lost if empty metadata body is
# passed
@@ -82,14 +82,14 @@
expected = {'key1': 'value1', 'key2': 'value2'}
self.assertEqual(expected, resp_metadata)
- @test.idempotent_id('3043c57d-7e0e-49a6-9a96-ad569c265e6a')
+ @decorators.idempotent_id('3043c57d-7e0e-49a6-9a96-ad569c265e6a')
def test_get_server_metadata_item(self):
# The value for a specific metadata key should be returned
meta = self.client.show_server_metadata_item(self.server['id'],
'key2')['meta']
self.assertEqual('value2', meta['key2'])
- @test.idempotent_id('58c02d4f-5c67-40be-8744-d3fa5982eb1c')
+ @decorators.idempotent_id('58c02d4f-5c67-40be-8744-d3fa5982eb1c')
def test_set_server_metadata_item(self):
# The item's value should be updated to the provided value
# Update the metadata value
@@ -102,7 +102,7 @@
expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
self.assertEqual(expected, resp_metadata)
- @test.idempotent_id('127642d6-4c7b-4486-b7cd-07265a378658')
+ @decorators.idempotent_id('127642d6-4c7b-4486-b7cd-07265a378658')
def test_delete_server_metadata_item(self):
# The metadata value/key pair should be deleted from the server
self.client.delete_server_metadata_item(self.server['id'], 'key1')
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index 62b8962..92ffa86 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -33,7 +34,7 @@
cls.server = cls.create_test_server(metadata={}, wait_until='ACTIVE')
@test.attr(type=['negative'])
- @test.idempotent_id('fe114a8f-3a57-4eff-9ee2-4e14628df049')
+ @decorators.idempotent_id('fe114a8f-3a57-4eff-9ee2-4e14628df049')
def test_server_create_metadata_key_too_long(self):
# Attempt to start a server with a meta-data key that is > 255
# characters
@@ -49,7 +50,7 @@
# no teardown - all creates should fail
@test.attr(type=['negative'])
- @test.idempotent_id('92431555-4d8b-467c-b95b-b17daa5e57ff')
+ @decorators.idempotent_id('92431555-4d8b-467c-b95b-b17daa5e57ff')
def test_create_server_metadata_blank_key(self):
# Blank key should trigger an error.
meta = {'': 'data1'}
@@ -58,7 +59,7 @@
metadata=meta)
@test.attr(type=['negative'])
- @test.idempotent_id('4d9cd7a3-2010-4b41-b8fe-3bbf0b169466')
+ @decorators.idempotent_id('4d9cd7a3-2010-4b41-b8fe-3bbf0b169466')
def test_server_metadata_non_existent_server(self):
# GET on a non-existent server should not succeed
non_existent_server_id = data_utils.rand_uuid()
@@ -68,7 +69,7 @@
'test2')
@test.attr(type=['negative'])
- @test.idempotent_id('f408e78e-3066-4097-9299-3b0182da812e')
+ @decorators.idempotent_id('f408e78e-3066-4097-9299-3b0182da812e')
def test_list_server_metadata_non_existent_server(self):
# List metadata on a non-existent server should not succeed
non_existent_server_id = data_utils.rand_uuid()
@@ -77,7 +78,7 @@
non_existent_server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('0025fbd6-a4ba-4cde-b8c2-96805dcfdabc')
+ @decorators.idempotent_id('0025fbd6-a4ba-4cde-b8c2-96805dcfdabc')
def test_wrong_key_passed_in_body(self):
# Raise BadRequest if key in uri does not match
# the key passed in body.
@@ -87,7 +88,7 @@
self.server['id'], 'key', meta)
@test.attr(type=['negative'])
- @test.idempotent_id('0df38c2a-3d4e-4db5-98d8-d4d9fa843a12')
+ @decorators.idempotent_id('0df38c2a-3d4e-4db5-98d8-d4d9fa843a12')
def test_set_metadata_non_existent_server(self):
# Set metadata on a non-existent server should not succeed
non_existent_server_id = data_utils.rand_uuid()
@@ -98,7 +99,7 @@
meta)
@test.attr(type=['negative'])
- @test.idempotent_id('904b13dc-0ef2-4e4c-91cd-3b4a0f2f49d8')
+ @decorators.idempotent_id('904b13dc-0ef2-4e4c-91cd-3b4a0f2f49d8')
def test_update_metadata_non_existent_server(self):
# An update should not happen for a non-existent server
non_existent_server_id = data_utils.rand_uuid()
@@ -109,7 +110,7 @@
meta)
@test.attr(type=['negative'])
- @test.idempotent_id('a452f38c-05c2-4b47-bd44-a4f0bf5a5e48')
+ @decorators.idempotent_id('a452f38c-05c2-4b47-bd44-a4f0bf5a5e48')
def test_update_metadata_with_blank_key(self):
# Blank key should trigger an error
meta = {'': 'data1'}
@@ -118,7 +119,7 @@
self.server['id'], meta=meta)
@test.attr(type=['negative'])
- @test.idempotent_id('6bbd88e1-f8b3-424d-ba10-ae21c45ada8d')
+ @decorators.idempotent_id('6bbd88e1-f8b3-424d-ba10-ae21c45ada8d')
def test_delete_metadata_non_existent_server(self):
# Should not be able to delete metadata item from a non-existent server
non_existent_server_id = data_utils.rand_uuid()
@@ -128,7 +129,7 @@
'd')
@test.attr(type=['negative'])
- @test.idempotent_id('d8c0a210-a5c3-4664-be04-69d96746b547')
+ @decorators.idempotent_id('d8c0a210-a5c3-4664-be04-69d96746b547')
def test_metadata_items_limit(self):
# A 403 Forbidden or 413 Overlimit (old behaviour) exception
# will be raised while exceeding metadata items limit for
@@ -154,7 +155,7 @@
self.server['id'], req_metadata)
@test.attr(type=['negative'])
- @test.idempotent_id('96100343-7fa9-40d8-80fa-d29ef588ce1c')
+ @decorators.idempotent_id('96100343-7fa9-40d8-80fa-d29ef588ce1c')
def test_set_server_metadata_blank_key(self):
# Raise a bad request error for blank key.
# set_server_metadata will replace all metadata with new value
@@ -164,7 +165,7 @@
self.server['id'], meta=meta)
@test.attr(type=['negative'])
- @test.idempotent_id('64a91aee-9723-4863-be44-4c9d9f1e7d0e')
+ @decorators.idempotent_id('64a91aee-9723-4863-be44-4c9d9f1e7d0e')
def test_set_server_metadata_missing_metadata(self):
# Raise a bad request error for a missing metadata field
# set_server_metadata will replace all metadata with new value
diff --git a/tempest/api/compute/servers/test_server_password.py b/tempest/api/compute/servers/test_server_password.py
index 9b41708..e7591a5 100644
--- a/tempest/api/compute/servers/test_server_password.py
+++ b/tempest/api/compute/servers/test_server_password.py
@@ -15,7 +15,7 @@
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class ServerPasswordTestJSON(base.BaseV2ComputeTest):
@@ -30,10 +30,10 @@
super(ServerPasswordTestJSON, cls).resource_setup()
cls.server = cls.create_test_server(wait_until="ACTIVE")
- @test.idempotent_id('f83b582f-62a8-4f22-85b0-0dee50ff783a')
+ @decorators.idempotent_id('f83b582f-62a8-4f22-85b0-0dee50ff783a')
def test_get_server_password(self):
self.client.show_password(self.server['id'])
- @test.idempotent_id('f8229e8b-b625-4493-800a-bde86ac611ea')
+ @decorators.idempotent_id('f8229e8b-b625-4493-800a-bde86ac611ea')
def test_delete_server_password(self):
self.client.delete_password(self.server['id'])
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index ab291b4..957d24a 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -20,8 +20,8 @@
from tempest.common import waiters
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
-from tempest import test
CONF = config.CONF
@@ -50,7 +50,7 @@
cls.client = cls.servers_client
cls.user_client = cls.limits_client
- @test.idempotent_id('3cfe87fd-115b-4a02-b942-7dc36a337fdf')
+ @decorators.idempotent_id('3cfe87fd-115b-4a02-b942-7dc36a337fdf')
def test_create_server_with_personality(self):
file_contents = 'This is a test file.'
file_path = '/test.txt'
@@ -73,7 +73,7 @@
linux_client.exec_command(
'sudo cat %s' % file_path))
- @test.idempotent_id('128966d8-71fc-443c-8cab-08e24114ecc9')
+ @decorators.idempotent_id('128966d8-71fc-443c-8cab-08e24114ecc9')
def test_rebuild_server_with_personality(self):
server = self.create_test_server(wait_until='ACTIVE', validatable=True)
server_id = server['id']
@@ -87,7 +87,7 @@
self.assertEqual(self.image_ref_alt,
rebuilt_server['server']['image']['id'])
- @test.idempotent_id('176cd8c9-b9e8-48ee-a480-180beab292bf')
+ @decorators.idempotent_id('176cd8c9-b9e8-48ee-a480-180beab292bf')
def test_personality_files_exceed_limit(self):
# Server creation should fail if greater than the maximum allowed
# number of files are injected into the server.
@@ -107,7 +107,7 @@
self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
self.create_test_server, personality=personality)
- @test.idempotent_id('52f12ee8-5180-40cc-b417-31572ea3d555')
+ @decorators.idempotent_id('52f12ee8-5180-40cc-b417-31572ea3d555')
def test_can_create_server_with_max_number_personality_files(self):
# Server should be created successfully if maximum allowed number of
# files is injected into the server during creation.
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 9834d02..5db7f4f 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -17,7 +17,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -74,7 +74,7 @@
waiters.wait_for_server_status(self.servers_client, server_id,
'ACTIVE')
- @test.idempotent_id('fd032140-714c-42e4-a8fd-adcd8df06be6')
+ @decorators.idempotent_id('fd032140-714c-42e4-a8fd-adcd8df06be6')
def test_rescue_unrescue_instance(self):
self.servers_client.rescue_server(
self.server_id, adminPass=self.password)
@@ -84,7 +84,7 @@
waiters.wait_for_server_status(self.servers_client, self.server_id,
'ACTIVE')
- @test.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
+ @decorators.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
def test_rescued_vm_associate_dissociate_floating_ip(self):
# Rescue the server
self.servers_client.rescue_server(
@@ -102,7 +102,7 @@
client.disassociate_floating_ip_from_server(self.floating_ip,
self.server_id)
- @test.idempotent_id('affca41f-7195-492d-8065-e09eee245404')
+ @decorators.idempotent_id('affca41f-7195-492d-8065-e09eee245404')
def test_rescued_vm_add_remove_security_group(self):
# Rescue the server
self.servers_client.rescue_server(
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 41b648c..c3a8c36 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -19,6 +19,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -70,7 +71,7 @@
waiters.wait_for_server_status(self.servers_client,
server_id, 'ACTIVE')
- @test.idempotent_id('cc3a883f-43c0-4fb6-a9bb-5579d64984ed')
+ @decorators.idempotent_id('cc3a883f-43c0-4fb6-a9bb-5579d64984ed')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
@test.attr(type=['negative'])
@@ -85,13 +86,13 @@
self.server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('db22b618-f157-4566-a317-1b6d467a8094')
+ @decorators.idempotent_id('db22b618-f157-4566-a317-1b6d467a8094')
def test_rescued_vm_reboot(self):
self.assertRaises(lib_exc.Conflict, self.servers_client.reboot_server,
self.rescue_id, type='HARD')
@test.attr(type=['negative'])
- @test.idempotent_id('6dfc0a55-3a77-4564-a144-1587b7971dde')
+ @decorators.idempotent_id('6dfc0a55-3a77-4564-a144-1587b7971dde')
def test_rescue_non_existent_server(self):
# Rescue a non-existing server
non_existent_server = data_utils.rand_uuid()
@@ -100,14 +101,14 @@
non_existent_server)
@test.attr(type=['negative'])
- @test.idempotent_id('70cdb8a1-89f8-437d-9448-8844fd82bf46')
+ @decorators.idempotent_id('70cdb8a1-89f8-437d-9448-8844fd82bf46')
def test_rescued_vm_rebuild(self):
self.assertRaises(lib_exc.Conflict,
self.servers_client.rebuild_server,
self.rescue_id,
self.image_ref_alt)
- @test.idempotent_id('d0ccac79-0091-4cf4-a1ce-26162d0cc55f')
+ @decorators.idempotent_id('d0ccac79-0091-4cf4-a1ce-26162d0cc55f')
@test.services('volume')
@test.attr(type=['negative'])
def test_rescued_vm_attach_volume(self):
@@ -127,7 +128,7 @@
volumeId=volume['id'],
device='/dev/%s' % self.device)
- @test.idempotent_id('f56e465b-fe10-48bf-b75d-646cda3a8bc9')
+ @decorators.idempotent_id('f56e465b-fe10-48bf-b75d-646cda3a8bc9')
@test.services('volume')
@test.attr(type=['negative'])
def test_rescued_vm_detach_volume(self):
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index 5aeba4e..b463726 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -19,7 +19,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -35,7 +35,7 @@
self.clear_servers()
super(ServersTestJSON, self).tearDown()
- @test.idempotent_id('b92d5ec7-b1dd-44a2-87e4-45e888c46ef0')
+ @decorators.idempotent_id('b92d5ec7-b1dd-44a2-87e4-45e888c46ef0')
@testtools.skipUnless(CONF.compute_feature_enabled.
enable_instance_password,
'Instance password not available.')
@@ -47,7 +47,7 @@
# Verify the password is set correctly in the response
self.assertEqual('testpassword', server['adminPass'])
- @test.idempotent_id('8fea6be7-065e-47cf-89b8-496e6f96c699')
+ @decorators.idempotent_id('8fea6be7-065e-47cf-89b8-496e6f96c699')
def test_create_with_existing_server_name(self):
# Creating a server with a name that already exists is allowed
@@ -67,7 +67,7 @@
name2 = server['name']
self.assertEqual(name1, name2)
- @test.idempotent_id('f9e15296-d7f9-4e62-b53f-a04e89160833')
+ @decorators.idempotent_id('f9e15296-d7f9-4e62-b53f-a04e89160833')
def test_create_specify_keypair(self):
# Specify a keypair while creating a server
@@ -94,7 +94,7 @@
self.assertEqual(new_name, server['name'])
return server
- @test.idempotent_id('5e6ccff8-349d-4852-a8b3-055df7988dd2')
+ @decorators.idempotent_id('5e6ccff8-349d-4852-a8b3-055df7988dd2')
def test_update_server_name(self):
# The server name should be changed to the provided value
server = self.create_test_server(wait_until='ACTIVE')
@@ -102,7 +102,7 @@
prefix_name = u'\u00CD\u00F1st\u00E1\u00F1c\u00E9'
self._update_server_name(server['id'], 'ACTIVE', prefix_name)
- @test.idempotent_id('6ac19cb1-27a3-40ec-b350-810bdc04c08e')
+ @decorators.idempotent_id('6ac19cb1-27a3-40ec-b350-810bdc04c08e')
def test_update_server_name_in_stop_state(self):
# The server name should be changed to the provided value
server = self.create_test_server(wait_until='ACTIVE')
@@ -115,7 +115,7 @@
prefix_name)
self.assertNotIn('progress', updated_server)
- @test.idempotent_id('89b90870-bc13-4b73-96af-f9d4f2b70077')
+ @decorators.idempotent_id('89b90870-bc13-4b73-96af-f9d4f2b70077')
def test_update_access_server_address(self):
# The server's access addresses should reflect the provided values
server = self.create_test_server(wait_until='ACTIVE')
@@ -131,7 +131,7 @@
self.assertEqual('1.1.1.1', server['accessIPv4'])
self.assertEqual('::babe:202:202', server['accessIPv6'])
- @test.idempotent_id('38fb1d02-c3c5-41de-91d3-9bc2025a75eb')
+ @decorators.idempotent_id('38fb1d02-c3c5-41de-91d3-9bc2025a75eb')
def test_create_server_with_ipv6_addr_only(self):
# Create a server without an IPv4 address(only IPv6 address).
server = self.create_test_server(accessIPv6='2001:2001::3')
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index f66bc72..b22a434 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -22,6 +22,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -54,7 +55,7 @@
cls.server_id = server['id']
@test.attr(type=['negative'])
- @test.idempotent_id('dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf')
+ @decorators.idempotent_id('dbbfd247-c40c-449e-8f6c-d2aa7c7da7cf')
def test_server_name_blank(self):
# Create a server with name parameter empty
@@ -63,7 +64,7 @@
name='')
@test.attr(type=['negative'])
- @test.idempotent_id('b8a7235e-5246-4a8f-a08e-b34877c6586f')
+ @decorators.idempotent_id('b8a7235e-5246-4a8f-a08e-b34877c6586f')
@testtools.skipUnless(CONF.compute_feature_enabled.personality,
'Nova personality feature disabled')
def test_personality_file_contents_not_encoded(self):
@@ -78,7 +79,7 @@
personality=person)
@test.attr(type=['negative'])
- @test.idempotent_id('fcba1052-0a50-4cf3-b1ac-fae241edf02f')
+ @decorators.idempotent_id('fcba1052-0a50-4cf3-b1ac-fae241edf02f')
def test_create_with_invalid_image(self):
# Create a server with an unknown image
@@ -87,7 +88,7 @@
image_id=-1)
@test.attr(type=['negative'])
- @test.idempotent_id('18f5227f-d155-4429-807c-ccb103887537')
+ @decorators.idempotent_id('18f5227f-d155-4429-807c-ccb103887537')
def test_create_with_invalid_flavor(self):
# Create a server with an unknown flavor
@@ -96,7 +97,7 @@
flavor=-1,)
@test.attr(type=['negative'])
- @test.idempotent_id('7f70a4d1-608f-4794-9e56-cb182765972c')
+ @decorators.idempotent_id('7f70a4d1-608f-4794-9e56-cb182765972c')
def test_invalid_access_ip_v4_address(self):
# An access IPv4 address must match a valid address pattern
@@ -105,7 +106,7 @@
self.create_test_server, accessIPv4=IPv4)
@test.attr(type=['negative'])
- @test.idempotent_id('5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0')
+ @decorators.idempotent_id('5226dd80-1e9c-4d8a-b5f9-b26ca4763fd0')
def test_invalid_ip_v6_address(self):
# An access IPv6 address must match a valid address pattern
@@ -114,7 +115,7 @@
self.assertRaises(lib_exc.BadRequest,
self.create_test_server, accessIPv6=IPv6)
- @test.idempotent_id('7ea45b3e-e770-46fa-bfcc-9daaf6d987c0')
+ @decorators.idempotent_id('7ea45b3e-e770-46fa-bfcc-9daaf6d987c0')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
@test.attr(type=['negative'])
@@ -125,7 +126,7 @@
self.client.resize_server,
nonexistent_server, self.flavor_ref)
- @test.idempotent_id('ced1a1d7-2ab6-45c9-b90f-b27d87b30efd')
+ @decorators.idempotent_id('ced1a1d7-2ab6-45c9-b90f-b27d87b30efd')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
@test.attr(type=['negative'])
@@ -135,7 +136,7 @@
self.assertRaises(lib_exc.BadRequest, self.client.resize_server,
self.server_id, flavor_ref=nonexistent_flavor)
- @test.idempotent_id('45436a7d-a388-4a35-a9d8-3adc5d0d940b')
+ @decorators.idempotent_id('45436a7d-a388-4a35-a9d8-3adc5d0d940b')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
@test.attr(type=['negative'])
@@ -145,14 +146,14 @@
self.server_id, flavor_ref="")
@test.attr(type=['negative'])
- @test.idempotent_id('d4c023a0-9c55-4747-9dd5-413b820143c7')
+ @decorators.idempotent_id('d4c023a0-9c55-4747-9dd5-413b820143c7')
def test_reboot_non_existent_server(self):
# Reboot a non existent server
nonexistent_server = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.client.reboot_server,
nonexistent_server, type='SOFT')
- @test.idempotent_id('d1417e7f-a509-41b5-a102-d5eed8613369')
+ @decorators.idempotent_id('d1417e7f-a509-41b5-a102-d5eed8613369')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
@test.attr(type=['negative'])
@@ -166,7 +167,7 @@
self.client.unpause_server(self.server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('98fa0458-1485-440f-873b-fe7f0d714930')
+ @decorators.idempotent_id('98fa0458-1485-440f-873b-fe7f0d714930')
def test_rebuild_deleted_server(self):
# Rebuild a deleted server
server = self.create_test_server()
@@ -177,8 +178,9 @@
self.client.rebuild_server,
server['id'], self.image_ref_alt)
+ @test.related_bug('1660878', status_code=409)
@test.attr(type=['negative'])
- @test.idempotent_id('581a397d-5eab-486f-9cf9-1014bbd4c984')
+ @decorators.idempotent_id('581a397d-5eab-486f-9cf9-1014bbd4c984')
def test_reboot_deleted_server(self):
# Reboot a deleted server
server = self.create_test_server()
@@ -189,7 +191,7 @@
server['id'], type='SOFT')
@test.attr(type=['negative'])
- @test.idempotent_id('d86141a7-906e-4731-b187-d64a2ea61422')
+ @decorators.idempotent_id('d86141a7-906e-4731-b187-d64a2ea61422')
def test_rebuild_non_existent_server(self):
# Rebuild a non existent server
nonexistent_server = data_utils.rand_uuid()
@@ -199,7 +201,7 @@
self.image_ref_alt)
@test.attr(type=['negative'])
- @test.idempotent_id('fd57f159-68d6-4c2a-902b-03070828a87e')
+ @decorators.idempotent_id('fd57f159-68d6-4c2a-902b-03070828a87e')
def test_create_numeric_server_name(self):
server_name = 12345
self.assertRaises(lib_exc.BadRequest,
@@ -207,9 +209,9 @@
name=server_name)
@test.attr(type=['negative'])
- @test.idempotent_id('c3e0fb12-07fc-4d76-a22e-37409887afe8')
+ @decorators.idempotent_id('c3e0fb12-07fc-4d76-a22e-37409887afe8')
def test_create_server_name_length_exceeds_256(self):
- # Create a server with name length exceeding 256 characters
+ # Create a server with name length exceeding 255 characters
server_name = 'a' * 256
self.assertRaises(lib_exc.BadRequest,
@@ -218,7 +220,7 @@
@test.attr(type=['negative'])
@test.related_bug('1651064', status_code=500)
- @test.idempotent_id('12146ac1-d7df-4928-ad25-b1f99e5286cd')
+ @decorators.idempotent_id('12146ac1-d7df-4928-ad25-b1f99e5286cd')
def test_create_server_invalid_bdm_in_2nd_dict(self):
volume = self.create_volume()
bdm_1st = {"source_type": "image",
@@ -237,7 +239,7 @@
block_device_mapping_v2=bdm)
@test.attr(type=['negative'])
- @test.idempotent_id('4e72dc2d-44c5-4336-9667-f7972e95c402')
+ @decorators.idempotent_id('4e72dc2d-44c5-4336-9667-f7972e95c402')
def test_create_with_invalid_network_uuid(self):
# Pass invalid network uuid while creating a server
@@ -248,7 +250,7 @@
networks=networks)
@test.attr(type=['negative'])
- @test.idempotent_id('7a2efc39-530c-47de-b875-2dd01c8d39bd')
+ @decorators.idempotent_id('7a2efc39-530c-47de-b875-2dd01c8d39bd')
def test_create_with_non_existent_keypair(self):
# Pass a non-existent keypair while creating a server
@@ -258,7 +260,7 @@
key_name=key_name)
@test.attr(type=['negative'])
- @test.idempotent_id('7fc74810-0bd2-4cd7-8244-4f33a9db865a')
+ @decorators.idempotent_id('7fc74810-0bd2-4cd7-8244-4f33a9db865a')
def test_create_server_metadata_exceeds_length_limit(self):
# Pass really long metadata while creating a server
@@ -268,7 +270,7 @@
metadata=metadata)
@test.attr(type=['negative'])
- @test.idempotent_id('aa8eed43-e2cb-4ebf-930b-da14f6a21d81')
+ @decorators.idempotent_id('aa8eed43-e2cb-4ebf-930b-da14f6a21d81')
def test_update_name_of_non_existent_server(self):
# Update name of a non-existent server
@@ -280,7 +282,7 @@
nonexistent_server, name=new_name)
@test.attr(type=['negative'])
- @test.idempotent_id('38204696-17c6-44da-9590-40f87fb5a899')
+ @decorators.idempotent_id('38204696-17c6-44da-9590-40f87fb5a899')
def test_update_server_set_empty_name(self):
# Update name of the server to an empty string
@@ -290,7 +292,7 @@
self.server_id, name=new_name)
@test.attr(type=['negative'])
- @test.idempotent_id('5c8e244c-dada-4590-9944-749c455b431f')
+ @decorators.idempotent_id('5c8e244c-dada-4590-9944-749c455b431f')
def test_update_server_name_length_exceeds_256(self):
# Update name of server exceed the name length limit
@@ -301,7 +303,7 @@
name=new_name)
@test.attr(type=['negative'])
- @test.idempotent_id('1041b4e6-514b-4855-96a5-e974b60870a3')
+ @decorators.idempotent_id('1041b4e6-514b-4855-96a5-e974b60870a3')
def test_delete_non_existent_server(self):
# Delete a non existent server
@@ -310,14 +312,14 @@
nonexistent_server)
@test.attr(type=['negative'])
- @test.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
+ @decorators.idempotent_id('75f79124-277c-45e6-a373-a1d6803f4cc4')
def test_delete_server_pass_negative_id(self):
# Pass an invalid string parameter to delete server
self.assertRaises(lib_exc.NotFound, self.client.delete_server, -1)
@test.attr(type=['negative'])
- @test.idempotent_id('f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5')
+ @decorators.idempotent_id('f4d7279b-5fd2-4bf2-9ba4-ae35df0d18c5')
def test_delete_server_pass_id_exceeding_length_limit(self):
# Pass a server ID that exceeds length limit to delete server
@@ -325,7 +327,7 @@
sys.maxsize + 1)
@test.attr(type=['negative'])
- @test.idempotent_id('c5fa6041-80cd-483b-aa6d-4e45f19d093c')
+ @decorators.idempotent_id('c5fa6041-80cd-483b-aa6d-4e45f19d093c')
def test_create_with_nonexistent_security_group(self):
# Create a server with a nonexistent security group
@@ -335,7 +337,7 @@
security_groups=security_groups)
@test.attr(type=['negative'])
- @test.idempotent_id('3436b02f-1b1e-4f03-881e-c6a602327439')
+ @decorators.idempotent_id('3436b02f-1b1e-4f03-881e-c6a602327439')
def test_get_non_existent_server(self):
# Get a non existent server details
nonexistent_server = data_utils.rand_uuid()
@@ -343,14 +345,14 @@
nonexistent_server)
@test.attr(type=['negative'])
- @test.idempotent_id('a31460a9-49e1-42aa-82ee-06e0bb7c2d03')
+ @decorators.idempotent_id('a31460a9-49e1-42aa-82ee-06e0bb7c2d03')
def test_stop_non_existent_server(self):
# Stop a non existent server
nonexistent_server = data_utils.rand_uuid()
self.assertRaises(lib_exc.NotFound, self.servers_client.stop_server,
nonexistent_server)
- @test.idempotent_id('6a8dc0c6-6cd4-4c0a-9f32-413881828091')
+ @decorators.idempotent_id('6a8dc0c6-6cd4-4c0a-9f32-413881828091')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
@test.attr(type=['negative'])
@@ -360,7 +362,7 @@
self.assertRaises(lib_exc.NotFound, self.client.pause_server,
nonexistent_server)
- @test.idempotent_id('705b8e3a-e8a7-477c-a19b-6868fc24ac75')
+ @decorators.idempotent_id('705b8e3a-e8a7-477c-a19b-6868fc24ac75')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
@test.attr(type=['negative'])
@@ -370,7 +372,7 @@
self.assertRaises(lib_exc.NotFound, self.client.unpause_server,
nonexistent_server)
- @test.idempotent_id('c8e639a7-ece8-42dd-a2e0-49615917ba4f')
+ @decorators.idempotent_id('c8e639a7-ece8-42dd-a2e0-49615917ba4f')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
'Pause is not available.')
@test.attr(type=['negative'])
@@ -380,7 +382,7 @@
self.client.unpause_server,
self.server_id)
- @test.idempotent_id('d1f032d5-7b6e-48aa-b252-d5f16dd994ca')
+ @decorators.idempotent_id('d1f032d5-7b6e-48aa-b252-d5f16dd994ca')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
@test.attr(type=['negative'])
@@ -390,7 +392,7 @@
self.assertRaises(lib_exc.NotFound, self.client.suspend_server,
nonexistent_server)
- @test.idempotent_id('7f323206-05a9-4bf8-996b-dd5b2036501b')
+ @decorators.idempotent_id('7f323206-05a9-4bf8-996b-dd5b2036501b')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
@test.attr(type=['negative'])
@@ -404,7 +406,7 @@
self.server_id)
self.client.resume_server(self.server_id)
- @test.idempotent_id('221cd282-bddb-4837-a683-89c2487389b6')
+ @decorators.idempotent_id('221cd282-bddb-4837-a683-89c2487389b6')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
@test.attr(type=['negative'])
@@ -414,7 +416,7 @@
self.assertRaises(lib_exc.NotFound, self.client.resume_server,
nonexistent_server)
- @test.idempotent_id('ccb6294d-c4c9-498f-8a43-554c098bfadb')
+ @decorators.idempotent_id('ccb6294d-c4c9-498f-8a43-554c098bfadb')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
@test.attr(type=['negative'])
@@ -425,7 +427,7 @@
self.server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('7dd919e7-413f-4198-bebb-35e2a01b13e9')
+ @decorators.idempotent_id('7dd919e7-413f-4198-bebb-35e2a01b13e9')
def test_get_console_output_of_non_existent_server(self):
# get the console output for a non existent server
nonexistent_server = data_utils.rand_uuid()
@@ -434,7 +436,7 @@
nonexistent_server, length=10)
@test.attr(type=['negative'])
- @test.idempotent_id('6f47992b-5144-4250-9f8b-f00aa33950f3')
+ @decorators.idempotent_id('6f47992b-5144-4250-9f8b-f00aa33950f3')
def test_force_delete_nonexistent_server_id(self):
# force-delete a non existent server
nonexistent_server = data_utils.rand_uuid()
@@ -443,7 +445,7 @@
nonexistent_server)
@test.attr(type=['negative'])
- @test.idempotent_id('9c6d38cc-fcfb-437a-85b9-7b788af8bf01')
+ @decorators.idempotent_id('9c6d38cc-fcfb-437a-85b9-7b788af8bf01')
def test_restore_nonexistent_server_id(self):
# restore-delete a non existent server
nonexistent_server = data_utils.rand_uuid()
@@ -452,14 +454,14 @@
nonexistent_server)
@test.attr(type=['negative'])
- @test.idempotent_id('7fcadfab-bd6a-4753-8db7-4a51e51aade9')
+ @decorators.idempotent_id('7fcadfab-bd6a-4753-8db7-4a51e51aade9')
def test_restore_server_invalid_state(self):
# we can only restore-delete a server in 'soft-delete' state
self.assertRaises(lib_exc.Conflict,
self.client.restore_soft_deleted_server,
self.server_id)
- @test.idempotent_id('abca56e2-a892-48ea-b5e5-e07e69774816')
+ @decorators.idempotent_id('abca56e2-a892-48ea-b5e5-e07e69774816')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
@test.attr(type=['negative'])
@@ -469,7 +471,7 @@
self.assertRaises(lib_exc.NotFound, self.client.shelve_server,
nonexistent_server)
- @test.idempotent_id('443e4f9b-e6bf-4389-b601-3a710f15fddd')
+ @decorators.idempotent_id('443e4f9b-e6bf-4389-b601-3a710f15fddd')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
@test.attr(type=['negative'])
@@ -490,7 +492,7 @@
self.client.unshelve_server(self.server_id)
- @test.idempotent_id('23d23b37-afaf-40d7-aa5d-5726f82d8821')
+ @decorators.idempotent_id('23d23b37-afaf-40d7-aa5d-5726f82d8821')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
@test.attr(type=['negative'])
@@ -500,7 +502,7 @@
self.assertRaises(lib_exc.NotFound, self.client.unshelve_server,
nonexistent_server)
- @test.idempotent_id('8f198ded-1cca-4228-9e65-c6b449c54880')
+ @decorators.idempotent_id('8f198ded-1cca-4228-9e65-c6b449c54880')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
@test.attr(type=['negative'])
@@ -511,7 +513,7 @@
self.server_id)
@test.attr(type=['negative'])
- @test.idempotent_id('74085be3-a370-4ca2-bc51-2d0e10e0f573')
+ @decorators.idempotent_id('74085be3-a370-4ca2-bc51-2d0e10e0f573')
@test.services('volume', 'image')
def test_create_server_from_non_bootable_volume(self):
# Create a volume
@@ -565,7 +567,7 @@
cls.server_id = server['id']
@test.attr(type=['negative'])
- @test.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
+ @decorators.idempotent_id('543d84c1-dd2e-4c6d-8cb2-b9da0efaa384')
def test_update_server_of_another_tenant(self):
# Update name of a server that belongs to another tenant
@@ -575,7 +577,7 @@
name=new_name)
@test.attr(type=['negative'])
- @test.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
+ @decorators.idempotent_id('5c75009d-3eea-423e-bea3-61b09fd25f9c')
def test_delete_a_server_of_another_tenant(self):
# Delete a server that belongs to another tenant
self.assertRaises(lib_exc.NotFound,
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 08c34d3..610121b 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -18,6 +18,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions
from tempest import test
@@ -42,7 +43,7 @@
super(VirtualInterfacesTestJSON, cls).resource_setup()
cls.server = cls.create_test_server(wait_until='ACTIVE')
- @test.idempotent_id('96c4e2ef-5e4d-4d7f-87f5-fed6dca18016')
+ @decorators.idempotent_id('96c4e2ef-5e4d-4d7f-87f5-fed6dca18016')
@test.services('network')
def test_list_virtual_interfaces(self):
# Positive test:Should be able to GET the virtual interfaces list
diff --git a/tempest/api/compute/servers/test_virtual_interfaces_negative.py b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
index 912b0a1..b1374d2 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces_negative.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces_negative.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.lib.common.utils import data_utils
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -33,7 +34,7 @@
cls.client = cls.servers_client
@test.attr(type=['negative'])
- @test.idempotent_id('64ebd03c-1089-4306-93fa-60f5eb5c803c')
+ @decorators.idempotent_id('64ebd03c-1089-4306-93fa-60f5eb5c803c')
@test.services('network')
def test_list_virtual_interfaces_invalid_server_id(self):
# Negative test: Should not be able to GET virtual interfaces
diff --git a/tempest/api/compute/test_extensions.py b/tempest/api/compute/test_extensions.py
index d171cd5..f87bf6d 100644
--- a/tempest/api/compute/test_extensions.py
+++ b/tempest/api/compute/test_extensions.py
@@ -17,6 +17,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest import test
CONF = config.CONF
@@ -27,7 +28,7 @@
class ExtensionsTestJSON(base.BaseV2ComputeTest):
- @test.idempotent_id('3bb27738-b759-4e0d-a5fa-37d7a6df07d1')
+ @decorators.idempotent_id('3bb27738-b759-4e0d-a5fa-37d7a6df07d1')
def test_list_extensions(self):
# List of all extensions
if len(CONF.compute_feature_enabled.api_extensions) == 0:
@@ -44,7 +45,7 @@
extension_list = map(lambda x: x['alias'], extensions)
LOG.debug("Nova extensions: %s", ','.join(extension_list))
- @test.idempotent_id('05762f39-bdfa-4cdb-9b46-b78f8e78e2fd')
+ @decorators.idempotent_id('05762f39-bdfa-4cdb-9b46-b78f8e78e2fd')
@test.requires_ext(extension='os-consoles', service='compute')
def test_get_extension(self):
# get the specified extensions
diff --git a/tempest/api/compute/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index 7853962..40d0746 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -17,6 +17,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -42,7 +43,7 @@
disk_over_commit=False)
@test.attr(type=['negative'])
- @test.idempotent_id('7fb7856e-ae92-44c9-861a-af62d7830bcb')
+ @decorators.idempotent_id('7fb7856e-ae92-44c9-861a-af62d7830bcb')
def test_invalid_host_for_migration(self):
# Migrating to an invalid host should not change the status
target_host = data_utils.rand_name('host')
diff --git a/tempest/api/compute/test_networks.py b/tempest/api/compute/test_networks.py
index d4b8003..4d21fed 100644
--- a/tempest/api/compute/test_networks.py
+++ b/tempest/api/compute/test_networks.py
@@ -14,7 +14,7 @@
from tempest.api.compute import base
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -31,7 +31,7 @@
super(ComputeNetworksTest, cls).setup_clients()
cls.client = cls.os.compute_networks_client
- @test.idempotent_id('3fe07175-312e-49a5-a623-5f52eeada4c2')
+ @decorators.idempotent_id('3fe07175-312e-49a5-a623-5f52eeada4c2')
def test_list_networks(self):
networks = self.client.list_networks()['networks']
self.assertNotEmpty(networks, "No networks found.")
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index b9e0c35..0ad2df8 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common import tempest_fixtures as fixtures
+from tempest.lib import decorators
from tempest import test
@@ -51,7 +52,7 @@
'cores', 'security_groups',
'server_group_members', 'server_groups'))
- @test.idempotent_id('f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107')
+ @decorators.idempotent_id('f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107')
def test_get_quotas(self):
# User can get the quota set for it's tenant
expected_quota_set = self.default_quota_set | set(['id'])
@@ -67,7 +68,7 @@
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
- @test.idempotent_id('9bfecac7-b966-4f47-913f-1a9e2c12134a')
+ @decorators.idempotent_id('9bfecac7-b966-4f47-913f-1a9e2c12134a')
def test_get_default_quotas(self):
# User can get the default quota set for it's tenant
expected_quota_set = self.default_quota_set | set(['id'])
@@ -77,7 +78,7 @@
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
- @test.idempotent_id('cd65d997-f7e4-4966-a7e9-d5001b674fdc')
+ @decorators.idempotent_id('cd65d997-f7e4-4966-a7e9-d5001b674fdc')
def test_compare_tenant_quotas_with_default_quotas(self):
# Tenants are created with the default quota values
default_quota_set = \
diff --git a/tempest/api/compute/test_tenant_networks.py b/tempest/api/compute/test_tenant_networks.py
index 96b7ef6..b203c7e 100644
--- a/tempest/api/compute/test_tenant_networks.py
+++ b/tempest/api/compute/test_tenant_networks.py
@@ -13,6 +13,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.lib import decorators
from tempest import test
@@ -29,7 +30,7 @@
cls.set_network_resources(network=True)
super(ComputeTenantNetworksTest, cls).setup_credentials()
- @test.idempotent_id('edfea98e-bbe3-4c7a-9739-87b986baff26')
+ @decorators.idempotent_id('edfea98e-bbe3-4c7a-9739-87b986baff26')
@test.services('network')
def test_list_show_tenant_networks(self):
# Fetch all networks that are visible to the tenant: this may include
diff --git a/tempest/api/compute/test_versions.py b/tempest/api/compute/test_versions.py
index 8b84a21..c9f0724 100644
--- a/tempest/api/compute/test_versions.py
+++ b/tempest/api/compute/test_versions.py
@@ -13,12 +13,12 @@
# under the License.
from tempest.api.compute import base
-from tempest import test
+from tempest.lib import decorators
class TestVersions(base.BaseV2ComputeTest):
- @test.idempotent_id('6c0a0990-43b6-4529-9b61-5fd8daf7c55c')
+ @decorators.idempotent_id('6c0a0990-43b6-4529-9b61-5fd8daf7c55c')
def test_list_api_versions(self):
"""Test that a get of the unversioned url returns the choices doc.
@@ -36,7 +36,7 @@
self.assertEqual(versions[0]['id'], 'v2.0',
"The first listed version should be v2.0")
- @test.idempotent_id('b953a29e-929c-4a8e-81be-ec3a7e03cb76')
+ @decorators.idempotent_id('b953a29e-929c-4a8e-81be-ec3a7e03cb76')
def test_get_version_details(self):
"""Test individual version endpoints info works.
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 30549ec..cbe7178 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import logging
+from oslo_log import log as logging
import testtools
from tempest.api.compute import base
@@ -21,8 +21,8 @@
from tempest.common.utils.linux import remote_client
from tempest.common import waiters
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
-from tempest import test
CONF = config.CONF
@@ -85,7 +85,7 @@
return attachment
- @test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
+ @decorators.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
def test_attach_detach_volume(self):
# Stop and Start a server with an attached volume, ensuring that
# the volume remains attached.
@@ -136,7 +136,7 @@
disks = linux_client.get_disks()
self.assertNotIn(device_name_to_match, disks)
- @test.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
+ @decorators.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
def test_list_get_volume_attachments(self):
# List volume attachment of the server
server = self._create_server()
@@ -156,7 +156,7 @@
self.assertEqual(volume['id'], body['volumeId'])
self.assertEqual(attachment['id'], body['id'])
- @test.idempotent_id('757d488b-a951-4bc7-b3cd-f417028da08a')
+ @decorators.idempotent_id('757d488b-a951-4bc7-b3cd-f417028da08a')
def test_list_get_two_volume_attachments(self):
# NOTE: This test is using the volume device auto-assignment
# without specifying the device ("/dev/sdb", etc). The feature
@@ -243,7 +243,7 @@
counted_volumes = self._count_volumes(server)
self.assertEqual(number_of_volumes, counted_volumes)
- @test.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
+ @decorators.idempotent_id('13a940b6-3474-4c3c-b03f-29b89112bfee')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
def test_attach_volume_shelved_or_offload_server(self):
@@ -269,7 +269,7 @@
# case of shelved_offloaded.
self.assertIsNotNone(volume_attachment['device'])
- @test.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
+ @decorators.idempotent_id('b54e86dd-a070-49c4-9c07-59ae6dae15aa')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
'Shelve is not available.')
def test_detach_volume_shelved_or_offload_server(self):
diff --git a/tempest/api/compute/volumes/test_attach_volume_negative.py b/tempest/api/compute/volumes/test_attach_volume_negative.py
index 1f18bfe..acab4b1 100644
--- a/tempest/api/compute/volumes/test_attach_volume_negative.py
+++ b/tempest/api/compute/volumes/test_attach_volume_negative.py
@@ -14,6 +14,7 @@
from tempest.api.compute import base
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -30,7 +31,7 @@
raise cls.skipException(skip_msg)
@test.related_bug('1630783', status_code=500)
- @test.idempotent_id('a313b5cd-fbd0-49cc-94de-870e99f763c7')
+ @decorators.idempotent_id('a313b5cd-fbd0-49cc-94de-870e99f763c7')
def test_delete_attached_volume(self):
server = self.create_test_server(wait_until='ACTIVE')
volume = self.create_volume()
diff --git a/tempest/api/compute/volumes/test_volume_snapshots.py b/tempest/api/compute/volumes/test_volume_snapshots.py
index 01718cc..3d5d23b 100644
--- a/tempest/api/compute/volumes/test_volume_snapshots.py
+++ b/tempest/api/compute/volumes/test_volume_snapshots.py
@@ -19,7 +19,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -40,7 +40,7 @@
cls.volumes_client = cls.volumes_extensions_client
cls.snapshots_client = cls.snapshots_extensions_client
- @test.idempotent_id('cd4ec87d-7825-450d-8040-6e2068f2da8f')
+ @decorators.idempotent_id('cd4ec87d-7825-450d-8040-6e2068f2da8f')
@testtools.skipUnless(CONF.volume_feature_enabled.snapshot,
'Cinder volume snapshots are disabled')
def test_volume_snapshot_create_get_list_delete(self):
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 7549d4a..63c247e 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -19,7 +19,7 @@
from tempest.common.utils import data_utils
from tempest.common import waiters
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -39,7 +39,7 @@
super(VolumesGetTestJSON, cls).setup_clients()
cls.client = cls.volumes_extensions_client
- @test.idempotent_id('f10f25eb-9775-4d9d-9cbe-1cf54dae9d5f')
+ @decorators.idempotent_id('f10f25eb-9775-4d9d-9cbe-1cf54dae9d5f')
def test_volume_create_get_delete(self):
# CREATE, GET, DELETE Volume
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 82cc653..dd9d408 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -15,7 +15,7 @@
from tempest.api.compute import base
from tempest import config
-from tempest import test
+from tempest.lib import decorators
CONF = config.CONF
@@ -45,14 +45,14 @@
# Create 3 Volumes
cls.volume_list = []
cls.volume_id_list = []
- for i in range(3):
+ 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'])
- @test.idempotent_id('bc2dd1a0-15af-48e5-9990-f2e75a48325d')
+ @decorators.idempotent_id('bc2dd1a0-15af-48e5-9990-f2e75a48325d')
def test_volume_list(self):
# Should return the list of Volumes
# Fetch all Volumes
@@ -67,7 +67,7 @@
', '.join(m_vol['displayName']
for m_vol in missing_volumes))
- @test.idempotent_id('bad0567a-5a4f-420b-851e-780b55bb867c')
+ @decorators.idempotent_id('bad0567a-5a4f-420b-851e-780b55bb867c')
def test_volume_list_with_details(self):
# Should return the list of Volumes with details
# Fetch all Volumes
@@ -82,7 +82,7 @@
', '.join(m_vol['displayName']
for m_vol in missing_volumes))
- @test.idempotent_id('1048ed81-2baf-487a-b284-c0622b86e7b8')
+ @decorators.idempotent_id('1048ed81-2baf-487a-b284-c0622b86e7b8')
def test_volume_list_param_limit(self):
# Return the list of volumes based on limit set
params = {'limit': 2}
@@ -91,7 +91,7 @@
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volumes by limit set")
- @test.idempotent_id('33985568-4965-49d5-9bcc-0aa007ca5b7a')
+ @decorators.idempotent_id('33985568-4965-49d5-9bcc-0aa007ca5b7a')
def test_volume_list_with_detail_param_limit(self):
# Return the list of volumes with details based on limit set.
params = {'limit': 2}
@@ -101,7 +101,7 @@
self.assertEqual(len(fetched_vol_list), params['limit'],
"Failed to list volume details by limit set")
- @test.idempotent_id('51c22651-a074-4ea7-af0b-094f9331303e')
+ @decorators.idempotent_id('51c22651-a074-4ea7-af0b-094f9331303e')
def test_volume_list_param_offset_and_limit(self):
# Return the list of volumes based on offset and limit set.
# get all volumes list
@@ -118,7 +118,7 @@
all_vol_list[index + params['offset']]['id'],
"Failed to list volumes by offset and limit")
- @test.idempotent_id('06b6abc4-3f10-48e9-a7a1-3facc98f03e5')
+ @decorators.idempotent_id('06b6abc4-3f10-48e9-a7a1-3facc98f03e5')
def test_volume_list_with_detail_param_offset_and_limit(self):
# Return the list of volumes details based on offset and limit set.
# get all volumes list
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index c4041cb..2ad8631 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -16,6 +16,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest import config
+from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
from tempest import test
@@ -37,7 +38,7 @@
cls.client = cls.volumes_extensions_client
@test.attr(type=['negative'])
- @test.idempotent_id('c03ea686-905b-41a2-8748-9635154b7c57')
+ @decorators.idempotent_id('c03ea686-905b-41a2-8748-9635154b7c57')
def test_volume_get_nonexistent_volume_id(self):
# Negative: Should not be able to get details of nonexistent volume
# Creating a nonexistent volume id
@@ -46,7 +47,7 @@
data_utils.rand_uuid())
@test.attr(type=['negative'])
- @test.idempotent_id('54a34226-d910-4b00-9ef8-8683e6c55846')
+ @decorators.idempotent_id('54a34226-d910-4b00-9ef8-8683e6c55846')
def test_volume_delete_nonexistent_volume_id(self):
# Negative: Should not be able to delete nonexistent Volume
# Creating nonexistent volume id
@@ -55,7 +56,7 @@
data_utils.rand_uuid())
@test.attr(type=['negative'])
- @test.idempotent_id('5125ae14-152b-40a7-b3c5-eae15e9022ef')
+ @decorators.idempotent_id('5125ae14-152b-40a7-b3c5-eae15e9022ef')
def test_create_volume_with_invalid_size(self):
# Negative: Should not be able to create volume with invalid size
# in request
@@ -65,7 +66,7 @@
size='#$%', display_name=v_name, metadata=metadata)
@test.attr(type=['negative'])
- @test.idempotent_id('131cb3a1-75cc-4d40-b4c3-1317f64719b0')
+ @decorators.idempotent_id('131cb3a1-75cc-4d40-b4c3-1317f64719b0')
def test_create_volume_without_passing_size(self):
# Negative: Should not be able to create volume without passing size
# in request
@@ -75,7 +76,7 @@
size='', display_name=v_name, metadata=metadata)
@test.attr(type=['negative'])
- @test.idempotent_id('8cce995e-0a83-479a-b94d-e1e40b8a09d1')
+ @decorators.idempotent_id('8cce995e-0a83-479a-b94d-e1e40b8a09d1')
def test_create_volume_with_size_zero(self):
# Negative: Should not be able to create volume with size zero
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
@@ -84,21 +85,22 @@
size='0', display_name=v_name, metadata=metadata)
@test.attr(type=['negative'])
- @test.idempotent_id('62bab09a-4c03-4617-8cca-8572bc94af9b')
+ @decorators.idempotent_id('62bab09a-4c03-4617-8cca-8572bc94af9b')
def test_get_volume_without_passing_volume_id(self):
# Negative: Should not be able to get volume when empty ID is passed
self.assertRaises(lib_exc.NotFound, self.client.show_volume, '')
@test.attr(type=['negative'])
- @test.idempotent_id('62972737-124b-4513-b6cf-2f019f178494')
+ @decorators.idempotent_id('62972737-124b-4513-b6cf-2f019f178494')
def test_delete_invalid_volume_id(self):
# Negative: Should not be able to delete volume when invalid ID is
# passed
self.assertRaises(lib_exc.NotFound,
- self.client.delete_volume, '!@#$%^&*()')
+ self.client.delete_volume,
+ data_utils.rand_name('invalid'))
@test.attr(type=['negative'])
- @test.idempotent_id('0d1417c5-4ae8-4c2c-adc5-5f0b864253e5')
+ @decorators.idempotent_id('0d1417c5-4ae8-4c2c-adc5-5f0b864253e5')
def test_delete_volume_without_passing_volume_id(self):
# Negative: Should not be able to delete volume when empty ID is passed
self.assertRaises(lib_exc.NotFound, self.client.delete_volume, '')
diff --git a/tempest/api/identity/admin/v2/test_endpoints.py b/tempest/api/identity/admin/v2/test_endpoints.py
index 651a316..0da579c 100644
--- a/tempest/api/identity/admin/v2/test_endpoints.py
+++ b/tempest/api/identity/admin/v2/test_endpoints.py
@@ -34,7 +34,7 @@
cls.service_ids.append(cls.service_id)
# Create endpoints so as to use for LIST and GET test cases
cls.setup_endpoints = list()
- for i in range(2):
+ for _ in range(2):
region = data_utils.rand_name('region')
url = data_utils.rand_url()
endpoint = cls.endpoints_client.create_endpoint(
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index a0d8748..d4fe32d 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -31,7 +31,7 @@
u_desc = '%s description' % u_name
u_email = '%s@testmail.tm' % u_name
u_password = data_utils.rand_password()
- for i in range(2):
+ for _ in range(2):
cls.project = cls.projects_client.create_project(
data_utils.rand_name('project'),
description=data_utils.rand_name('project-desc'))['project']
@@ -92,7 +92,7 @@
created_cred_ids = list()
fetched_cred_ids = list()
- for i in range(2):
+ for _ in range(2):
blob = '{"access": "%s", "secret": "%s"}' % (
data_utils.rand_name('Access'), data_utils.rand_name('Secret'))
cred = self.creds_client.create_credential(
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 655e4ef..ef450a2 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -40,7 +40,7 @@
cls.service_ids.append(cls.service_id)
# Create endpoints so as to use for LIST and GET test cases
cls.setup_endpoints = list()
- for i in range(2):
+ for _ in range(2):
region = data_utils.rand_name('region')
url = data_utils.rand_url()
interface = 'public'
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 3cbcc1f..34b4468 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -80,7 +80,7 @@
self.addCleanup(self.groups_client.delete_group, group['id'])
# add user into group
users = []
- for i in range(3):
+ for _ in range(3):
name = data_utils.rand_name('User')
password = data_utils.rand_password()
user = self.users_client.create_user(name=name,
@@ -110,7 +110,7 @@
self.addCleanup(self.users_client.delete_user, user['id'])
# create two groups, and add user into them
groups = []
- for i in range(2):
+ for _ in range(2):
name = data_utils.rand_name('Group')
group = self.groups_client.create_group(
name=name, domain_id=self.domain['id'])['group']
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index 95894a6..b5ea90d 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -30,7 +30,7 @@
def resource_setup(cls):
super(RegionsTestJSON, cls).resource_setup()
cls.setup_regions = list()
- for i in range(2):
+ for _ in range(2):
r_description = data_utils.rand_name('description')
region = cls.client.create_region(
description=r_description)['region']
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 3ec4ff1..54c62c7 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -125,7 +125,7 @@
user = self.users_client.show_user(user_body['id'])['user']
role = self.roles_client.show_role(role_body['id'])['role']
- for i in range(2):
+ for _ in range(2):
# Creating project so as to assign role
project_body = self.projects_client.create_project(
data_utils.rand_name('project'),
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 14bf4f8..9515788 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -105,6 +105,15 @@
credentials = ['primary', 'admin']
+ # NOTE(andreaf) Identity tests work with credentials, so it is safer
+ # for them to always use disposable credentials. Forcing dynamic creds
+ # on regular identity tests would be however to restrictive, since it
+ # would prevent any identity test from being executed against clouds where
+ # admin credentials are not available.
+ # Since All admin tests require admin credentials to be
+ # executed, so this will not impact the ability to execute tests.
+ force_tenant_isolation = True
+
@classmethod
def setup_clients(cls):
super(BaseIdentityV2AdminTest, cls).setup_clients()
@@ -165,6 +174,15 @@
credentials = ['primary', 'admin']
+ # NOTE(andreaf) Identity tests work with credentials, so it is safer
+ # for them to always use disposable credentials. Forcing dynamic creds
+ # on regular identity tests would be however to restrictive, since it
+ # would prevent any identity test from being executed against clouds where
+ # admin credentials are not available.
+ # Since All admin tests require admin credentials to be
+ # executed, so this will not impact the ability to execute tests.
+ force_tenant_isolation = True
+
@classmethod
def setup_clients(cls):
super(BaseIdentityV3AdminTest, cls).setup_clients()
diff --git a/tempest/api/identity/v2/test_users.py b/tempest/api/identity/v2/test_users.py
index bafb1f2..06730f8 100644
--- a/tempest/api/identity/v2/test_users.py
+++ b/tempest/api/identity/v2/test_users.py
@@ -58,7 +58,7 @@
if CONF.identity_feature_enabled.security_compliance:
# First we need to clear the password history
unique_count = CONF.identity.user_unique_last_password_count
- for i in range(unique_count):
+ for _ in range(unique_count):
random_pass = data_utils.rand_password()
self._update_password(
user_id, original_password=new_pass, password=random_pass)
diff --git a/tempest/api/identity/v3/test_users.py b/tempest/api/identity/v3/test_users.py
index f389a8f..9592cb9 100644
--- a/tempest/api/identity/v3/test_users.py
+++ b/tempest/api/identity/v3/test_users.py
@@ -60,7 +60,7 @@
if CONF.identity_feature_enabled.security_compliance:
# First we need to clear the password history
unique_count = CONF.identity.user_unique_last_password_count
- for i in range(unique_count):
+ for _ in range(unique_count):
random_pass = data_utils.rand_password()
self._update_password(
original_password=new_pass, password=random_pass)
@@ -142,7 +142,7 @@
# Lock user account by using the wrong password to login
bad_password = data_utils.rand_password()
- for i in range(CONF.identity.user_lockout_failure_attempts):
+ for _ in range(CONF.identity.user_lockout_failure_attempts):
self.assertRaises(exceptions.Unauthorized,
self.non_admin_token.auth,
user_id=self.user_id,
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 23bd628..cd4f820 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -143,6 +143,7 @@
cls.resource_types_client = cls.os.resource_types_client
cls.namespace_properties_client = cls.os.namespace_properties_client
cls.namespace_objects_client = cls.os.namespace_objects_client
+ cls.namespace_tags_client = cls.os.namespace_tags_client
cls.schemas_client = cls.os.schemas_client
def create_namespace(cls, namespace_name=None, visibility='public',
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 0caaa67..b22ceed 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -30,13 +30,23 @@
a_formats = ['ami', 'ari', 'aki']
container_format = CONF.image.container_formats[0]
- disk_format = CONF.image.disk_formats[0]
- if container_format in a_formats and container_format != disk_format:
- msg = ("The container format and the disk format don't match. "
- "Container format: %(container)s, Disk format: %(disk)s." %
- {'container': container_format, 'disk': disk_format})
- raise exceptions.InvalidConfiguration(msg)
+ # In v1, If container_format is one of ['ami', 'ari', 'aki'], then
+ # disk_format must be same with container_format.
+ # If they are of different item sequence in tempest.conf, such as:
+ # container_formats = ami,ari,aki,bare
+ # disk_formats = ari,ami,aki,vhd
+ # we can select one in disk_format list that is same with container_format.
+ if container_format in a_formats:
+ if container_format in CONF.image.disk_formats:
+ disk_format = container_format
+ else:
+ msg = ("The container format and the disk format don't match. "
+ "Container format: %(container)s, Disk format: %(disk)s." %
+ {'container': container_format, 'disk': disk_format})
+ raise exceptions.InvalidConfiguration(msg)
+ else:
+ disk_format = CONF.image.disk_formats[0]
return container_format, disk_format
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 453bb34..36dc6c3 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -126,11 +126,12 @@
self.assertEqual(new_image_name, body['name'])
-class ListImagesTest(base.BaseV2ImageTest):
+class ListUserImagesTest(base.BaseV2ImageTest):
+ """Here we test the listing of image information"""
@classmethod
def resource_setup(cls):
- super(ListImagesTest, cls).resource_setup()
+ super(ListUserImagesTest, cls).resource_setup()
# We add a few images here to test the listing functionality of
# the images API
container_fmts = CONF.image.container_formats
@@ -166,10 +167,6 @@
return image['id']
-
-class ListUserImagesTest(ListImagesTest):
- """Here we test the listing of image information"""
-
def _list_by_param_value_and_assert(self, params):
"""Perform list action with given params and validates result."""
# Retrieve the list of images that meet the filter
@@ -323,7 +320,7 @@
self.assertEqual("images", body['name'])
-class ListSharedImagesTest(ListImagesTest):
+class ListSharedImagesTest(base.BaseV2ImageTest):
"""Here we test the listing of a shared image information"""
credentials = ['primary', 'alt']
@@ -336,17 +333,22 @@
@test.idempotent_id('3fa50be4-8e38-4c02-a8db-7811bb780122')
def test_list_images_param_member_status(self):
- # Share one of the images created with the alt user
+ # Create an image to be shared using default visibility
+ image_file = six.BytesIO(data_utils.random_bytes(2048))
+ container_format = CONF.image.container_formats[0]
+ disk_format = CONF.image.disk_formats[0]
+ image = self.create_image(container_format=container_format,
+ disk_format=disk_format)
+ self.client.store_image_file(image['id'], data=image_file)
+
+ # Share the image created with the alt user
self.image_member_client.create_image_member(
- image_id=self.test_data['id'],
- member=self.alt_img_client.tenant_id)
- # Update the info on the test data so it remains accurate
- self.test_data['updated_at'] = self.client.show_image(
- self.test_data['id'])['updated_at']
+ image_id=image['id'], member=self.alt_img_client.tenant_id)
+
# As an image consumer you need to provide the member_status parameter
# along with the visibility=shared parameter in order for it to show
# results
params = {'member_status': 'pending', 'visibility': 'shared'}
fetched_images = self.alt_img_client.list_images(params)['images']
self.assertEqual(1, len(fetched_images))
- self.assertEqual(self.test_data['id'], fetched_images[0]['id'])
+ self.assertEqual(image['id'], fetched_images[0]['id'])
diff --git a/tempest/api/image/v2/test_images_metadefs_namespace_tags.py b/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
new file mode 100644
index 0000000..186d9c8
--- /dev/null
+++ b/tempest/api/image/v2/test_images_metadefs_namespace_tags.py
@@ -0,0 +1,90 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.image import base
+from tempest.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
+from tempest import test
+
+
+class MetadataNamespaceTagsTest(base.BaseV2ImageTest):
+ """Test the Metadata definition namespace tags basic functionality"""
+
+ tags = [
+ {
+ "name": "sample-tag1"
+ },
+ {
+ "name": "sample-tag2"
+ },
+ {
+ "name": "sample-tag3"
+ }
+ ]
+ tag_list = ["sample-tag1", "sample-tag2", "sample-tag3"]
+
+ def _create_namespace_tags(self, namespace):
+ # Create a namespace
+ namespace_tags = self.namespace_tags_client.create_namespace_tags(
+ namespace['namespace'], tags=self.tags)
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ self.namespace_tags_client.delete_namespace_tags,
+ namespace['namespace'])
+ return namespace_tags
+
+ @test.idempotent_id('a2a3765e-3a6d-4f6d-a3a7-3cc3476aa876')
+ def test_create_list_delete_namespace_tags(self):
+ # Create a namespace
+ namespace = self.create_namespace()
+ self._create_namespace_tags(namespace)
+ # List namespace tags
+ body = self.namespace_tags_client.list_namespace_tags(
+ namespace['namespace'])
+ self.assertTrue(3, len(body['tags']))
+ self.assertIn(body['tags'][0]['name'], self.tag_list)
+ self.assertIn(body['tags'][1]['name'], self.tag_list)
+ self.assertIn(body['tags'][2]['name'], self.tag_list)
+ # Delete all tag definitions
+ self.namespace_tags_client.delete_namespace_tags(
+ namespace['namespace'])
+ body = self.namespace_tags_client.list_namespace_tags(
+ namespace['namespace'])
+ self.assertEqual([], body['tags'])
+
+ @test.idempotent_id('a2a3765e-1a2c-3f6d-a3a7-3cc3466ab875')
+ def test_create_update_delete_tag(self):
+ # Create a namespace
+ namespace = self.create_namespace()
+ self._create_namespace_tags(namespace)
+ # Create a tag
+ tag_name = data_utils.rand_name('tag_name')
+ self.namespace_tags_client.create_namespace_tag(
+ namespace=namespace['namespace'], tag_name=tag_name)
+
+ body = self.namespace_tags_client.show_namespace_tag(
+ namespace['namespace'], tag_name)
+ self.assertEqual(tag_name, body['name'])
+ # Update tag definition
+ update_tag_definition = data_utils.rand_name('update-tag')
+ body = self.namespace_tags_client.update_namespace_tag(
+ namespace['namespace'], tag_name=tag_name,
+ name=update_tag_definition)
+ self.assertEqual(update_tag_definition, body['name'])
+ # Delete tag definition
+ self.namespace_tags_client.delete_namespace_tag(
+ namespace['namespace'], update_tag_definition)
+ # List namespace tags and validate deletion
+ namespace_tags = [
+ namespace_tag['name'] for namespace_tag in
+ self.namespace_tags_client.list_namespace_tags(
+ namespace['namespace'])['tags']]
+ self.assertNotIn(update_tag_definition, namespace_tags)
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index c2c42bb..132e23e 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -108,10 +108,10 @@
# Not all classes in the hierarchy have the client class variable
if len(cls.metering_label_rules) > 0:
label_rules_client = cls.admin_metering_label_rules_client
- for metering_label_rule in cls.metering_label_rules:
- test_utils.call_and_ignore_notfound_exc(
- label_rules_client.delete_metering_label_rule,
- metering_label_rule['id'])
+ for metering_label_rule in cls.metering_label_rules:
+ test_utils.call_and_ignore_notfound_exc(
+ label_rules_client.delete_metering_label_rule,
+ metering_label_rule['id'])
# Clean up metering labels
for metering_label in cls.metering_labels:
test_utils.call_and_ignore_notfound_exc(
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 535137e..e0216fd 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -121,7 +121,7 @@
if object_name is None:
object_name = data_utils.rand_name(name='TestObject')
if data is None:
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
cls.object_client.create_object(container_name,
object_name,
data,
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index ffdd1de..e555fd9 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -26,17 +26,6 @@
credentials = [['operator', CONF.object_storage.operator_role],
['operator_alt', CONF.object_storage.operator_role]]
- @classmethod
- def setup_credentials(cls):
- super(ObjectTestACLs, cls).setup_credentials()
- cls.os = cls.os_roles_operator
- cls.os_operator = cls.os_roles_operator_alt
-
- @classmethod
- def resource_setup(cls):
- super(ObjectTestACLs, cls).resource_setup()
- cls.test_auth_data = cls.os_operator.auth_provider.auth_data
-
def setUp(self):
super(ObjectTestACLs, self).setUp()
self.container_name = self.create_container()
@@ -49,24 +38,26 @@
def test_read_object_with_rights(self):
# attempt to read object using authorized user
# update X-Container-Read metadata ACL
- tenant_name = self.os_operator.credentials.tenant_name
- username = self.os_operator.credentials.username
+ tenant_name = self.os_roles_operator_alt.credentials.tenant_name
+ username = self.os_roles_operator_alt.credentials.username
cont_headers = {'X-Container-Read': tenant_name + ':' + username}
- resp_meta, body = self.container_client.update_container_metadata(
- self.container_name, metadata=cont_headers,
- metadata_prefix='')
+ resp_meta, body = self.os_roles_operator.container_client.\
+ update_container_metadata(
+ self.container_name, metadata=cont_headers,
+ metadata_prefix='')
self.assertHeaders(resp_meta, 'Container', 'POST')
# create object
object_name = data_utils.rand_name(name='Object')
- resp, _ = self.object_client.create_object(self.container_name,
- object_name, 'data')
+ resp, _ = self.os_roles_operator.object_client.create_object(
+ self.container_name, object_name, 'data')
self.assertHeaders(resp, 'Object', 'PUT')
- # Trying to read the object with rights
- self.object_client.auth_provider.set_alt_auth_data(
+ # set alternative authentication data; cannot simply use the
+ # other object client.
+ self.os_roles_operator.object_client.auth_provider.set_alt_auth_data(
request_part='headers',
- auth_data=self.test_auth_data
- )
- resp, _ = self.object_client.get_object(
+ auth_data=self.os_roles_operator_alt.object_client.auth_provider.
+ auth_data)
+ resp, _ = self.os_roles_operator.object_client.get_object(
self.container_name, object_name)
self.assertHeaders(resp, 'Object', 'GET')
@@ -74,20 +65,23 @@
def test_write_object_with_rights(self):
# attempt to write object using authorized user
# update X-Container-Write metadata ACL
- tenant_name = self.os_operator.credentials.tenant_name
- username = self.os_operator.credentials.username
+ tenant_name = self.os_roles_operator_alt.credentials.tenant_name
+ username = self.os_roles_operator_alt.credentials.username
cont_headers = {'X-Container-Write': tenant_name + ':' + username}
- resp_meta, body = self.container_client.update_container_metadata(
- self.container_name, metadata=cont_headers,
- metadata_prefix='')
+ resp_meta, body = self.os_roles_operator.container_client.\
+ update_container_metadata(self.container_name,
+ metadata=cont_headers,
+ metadata_prefix='')
self.assertHeaders(resp_meta, 'Container', 'POST')
- # Trying to write the object with rights
- self.object_client.auth_provider.set_alt_auth_data(
+ # set alternative authentication data; cannot simply use the
+ # other object client.
+ self.os_roles_operator.object_client.auth_provider.set_alt_auth_data(
request_part='headers',
- auth_data=self.test_auth_data
- )
+ auth_data=self.os_roles_operator_alt.object_client.auth_provider.
+ auth_data)
+ # Trying to write the object with rights
object_name = data_utils.rand_name(name='Object')
- resp, _ = self.object_client.create_object(
+ resp, _ = self.os_roles_operator.object_client.create_object(
self.container_name,
object_name, 'data', headers={})
self.assertHeaders(resp, 'Object', 'PUT')
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index 9ce1b18..e4476a1 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -133,7 +133,7 @@
resp, object_list = self.container_client.list_container_contents(
container_name)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual(object_name, object_list.strip('\n'))
+ self.assertEqual([object_name], object_list)
@test.idempotent_id('4646ac2d-9bfb-4c7d-a3c5-0f527402b3df')
def test_list_container_contents_with_no_object(self):
@@ -143,7 +143,7 @@
resp, object_list = self.container_client.list_container_contents(
container_name)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual('', object_list.strip('\n'))
+ self.assertEmpty(object_list)
@test.idempotent_id('fe323a32-57b9-4704-a996-2e68f83b09bc')
def test_list_container_contents_with_delimiter(self):
@@ -157,7 +157,7 @@
container_name,
params=params)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual(object_name.split('/')[0], object_list.strip('/\n'))
+ self.assertEqual([object_name.split('/')[0] + '/'], object_list)
@test.idempotent_id('55b4fa5c-e12e-4ca9-8fcf-a79afe118522')
def test_list_container_contents_with_end_marker(self):
@@ -170,7 +170,7 @@
container_name,
params=params)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual(object_name, object_list.strip('\n'))
+ self.assertEqual([object_name], object_list)
@test.idempotent_id('196f5034-6ab0-4032-9da9-a937bbb9fba9')
def test_list_container_contents_with_format_json(self):
@@ -226,7 +226,7 @@
container_name,
params=params)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual(object_name, object_list.strip('\n'))
+ self.assertEqual([object_name], object_list)
@test.idempotent_id('c31ddc63-2a58-4f6b-b25c-94d2937e6867')
def test_list_container_contents_with_marker(self):
@@ -239,7 +239,7 @@
container_name,
params=params)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual(object_name, object_list.strip('\n'))
+ self.assertEqual([object_name], object_list)
@test.idempotent_id('58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9')
def test_list_container_contents_with_path(self):
@@ -253,7 +253,7 @@
container_name,
params=params)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual(object_name, object_list.strip('\n'))
+ self.assertEqual([object_name], object_list)
@test.idempotent_id('77e742c7-caf2-4ec9-8aa4-f7d509a3344c')
def test_list_container_contents_with_prefix(self):
@@ -267,7 +267,7 @@
container_name,
params=params)
self.assertHeaders(resp, 'Container', 'GET')
- self.assertEqual(object_name, object_list.strip('\n'))
+ self.assertEqual([object_name], object_list)
@test.attr(type='smoke')
@test.idempotent_id('96e68f0e-19ec-4aa2-86f3-adc6a45e14dd')
diff --git a/tempest/api/object_storage/test_container_staticweb.py b/tempest/api/object_storage/test_container_staticweb.py
index 47ef0d3..edc9271 100644
--- a/tempest/api/object_storage/test_container_staticweb.py
+++ b/tempest/api/object_storage/test_container_staticweb.py
@@ -96,7 +96,7 @@
# Check only the format of common headers with custom matcher
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
- self.assertIn(self.object_name, body)
+ self.assertIn(self.object_name, body.decode())
# clean up before exiting
self.container_client.update_container_metadata(self.container_name,
@@ -126,9 +126,9 @@
resp, body = self.account_client.request("GET",
self.container_name,
headers={})
- self.assertIn(self.object_name, body)
+ self.assertIn(self.object_name, body.decode())
css = '<link rel="stylesheet" type="text/css" href="listings.css" />'
- self.assertIn(css, body)
+ self.assertIn(css, body.decode())
@test.idempotent_id('f18b4bef-212e-45e7-b3ca-59af3a465f82')
@test.requires_ext(extension='staticweb', service='object')
diff --git a/tempest/api/object_storage/test_container_sync.py b/tempest/api/object_storage/test_container_sync.py
index e10b900..f134335 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -96,7 +96,7 @@
cont_client[0].put(str(cont[0]), body=None, headers=headers)
# create object in container
object_name = data_utils.rand_name(name='TestSyncObject')
- data = object_name[::-1] # data_utils.arbitrary_string()
+ data = object_name[::-1].encode() # Raw data, we need bytes
resp, _ = obj_client[0].create_object(cont[0], object_name, data)
self.objects.append(object_name)
@@ -127,7 +127,7 @@
for obj_client, cont in obj_clients:
for obj_name in object_lists[0]:
resp, object_content = obj_client.get_object(cont, obj_name)
- self.assertEqual(object_content, obj_name[::-1])
+ self.assertEqual(object_content, obj_name[::-1].encode())
@test.attr(type='slow')
@decorators.skip_because(bug='1317133')
diff --git a/tempest/api/object_storage/test_crossdomain.py b/tempest/api/object_storage/test_crossdomain.py
index 8dbfd06..18dc254 100644
--- a/tempest/api/object_storage/test_crossdomain.py
+++ b/tempest/api/object_storage/test_crossdomain.py
@@ -40,6 +40,7 @@
@test.requires_ext(extension='crossdomain', service='object')
def test_get_crossdomain_policy(self):
resp, body = self.account_client.get("crossdomain.xml", {})
+ body = body.decode()
self.assertTrue(body.startswith(self.xml_start) and
body.endswith(self.xml_end))
diff --git a/tempest/api/object_storage/test_object_formpost.py b/tempest/api/object_storage/test_object_formpost.py
index 102ec2f..0a87a64 100644
--- a/tempest/api/object_storage/test_object_formpost.py
+++ b/tempest/api/object_storage/test_object_formpost.py
@@ -72,7 +72,9 @@
max_file_count,
expires)
- signature = hmac.new(self.key, hmac_body, hashlib.sha1).hexdigest()
+ signature = hmac.new(
+ self.key.encode(), hmac_body.encode(), hashlib.sha1
+ ).hexdigest()
fields = {'redirect': redirect,
'max_file_size': str(max_file_size),
@@ -119,4 +121,4 @@
resp, body = self.object_client.get("%s/%s%s" % (
self.container_name, self.object_name, "testfile"))
self.assertHeaders(resp, "Object", "GET")
- self.assertEqual(body, "hello world")
+ self.assertEqual(body.decode(), "hello world")
diff --git a/tempest/api/object_storage/test_object_formpost_negative.py b/tempest/api/object_storage/test_object_formpost_negative.py
index 8ff5d82..f193111 100644
--- a/tempest/api/object_storage/test_object_formpost_negative.py
+++ b/tempest/api/object_storage/test_object_formpost_negative.py
@@ -73,7 +73,9 @@
max_file_count,
expires)
- signature = hmac.new(self.key, hmac_body, hashlib.sha1).hexdigest()
+ signature = hmac.new(
+ self.key.encode(), hmac_body.encode(), hashlib.sha1
+ ).hexdigest()
fields = {'redirect': redirect,
'max_file_size': str(max_file_size),
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index e2e9919..7716bdb 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -79,12 +79,12 @@
def test_create_object(self):
# create object
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
resp, _ = self.object_client.create_object(self.container_name,
object_name, data)
# create another object
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
resp, _ = self.object_client.create_object(self.container_name,
object_name, data)
self.assertHeaders(resp, 'Object', 'PUT')
@@ -98,7 +98,7 @@
def test_create_object_with_content_disposition(self):
# create object with content_disposition
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata = {}
metadata['content-disposition'] = 'inline'
resp, _ = self.object_client.create_object(
@@ -122,7 +122,7 @@
object_name = data_utils.rand_name(name='TestObject')
# put compressed string
- data_before = 'x' * 2000
+ data_before = b'x' * 2000
data = zlib.compress(data_before)
metadata = {}
metadata['content-encoding'] = 'deflate'
@@ -147,7 +147,7 @@
def test_create_object_with_etag(self):
# create object with etag
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
md5 = hashlib.md5(data).hexdigest()
metadata = {'Etag': md5}
resp, _ = self.object_client.create_object(
@@ -167,7 +167,7 @@
# create object with expect_continue
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
status, _ = self.object_client.create_object_continue(
self.container_name, object_name, data)
@@ -183,7 +183,7 @@
def test_create_object_with_transfer_encoding(self):
# create object with transfer_encoding
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string(1024)
+ data = data_utils.random_bytes(1024)
status, _, resp_headers = self.object_client.put_object_with_chunk(
container=self.container_name,
name=object_name,
@@ -200,7 +200,7 @@
def test_create_object_with_x_fresh_metadata(self):
# create object with x_fresh_metadata
object_name_base = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata_1 = {'X-Object-Meta-test-meta': 'Meta'}
self.object_client.create_object(self.container_name,
object_name_base,
@@ -226,7 +226,7 @@
def test_create_object_with_x_object_meta(self):
# create object with object_meta
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata = {'X-Object-Meta-test-meta': 'Meta'}
resp, _ = self.object_client.create_object(
self.container_name,
@@ -245,7 +245,7 @@
def test_create_object_with_x_object_metakey(self):
# create object with the blank value of metadata
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata = {'X-Object-Meta-test-meta': ''}
resp, _ = self.object_client.create_object(
self.container_name,
@@ -264,7 +264,7 @@
def test_create_object_with_x_remove_object_meta(self):
# create object with x_remove_object_meta
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata_add = {'X-Object-Meta-test-meta': 'Meta'}
self.object_client.create_object(self.container_name,
object_name,
@@ -287,7 +287,7 @@
def test_create_object_with_x_remove_object_metakey(self):
# create object with the blank value of remove metadata
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata_add = {'X-Object-Meta-test-meta': 'Meta'}
self.object_client.create_object(self.container_name,
object_name,
@@ -310,7 +310,7 @@
def test_delete_object(self):
# create object
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
resp, _ = self.object_client.create_object(self.container_name,
object_name, data)
# delete object
@@ -342,7 +342,7 @@
def test_update_object_metadata_with_remove_metadata(self):
# update object metadata with remove metadata
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
create_metadata = {'X-Object-Meta-test-meta1': 'Meta1'}
self.object_client.create_object(self.container_name,
object_name,
@@ -366,7 +366,7 @@
def test_update_object_metadata_with_create_and_remove_metadata(self):
# creation and deletion of metadata with one request
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
create_metadata = {'X-Object-Meta-test-meta1': 'Meta1'}
self.object_client.create_object(self.container_name,
object_name,
@@ -464,7 +464,7 @@
def test_list_object_metadata(self):
# get object metadata
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata = {'X-Object-Meta-test-meta': 'Meta'}
self.object_client.create_object(self.container_name,
object_name,
@@ -547,7 +547,7 @@
def test_get_object_with_metadata(self):
# get object with metadata
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
metadata = {'X-Object-Meta-test-meta': 'Meta'}
self.object_client.create_object(self.container_name,
object_name,
@@ -566,7 +566,7 @@
def test_get_object_with_range(self):
# get object with range
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string(100)
+ data = data_utils.random_bytes(100)
self.object_client.create_object(self.container_name,
object_name,
data,
@@ -621,13 +621,13 @@
self.assertEqual(resp['x-object-manifest'],
'%s/%s' % (self.container_name, object_name))
- self.assertEqual(''.join(data_segments), body)
+ self.assertEqual(''.join(data_segments), body.decode())
@test.idempotent_id('c05b4013-e4de-47af-be84-e598062b16fc')
def test_get_object_with_if_match(self):
# get object with if_match
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string(10)
+ data = data_utils.random_bytes(10)
create_md5 = hashlib.md5(data).hexdigest()
create_metadata = {'Etag': create_md5}
self.object_client.create_object(self.container_name,
@@ -647,7 +647,7 @@
def test_get_object_with_if_modified_since(self):
# get object with if_modified_since
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string()
+ data = data_utils.random_bytes()
time_now = time.time()
self.object_client.create_object(self.container_name,
object_name,
@@ -667,7 +667,7 @@
def test_get_object_with_if_none_match(self):
# get object with if_none_match
object_name = data_utils.rand_name(name='TestObject')
- data = data_utils.arbitrary_string(10)
+ data = data_utils.random_bytes()
create_md5 = hashlib.md5(data).hexdigest()
create_metadata = {'Etag': create_md5}
self.object_client.create_object(self.container_name,
@@ -675,7 +675,7 @@
data,
metadata=create_metadata)
- list_data = data_utils.arbitrary_string(15)
+ list_data = data_utils.random_bytes()
list_md5 = hashlib.md5(list_data).hexdigest()
list_metadata = {'If-None-Match': list_md5}
resp, body = self.object_client.get_object(
@@ -717,15 +717,13 @@
def test_copy_object_in_same_container(self):
# create source object
src_object_name = data_utils.rand_name(name='SrcObject')
- src_data = data_utils.arbitrary_string(size=len(src_object_name) * 2,
- base_text=src_object_name)
+ src_data = data_utils.random_bytes(size=len(src_object_name) * 2)
resp, _ = self.object_client.create_object(self.container_name,
src_object_name,
src_data)
# create destination object
dst_object_name = data_utils.rand_name(name='DstObject')
- dst_data = data_utils.arbitrary_string(size=len(dst_object_name) * 3,
- base_text=dst_object_name)
+ dst_data = data_utils.random_bytes(size=len(dst_object_name) * 3)
resp, _ = self.object_client.create_object(self.container_name,
dst_object_name,
dst_data)
@@ -764,14 +762,12 @@
def test_copy_object_2d_way(self):
# create source object
src_object_name = data_utils.rand_name(name='SrcObject')
- src_data = data_utils.arbitrary_string(size=len(src_object_name) * 2,
- base_text=src_object_name)
+ src_data = data_utils.random_bytes(size=len(src_object_name) * 2)
resp, _ = self.object_client.create_object(self.container_name,
src_object_name, src_data)
# create destination object
dst_object_name = data_utils.rand_name(name='DstObject')
- dst_data = data_utils.arbitrary_string(size=len(dst_object_name) * 3,
- base_text=dst_object_name)
+ dst_data = data_utils.random_bytes(size=len(dst_object_name) * 3)
resp, _ = self.object_client.create_object(self.container_name,
dst_object_name, dst_data)
# copy source object to destination
@@ -799,8 +795,7 @@
self.containers.append(dst_container_name)
# create object in source container
object_name = data_utils.rand_name(name='Object')
- data = data_utils.arbitrary_string(size=len(object_name) * 2,
- base_text=object_name)
+ data = data_utils.random_bytes(size=len(object_name) * 2)
resp, _ = self.object_client.create_object(src_container_name,
object_name, data)
# set object metadata
@@ -933,7 +928,7 @@
# downloading the object
resp, body = self.object_client.get_object(
self.container_name, object_name)
- self.assertEqual(''.join(data_segments), body)
+ self.assertEqual(''.join(data_segments), body.decode())
@test.idempotent_id('50d01f12-526f-4360-9ac2-75dd508d7b68')
def test_get_object_if_different(self):
@@ -958,7 +953,7 @@
# local copy is different, download
local_data = "something different"
- md5 = hashlib.md5(local_data).hexdigest()
+ md5 = hashlib.md5(local_data.encode()).hexdigest()
headers = {'If-None-Match': md5}
resp, body = self.object_client.get(url, headers=headers)
self.assertHeaders(resp, 'Object', 'GET')
@@ -1002,8 +997,7 @@
# create object
object_name = data_utils.rand_name(name='Object')
- data = data_utils.arbitrary_string(size=len(object_name),
- base_text=object_name)
+ data = data_utils.random_bytes(size=len(object_name))
resp, _ = self.object_client.create_object(self.container_name,
object_name, data)
self.assertHeaders(resp, 'Object', 'PUT')
@@ -1039,8 +1033,7 @@
# create object
object_name = data_utils.rand_name(name='Object')
- data = data_utils.arbitrary_string(size=len(object_name) * 1,
- base_text=object_name)
+ data = data_utils.random_bytes(size=len(object_name))
resp, _ = self.object_client.create_object(self.container_name,
object_name, data)
self.assertHeaders(resp, 'Object', 'PUT')
diff --git a/tempest/api/object_storage/test_object_slo.py b/tempest/api/object_storage/test_object_slo.py
index e00bbab..f9c1148 100644
--- a/tempest/api/object_storage/test_object_slo.py
+++ b/tempest/api/object_storage/test_object_slo.py
@@ -56,7 +56,7 @@
object_name_base_1 = object_name + '_01'
object_name_base_2 = object_name + '_02'
data_size = MIN_SEGMENT_SIZE
- self.content = data_utils.arbitrary_string(data_size)
+ self.content = data_utils.random_bytes(data_size)
self._create_object(self.container_name,
object_name_base_1,
self.content)
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index 7287a2d..bd0d213 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -75,7 +75,9 @@
container, object_name)
hmac_body = '%s\n%s\n%s' % (method, expires, path)
- sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest()
+ sig = hmac.new(
+ key.encode(), hmac_body.encode(), hashlib.sha1
+ ).hexdigest()
url = "%s/%s?temp_url_sig=%s&temp_url_expires=%s" % (container,
object_name,
@@ -129,9 +131,7 @@
@test.idempotent_id('9b08dade-3571-4152-8a4f-a4f2a873a735')
@test.requires_ext(extension='tempurl', service='object')
def test_put_object_using_temp_url(self):
- new_data = data_utils.arbitrary_string(
- size=len(self.object_name),
- base_text=data_utils.rand_name(name="random"))
+ new_data = data_utils.random_bytes(size=len(self.object_name))
expires = self._get_expiry_date()
url = self._get_temp_url(self.container_name,
diff --git a/tempest/api/object_storage/test_object_temp_url_negative.py b/tempest/api/object_storage/test_object_temp_url_negative.py
index 577f3bd..df7a7f6 100644
--- a/tempest/api/object_storage/test_object_temp_url_negative.py
+++ b/tempest/api/object_storage/test_object_temp_url_negative.py
@@ -80,7 +80,9 @@
container, object_name)
hmac_body = '%s\n%s\n%s' % (method, expires, path)
- sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest()
+ sig = hmac.new(
+ key.encode(), hmac_body.encode(), hashlib.sha1
+ ).hexdigest()
url = "%s/%s?temp_url_sig=%s&temp_url_expires=%s" % (container,
object_name,
diff --git a/tempest/api/object_storage/test_object_version.py b/tempest/api/object_storage/test_object_version.py
index 3f6623b..6d064a2 100644
--- a/tempest/api/object_storage/test_object_version.py
+++ b/tempest/api/object_storage/test_object_version.py
@@ -69,22 +69,24 @@
vers_container_name)
object_name = data_utils.rand_name(name='TestObject')
# create object
+ data_1 = data_utils.random_bytes()
resp, _ = self.object_client.create_object(base_container_name,
- object_name, '1')
+ object_name, data_1)
# create 2nd version of object
+ data_2 = data_utils.random_bytes()
resp, _ = self.object_client.create_object(base_container_name,
- object_name, '2')
+ object_name, data_2)
resp, body = self.object_client.get_object(base_container_name,
object_name)
- self.assertEqual(body, '2')
+ self.assertEqual(body, data_2)
# delete object version 2
resp, _ = self.object_client.delete_object(base_container_name,
object_name)
- self.assertContainer(base_container_name, '1', '1',
+ self.assertContainer(base_container_name, '1', '1024',
vers_container_name)
resp, body = self.object_client.get_object(base_container_name,
object_name)
- self.assertEqual(body, '1')
+ self.assertEqual(body, data_1)
# delete object version 1
resp, _ = self.object_client.delete_object(base_container_name,
object_name)
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
index c0f1c4b..3672526 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/api/volume/admin/test_volume_retype_with_migration.py b/tempest/api/volume/admin/test_volume_retype_with_migration.py
new file mode 100644
index 0000000..8a69ea3
--- /dev/null
+++ b/tempest/api/volume/admin/test_volume_retype_with_migration.py
@@ -0,0 +1,109 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+
+from oslo_log import log as logging
+
+from tempest.api.volume import base
+from tempest.common import waiters
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+LOG = logging.getLogger(__name__)
+
+
+class VolumeRetypeWithMigrationV2Test(base.BaseVolumeAdminTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(VolumeRetypeWithMigrationV2Test, cls).skip_checks()
+
+ if not CONF.volume_feature_enabled.multi_backend:
+ raise cls.skipException("Cinder multi-backend feature disabled.")
+
+ if len(set(CONF.volume.backend_names)) < 2:
+ raise cls.skipException("Requires at least two different "
+ "backend names")
+
+ @classmethod
+ 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]
+
+ extra_specs_src = {"volume_backend_name": cls.backend_src}
+ extra_specs_dst = {"volume_backend_name": cls.backend_dst}
+
+ cls.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'])
+
+ @classmethod
+ def resource_cleanup(cls):
+ # When retyping a volume, Cinder creates an internal volume in the
+ # target backend. The volume in the source backend is deleted after
+ # the migration, so we need to wait for Cinder delete this volume
+ # before deleting the types we've created.
+
+ # This list should return 2 volumes until the copy and cleanup
+ # process is finished.
+ fetched_list = cls.admin_volume_client.list_volumes(
+ params={'all_tenants': True,
+ 'display_name': cls.src_vol['name']})['volumes']
+
+ for fetched_vol in fetched_list:
+ if fetched_vol['id'] != cls.src_vol['id']:
+ # This is the Cinder internal volume
+ LOG.debug('Waiting for internal volume %s deletion',
+ fetched_vol['id'])
+ cls.admin_volume_client.wait_for_resource_deletion(
+ fetched_vol['id'])
+ break
+
+ super(VolumeRetypeWithMigrationV2Test, cls).resource_cleanup()
+
+ @test.idempotent_id('a1a41f3f-9dad-493e-9f09-3ff197d477cd')
+ def test_available_volume_retype_with_migration(self):
+
+ keys_with_no_change = ('id', 'size', 'description', 'name', 'user_id',
+ 'os-vol-tenant-attr:tenant_id')
+ keys_with_change = ('volume_type', 'os-vol-host-attr:host')
+
+ volume_source = self.admin_volume_client.show_volume(
+ self.src_vol['id'])['volume']
+
+ # TODO(erlon): change this to volumes_client client after Bug
+ # #1657806 is fixed
+ self.admin_volume_client.retype_volume(
+ self.src_vol['id'],
+ new_type=self.dst_vol_type['name'],
+ migration_policy='on-demand')
+
+ waiters.wait_for_volume_retype(self.volumes_client, self.src_vol['id'],
+ self.dst_vol_type['name'])
+ volume_dest = self.admin_volume_client.show_volume(
+ self.src_vol['id'])['volume']
+
+ # Check the volume information after the migration.
+ self.assertEqual('success',
+ volume_dest['os-vol-mig-status-attr:migstat'])
+ self.assertEqual('success', volume_dest['migration_status'])
+
+ for key in keys_with_no_change:
+ self.assertEqual(volume_source[key], volume_dest[key])
+
+ for key in keys_with_change:
+ self.assertNotEqual(volume_source[key], volume_dest[key])
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 6b2acc6..16be463 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -42,7 +42,7 @@
extra_specs = {"storage_protocol": proto,
"vendor_name": vendor}
# Create two volume_types
- for i in range(2):
+ for _ in range(2):
vol_type = self.create_volume_type(
extra_specs=extra_specs)
volume_types.append(vol_type)
@@ -84,7 +84,6 @@
@test.idempotent_id('4e955c3b-49db-4515-9590-0c99f8e471ad')
def test_volume_type_create_get_delete(self):
# Create/get volume type.
- body = {}
name = data_utils.rand_name(self.__class__.__name__ + '-volume-type')
description = data_utils.rand_name("volume-type-description")
proto = CONF.volume.storage_protocol
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index 857e7d2..5332f1e 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -51,6 +51,14 @@
self.admin_volume_types_client.delete_volume_type,
data_utils.rand_uuid())
+ @test.idempotent_id('8c09f849-f225-4d78-ba87-bffd9a5e0c6f')
+ def test_create_volume_with_private_volume_type(self):
+ # Should not be able to create volume with private volume type.
+ params = {'os-volume-type-access:is_public': False}
+ volume_type = self.create_volume_type(**params)
+ self.assertRaises(lib_exc.NotFound,
+ self.create_volume, volume_type=volume_type['id'])
+
class VolumeTypesNegativeV1Test(VolumeTypesNegativeV2Test):
_api_version = 1
diff --git a/tempest/api/volume/admin/v2/test_backends_capabilities.py b/tempest/api/volume/admin/v2/test_backends_capabilities.py
index fc9066c..9751845 100644
--- a/tempest/api/volume/admin/v2/test_backends_capabilities.py
+++ b/tempest/api/volume/admin/v2/test_backends_capabilities.py
@@ -72,8 +72,8 @@
]
# Returns a tuple of VOLUME_STATS values
- expected_list = map(operator.itemgetter(*VOLUME_STATS),
- cinder_pools)
- observed_list = map(operator.itemgetter(*VOLUME_STATS),
- capabilities)
+ expected_list = list(map(operator.itemgetter(*VOLUME_STATS),
+ cinder_pools))
+ observed_list = list(map(operator.itemgetter(*VOLUME_STATS),
+ capabilities))
self.assertEqual(expected_list, observed_list)
diff --git a/tempest/api/volume/admin/v2/test_snapshot_manage.py b/tempest/api/volume/admin/v2/test_snapshot_manage.py
new file mode 100644
index 0000000..6a3f9ee
--- /dev/null
+++ b/tempest/api/volume/admin/v2/test_snapshot_manage.py
@@ -0,0 +1,73 @@
+# Copyright 2016 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 testtools
+
+from tempest.api.volume import base
+from tempest.common import waiters
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class SnapshotManageAdminV2Test(base.BaseVolumeAdminTest):
+ """Unmanage & manage snapshots
+
+ This feature provides the ability to import/export volume snapshot
+ from one Cinder to another and to import snapshots that have not been
+ managed by Cinder from a storage back end to Cinder
+ """
+
+ @test.idempotent_id('0132f42d-0147-4b45-8501-cc504bbf7810')
+ @testtools.skipUnless(CONF.volume_feature_enabled.manage_snapshot,
+ "Manage snapshot tests are disabled")
+ def test_unmanage_manage_snapshot(self):
+ # Create a volume
+ volume = self.create_volume()
+
+ # Create a snapshot
+ snapshot = self.create_snapshot(volume_id=volume['id'])
+
+ # Unmanage the snapshot
+ # Unmanage snapshot function works almost the same as delete snapshot,
+ # but it does not delete the snapshot data
+ self.admin_snapshots_client.unmanage_snapshot(snapshot['id'])
+ self.admin_snapshots_client.wait_for_resource_deletion(snapshot['id'])
+
+ # Fetch snapshot ids
+ snapshot_list = [
+ snap['id'] for snap in
+ self.snapshots_client.list_snapshots()['snapshots']
+ ]
+
+ # Verify snapshot does not exist in snapshot list
+ self.assertNotIn(snapshot['id'], snapshot_list)
+
+ # Manage the snapshot
+ snapshot_ref = '_snapshot-%s' % snapshot['id']
+ new_snapshot = self.admin_snapshot_manage_client.manage_snapshot(
+ volume_id=volume['id'],
+ ref={'source-name': snapshot_ref})['snapshot']
+ self.addCleanup(self.delete_snapshot,
+ self.admin_snapshots_client, new_snapshot['id'])
+
+ # Wait for the snapshot to be available after manage operation
+ waiters.wait_for_snapshot_status(self.admin_snapshots_client,
+ new_snapshot['id'],
+ 'available')
+
+ # Verify the managed snapshot has the expected parent volume
+ self.assertEqual(new_snapshot['volume_id'], volume['id'])
diff --git a/tempest/api/volume/admin/v2/test_volumes_list.py b/tempest/api/volume/admin/v2/test_volumes_list.py
index cdd9df9..fd36d0a 100644
--- a/tempest/api/volume/admin/v2/test_volumes_list.py
+++ b/tempest/api/volume/admin/v2/test_volumes_list.py
@@ -32,7 +32,7 @@
# NOTE(zhufl): When using pre-provisioned credentials, the project
# may have volumes other than those created below.
cls.volume_list = cls.volumes_client.list_volumes()['volumes']
- for i in range(3):
+ for _ in range(3):
volume = cls.create_volume()
# Fetch volume details
volume_details = cls.volumes_client.show_volume(
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 90dc7f4..98e050e 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -165,14 +165,20 @@
# NOTE(afazekas): these create_* and clean_* could be defined
# only in a single location in the source, and could be more general.
- @classmethod
- def delete_volume(cls, client, volume_id):
+ @staticmethod
+ def delete_volume(client, volume_id):
"""Delete volume by the given client"""
client.delete_volume(volume_id)
client.wait_for_resource_deletion(volume_id)
+ @staticmethod
+ def delete_snapshot(client, snapshot_id):
+ """Delete snapshot by the given client"""
+ client.delete_snapshot(snapshot_id)
+ client.wait_for_resource_deletion(snapshot_id)
+
def attach_volume(self, server_id, volume_id):
- """Attachs a volume to a server"""
+ """Attach a volume to a server"""
self.servers_client.attach_volume(
server_id, volumeId=volume_id,
device='/dev/%s' % CONF.compute.volume_device_name)
@@ -257,6 +263,8 @@
cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
cls.admin_volume_client = cls.os_adm.volumes_v2_client
cls.admin_hosts_client = cls.os_adm.volume_hosts_v2_client
+ cls.admin_snapshot_manage_client = \
+ cls.os_adm.snapshot_manage_v2_client
cls.admin_snapshots_client = cls.os_adm.snapshots_v2_client
cls.admin_backups_client = cls.os_adm.backups_v2_client
cls.admin_encryption_types_client = \
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 70b3c58..6dcde08 100644
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -89,14 +89,7 @@
volume['id'])
server = self.create_server(wait_until='ACTIVE')
# Attach volume to instance
- self.servers_client.attach_volume(server['id'],
- volumeId=volume['id'])
- waiters.wait_for_volume_status(self.volumes_client,
- volume['id'], 'in-use')
- self.addCleanup(waiters.wait_for_volume_status, self.volumes_client,
- volume['id'], 'available')
- self.addCleanup(self.servers_client.detach_volume, server['id'],
- volume['id'])
+ self.attach_volume(server['id'], volume['id'])
# Create backup using force flag
backup_name = data_utils.rand_name(
self.__class__.__name__ + '-Backup')
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 030ea6c..5e3f49f 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -61,7 +61,7 @@
# Create 3 test volumes
cls.volume_list = []
cls.metadata = {'Type': 'work'}
- for i in range(3):
+ for _ in range(3):
volume = cls.create_volume(metadata=cls.metadata)
volume = cls.volumes_client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index c45ace6..bcdbd22 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -133,7 +133,8 @@
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
metadata = {'Type': 'work'}
self.assertRaises(lib_exc.NotFound, self.volumes_client.update_volume,
- volume_id='#$%%&^&^', display_name=v_name,
+ volume_id=data_utils.rand_name('invalid'),
+ display_name=v_name,
metadata=metadata)
@test.attr(type=['negative'])
@@ -150,7 +151,7 @@
def test_get_invalid_volume_id(self):
# Should not be able to get volume with invalid id
self.assertRaises(lib_exc.NotFound, self.volumes_client.show_volume,
- '#$%%&^&^')
+ data_utils.rand_name('invalid'))
@test.attr(type=['negative'])
@test.idempotent_id('c6c3db06-29ad-4e91-beb0-2ab195fe49e3')
@@ -164,7 +165,7 @@
def test_delete_invalid_volume_id(self):
# Should not be able to delete volume when invalid ID is passed
self.assertRaises(lib_exc.NotFound, self.volumes_client.delete_volume,
- '!@#$%^&*()')
+ data_utils.rand_name('invalid'))
@test.attr(type=['negative'])
@test.idempotent_id('441a1550-5d44-4b30-af0f-a6d402f52026')
diff --git a/tempest/api/volume/test_volumes_snapshots_list.py b/tempest/api/volume/test_volumes_snapshots_list.py
index 4416bef..b831252 100644
--- a/tempest/api/volume/test_volumes_snapshots_list.py
+++ b/tempest/api/volume/test_volumes_snapshots_list.py
@@ -105,12 +105,6 @@
# List returns zero elements
self._list_snapshots_by_param_limit(limit=0, expected_elements=0)
- def cleanup_snapshot(self, snapshot):
- # Delete the snapshot
- self.snapshots_client.delete_snapshot(snapshot['id'])
- self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
- self.snapshots.remove(snapshot)
-
class VolumesV1SnapshotLimitTestJSON(VolumesV2SnapshotListTestJSON):
_api_version = 1
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index fb8c65d..28ba941 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -42,7 +42,7 @@
# 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 i in range(3):
+ for _ in range(3):
volume = cls.create_volume(metadata=cls.metadata)
cls.volume_id_list.append(volume['id'])
diff --git a/tempest/api/volume/v2/test_volumes_snapshots_list.py b/tempest/api/volume/v2/test_volumes_snapshots_list.py
new file mode 100644
index 0000000..f389b59
--- /dev/null
+++ b/tempest/api/volume/v2/test_volumes_snapshots_list.py
@@ -0,0 +1,94 @@
+# Copyright 2016 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.
+
+from tempest.api.volume import base
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class VolumesV2SnapshotListTestJSON(base.BaseVolumeTest):
+
+ @classmethod
+ def skip_checks(cls):
+ super(VolumesV2SnapshotListTestJSON, cls).skip_checks()
+ if not CONF.volume_feature_enabled.snapshot:
+ raise cls.skipException("Cinder volume snapshots are disabled")
+
+ @classmethod
+ def resource_setup(cls):
+ 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']
+ # Create 3 snapshots
+ for _ in range(3):
+ snapshot = cls.create_snapshot(cls.volume_origin['id'])
+ cls.snapshot_id_list.append(snapshot['id'])
+
+ def _list_snapshots_param_sort(self, sort_key, sort_dir):
+ """list snapshots by sort param"""
+ snap_list = self.snapshots_client.list_snapshots(
+ sort_key=sort_key, sort_dir=sort_dir)['snapshots']
+ self.assertNotEmpty(snap_list)
+ if sort_key is 'display_name':
+ sort_key = 'name'
+ # Note: On Cinder V2 API, 'display_name' works as a sort key
+ # on a request, a volume name appears as 'name' on the response.
+ # So Tempest needs to change the key name here for this inconsistent
+ # API behavior.
+ sorted_list = [snapshot[sort_key] for snapshot in snap_list]
+ msg = 'The list of snapshots was not sorted correctly.'
+ self.assertEqual(sorted(sorted_list, reverse=(sort_dir == 'desc')),
+ sorted_list, msg)
+
+ @test.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')
+ 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')
+ 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')
+ 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')
+ 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')
+ 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')
+ def test_snapshot_list_param_marker(self):
+ # The list of snapshots should end before the provided marker
+ params = {'marker': self.snapshot_id_list[1]}
+ snap_list = self.snapshots_client.list_snapshots(**params)['snapshots']
+ fetched_list_id = [snap['id'] for snap in snap_list]
+ # Verify the list of snapshots ends before the provided
+ # marker(second snapshot), therefore only the first snapshot
+ # should displayed.
+ self.assertEqual(self.snapshot_id_list[:1], fetched_list_id)
diff --git a/tempest/clients.py b/tempest/clients.py
index f99060a..cdd6925 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -19,7 +19,6 @@
from tempest.lib import auth
from tempest.lib import exceptions as lib_exc
from tempest.lib.services import clients
-from tempest.lib.services import identity
from tempest.services import object_storage
from tempest.services import orchestration
@@ -32,14 +31,6 @@
default_params = config.service_client_config()
- # TODO(jordanP): remove this once no Tempest plugin use that class
- # variable.
- default_params_with_timeout_values = {
- 'build_interval': CONF.compute.build_interval,
- 'build_timeout': CONF.compute.build_timeout
- }
- default_params_with_timeout_values.update(default_params)
-
def __init__(self, credentials, scope='project'):
"""Initialization of Manager class.
@@ -132,6 +123,8 @@
self.schemas_client = self.image_v2.SchemasClient()
self.namespace_properties_client = \
self.image_v2.NamespacePropertiesClient()
+ self.namespace_tags_client = \
+ self.image_v2.NamespaceTagsClient()
def _set_compute_clients(self):
self.agents_client = self.compute.AgentsClient()
@@ -164,6 +157,7 @@
self.aggregates_client = self.compute.AggregatesClient()
self.services_client = self.compute.ServicesClient()
self.tenant_usages_client = self.compute.TenantUsagesClient()
+ self.baremetal_nodes_client = self.compute.BaremetalNodesClient()
self.hosts_client = self.compute.HostsClient()
self.hypervisor_client = self.compute.HypervisorClient()
self.instance_usages_audit_log_client = (
@@ -237,15 +231,15 @@
# API version is marked as enabled
if CONF.identity_feature_enabled.api_v2:
if CONF.identity.uri:
- self.token_client = identity.v2.TokenClient(
- CONF.identity.uri, **self.default_params)
+ self.token_client = self.identity_v2.TokenClient(
+ auth_url=CONF.identity.uri)
else:
msg = 'Identity v2 API enabled, but no identity.uri set'
raise lib_exc.InvalidConfiguration(msg)
if CONF.identity_feature_enabled.api_v3:
if CONF.identity.uri_v3:
- self.token_v3_client = identity.v3.V3TokenClient(
- CONF.identity.uri_v3, **self.default_params)
+ self.token_v3_client = self.identity_v3.V3TokenClient(
+ auth_url=CONF.identity.uri_v3)
else:
msg = 'Identity v3 API enabled, but no identity.uri_v3 set'
raise lib_exc.InvalidConfiguration(msg)
@@ -261,6 +255,7 @@
self.encryption_types_client = self.volume_v1.EncryptionTypesClient()
self.encryption_types_v2_client = \
self.volume_v2.EncryptionTypesClient()
+ self.snapshot_manage_v2_client = self.volume_v2.SnapshotManageClient()
self.snapshots_client = self.volume_v1.SnapshotsClient()
self.snapshots_v2_client = self.volume_v2.SnapshotsClient()
self.volumes_client = self.volume_v1.VolumesClient()
diff --git a/tempest/cmd/run.py b/tempest/cmd/run.py
index a3105e0..54b844a 100644
--- a/tempest/cmd/run.py
+++ b/tempest/cmd/run.py
@@ -21,7 +21,7 @@
* **--regex/-r**: This is a selection regex like what testr uses. It will run
any tests that match on re.match() with the regex
- * **--smoke**: Run all the tests tagged as smoke
+ * **--smoke/-s**: Run all the tests tagged as smoke
There are also the **--blacklist-file** and **--whitelist-file** options that
let you pass a filepath to tempest run with the file format being a line
@@ -52,7 +52,7 @@
There are several options to control how the tests are executed. By default
tempest will run in parallel with a worker for each CPU present on the machine.
If you want to adjust the number of workers use the **--concurrency** option
-and if you want to run tests serially use **--serial**
+and if you want to run tests serially use **--serial/-t**
Running with Workspaces
-----------------------
@@ -198,7 +198,7 @@
help='Configuration file to run tempest with')
# test selection args
regex = parser.add_mutually_exclusive_group()
- regex.add_argument('--smoke', action='store_true',
+ regex.add_argument('--smoke', '-s', action='store_true',
help="Run the smoke tests only")
regex.add_argument('--regex', '-r', default='',
help='A normal testr selection regex used to '
@@ -225,7 +225,7 @@
action='store_true',
help='Run tests in parallel (this is the'
' default)')
- parallel.add_argument('--serial', dest='parallel',
+ parallel.add_argument('--serial', '-t', dest='parallel',
action='store_false',
help='Run tests serially')
# output args
diff --git a/tempest/cmd/workspace.py b/tempest/cmd/workspace.py
index 3c58648..d2dc00d 100644
--- a/tempest/cmd/workspace.py
+++ b/tempest/cmd/workspace.py
@@ -151,7 +151,7 @@
if not os.path.isfile(self.path):
return
with open(self.path, 'r') as f:
- self.workspaces = yaml.load(f) or {}
+ self.workspaces = yaml.safe_load(f) or {}
class TempestWorkspace(command.Command):
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 4f2fe67..01de704 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -30,8 +30,7 @@
def create_test_server(clients, validatable=False, validation_resources=None,
tenant_network=None, wait_until=None,
volume_backed=False, name=None, flavor=None,
- image_id=None, delete_vol_on_termination=True,
- **kwargs):
+ image_id=None, **kwargs):
"""Common wrapper utility returning a test server.
This method is a common wrapper returning a test server that can be
@@ -44,16 +43,30 @@
:param tenant_network: Tenant network to be used for creating a server.
:param wait_until: Server status to wait for the server to reach after
its creation.
- :param volume_backed: Whether the instance is volume backed or not.
+ :param volume_backed: Whether the server is volume backed or not.
+ If this is true, a volume will be created and
+ create server will be requested with
+ 'block_device_mapping_v2' populated with below
+ values:
+ --------------------------------------------
+ bd_map_v2 = [{
+ 'uuid': volume['volume']['id'],
+ 'source_type': 'volume',
+ 'destination_type': 'volume',
+ 'boot_index': 0,
+ 'delete_on_termination': True}]
+ kwargs['block_device_mapping_v2'] = bd_map_v2
+ ---------------------------------------------
+ If server needs to be booted from volume with other
+ combination of bdm inputs than mentioned above, then
+ pass the bdm inputs explicitly as kwargs and image_id
+ as empty string ('').
:param name: Name of the server to be provisioned. If not defined a random
string ending with '-instance' will be generated.
:param flavor: Flavor of the server to be provisioned. If not defined,
CONF.compute.flavor_ref will be used instead.
:param image_id: ID of the image to be used to provision the server. If not
defined, CONF.compute.image_ref will be used instead.
- :param delete_vol_on_termination: Controls whether the backing volume
- should be deleted when the server is deleted. Only applies to volume
- backed servers.
:returns: a tuple
"""
@@ -103,12 +116,14 @@
if volume_backed:
volume_name = data_utils.rand_name(__name__ + '-volume')
volumes_client = clients.volumes_v2_client
- if CONF.volume_feature_enabled.api_v1:
+ name_field = 'name'
+ if not CONF.volume_feature_enabled.api_v2:
volumes_client = clients.volumes_client
- volume = volumes_client.create_volume(
- display_name=volume_name,
- imageRef=image_id,
- size=CONF.volume.volume_size)
+ name_field = 'display_name'
+ params = {name_field: volume_name,
+ 'imageRef': image_id,
+ 'size': CONF.volume.volume_size}
+ volume = volumes_client.create_volume(**params)
waiters.wait_for_volume_status(volumes_client,
volume['volume']['id'], 'available')
@@ -117,7 +132,7 @@
'source_type': 'volume',
'destination_type': 'volume',
'boot_index': 0,
- 'delete_on_termination': delete_vol_on_termination}]
+ 'delete_on_termination': True}]
kwargs['block_device_mapping_v2'] = bd_map_v2
# Since this is boot from volume an image does not need
diff --git a/tempest/common/preprov_creds.py b/tempest/common/preprov_creds.py
index 6a95588..a92d16a 100644
--- a/tempest/common/preprov_creds.py
+++ b/tempest/common/preprov_creds.py
@@ -33,7 +33,7 @@
def read_accounts_yaml(path):
try:
with open(path, 'r') as yaml_file:
- accounts = yaml.load(yaml_file)
+ accounts = yaml.safe_load(yaml_file)
except IOError:
raise lib_exc.InvalidConfiguration(
'The path for the test accounts file: %s '
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index fe648a0..8303caf 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -189,6 +189,25 @@
raise lib_exc.TimeoutException(message)
+def wait_for_volume_retype(client, volume_id, new_volume_type):
+ """Waits for a Volume to have a new volume type."""
+ body = client.show_volume(volume_id)['volume']
+ current_volume_type = body['volume_type']
+ start = int(time.time())
+
+ while current_volume_type != new_volume_type:
+ time.sleep(client.build_interval)
+ body = client.show_volume(volume_id)['volume']
+ current_volume_type = body['volume_type']
+
+ if int(time.time()) - start >= client.build_timeout:
+ message = ('Volume %s failed to reach %s volume type (current %s) '
+ 'within the required time (%s s).' %
+ (volume_id, new_volume_type, current_volume_type,
+ client.build_timeout))
+ raise exceptions.TimeoutException(message)
+
+
def wait_for_snapshot_status(client, snapshot_id, status):
"""Waits for a Snapshot to reach a given status."""
body = client.show_snapshot(snapshot_id)['snapshot']
diff --git a/tempest/config.py b/tempest/config.py
index ea7811d..fe8c175 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -16,7 +16,6 @@
from __future__ import print_function
import functools
-import logging as std_logging
import os
import tempfile
@@ -332,9 +331,12 @@
# NOTE(mriedem): This is a feature toggle for bug 1175464 which is fixed in
# mitaka and newton. This option can be removed after liberty-eol.
cfg.BoolOpt('allow_port_security_disabled',
- default=False,
+ default=True,
help='Does the test environment support creating ports in a '
- 'network where port security is disabled?'),
+ 'network where port security is disabled?',
+ deprecated_for_removal=True,
+ deprecated_reason='This config switch was added for Liberty '
+ 'which is not supported anymore.'),
cfg.BoolOpt('disk_config',
default=True,
help="If false, skip disk config tests"),
@@ -804,6 +806,9 @@
cfg.BoolOpt('clone',
default=True,
help='Runs Cinder volume clone test'),
+ cfg.BoolOpt('manage_snapshot',
+ default=False,
+ help='Runs Cinder manage snapshot tests'),
cfg.ListOpt('api_extensions',
default=['all'],
help='A list of enabled volume extensions with a special '
@@ -1193,7 +1198,7 @@
register_opts()
self._set_attrs()
if parse_conf:
- _CONF.log_opt_values(LOG, std_logging.DEBUG)
+ _CONF.log_opt_values(LOG, logging.DEBUG)
class TempestConfigProxy(object):
@@ -1201,14 +1206,14 @@
_path = None
_extra_log_defaults = [
- ('paramiko.transport', std_logging.INFO),
- ('requests.packages.urllib3.connectionpool', std_logging.WARN),
+ ('paramiko.transport', logging.INFO),
+ ('requests.packages.urllib3.connectionpool', logging.WARN),
]
def _fix_log_levels(self):
"""Tweak the oslo log defaults."""
for name, level in self._extra_log_defaults:
- std_logging.getLogger(name).setLevel(level)
+ logging.getLogger(name).logger.setLevel(level)
def __getattr__(self, attr):
if not self._config:
diff --git a/tempest/lib/api_schema/response/compute/v2_1/aggregates.py b/tempest/lib/api_schema/response/compute/v2_1/aggregates.py
index 1a9fe41..3289a34 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/aggregates.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/aggregates.py
@@ -14,17 +14,19 @@
import copy
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
# create-aggregate api doesn't have 'hosts' and 'metadata' attributes.
aggregate_for_create = {
'type': 'object',
'properties': {
'availability_zone': {'type': ['string', 'null']},
- 'created_at': {'type': 'string'},
+ 'created_at': parameter_types.date_time,
'deleted': {'type': 'boolean'},
- 'deleted_at': {'type': ['string', 'null']},
+ 'deleted_at': parameter_types.date_time_or_null,
'id': {'type': 'integer'},
'name': {'type': 'string'},
- 'updated_at': {'type': ['string', 'null']}
+ 'updated_at': parameter_types.date_time_or_null
},
'additionalProperties': False,
'required': ['availability_zone', 'created_at', 'deleted',
@@ -69,9 +71,7 @@
# The 'updated_at' attribute of 'update_aggregate' can't be null.
update_aggregate = copy.deepcopy(get_aggregate)
update_aggregate['response_body']['properties']['aggregate']['properties'][
- 'updated_at'] = {
- 'type': 'string'
- }
+ 'updated_at'] = parameter_types.date_time
delete_aggregate = {
'status_code': [200]
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 d9aebce..f7b77a1 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
@@ -14,6 +14,8 @@
import copy
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
base = {
'status_code': [200],
@@ -61,7 +63,7 @@
'properties': {
'available': {'type': 'boolean'},
'active': {'type': 'boolean'},
- 'updated_at': {'type': ['string', 'null']}
+ 'updated_at': parameter_types.date_time_or_null
},
'additionalProperties': False,
'required': ['available', 'active', 'updated_at']
diff --git a/tempest/lib/api_schema/response/compute/v2_1/extensions.py b/tempest/lib/api_schema/response/compute/v2_1/extensions.py
index a6a455c..b5962d7 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/extensions.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/extensions.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
list_extensions = {
'status_code': [200],
'response_body': {
@@ -22,10 +24,7 @@
'items': {
'type': 'object',
'properties': {
- 'updated': {
- 'type': 'string',
- 'format': 'data-time'
- },
+ 'updated': parameter_types.date_time,
'name': {'type': 'string'},
'links': {'type': 'array'},
'namespace': {
diff --git a/tempest/lib/api_schema/response/compute/v2_1/hosts.py b/tempest/lib/api_schema/response/compute/v2_1/hosts.py
index ae70ff1..cae3435 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/hosts.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/hosts.py
@@ -111,6 +111,9 @@
'status': {'enum': ['enabled', 'disabled']}
},
'additionalProperties': False,
- 'required': ['host', 'maintenance_mode', 'status']
+ 'anyOf': [
+ {'required': ['host', 'status']},
+ {'required': ['host', 'maintenance_mode']}
+ ]
}
}
diff --git a/tempest/lib/api_schema/response/compute/v2_1/images.py b/tempest/lib/api_schema/response/compute/v2_1/images.py
index f65b9d8..156ff4a 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/images.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/images.py
@@ -26,10 +26,10 @@
'properties': {
'id': {'type': 'string'},
'status': {'enum': image_status_enums},
- 'updated': {'type': 'string'},
+ 'updated': parameter_types.date_time,
'links': image_links,
'name': {'type': ['string', 'null']},
- 'created': {'type': 'string'},
+ 'created': parameter_types.date_time,
'minDisk': {'type': 'integer'},
'minRam': {'type': 'integer'},
'progress': {'type': 'integer'},
diff --git a/tempest/lib/api_schema/response/compute/v2_1/keypairs.py b/tempest/lib/api_schema/response/compute/v2_1/keypairs.py
index 9c04c79..2828097 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/keypairs.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/keypairs.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
get_keypair = {
'status_code': [200],
'response_body': {
@@ -25,9 +27,9 @@
'fingerprint': {'type': 'string'},
'user_id': {'type': 'string'},
'deleted': {'type': 'boolean'},
- 'created_at': {'type': 'string'},
- 'updated_at': {'type': ['string', 'null']},
- 'deleted_at': {'type': ['string', 'null']},
+ 'created_at': parameter_types.date_time,
+ 'updated_at': parameter_types.date_time_or_null,
+ 'deleted_at': parameter_types.date_time_or_null,
'id': {'type': 'integer'}
},
diff --git a/tempest/lib/api_schema/response/compute/v2_1/migrations.py b/tempest/lib/api_schema/response/compute/v2_1/migrations.py
index b7d66ea..c50286d 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/migrations.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/migrations.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
list_migrations = {
'status_code': [200],
'response_body': {
@@ -32,8 +34,8 @@
'dest_host': {'type': ['string', 'null']},
'old_instance_type_id': {'type': ['integer', 'null']},
'new_instance_type_id': {'type': ['integer', 'null']},
- 'created_at': {'type': 'string'},
- 'updated_at': {'type': ['string', 'null']}
+ 'created_at': parameter_types.date_time,
+ 'updated_at': parameter_types.date_time_or_null
},
'additionalProperties': False,
'required': [
diff --git a/tempest/lib/api_schema/response/compute/v2_1/parameter_types.py b/tempest/lib/api_schema/response/compute/v2_1/parameter_types.py
index 3cc5ca4..a3c9099 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/parameter_types.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/parameter_types.py
@@ -81,6 +81,16 @@
}
}
+date_time = {
+ 'type': 'string',
+ 'format': 'iso8601-date-time'
+}
+
+date_time_or_null = {
+ 'type': ['string', 'null'],
+ 'format': 'iso8601-date-time'
+}
+
response_header = {
'connection': {'type': 'string'},
'content-length': {'type': 'string'},
@@ -89,9 +99,14 @@
'x-compute-request-id': {'type': 'string'},
'vary': {'type': 'string'},
'x-openstack-nova-api-version': {'type': 'string'},
+ # NOTE(gmann): Validating this as string only as this
+ # date in header is returned in different format than
+ # ISO 8601 date time format which is not consistent with
+ # other date-time format in nova.
+ # This API is already deprecated so not worth to fix
+ # on nova side.
'date': {
- 'type': 'string',
- 'format': 'data-time'
+ 'type': 'string'
}
}
diff --git a/tempest/lib/api_schema/response/compute/v2_1/servers.py b/tempest/lib/api_schema/response/compute/v2_1/servers.py
index 63e8467..4ccca6f 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/servers.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/servers.py
@@ -118,8 +118,8 @@
},
'user_id': {'type': 'string'},
'tenant_id': {'type': 'string'},
- 'created': {'type': 'string'},
- 'updated': {'type': 'string'},
+ 'created': parameter_types.date_time,
+ 'updated': parameter_types.date_time,
'progress': {'type': 'integer'},
'metadata': {'type': 'object'},
'links': parameter_types.links,
@@ -238,14 +238,17 @@
'status_code': [200],
'response_body': {
'type': 'object',
- 'properties': {
- 'adminPass': {'type': 'string'}
- },
'additionalProperties': False,
- 'required': ['adminPass']
}
}
+rescue_server_with_admin_pass = copy.deepcopy(rescue_server)
+rescue_server_with_admin_pass['response_body'].update(
+ {'properties': {'adminPass': {'type': 'string'}}})
+rescue_server_with_admin_pass['response_body'].update(
+ {'required': ['adminPass']})
+
+
list_virtual_interfaces = {
'status_code': [200],
'response_body': {
@@ -399,7 +402,7 @@
'request_id': {'type': 'string'},
'user_id': {'type': 'string'},
'project_id': {'type': 'string'},
- 'start_time': {'type': 'string'},
+ 'start_time': parameter_types.date_time,
'message': {'type': ['string', 'null']},
'instance_uuid': {'type': 'string'}
},
@@ -414,8 +417,8 @@
'type': 'object',
'properties': {
'event': {'type': 'string'},
- 'start_time': {'type': 'string'},
- 'finish_time': {'type': 'string'},
+ 'start_time': parameter_types.date_time,
+ 'finish_time': parameter_types.date_time,
'result': {'type': 'string'},
'traceback': {'type': ['string', 'null']}
},
diff --git a/tempest/lib/api_schema/response/compute/v2_1/services.py b/tempest/lib/api_schema/response/compute/v2_1/services.py
index ddef7b2..6949f86 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/services.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/services.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
list_services = {
'status_code': [200],
'response_body': {
@@ -29,7 +31,7 @@
'state': {'type': 'string'},
'binary': {'type': 'string'},
'status': {'type': 'string'},
- 'updated_at': {'type': ['string', 'null']},
+ 'updated_at': parameter_types.date_time_or_null,
'disabled_reason': {'type': ['string', 'null']}
},
'additionalProperties': False,
diff --git a/tempest/lib/api_schema/response/compute/v2_1/snapshots.py b/tempest/lib/api_schema/response/compute/v2_1/snapshots.py
index 01a524b..826f854 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/snapshots.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/snapshots.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
common_snapshot_info = {
'type': 'object',
'properties': {
@@ -20,7 +22,7 @@
'volumeId': {'type': 'string'},
'status': {'type': 'string'},
'size': {'type': 'integer'},
- 'createdAt': {'type': 'string'},
+ 'createdAt': parameter_types.date_time,
'displayName': {'type': ['string', 'null']},
'displayDescription': {'type': ['string', 'null']}
},
diff --git a/tempest/lib/api_schema/response/compute/v2_1/tenant_usages.py b/tempest/lib/api_schema/response/compute/v2_1/tenant_usages.py
index d51ef12..b531d2e 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/tenant_usages.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/tenant_usages.py
@@ -14,24 +14,21 @@
import copy
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
_server_usages = {
'type': 'array',
'items': {
'type': 'object',
'properties': {
- 'ended_at': {
- 'oneOf': [
- {'type': 'string'},
- {'type': 'null'}
- ]
- },
+ 'ended_at': parameter_types.date_time_or_null,
'flavor': {'type': 'string'},
'hours': {'type': 'number'},
'instance_id': {'type': 'string'},
'local_gb': {'type': 'integer'},
'memory_mb': {'type': 'integer'},
'name': {'type': 'string'},
- 'started_at': {'type': 'string'},
+ 'started_at': parameter_types.date_time,
'state': {'type': 'string'},
'tenant_id': {'type': 'string'},
'uptime': {'type': 'integer'},
@@ -47,8 +44,8 @@
'type': 'object',
'properties': {
'server_usages': _server_usages,
- 'start': {'type': 'string'},
- 'stop': {'type': 'string'},
+ 'start': parameter_types.date_time,
+ 'stop': parameter_types.date_time,
'tenant_id': {'type': 'string'},
'total_hours': {'type': 'number'},
'total_local_gb_usage': {'type': 'number'},
diff --git a/tempest/lib/api_schema/response/compute/v2_1/versions.py b/tempest/lib/api_schema/response/compute/v2_1/versions.py
index 08a9fab..7f56239 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/versions.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/versions.py
@@ -14,6 +14,8 @@
import copy
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
_version = {
'type': 'object',
@@ -33,7 +35,7 @@
}
},
'status': {'type': 'string'},
- 'updated': {'type': 'string', 'format': 'date-time'},
+ 'updated': parameter_types.date_time,
'version': {'type': 'string'},
'min_version': {'type': 'string'},
'media-types': {
diff --git a/tempest/lib/api_schema/response/compute/v2_1/volumes.py b/tempest/lib/api_schema/response/compute/v2_1/volumes.py
index bb34acb..c35dae9 100644
--- a/tempest/lib/api_schema/response/compute/v2_1/volumes.py
+++ b/tempest/lib/api_schema/response/compute/v2_1/volumes.py
@@ -12,6 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+
create_get_volume = {
'status_code': [200],
'response_body': {
@@ -24,7 +26,7 @@
'status': {'type': 'string'},
'displayName': {'type': ['string', 'null']},
'availabilityZone': {'type': 'string'},
- 'createdAt': {'type': 'string'},
+ 'createdAt': parameter_types.date_time,
'displayDescription': {'type': ['string', 'null']},
'volumeType': {'type': ['string', 'null']},
'snapshotId': {'type': ['string', 'null']},
@@ -75,7 +77,7 @@
'status': {'type': 'string'},
'displayName': {'type': ['string', 'null']},
'availabilityZone': {'type': 'string'},
- 'createdAt': {'type': 'string'},
+ 'createdAt': parameter_types.date_time,
'displayDescription': {'type': ['string', 'null']},
'volumeType': {'type': ['string', 'null']},
'snapshotId': {'type': ['string', 'null']},
diff --git a/tempest/lib/cli/base.py b/tempest/lib/cli/base.py
index 5d7fbe3..5468a7b 100644
--- a/tempest/lib/cli/base.py
+++ b/tempest/lib/cli/base.py
@@ -13,11 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-import logging
import os
import shlex
import subprocess
+from oslo_log import log as logging
import six
from tempest.lib import base
diff --git a/tempest/lib/cli/output_parser.py b/tempest/lib/cli/output_parser.py
index c71c7a7..716f374 100644
--- a/tempest/lib/cli/output_parser.py
+++ b/tempest/lib/cli/output_parser.py
@@ -15,9 +15,10 @@
"""Collection of utilities for parsing CLI clients output."""
-import logging
import re
+from oslo_log import log as logging
+
from tempest.lib import exceptions
diff --git a/tempest/lib/cmd/check_uuid.py b/tempest/lib/cmd/check_uuid.py
index 88ce775..2fe957b 100755
--- a/tempest/lib/cmd/check_uuid.py
+++ b/tempest/lib/cmd/check_uuid.py
@@ -26,7 +26,10 @@
from oslo_utils import uuidutils
import six.moves.urllib.parse as urlparse
-DECORATOR_MODULE = 'test'
+# TODO(oomichi): Need to remove this after switching all modules to decorators
+OLD_DECORATOR_MODULE = 'test'
+
+DECORATOR_MODULE = 'decorators'
DECORATOR_NAME = 'idempotent_id'
DECORATOR_IMPORT = 'tempest.%s' % DECORATOR_MODULE
IMPORT_LINE = 'from tempest import %s' % DECORATOR_MODULE
@@ -124,7 +127,8 @@
hasattr(decorator.func, 'attr') and
decorator.func.attr == DECORATOR_NAME and
hasattr(decorator.func, 'value') and
- decorator.func.value.id == DECORATOR_MODULE):
+ (decorator.func.value.id == DECORATOR_MODULE or
+ decorator.func.value.id == OLD_DECORATOR_MODULE)):
for arg in decorator.args:
idempotent_id = ast.literal_eval(arg)
return idempotent_id
diff --git a/tempest/lib/cmd/skip_tracker.py b/tempest/lib/cmd/skip_tracker.py
index d95aa46..07b811d 100755
--- a/tempest/lib/cmd/skip_tracker.py
+++ b/tempest/lib/cmd/skip_tracker.py
@@ -21,16 +21,18 @@
"""
import argparse
-import logging
import os
import re
+from oslo_log import log as logging
+
try:
from launchpadlib import launchpad
except ImportError:
launchpad = None
LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache')
+LOG = logging.getLogger(__name__)
def parse_args():
@@ -40,11 +42,11 @@
def info(msg, *args, **kwargs):
- logging.info(msg, *args, **kwargs)
+ LOG.info(msg, *args, **kwargs)
def debug(msg, *args, **kwargs):
- logging.debug(msg, *args, **kwargs)
+ LOG.debug(msg, *args, **kwargs)
def find_skips(start):
@@ -110,8 +112,6 @@
def main():
- logging.basicConfig(format='%(levelname)s: %(message)s',
- level=logging.INFO)
parser = parse_args()
results = find_skips(parser.test_path)
unique_bugs = sorted(set([bug for (method, bug) in get_results(results)]))
diff --git a/tempest/lib/common/http.py b/tempest/lib/common/http.py
index 86ea26e..8a47d44 100644
--- a/tempest/lib/common/http.py
+++ b/tempest/lib/common/http.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
import urllib3
@@ -39,7 +40,9 @@
class Response(dict):
def __init__(self, info):
for key, value in info.getheaders().items():
- self[key.lower()] = value
+ # We assume HTTP header name to be string, not random
+ # bytes, thus ensure we have string keys.
+ self[six.u(key).lower()] = value
self.status = info.status
self['status'] = str(self.status)
self.reason = info.reason
diff --git a/tempest/lib/common/jsonschema_validator.py b/tempest/lib/common/jsonschema_validator.py
new file mode 100644
index 0000000..bbdf382
--- /dev/null
+++ b/tempest/lib/common/jsonschema_validator.py
@@ -0,0 +1,39 @@
+# Copyright 2016 NEC Corporation.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import jsonschema
+from oslo_utils import timeutils
+
+# JSON Schema validator and format checker used for JSON Schema validation
+JSONSCHEMA_VALIDATOR = jsonschema.Draft4Validator
+FORMAT_CHECKER = jsonschema.draft4_format_checker
+
+
+# NOTE(gmann): Add customized format checker for 'date-time' format because:
+# 1. jsonschema needs strict_rfc3339 or isodate module to be installed
+# for proper date-time checking as per rfc3339.
+# 2. Nova or other OpenStack components handle the date time format as
+# ISO 8601 which is defined in oslo_utils.timeutils
+# so this checker will validate the date-time as defined in
+# oslo_utils.timeutils
+@FORMAT_CHECKER.checks('iso8601-date-time')
+def _validate_datetime_format(instance):
+ try:
+ if isinstance(instance, jsonschema.compat.str_types):
+ timeutils.parse_isotime(instance)
+ except ValueError:
+ return False
+ else:
+ return True
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index 31d2ba5..d0e21ff 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -16,7 +16,6 @@
import collections
import email.utils
-import logging as real_logging
import re
import time
@@ -26,6 +25,7 @@
import six
from tempest.lib.common import http
+from tempest.lib.common import jsonschema_validator
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
@@ -39,8 +39,8 @@
HTTP_REDIRECTION = (300, 301, 302, 303, 304, 305, 306, 307)
# JSON Schema validator and format checker used for JSON Schema validation
-JSONSCHEMA_VALIDATOR = jsonschema.Draft4Validator
-FORMAT_CHECKER = jsonschema.draft4_format_checker
+JSONSCHEMA_VALIDATOR = jsonschema_validator.JSONSCHEMA_VALIDATOR
+FORMAT_CHECKER = jsonschema_validator.FORMAT_CHECKER
class RestClient(object):
@@ -248,8 +248,8 @@
# NOTE(afazekas): the http status code above 400 is processed by
# the _error_checker method
if read_code < 400:
- pattern = """Unexpected http success status code {0},
- The expected status code is {1}"""
+ pattern = ("Unexpected http success status code {0}, "
+ "The expected status code is {1}")
if ((not isinstance(expected_code, list) and
(read_code != expected_code)) or
(isinstance(expected_code, list) and
@@ -455,7 +455,7 @@
# Also look everything at DEBUG if you want to filter this
# out, don't run at debug.
- if self.LOG.isEnabledFor(real_logging.DEBUG):
+ if self.LOG.isEnabledFor(logging.DEBUG):
self._log_request_full(resp, req_headers, req_body,
resp_body, extra)
diff --git a/tempest/lib/common/ssh.py b/tempest/lib/common/ssh.py
index 4226cd6..5e65bee 100644
--- a/tempest/lib/common/ssh.py
+++ b/tempest/lib/common/ssh.py
@@ -37,7 +37,30 @@
def __init__(self, host, username, password=None, timeout=300, pkey=None,
channel_timeout=10, look_for_keys=False, key_filename=None,
- port=22):
+ port=22, proxy_client=None):
+ """SSH client.
+
+ Many of parameters are just passed to the underlying implementation
+ as it is. See the paramiko documentation for more details.
+ http://docs.paramiko.org/en/2.1/api/client.html#paramiko.client.SSHClient.connect
+
+ :param host: Host to login.
+ :param username: SSH username.
+ :param password: SSH password, or a password to unlock private key.
+ :param timeout: Timeout in seconds, including retries.
+ Default is 300 seconds.
+ :param pkey: Private key.
+ :param channel_timeout: Channel timeout in seconds, passed to the
+ paramiko. Default is 10 seconds.
+ :param look_for_keys: Whether or not to search for private keys
+ in ``~/.ssh``. Default is False.
+ :param key_filename: Filename for private key to use.
+ :param port: SSH port number.
+ :param proxy_client: Another SSH client to provide a transport
+ for ssh-over-ssh. The default is None, which means
+ not to use ssh-over-ssh.
+ :type proxy_client: ``tempest.lib.common.ssh.Client`` object
+ """
self.host = host
self.username = username
self.port = port
@@ -51,6 +74,8 @@
self.timeout = int(timeout)
self.channel_timeout = float(channel_timeout)
self.buf_size = 1024
+ self.proxy_client = proxy_client
+ self._proxy_conn = None
def _get_ssh_connection(self, sleep=1.5, backoff=1):
"""Returns an ssh connection to the specified host."""
@@ -59,6 +84,10 @@
ssh.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
_start_time = time.time()
+ if self.proxy_client is not None:
+ proxy_chan = self._get_proxy_channel()
+ else:
+ proxy_chan = None
if self.pkey is not None:
LOG.info("Creating ssh connection to '%s:%d' as '%s'"
" with public key authentication",
@@ -74,7 +103,8 @@
password=self.password,
look_for_keys=self.look_for_keys,
key_filename=self.key_filename,
- timeout=self.channel_timeout, pkey=self.pkey)
+ timeout=self.channel_timeout, pkey=self.pkey,
+ sock=proxy_chan)
LOG.info("ssh connection to %s@%s successfully created",
self.username, self.host)
return ssh
@@ -175,3 +205,14 @@
"""Raises an exception when we can not connect to server via ssh."""
connection = self._get_ssh_connection()
connection.close()
+
+ def _get_proxy_channel(self):
+ conn = self.proxy_client._get_ssh_connection()
+ # Keep a reference to avoid g/c
+ # https://github.com/paramiko/paramiko/issues/440
+ self._proxy_conn = conn
+ transport = conn.get_transport()
+ chan = transport.open_session()
+ cmd = 'nc %s %s' % (self.host, self.port)
+ chan.exec_command(cmd)
+ return chan
diff --git a/tempest/lib/services/clients.py b/tempest/lib/services/clients.py
index 262a894..445e8bd 100644
--- a/tempest/lib/services/clients.py
+++ b/tempest/lib/services/clients.py
@@ -17,7 +17,8 @@
import copy
import importlib
import inspect
-import logging
+
+from oslo_log import log as logging
from tempest.lib import auth
from tempest.lib.common.utils import misc
@@ -279,7 +280,7 @@
a dictionary ready to be injected in kwargs.
Exceptions are:
- - Token clients for 'identity' have a very different interface
+ - Token clients for 'identity' must be given an 'auth_url' parameter
- Volume client for 'volume' accepts 'default_volume_size'
- Servers client from 'compute' accepts 'enable_instance_password'
diff --git a/tempest/lib/services/compute/servers_client.py b/tempest/lib/services/compute/servers_client.py
index 597e815..50ce32e 100644
--- a/tempest/lib/services/compute/servers_client.py
+++ b/tempest/lib/services/compute/servers_client.py
@@ -616,7 +616,11 @@
API reference:
http://developer.openstack.org/api-ref-compute-v2.1.html#rescue
"""
- return self.action(server_id, 'rescue', schema.rescue_server, **kwargs)
+ if self.enable_instance_password:
+ rescue_schema = schema.rescue_server_with_admin_pass
+ else:
+ rescue_schema = schema.rescue_server
+ return self.action(server_id, 'rescue', rescue_schema, **kwargs)
def unrescue_server(self, server_id):
"""Unrescue the provided server.
diff --git a/tempest/lib/services/identity/v2/token_client.py b/tempest/lib/services/identity/v2/token_client.py
index c4fd483..458c862 100644
--- a/tempest/lib/services/identity/v2/token_client.py
+++ b/tempest/lib/services/identity/v2/token_client.py
@@ -23,7 +23,22 @@
def __init__(self, auth_url, disable_ssl_certificate_validation=None,
ca_certs=None, trace_requests=None, **kwargs):
+ """Initialises the Token client
+
+ :param auth_url: URL to which the token request is sent
+ :param disable_ssl_certificate_validation: pass-through to rest client
+ :param ca_certs: pass-through to rest client
+ :param trace_requests: pass-through to rest client
+ :param kwargs: any extra parameter to pass through the rest client.
+ region, service and auth_provider will be ignored, if passed,
+ as they are not meaningful for token client
+ """
dscv = disable_ssl_certificate_validation
+ # NOTE(andreaf) region, service and auth_provider are passed
+ # positionally with None. Having them in kwargs would raise a
+ # "multiple values for keyword arguments" error
+ for unwanted_kwargs in ['region', 'service', 'auth_provider']:
+ kwargs.pop(unwanted_kwargs, None)
super(TokenClient, self).__init__(
None, None, None, disable_ssl_certificate_validation=dscv,
ca_certs=ca_certs, trace_requests=trace_requests, **kwargs)
diff --git a/tempest/lib/services/identity/v3/token_client.py b/tempest/lib/services/identity/v3/token_client.py
index 06927f4..33f6f16 100644
--- a/tempest/lib/services/identity/v3/token_client.py
+++ b/tempest/lib/services/identity/v3/token_client.py
@@ -23,7 +23,19 @@
def __init__(self, auth_url, disable_ssl_certificate_validation=None,
ca_certs=None, trace_requests=None, **kwargs):
+ """Initialises the Token client
+
+ :param auth_url: URL to which the token request is sent
+ :param disable_ssl_certificate_validation: pass-through to rest client
+ :param ca_certs: pass-through to rest client
+ :param trace_requests: pass-through to rest client
+ :param kwargs: any extra parameter to pass through the rest client.
+ Three kwargs are forbidden: region, service and auth_provider
+ as they are not meaningful for token client
+ """
dscv = disable_ssl_certificate_validation
+ for unwanted_kwargs in ['region', 'service', 'auth_provider']:
+ kwargs.pop(unwanted_kwargs, None)
super(V3TokenClient, self).__init__(
None, None, None, disable_ssl_certificate_validation=dscv,
ca_certs=ca_certs, trace_requests=trace_requests, **kwargs)
diff --git a/tempest/lib/services/image/v2/__init__.py b/tempest/lib/services/image/v2/__init__.py
index a35ce17..7d973e5 100644
--- a/tempest/lib/services/image/v2/__init__.py
+++ b/tempest/lib/services/image/v2/__init__.py
@@ -19,11 +19,13 @@
NamespaceObjectsClient
from tempest.lib.services.image.v2.namespace_properties_client import \
NamespacePropertiesClient
+from tempest.lib.services.image.v2.namespace_tags_client import \
+ NamespaceTagsClient
from tempest.lib.services.image.v2.namespaces_client import NamespacesClient
from tempest.lib.services.image.v2.resource_types_client import \
ResourceTypesClient
from tempest.lib.services.image.v2.schemas_client import SchemasClient
__all__ = ['ImageMembersClient', 'ImagesClient', 'NamespaceObjectsClient',
- 'NamespacePropertiesClient', 'NamespacesClient',
- 'ResourceTypesClient', 'SchemasClient']
+ 'NamespacePropertiesClient', 'NamespaceTagsClient',
+ 'NamespacesClient', 'ResourceTypesClient', 'SchemasClient']
diff --git a/tempest/lib/services/image/v2/namespace_tags_client.py b/tempest/lib/services/image/v2/namespace_tags_client.py
new file mode 100644
index 0000000..ac8b569
--- /dev/null
+++ b/tempest/lib/services/image/v2/namespace_tags_client.py
@@ -0,0 +1,119 @@
+# Copyright 2016 EasyStack.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
+
+from tempest.lib.common import rest_client
+
+
+class NamespaceTagsClient(rest_client.RestClient):
+ api_version = "v2"
+
+ def create_namespace_tag(self, namespace, tag_name):
+ """Adds a tag to the list of namespace tag definitions.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-tag-definition
+ """
+ url = 'metadefs/namespaces/%s/tags/%s' % (namespace,
+ tag_name)
+ resp, body = self.post(url, None)
+ self.expected_success(201, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def show_namespace_tag(self, namespace, tag_name):
+ """Gets a definition for a tag.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#get_tag_definition
+ """
+ url = 'metadefs/namespaces/%s/tags/%s' % (namespace,
+ tag_name)
+ resp, body = self.get(url)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def update_namespace_tag(self, namespace, tag_name, **kwargs):
+ """Renames a tag definition.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#update-tag-definition
+ """
+ url = 'metadefs/namespaces/%s/tags/%s' % (namespace,
+ tag_name)
+ data = json.dumps(kwargs)
+ resp, body = self.put(url, data)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_namespace_tag(self, namespace, tag_name):
+ """Deletes a tag definition within a namespace.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-tag-definition
+ """
+ url = 'metadefs/namespaces/%s/tags/%s' % (namespace, tag_name)
+ resp, _ = self.delete(url)
+ self.expected_success(204, resp.status)
+ return rest_client.ResponseBody(resp)
+
+ def create_namespace_tags(self, namespace, **kwargs):
+ """Creates one or more tag definitions in a namespace.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#create-tags
+ """
+ url = 'metadefs/namespaces/%s/tags' % namespace
+ data = json.dumps(kwargs)
+ resp, body = self.post(url, data)
+ self.expected_success(201, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def list_namespace_tags(self, namespace, **params):
+ """Lists the tag definitions within a namespace.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#list-tags
+ """
+ url = 'metadefs/namespaces/%s/tags' % namespace
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
+ self.expected_success(200, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
+
+ def delete_namespace_tags(self, namespace):
+ """Deletes all tag definitions within a namespace.
+
+ For a full list of available parameters, please refer to the official
+ API reference:
+ http://developer.openstack.org/api-ref/image/v2/metadefs-index.html#delete-all-tag-definitions
+ """
+ url = 'metadefs/namespaces/%s/tags' % namespace
+ resp, _ = self.delete(url)
+ self.expected_success(200, resp.status)
+ return rest_client.ResponseBody(resp)
diff --git a/tempest/lib/services/volume/v2/__init__.py b/tempest/lib/services/volume/v2/__init__.py
index 837b4f6..8acad0f 100644
--- a/tempest/lib/services/volume/v2/__init__.py
+++ b/tempest/lib/services/volume/v2/__init__.py
@@ -27,6 +27,8 @@
from tempest.lib.services.volume.v2.scheduler_stats_client import \
SchedulerStatsClient
from tempest.lib.services.volume.v2.services_client import ServicesClient
+from tempest.lib.services.volume.v2.snapshot_manage_client import \
+ SnapshotManageClient
from tempest.lib.services.volume.v2.snapshots_client import SnapshotsClient
from tempest.lib.services.volume.v2.types_client import TypesClient
from tempest.lib.services.volume.v2.volumes_client import VolumesClient
@@ -34,4 +36,5 @@
__all__ = ['AvailabilityZoneClient', 'BackupsClient', 'EncryptionTypesClient',
'ExtensionsClient', 'HostsClient', 'QosSpecsClient', 'QuotasClient',
'ServicesClient', 'SnapshotsClient', 'TypesClient', 'VolumesClient',
- 'LimitsClient', 'CapabilitiesClient', 'SchedulerStatsClient']
+ 'LimitsClient', 'CapabilitiesClient', 'SchedulerStatsClient',
+ 'SnapshotManageClient']
diff --git a/tempest/lib/services/volume/v2/snapshot_manage_client.py b/tempest/lib/services/volume/v2/snapshot_manage_client.py
new file mode 100644
index 0000000..aecd30b
--- /dev/null
+++ b/tempest/lib/services/volume/v2/snapshot_manage_client.py
@@ -0,0 +1,33 @@
+# Copyright 2016 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.
+
+from oslo_serialization import jsonutils as json
+
+from tempest.lib.common import rest_client
+
+
+class SnapshotManageClient(rest_client.RestClient):
+ """Snapshot manage V2 client."""
+
+ api_version = "v2"
+
+ def manage_snapshot(self, **kwargs):
+ """Manage a snapshot."""
+ post_body = json.dumps({'snapshot': kwargs})
+ url = 'os-snapshot-manage'
+ resp, body = self.post(url, post_body)
+ self.expected_success(202, resp.status)
+ body = json.loads(body)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v2/snapshots_client.py b/tempest/lib/services/volume/v2/snapshots_client.py
index 6f51b51..2bdf1b1 100644
--- a/tempest/lib/services/volume/v2/snapshots_client.py
+++ b/tempest/lib/services/volume/v2/snapshots_client.py
@@ -184,3 +184,11 @@
resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body)
self.expected_success(202, resp.status)
return rest_client.ResponseBody(resp, body)
+
+ def unmanage_snapshot(self, snapshot_id):
+ """Unmanage a snapshot."""
+ post_body = json.dumps({'os-unmanage': {}})
+ url = 'snapshots/%s/action' % (snapshot_id)
+ resp, body = self.post(url, post_body)
+ self.expected_success(202, resp.status)
+ return rest_client.ResponseBody(resp, body)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 2da2f92..8c930c3 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -248,6 +248,27 @@
volume = self.volumes_client.show_volume(volume['id'])['volume']
return volume
+ def create_volume_type(self, client=None, name=None, backend_name=None):
+ if not client:
+ client = self.admin_volume_types_client
+ if not name:
+ class_name = self.__class__.__name__
+ name = data_utils.rand_name(class_name + '-volume-type')
+ randomized_name = data_utils.rand_name('scenario-type-' + name)
+
+ LOG.debug("Creating a volume type: %s on backend %s",
+ randomized_name, backend_name)
+ extra_specs = {}
+ if backend_name:
+ extra_specs = {"volume_backend_name": backend_name}
+
+ body = client.create_volume_type(name=randomized_name,
+ extra_specs=extra_specs)
+ volume_type = body['volume_type']
+ self.assertIn('id', volume_type)
+ self.addCleanup(client.delete_volume_type, volume_type['id'])
+ return volume_type
+
def _create_loginable_secgroup_rule(self, secgroup_id=None):
_client = self.compute_security_groups_client
_client_rules = self.compute_security_group_rules_client
@@ -529,14 +550,14 @@
caller = test_utils.find_test_caller()
LOG.debug('%(caller)s begins to ping %(ip)s in %(timeout)s sec and the'
- ' expected result is %(should_succeed)s', **{
+ ' expected result is %(should_succeed)s', {
'caller': caller, 'ip': ip_address, 'timeout': timeout,
'should_succeed':
'reachable' if should_succeed else 'unreachable'
})
result = test_utils.call_until_true(ping, timeout, 1)
LOG.debug('%(caller)s finishes ping %(ip)s in %(timeout)s sec and the '
- 'ping result is %(result)s', **{
+ 'ping result is %(result)s', {
'caller': caller, 'ip': ip_address, 'timeout': timeout,
'result': 'expected' if result else 'unexpected'
})
@@ -1246,19 +1267,6 @@
cls.admin_encryption_types_client =\
cls.os_adm.encryption_types_client
- def create_volume_type(self, client=None, name=None):
- if not client:
- client = self.admin_volume_types_client
- if not name:
- name = 'generic'
- randomized_name = data_utils.rand_name('scenario-type-' + name)
- LOG.debug("Creating a volume type: %s", randomized_name)
- body = client.create_volume_type(
- name=randomized_name)['volume_type']
- self.assertIn('id', body)
- self.addCleanup(client.delete_volume_type, body['id'])
- return body
-
def create_encryption_type(self, client=None, type_id=None, provider=None,
key_size=None, cipher=None,
control_location=None):
@@ -1326,7 +1334,7 @@
def upload_object_to_container(self, container_name, obj_name=None):
obj_name = obj_name or data_utils.rand_name('swift-scenario-object')
- obj_data = data_utils.arbitrary_string()
+ obj_data = data_utils.random_bytes()
self.object_client.create_object(container_name, obj_name, obj_data)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
self.object_client.delete_object,
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 2d2f7df..4a938f9 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -18,6 +18,7 @@
from tempest.common import waiters
from tempest import config
+from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
from tempest.scenario import manager
@@ -79,6 +80,14 @@
'verify metadata on server. '
'%s is empty.' % md_url)
+ # Also, test a POST
+ md_url = 'http://169.254.169.254/openstack/2013-10-17/password'
+ data = data_utils.arbitrary_string(100)
+ cmd = 'curl -X POST -d ' + data + ' ' + md_url
+ self.ssh_client.exec_command(cmd)
+ result = self.servers_client.show_password(self.instance['id'])
+ self.assertEqual(data, result['password'])
+
def _mount_config_drive(self):
cmd_blkid = 'blkid | grep -i config-2'
result = self.ssh_client.exec_command(cmd_blkid)
diff --git a/tempest/scenario/test_volume_migrate_attached.py b/tempest/scenario/test_volume_migrate_attached.py
new file mode 100644
index 0000000..dfda18d
--- /dev/null
+++ b/tempest/scenario/test_volume_migrate_attached.py
@@ -0,0 +1,128 @@
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from oslo_log import log as logging
+
+from tempest.common import waiters
+from tempest import config
+from tempest.scenario import manager
+from tempest import test
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+class TestVolumeMigrateRetypeAttached(manager.ScenarioTest):
+
+ """This test case attempts to reproduce the following steps:
+
+ * Create 2 volume types representing 2 different backends
+ * Create in Cinder some bootable volume importing a Glance image using
+ * volume_type_1
+ * Boot an instance from the bootable volume
+ * Write to the volume
+ * Perform a cinder retype --on-demand of the volume to type of backend #2
+ * Check written content of migrated volume
+ """
+
+ credentials = ['primary', 'admin']
+
+ @classmethod
+ def setup_clients(cls):
+ super(TestVolumeMigrateRetypeAttached, cls).setup_clients()
+ if CONF.volume_feature_enabled.api_v1:
+ cls.admin_volume_types_client = cls.os_adm.volume_types_client
+ else:
+ cls.admin_volume_types_client = cls.os_adm.volume_types_v2_client
+
+ @classmethod
+ def skip_checks(cls):
+ super(TestVolumeMigrateRetypeAttached, cls).skip_checks()
+ if not CONF.volume_feature_enabled.multi_backend:
+ raise cls.skipException("Cinder multi-backend feature disabled")
+
+ if len(set(CONF.volume.backend_names)) < 2:
+ raise cls.skipException("Requires at least two different "
+ "backend names")
+
+ def _boot_instance_from_volume(self, vol_id, keypair, security_group):
+
+ key_name = keypair['name']
+ security_groups = [{'name': security_group['name']}]
+ block_device_mapping = [{'device_name': 'vda', 'volume_id': vol_id,
+ 'delete_on_termination': False}]
+
+ return self.create_server(image_id='', wait_until='ACTIVE',
+ key_name=key_name,
+ security_groups=security_groups,
+ block_device_mapping=block_device_mapping)
+
+ def _create_volume_types(self):
+ backend_names = CONF.volume.backend_names
+
+ backend_source = backend_names[0]
+ backend_dest = backend_names[1]
+
+ source_body = self.create_volume_type(backend_name=backend_source)
+ dest_body = self.create_volume_type(backend_name=backend_dest)
+
+ LOG.info("Created Volume types: %(src)s -> %(src_backend)s, %(dst)s "
+ "-> %(dst_backend)s", {'src': source_body['name'],
+ 'src_backend': backend_source,
+ 'dst': dest_body['name'],
+ 'dst_backend': backend_dest})
+ return source_body['name'], dest_body['name']
+
+ def _volume_retype_with_migration(self, volume_id, new_volume_type):
+ migration_policy = 'on-demand'
+ self.volumes_client.retype_volume(
+ volume_id, new_type=new_volume_type,
+ migration_policy=migration_policy)
+ waiters.wait_for_volume_retype(self.volumes_client,
+ volume_id, new_volume_type)
+
+ @test.idempotent_id('deadd2c2-beef-4dce-98be-f86765ff311b')
+ @test.services('compute', 'volume')
+ def test_volume_migrate_attached(self):
+ LOG.info("Creating keypair and security group")
+ keypair = self.create_keypair()
+ security_group = self._create_security_group()
+
+ # create volume types
+ LOG.info("Creating Volume types")
+ source_type, dest_type = self._create_volume_types()
+
+ # create an instance from volume
+ LOG.info("Booting instance from volume")
+ volume_origin = self.create_volume(imageRef=CONF.compute.image_ref,
+ volume_type=source_type)
+
+ instance = self._boot_instance_from_volume(volume_origin['id'],
+ keypair, security_group)
+
+ # write content to volume on instance
+ LOG.info("Setting timestamp in instance %s", instance['id'])
+ ip_instance = self.get_server_ip(instance)
+ timestamp = self.create_timestamp(ip_instance,
+ private_key=keypair['private_key'])
+
+ # retype volume with migration from backend #1 to backend #2
+ LOG.info("Retyping Volume %s to new type %s", volume_origin['id'],
+ dest_type)
+ self._volume_retype_with_migration(volume_origin['id'], dest_type)
+
+ # check the content of written file
+ LOG.info("Getting timestamp in postmigrated instance %s",
+ instance['id'])
+ timestamp2 = self.get_timestamp(ip_instance,
+ private_key=keypair['private_key'])
+ self.assertEqual(timestamp, timestamp2)
diff --git a/tempest/services/object_storage/container_client.py b/tempest/services/object_storage/container_client.py
index 2509156..afedd36 100644
--- a/tempest/services/object_storage/container_client.py
+++ b/tempest/services/object_storage/container_client.py
@@ -140,5 +140,11 @@
body = json.loads(body)
elif params and params.get('format') == 'xml':
body = etree.fromstring(body)
+ # Else the content-type is plain/text
+ else:
+ body = [
+ obj_name for obj_name in body.decode().split('\n') if obj_name
+ ]
+
self.expected_success([200, 204], resp.status)
return resp, body
diff --git a/tempest/test_discover/plugins.py b/tempest/test_discover/plugins.py
index e9f59af..abe2b73 100644
--- a/tempest/test_discover/plugins.py
+++ b/tempest/test_discover/plugins.py
@@ -13,8 +13,8 @@
# under the License.
import abc
-import logging
+from oslo_log import log as logging
import six
import stevedore
diff --git a/tempest/tests/lib/common/test_jsonschema_validator.py b/tempest/tests/lib/common/test_jsonschema_validator.py
new file mode 100644
index 0000000..8694f3d
--- /dev/null
+++ b/tempest/tests/lib/common/test_jsonschema_validator.py
@@ -0,0 +1,83 @@
+# Copyright 2016 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.lib.api_schema.response.compute.v2_1 import parameter_types
+from tempest.lib.common import rest_client
+from tempest.lib import exceptions
+from tempest.tests import base
+from tempest.tests.lib import fake_http
+
+
+class TestJSONSchemaDateTimeFormat(base.TestCase):
+ date_time_schema = [
+ {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'date-time': parameter_types.date_time
+ }
+ }
+ },
+ {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'date-time': parameter_types.date_time_or_null
+ }
+ }
+ }
+ ]
+
+ def test_valid_date_time_format(self):
+ valid_instances = ['2016-10-02T10:00:00-05:00',
+ '2016-10-02T10:00:00+09:00',
+ '2016-10-02T15:00:00Z',
+ '2016-10-02T15:00:00.05Z']
+ resp = fake_http.fake_http_response('', status=200)
+ for instance in valid_instances:
+ body = {'date-time': instance}
+ for schema in self.date_time_schema:
+ rest_client.RestClient.validate_response(schema, resp, body)
+
+ def test_invalid_date_time_format(self):
+ invalid_instances = ['2016-10-02 T10:00:00-05:00',
+ '2016-10-02T 15:00:00',
+ '2016-10-02T15:00:00.05 Z',
+ '2016-10-02:15:00:00.05Z',
+ 'T15:00:00.05Z',
+ '2016:10:02T15:00:00',
+ '2016-10-02T15-00-00',
+ '2016-10-02T15.05Z',
+ '09MAR2015 11:15',
+ '13 Oct 2015 05:55:36 GMT',
+ '']
+ resp = fake_http.fake_http_response('', status=200)
+ for instance in invalid_instances:
+ body = {'date-time': instance}
+ for schema in self.date_time_schema:
+ self.assertRaises(exceptions.InvalidHTTPResponseBody,
+ rest_client.RestClient.validate_response,
+ schema, resp, body)
+
+ def test_date_time_or_null_format(self):
+ instance = None
+ resp = fake_http.fake_http_response('', status=200)
+ body = {'date-time': instance}
+ rest_client.RestClient.validate_response(self.date_time_schema[1],
+ resp, body)
+ self.assertRaises(exceptions.InvalidHTTPResponseBody,
+ rest_client.RestClient.validate_response,
+ self.date_time_schema[0], resp, body)
diff --git a/tempest/tests/lib/services/compute/test_servers_client.py b/tempest/tests/lib/services/compute/test_servers_client.py
index 93550fd..adfaaf2 100644
--- a/tempest/tests/lib/services/compute/test_servers_client.py
+++ b/tempest/tests/lib/services/compute/test_servers_client.py
@@ -154,7 +154,7 @@
"request_id": "16fb98f-46ca-475e-917e-2563e5a8cd19",
"user_id": "16fb98f-46ca-475e-917e-2563e5a8cd12",
"project_id": "16fb98f-46ca-475e-917e-2563e5a8cd34",
- "start_time": "09MAR2015 11:15",
+ "start_time": "2016-10-02T10:00:00-05:00",
"message": "fake-msg",
"instance_uuid": "16fb98f-46ca-475e-917e-2563e5a8cd12"
}
@@ -166,8 +166,8 @@
FAKE_INSTANCE_ACTION_EVENTS = {
"event": "fake-event",
- "start_time": "09MAR2015 11:15",
- "finish_time": "09MAR2015 11:15",
+ "start_time": "2016-10-02T10:00:00-05:00",
+ "finish_time": "2016-10-02T10:00:00-05:00",
"result": "fake-result",
"traceback": "fake-trace-back"
}
diff --git a/tempest/tests/lib/services/identity/v3/test_roles_client.py b/tempest/tests/lib/services/identity/v3/test_roles_client.py
index bad1ef9..4f70b47 100644
--- a/tempest/tests/lib/services/identity/v3/test_roles_client.py
+++ b/tempest/tests/lib/services/identity/v3/test_roles_client.py
@@ -18,32 +18,40 @@
class TestRolesClient(base.BaseServiceTest):
+
+ FAKE_ROLE_ID = "1"
+ FAKE_ROLE_NAME = "test"
+ FAKE_DOMAIN_ID = "1"
+
+ FAKE_ROLE_ID_2 = "2"
+ FAKE_ROLE_NAME_2 = "test2"
+
FAKE_ROLE_INFO = {
"role": {
- "domain_id": "1",
- "id": "1",
- "name": "test",
- "links": "example.com"
+ "domain_id": FAKE_DOMAIN_ID,
+ "id": FAKE_ROLE_ID,
+ "name": FAKE_ROLE_NAME,
+ "links": {
+ "self": "http://example.com/identity/v3/roles/%s" % (
+ FAKE_ROLE_ID)
+ }
}
}
- FAKE_LIST_ROLES = {
- "roles": [
- {
- "domain_id": "1",
- "id": "1",
- "name": "test",
- "links": "example.com"
- },
- {
- "domain_id": "2",
- "id": "2",
- "name": "test2",
- "links": "example.com"
+ FAKE_ROLE_INFO_2 = {
+ "role": {
+ "domain_id": FAKE_DOMAIN_ID,
+ "id": FAKE_ROLE_ID_2,
+ "name": FAKE_ROLE_NAME_2,
+ "links": {
+ "self": "http://example.com/identity/v3/roles/%s" % (
+ FAKE_ROLE_ID_2)
}
- ]
+ }
}
+ FAKE_LIST_ROLES = {"roles": [FAKE_ROLE_INFO, FAKE_ROLE_INFO_2]}
+
def setUp(self):
super(TestRolesClient, self).setUp()
fake_auth = fake_auth_provider.FakeAuthProvider()
@@ -56,8 +64,8 @@
'tempest.lib.common.rest_client.RestClient.post',
self.FAKE_ROLE_INFO,
bytes_body,
- domain_id="1",
- name="test",
+ domain_id=self.FAKE_DOMAIN_ID,
+ name=self.FAKE_ROLE_NAME,
status=201)
def _test_show_role(self, bytes_body=False):
@@ -66,7 +74,7 @@
'tempest.lib.common.rest_client.RestClient.get',
self.FAKE_ROLE_INFO,
bytes_body,
- role_id="1")
+ role_id=self.FAKE_ROLE_ID)
def _test_list_roles(self, bytes_body=False):
self.check_service_client_function(
@@ -81,8 +89,8 @@
'tempest.lib.common.rest_client.RestClient.patch',
self.FAKE_ROLE_INFO,
bytes_body,
- role_id="1",
- name="test")
+ role_id=self.FAKE_ROLE_ID,
+ name=self.FAKE_ROLE_NAME)
def _test_create_user_role_on_project(self, bytes_body=False):
self.check_service_client_function(
@@ -193,7 +201,7 @@
self.client.delete_role,
'tempest.lib.common.rest_client.RestClient.delete',
{},
- role_id="1",
+ role_id=self.FAKE_ROLE_ID,
status=204)
def test_create_user_role_on_project_with_str_body(self):
diff --git a/tempest/tests/lib/services/image/v2/test_namespace_tags_client.py b/tempest/tests/lib/services/image/v2/test_namespace_tags_client.py
new file mode 100644
index 0000000..2faa5be
--- /dev/null
+++ b/tempest/tests/lib/services/image/v2/test_namespace_tags_client.py
@@ -0,0 +1,126 @@
+# Copyright 2016 EasyStack. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.lib.services.image.v2 import namespace_tags_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestNamespaceTagsClient(base.BaseServiceTest):
+ FAKE_CREATE_SHOW_TAGS = {
+ "created_at": "2015-05-09T01:12:31Z",
+ "name": "added-sample-tag",
+ "updated_at": "2015-05-09T01:12:31Z"
+ }
+
+ FAKE_LIST_TAGS = {
+ "tags": [
+ {
+ "name": "sample-tag1"
+ },
+ {
+ "name": "sample-tag2"
+ },
+ {
+ "name": "sample-tag3"
+ }
+ ]
+ }
+
+ FAKE_UPDATE_TAGS = {"name": "new-tag-name"}
+
+ def setUp(self):
+ super(TestNamespaceTagsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = namespace_tags_client.NamespaceTagsClient(
+ fake_auth, 'image', 'regionOne')
+
+ def _test_create_namespace_tags(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_namespace_tags,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_CREATE_SHOW_TAGS,
+ bytes_body, status=201,
+ namespace="OS::Compute::Hypervisor",
+ tags=[{"name": "sample-tag1"},
+ {"name": "sample-tag2"},
+ {"name": "sample-tag3"}])
+
+ def _test_list_namespace_tags(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.list_namespace_tags,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_LIST_TAGS,
+ bytes_body,
+ namespace="OS::Compute::Hypervisor")
+
+ def _test_create_namespace_tag_definition(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.create_namespace_tag,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_CREATE_SHOW_TAGS,
+ bytes_body,
+ status=201,
+ namespace="OS::Compute::Hypervisor",
+ tag_name="added-sample-tag")
+
+ def _test_show_namespace_tag_definition(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.show_namespace_tag,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_CREATE_SHOW_TAGS,
+ bytes_body,
+ namespace="OS::Compute::Hypervisor",
+ tag_name="added-sample-tag")
+
+ def _test_update_namespace_tag_definition(self, bytes_body=False):
+ self.check_service_client_function(
+ self.client.update_namespace_tag,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ self.FAKE_UPDATE_OBJECTS,
+ bytes_body,
+ namespace="OS::Compute::Hypervisor",
+ tag_name="added-sample-tag",
+ name="new-tag-name")
+
+ def test_create_namespace_tags_with_str_body(self):
+ self._test_create_namespace_tags()
+
+ def test_create_namespace_tags_with_bytes_body(self):
+ self._test_create_namespace_tags(bytes_body=True)
+
+ def test_list_namespace_tags_with_str_body(self):
+ self._test_list_namespace_tags()
+
+ def test_list_namespace_tags_with_bytes_body(self):
+ self._test_list_namespace_tags(bytes_body=True)
+
+ def test_create_namespace_tag_with_str_body(self):
+ self._test_create_namespace_tag_definition()
+
+ def test_create_namespace_tag_with_bytes_body(self):
+ self._test_create_namespace_tag_definition(bytes_body=True)
+
+ def test_show_namespace_tag_with_str_body(self):
+ self._test_show_namespace_tag_definition()
+
+ def test_show_namespace_tag_with_bytes_body(self):
+ self._test_show_namespace_tag_definition(bytes_body=True)
+
+ def test_delete_all_namespace_tags(self):
+ self.check_service_client_function(
+ self.client.delete_namespace_tags,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {}, status=200,
+ namespace="OS::Compute::Hypervisor")
diff --git a/tempest/tests/lib/test_ssh.py b/tempest/tests/lib/test_ssh.py
index 8a0a84c..a16da1c 100644
--- a/tempest/tests/lib/test_ssh.py
+++ b/tempest/tests/lib/test_ssh.py
@@ -75,7 +75,54 @@
key_filename=None,
look_for_keys=False,
timeout=10.0,
- password=None
+ password=None,
+ sock=None
+ )]
+ self.assertEqual(expected_connect, client_mock.connect.mock_calls)
+ self.assertEqual(0, s_mock.call_count)
+
+ def test_get_ssh_connection_over_ssh(self):
+ c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks()
+ proxy_client_mock = mock.MagicMock()
+ proxy_client_mock.connect.return_value = True
+ s_mock = self.patch('time.sleep')
+
+ c_mock.side_effect = [client_mock, proxy_client_mock]
+ aa_mock.return_value = mock.sentinel.aa
+
+ proxy_client = ssh.Client('proxy-host', 'proxy-user', timeout=2)
+ client = ssh.Client('localhost', 'root', timeout=2,
+ proxy_client=proxy_client)
+ client._get_ssh_connection(sleep=1)
+
+ aa_mock.assert_has_calls([mock.call(), mock.call()])
+ proxy_client_mock.set_missing_host_key_policy.assert_called_once_with(
+ mock.sentinel.aa)
+ proxy_expected_connect = [mock.call(
+ 'proxy-host',
+ port=22,
+ username='proxy-user',
+ pkey=None,
+ key_filename=None,
+ look_for_keys=False,
+ timeout=10.0,
+ password=None,
+ sock=None
+ )]
+ self.assertEqual(proxy_expected_connect,
+ proxy_client_mock.connect.mock_calls)
+ client_mock.set_missing_host_key_policy.assert_called_once_with(
+ mock.sentinel.aa)
+ expected_connect = [mock.call(
+ 'localhost',
+ port=22,
+ username='root',
+ pkey=None,
+ key_filename=None,
+ look_for_keys=False,
+ timeout=10.0,
+ password=None,
+ sock=proxy_client_mock.get_transport().open_session()
)]
self.assertEqual(expected_connect, client_mock.connect.mock_calls)
self.assertEqual(0, s_mock.call_count)
diff --git a/tempest/tests/lib/test_tempest_lib.py b/tempest/tests/lib/test_tempest_lib.py
index d70e53d..4d9f099 100644
--- a/tempest/tests/lib/test_tempest_lib.py
+++ b/tempest/tests/lib/test_tempest_lib.py
@@ -1,5 +1,3 @@
-# -*- coding: utf-8 -*-
-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
diff --git a/tools/skip_tracker.py b/tools/skip_tracker.py
index 55f41a6..9735f77 100755
--- a/tools/skip_tracker.py
+++ b/tools/skip_tracker.py
@@ -20,23 +20,25 @@
is fixed but a skip is still in the Tempest test code
"""
-import logging
import os
import re
from launchpadlib import launchpad
+from oslo_log import log as logging
BASEDIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
TESTDIR = os.path.join(BASEDIR, 'tempest')
LPCACHEDIR = os.path.expanduser('~/.launchpadlib/cache')
+LOG = logging.getLogger(__name__)
+
def info(msg, *args, **kwargs):
- logging.info(msg, *args, **kwargs)
+ LOG.info(msg, *args, **kwargs)
def debug(msg, *args, **kwargs):
- logging.debug(msg, *args, **kwargs)
+ LOG.debug(msg, *args, **kwargs)
def find_skips(start=TESTDIR):
@@ -102,8 +104,6 @@
if __name__ == '__main__':
- logging.basicConfig(format='%(levelname)s: %(message)s',
- level=logging.INFO)
results = find_skips()
unique_bugs = sorted(set([bug for (method, bug) in get_results(results)]))
unskips = []