Merge "Move identity_version to class level"
diff --git a/README.rst b/README.rst
index ba93712..af24569 100644
--- a/README.rst
+++ b/README.rst
@@ -18,7 +18,7 @@
incorrect assessment of their cloud. Explicit is always better.
- Tempest uses OpenStack public interfaces. Tests in Tempest should
only touch public interfaces, API calls (native or 3rd party),
- public CLI or libraries.
+ or libraries.
- Tempest should not touch private or implementation specific
interfaces. This means not directly going to the database, not
directly hitting the hypervisors, not testing extensions not
@@ -117,8 +117,8 @@
Tempest suite.
Alternatively, you can use the run_tests.sh script which will create a venv and
-run the unit tests. There are also the py26, py27, or py33 tox jobs which will
-run the unit tests with the corresponding version of python.
+run the unit tests. There are also the py27 and py34 tox jobs which will run
+the unit tests with the corresponding version of python.
Python 2.6
----------
@@ -131,3 +131,16 @@
on an earlier release with python 2.6 you can easily run Tempest against it
from a remote system running python 2.7. (or deploy a cloud guest in your cloud
that has python 2.7)
+
+Python 3.4
+----------
+
+Starting during the Liberty release development cycle work began on enabling
+Tempest to run under both Python 2.7 and Python 3.4. Tempest strives to fully
+support running with Python 3.4. A gating unit test job was added to also run
+Tempest's unit tests under Python 3.4. This means that the Tempest code at
+least imports under Python 3.4 and things that have unit test coverage will
+work on Python 3.4. However, because large parts of Tempest are self verifying
+there might be uncaught issues running on Python 3.4. So until there is a gating
+job which does a full Tempest run using Python 3.4 there isn't any guarantee
+that running Tempest under Python 3.4 is bug free.
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index b6e00ce..b434fdc 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -115,6 +115,8 @@
#. Provide tempest with the location of you accounts.yaml file with the
test_accounts_file option in the auth section
+ #. Set allow_tenant_isolation = False in the auth group
+
It is worth pointing out that each set of credentials in the accounts.yaml
should have a unique tenant. This is required to provide proper isolation
to the tests using the credentials, and failure to do this will likely cause
@@ -140,6 +142,11 @@
#. alt_password
#. alt_tenant_name
+And in the auth secion:
+
+ #. allow_tenant_isolation = False
+ #. comment out 'test_accounts_file' or keep it as empty
+
It only makes sense to use it if parallel execution isn't needed, since tempest
won't be able to properly isolate tests using this. Additionally, using the
traditional config options for credentials is not able to provide credentials to
diff --git a/doc/source/field_guide/cli.rst b/doc/source/field_guide/cli.rst
deleted file mode 120000
index 13caef5..0000000
--- a/doc/source/field_guide/cli.rst
+++ /dev/null
@@ -1 +0,0 @@
-../../../tempest/cli/README.rst
\ No newline at end of file
diff --git a/etc/logging.conf.sample b/etc/logging.conf.sample
index cdeedef..36cd324 100644
--- a/etc/logging.conf.sample
+++ b/etc/logging.conf.sample
@@ -34,7 +34,7 @@
formatter=simple
[formatter_tests]
-class = tempest.openstack.common.log.ContextFormatter
+class = oslo_log.formatters.ContextFormatter
[formatter_simple]
format=%(asctime)s.%(msecs)03d %(process)d %(levelname)s: %(message)s
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 2a72635..3f9e70e 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -45,9 +45,9 @@
# (Optional) Enables or disables syslog rfc5424 format for logging. If
# enabled, prefixes the MSG part of the syslog message with APP-NAME
-# (RFC5424). The format without the APP-NAME is deprecated in I, and
-# will be removed in J. (boolean value)
-#use_syslog_rfc_format = false
+# (RFC5424). The format without the APP-NAME is deprecated in K, and
+# will be removed in L, along with this option. (boolean value)
+#use_syslog_rfc_format = true
# Syslog facility to receive log lines. (string value)
#syslog_log_facility = LOG_USER
@@ -201,27 +201,6 @@
#build_interval = 1
-[cli]
-
-#
-# From tempest.config
-#
-
-# enable cli tests (boolean value)
-#enabled = true
-
-# directory where python client binaries are located (string value)
-#cli_dir = /usr/local/bin
-
-# Whether the tempest run location has access to the *-manage
-# commands. In a pure blackbox environment it will not. (boolean
-# value)
-#has_manage = true
-
-# Number of seconds to wait on a CLI timeout (integer value)
-#timeout = 15
-
-
[compute]
#
@@ -261,9 +240,6 @@
# value)
#build_timeout = 300
-# Should the tests ssh to instances? (boolean value)
-#run_ssh = false
-
# Auth method used for authenticate to the instance. Valid choices
# are: keypair, configured, adminpass and disabled. Keypair: start the
# servers with a ssh keypair. Configured: use the configured user and
@@ -310,7 +286,7 @@
#fixed_network_name = <None>
# Network used for SSH connections. Ignored if
-# use_floatingip_for_ssh=true or run_ssh=false. (string value)
+# use_floatingip_for_ssh=true or run_validation=false. (string value)
#network_for_ssh = public
# IP version used for SSH connections. (integer value)
@@ -396,6 +372,11 @@
# https://bugs.launchpad.net/nova/+bug/1398999 (boolean value)
#block_migrate_cinder_iscsi = false
+# Does the test system allow live-migration of paused instances? Note,
+# this is more than just the ANDing of paused and live_migrate, but
+# all 3 should be set to True to run those tests (boolean value)
+#live_migrate_paused_instances = false
+
# Enable VNC console. This configuration value should be same as
# [nova.vnc]->vnc_enabled in nova.conf (boolean value)
#vnc_console = false
@@ -1087,6 +1068,11 @@
# From tempest.config
#
+# Enable ssh on created servers and creation of additional validation
+# resources to enable remote access (boolean value)
+# Deprecated group/name - [compute]/run_ssh
+#run_validation = false
+
# Default IP type used for validation: -fixed: uses the first IP
# belonging to the fixed network -floating: creates and uses a
# floating IP (string value)
diff --git a/requirements.txt b/requirements.txt
index 0d7fc0d..7fe8858 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-pbr>=0.6,!=0.7,<1.0
+pbr>=0.11,<2.0
anyjson>=0.3.3
httplib2>=0.7.5
jsonschema>=2.0.0,<3.0.0
@@ -9,18 +9,17 @@
boto>=2.32.1
paramiko>=1.13.0
netaddr>=0.7.12
-python-glanceclient>=0.15.0
-python-cinderclient>=1.1.0
-python-heatclient>=0.3.0
testrepository>=0.0.18
-oslo.concurrency>=1.8.0,<1.9.0 # Apache-2.0
-oslo.config>=1.9.3,<1.10.0 # Apache-2.0
-oslo.i18n>=1.5.0,<1.6.0 # Apache-2.0
-oslo.log>=1.0.0,<1.1.0 # Apache-2.0
-oslo.serialization>=1.4.0,<1.5.0 # Apache-2.0
-oslo.utils>=1.4.0,<1.5.0 # Apache-2.0
+pyOpenSSL>=0.11
+oslo.concurrency>=1.8.0 # Apache-2.0
+oslo.config>=1.11.0 # Apache-2.0
+oslo.i18n>=1.5.0 # Apache-2.0
+oslo.log>=1.0.0 # Apache-2.0
+oslo.serialization>=1.4.0 # Apache-2.0
+oslo.utils>=1.4.0 # Apache-2.0
six>=1.9.0
iso8601>=0.1.9
fixtures>=0.3.14
testscenarios>=0.4
-tempest-lib>=0.4.0
+tempest-lib>=0.5.0
+PyYAML>=3.1.0
diff --git a/setup.cfg b/setup.cfg
index 1e7cc2b..3a14bba 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,5 @@
[metadata]
name = tempest
-version = 4
summary = OpenStack Integration Testing
description-file =
README.rst
@@ -16,6 +15,8 @@
Programming Language :: Python
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
+ Programming Language :: Python :: 3
+ Programming Language :: Python :: 3.4
[entry_points]
console_scripts =
@@ -23,6 +24,7 @@
javelin2 = tempest.cmd.javelin:main
run-tempest-stress = tempest.cmd.run_stress:main
tempest-cleanup = tempest.cmd.cleanup:main
+ tempest-account-generator = tempest.cmd.account_generator:main
oslo.config.opts =
tempest.config = tempest.config:list_opts
diff --git a/tempest/README.rst b/tempest/README.rst
index d28c3f9..fec2874 100644
--- a/tempest/README.rst
+++ b/tempest/README.rst
@@ -14,7 +14,6 @@
| tempest/
| api/ - API tests
-| cli/ - CLI tests
| scenario/ - complex scenario tests
| stress/ - stress tests
| thirdparty/ - 3rd party api tests
@@ -38,16 +37,6 @@
frameworks.
-:ref:`cli_field_guide`
-----------------------
-
-CLI tests use the openstack CLI to interact with the OpenStack
-cloud. CLI testing in unit tests is somewhat difficult because unlike
-server testing, there is no access to server code to
-instantiate. Tempest seems like a logical place for this, as it
-prereqs having a running OpenStack cloud.
-
-
:ref:`scenario_field_guide`
---------------------------
diff --git a/tempest/api/baremetal/admin/test_api_discovery.py b/tempest/api/baremetal/admin/test_api_discovery.py
index f0b8b7f..41388ad 100644
--- a/tempest/api/baremetal/admin/test_api_discovery.py
+++ b/tempest/api/baremetal/admin/test_api_discovery.py
@@ -17,7 +17,6 @@
class TestApiDiscovery(base.BaseBaremetalTest):
"""Tests for API discovery features."""
- @test.attr(type='smoke')
@test.idempotent_id('a3c27e94-f56c-42c4-8600-d6790650b9c5')
def test_api_versions(self):
_, descr = self.client.get_api_description()
@@ -27,14 +26,12 @@
for v in expected_versions:
self.assertIn(v, versions)
- @test.attr(type='smoke')
@test.idempotent_id('896283a6-488e-4f31-af78-6614286cbe0d')
def test_default_version(self):
_, descr = self.client.get_api_description()
default_version = descr['default_version']
self.assertEqual(default_version['id'], 'v1')
- @test.attr(type='smoke')
@test.idempotent_id('abc0b34d-e684-4546-9728-ab7a9ad9f174')
def test_version_1_resources(self):
_, descr = self.client.get_version_description(version='v1')
diff --git a/tempest/api/baremetal/admin/test_chassis.py b/tempest/api/baremetal/admin/test_chassis.py
index 2011905..5ad05cc 100644
--- a/tempest/api/baremetal/admin/test_chassis.py
+++ b/tempest/api/baremetal/admin/test_chassis.py
@@ -11,6 +11,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
@@ -28,19 +29,17 @@
def _assertExpected(self, expected, actual):
# Check if not expected keys/values exists in actual response body
- for key, value in expected.iteritems():
+ for key, value in six.iteritems(expected):
if key not in ('created_at', 'updated_at'):
self.assertIn(key, actual)
self.assertEqual(value, actual[key])
- @test.attr(type='smoke')
@test.idempotent_id('7c5a2e09-699c-44be-89ed-2bc189992d42')
def test_create_chassis(self):
descr = data_utils.rand_name('test-chassis')
_, chassis = self.create_chassis(description=descr)
self.assertEqual(chassis['description'], descr)
- @test.attr(type='smoke')
@test.idempotent_id('cabe9c6f-dc16-41a7-b6b9-0a90c212edd5')
def test_create_chassis_unicode_description(self):
# Use a unicode string for testing:
@@ -49,20 +48,17 @@
_, chassis = self.create_chassis(description=descr)
self.assertEqual(chassis['description'], descr)
- @test.attr(type='smoke')
@test.idempotent_id('c84644df-31c4-49db-a307-8942881f41c0')
def test_show_chassis(self):
_, chassis = self.client.show_chassis(self.chassis['uuid'])
self._assertExpected(self.chassis, chassis)
- @test.attr(type="smoke")
@test.idempotent_id('29c9cd3f-19b5-417b-9864-99512c3b33b3')
def test_list_chassis(self):
_, body = self.client.list_chassis()
self.assertIn(self.chassis['uuid'],
[i['uuid'] for i in body['chassis']])
- @test.attr(type='smoke')
@test.idempotent_id('5ae649ad-22d1-4fe1-bbc6-97227d199fb3')
def test_delete_chassis(self):
_, body = self.create_chassis()
@@ -71,7 +67,6 @@
self.delete_chassis(uuid)
self.assertRaises(lib_exc.NotFound, self.client.show_chassis, uuid)
- @test.attr(type='smoke')
@test.idempotent_id('cda8a41f-6be2-4cbf-840c-994b00a89b44')
def test_update_chassis(self):
_, body = self.create_chassis()
@@ -83,7 +78,6 @@
_, chassis = self.client.show_chassis(uuid)
self.assertEqual(chassis['description'], new_description)
- @test.attr(type='smoke')
@test.idempotent_id('76305e22-a4e2-4ab3-855c-f4e2368b9335')
def test_chassis_node_list(self):
_, node = self.create_node(self.chassis['uuid'])
diff --git a/tempest/api/baremetal/admin/test_drivers.py b/tempest/api/baremetal/admin/test_drivers.py
index de04562..f08d7ab 100644
--- a/tempest/api/baremetal/admin/test_drivers.py
+++ b/tempest/api/baremetal/admin/test_drivers.py
@@ -26,14 +26,12 @@
super(TestDrivers, cls).resource_setup()
cls.driver_name = CONF.baremetal.driver
- @test.attr(type="smoke")
@test.idempotent_id('5aed2790-7592-4655-9b16-99abcc2e6ec5')
def test_list_drivers(self):
_, drivers = self.client.list_drivers()
self.assertIn(self.driver_name,
[d['name'] for d in drivers['drivers']])
- @test.attr(type="smoke")
@test.idempotent_id('fb3287a3-c4d7-44bf-ae9d-1eef906d78ce')
def test_show_driver(self):
_, driver = self.client.show_driver(self.driver_name)
diff --git a/tempest/api/baremetal/admin/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
index fb5590e..6b963c7 100644
--- a/tempest/api/baremetal/admin/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -46,7 +46,6 @@
uuid=self.node['uuid'], instance_uuid=None)
return instance_uuid
- @test.attr(type='smoke')
@test.idempotent_id('4e939eb2-8a69-4e84-8652-6fffcbc9db8f')
def test_create_node(self):
params = {'cpu_arch': 'x86_64',
@@ -57,7 +56,6 @@
_, body = self.create_node(self.chassis['uuid'], **params)
self._assertExpected(params, body['properties'])
- @test.attr(type='smoke')
@test.idempotent_id('9ade60a4-505e-4259-9ec4-71352cbbaf47')
def test_delete_node(self):
_, node = self.create_node(self.chassis['uuid'])
@@ -67,20 +65,17 @@
self.assertRaises(lib_exc.NotFound, self.client.show_node,
node['uuid'])
- @test.attr(type='smoke')
@test.idempotent_id('55451300-057c-4ecf-8255-ba42a83d3a03')
def test_show_node(self):
_, loaded_node = self.client.show_node(self.node['uuid'])
self._assertExpected(self.node, loaded_node)
- @test.attr(type='smoke')
@test.idempotent_id('4ca123c4-160d-4d8d-a3f7-15feda812263')
def test_list_nodes(self):
_, body = self.client.list_nodes()
self.assertIn(self.node['uuid'],
[i['uuid'] for i in body['nodes']])
- @test.attr(type='smoke')
@test.idempotent_id('85b1f6e0-57fd-424c-aeff-c3422920556f')
def test_list_nodes_association(self):
_, body = self.client.list_nodes(associated=True)
@@ -95,7 +90,6 @@
_, body = self.client.list_nodes(associated=False)
self.assertNotIn(self.node['uuid'], [n['uuid'] for n in body['nodes']])
- @test.attr(type='smoke')
@test.idempotent_id('18c4ebd8-f83a-4df7-9653-9fb33a329730')
def test_node_port_list(self):
_, port = self.create_port(self.node['uuid'],
@@ -104,14 +98,12 @@
self.assertIn(port['uuid'],
[p['uuid'] for p in body['ports']])
- @test.attr(type='smoke')
@test.idempotent_id('72591acb-f215-49db-8395-710d14eb86ab')
def test_node_port_list_no_ports(self):
_, node = self.create_node(self.chassis['uuid'])
_, body = self.client.list_node_ports(node['uuid'])
self.assertEmpty(body['ports'])
- @test.attr(type='smoke')
@test.idempotent_id('4fed270a-677a-4d19-be87-fd38ae490320')
def test_update_node(self):
props = {'cpu_arch': 'x86_64',
@@ -130,7 +122,6 @@
_, node = self.client.show_node(node['uuid'])
self._assertExpected(new_p, node['properties'])
- @test.attr(type='smoke')
@test.idempotent_id('cbf1f515-5f4b-4e49-945c-86bcaccfeb1d')
def test_validate_driver_interface(self):
_, body = self.client.validate_driver_interface(self.node['uuid'])
@@ -138,12 +129,10 @@
for interface in core_interfaces:
self.assertIn(interface, body)
- @test.attr(type='smoke')
@test.idempotent_id('5519371c-26a2-46e9-aa1a-f74226e9d71f')
def test_set_node_boot_device(self):
self.client.set_node_boot_device(self.node['uuid'], 'pxe')
- @test.attr(type='smoke')
@test.idempotent_id('9ea73775-f578-40b9-bc34-efc639c4f21f')
def test_get_node_boot_device(self):
body = self.client.get_node_boot_device(self.node['uuid'])
@@ -152,14 +141,12 @@
self.assertTrue(isinstance(body['boot_device'], six.string_types))
self.assertTrue(isinstance(body['persistent'], bool))
- @test.attr(type='smoke')
@test.idempotent_id('3622bc6f-3589-4bc2-89f3-50419c66b133')
def test_get_node_supported_boot_devices(self):
body = self.client.get_node_supported_boot_devices(self.node['uuid'])
self.assertIn('supported_boot_devices', body)
self.assertTrue(isinstance(body['supported_boot_devices'], list))
- @test.attr(type='smoke')
@test.idempotent_id('f63b6288-1137-4426-8cfe-0d5b7eb87c06')
def test_get_console(self):
_, body = self.client.get_console(self.node['uuid'])
@@ -167,7 +154,6 @@
for key in con_info:
self.assertIn(key, body)
- @test.attr(type='smoke')
@test.idempotent_id('80504575-9b21-4670-92d1-143b948f9437')
def test_set_console_mode(self):
self.client.set_console_mode(self.node['uuid'], True)
@@ -175,7 +161,6 @@
_, body = self.client.get_console(self.node['uuid'])
self.assertEqual(True, body['console_enabled'])
- @test.attr(type='smoke')
@test.idempotent_id('b02a4f38-5e8b-44b2-aed2-a69a36ecfd69')
def test_get_node_by_instance_uuid(self):
instance_uuid = self._associate_node_with_instance()
diff --git a/tempest/api/baremetal/admin/test_nodestates.py b/tempest/api/baremetal/admin/test_nodestates.py
index e7b6081..1ffea25 100644
--- a/tempest/api/baremetal/admin/test_nodestates.py
+++ b/tempest/api/baremetal/admin/test_nodestates.py
@@ -42,14 +42,12 @@
'the required time: %s sec.' % self.power_timeout)
raise exceptions.TimeoutException(message)
- @test.attr(type='smoke')
@test.idempotent_id('cd8afa5e-3f57-4e43-8185-beb83d3c9015')
def test_list_nodestates(self):
_, nodestates = self.client.list_nodestates(self.node['uuid'])
for key in nodestates:
self.assertEqual(nodestates[key], self.node[key])
- @test.attr(type='smoke')
@test.idempotent_id('fc5b9320-0c98-4e5a-8848-877fe5a0322c')
def test_set_node_power_state(self):
_, node = self.create_node(self.chassis['uuid'])
diff --git a/tempest/api/baremetal/admin/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
index f6615fe..ece4471 100644
--- a/tempest/api/baremetal/admin/test_ports.py
+++ b/tempest/api/baremetal/admin/test_ports.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest_lib.common.utils import data_utils
from tempest_lib import decorators
from tempest_lib import exceptions as lib_exc
@@ -31,12 +32,11 @@
def _assertExpected(self, expected, actual):
# Check if not expected keys/values exists in actual response body
- for key, value in expected.iteritems():
+ for key, value in six.iteritems(expected):
if key not in ('created_at', 'updated_at'):
self.assertIn(key, actual)
self.assertEqual(value, actual[key])
- @test.attr(type='smoke')
@test.idempotent_id('83975898-2e50-42ed-b5f0-e510e36a0b56')
def test_create_port(self):
node_id = self.node['uuid']
@@ -48,7 +48,6 @@
self._assertExpected(port, body)
- @test.attr(type='smoke')
@test.idempotent_id('d1f6b249-4cf6-4fe6-9ed6-a6e84b1bf67b')
def test_create_port_specifying_uuid(self):
node_id = self.node['uuid']
@@ -62,7 +61,6 @@
self._assertExpected(port, body)
@decorators.skip_because(bug='1398350')
- @test.attr(type='smoke')
@test.idempotent_id('4a02c4b0-6573-42a4-a513-2e36ad485b62')
def test_create_port_with_extra(self):
node_id = self.node['uuid']
@@ -76,7 +74,6 @@
_, body = self.client.show_port(port['uuid'])
self._assertExpected(port, body)
- @test.attr(type='smoke')
@test.idempotent_id('1bf257a9-aea3-494e-89c0-63f657ab4fdd')
def test_delete_port(self):
node_id = self.node['uuid']
@@ -88,19 +85,16 @@
self.assertRaises(lib_exc.NotFound, self.client.show_port,
port['uuid'])
- @test.attr(type='smoke')
@test.idempotent_id('9fa77ab5-ce59-4f05-baac-148904ba1597')
def test_show_port(self):
_, port = self.client.show_port(self.port['uuid'])
self._assertExpected(self.port, port)
- @test.attr(type='smoke')
@test.idempotent_id('7c1114ff-fc3f-47bb-bc2f-68f61620ba8b')
def test_show_port_by_address(self):
_, port = self.client.show_port_by_address(self.port['address'])
self._assertExpected(self.port, port['ports'][0])
- @test.attr(type='smoke')
@test.idempotent_id('bd773405-aea5-465d-b576-0ab1780069e5')
def test_show_port_with_links(self):
_, port = self.client.show_port(self.port['uuid'])
@@ -108,7 +102,6 @@
self.assertEqual(2, len(port['links']))
self.assertIn(port['uuid'], port['links'][0]['href'])
- @test.attr(type='smoke')
@test.idempotent_id('b5e91854-5cd7-4a8e-bb35-3e0a1314606d')
def test_list_ports(self):
_, body = self.client.list_ports()
@@ -119,7 +112,6 @@
self.validate_self_link('ports', port['uuid'],
port['links'][0]['href'])
- @test.attr(type='smoke')
@test.idempotent_id('324a910e-2f80-4258-9087-062b5ae06240')
def test_list_with_limit(self):
_, body = self.client.list_ports(limit=3)
@@ -165,7 +157,6 @@
self.assertEqual(1, len(body['ports']))
self.assertEqual(address, body['ports'][0]['address'])
- @test.attr(type='smoke')
@test.idempotent_id('9c26298b-1bcb-47b7-9b9e-8bdd6e3c4aba')
def test_update_port_replace(self):
node_id = self.node['uuid']
@@ -198,7 +189,6 @@
self.assertEqual(new_address, body['address'])
self.assertEqual(new_extra, body['extra'])
- @test.attr(type='smoke')
@test.idempotent_id('d7e7fece-6ed9-460a-9ebe-9267217e8580')
def test_update_port_remove(self):
node_id = self.node['uuid']
@@ -226,7 +216,6 @@
self.assertEqual(node_id, body['node_uuid'])
self.assertEqual(address, body['address'])
- @test.attr(type='smoke')
@test.idempotent_id('241288b3-e98a-400f-a4d7-d1f716146361')
def test_update_port_add(self):
node_id = self.node['uuid']
@@ -249,7 +238,6 @@
self.assertEqual(extra, body['extra'])
@decorators.skip_because(bug='1398350')
- @test.attr(type='smoke')
@test.idempotent_id('5309e897-0799-4649-a982-0179b04c3876')
def test_update_port_mixed_ops(self):
node_id = self.node['uuid']
diff --git a/tempest/api/baremetal/admin/test_ports_negative.py b/tempest/api/baremetal/admin/test_ports_negative.py
index 9db77db..3d80ee4 100644
--- a/tempest/api/baremetal/admin/test_ports_negative.py
+++ b/tempest/api/baremetal/admin/test_ports_negative.py
@@ -26,7 +26,7 @@
_, self.chassis = self.create_chassis()
_, self.node = self.create_node(self.chassis['uuid'])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('0a6ee1f7-d0d9-4069-8778-37f3aa07303a')
def test_create_port_malformed_mac(self):
node_id = self.node['uuid']
@@ -35,7 +35,7 @@
self.assertRaises(lib_exc.BadRequest,
self.create_port, node_id=node_id, address=address)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('30277ee8-0c60-4f1d-b125-0e51c2f43369')
def test_create_port_nonexsistent_node_id(self):
node_id = str(data_utils.rand_uuid())
@@ -43,25 +43,25 @@
self.assertRaises(lib_exc.BadRequest, self.create_port,
node_id=node_id, address=address)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('029190f6-43e1-40a3-b64a-65173ba653a3')
def test_show_port_malformed_uuid(self):
self.assertRaises(lib_exc.BadRequest, self.client.show_port,
'malformed:uuid')
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('0d00e13d-e2e0-45b1-bcbc-55a6d90ca793')
def test_show_port_nonexistent_uuid(self):
self.assertRaises(lib_exc.NotFound, self.client.show_port,
data_utils.rand_uuid())
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('4ad85266-31e9-4942-99ac-751897dc9e23')
def test_show_port_by_mac_not_allowed(self):
self.assertRaises(lib_exc.BadRequest, self.client.show_port,
data_utils.rand_mac_address())
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('89a34380-3c61-4c32-955c-2cd9ce94da21')
def test_create_port_duplicated_port_uuid(self):
node_id = self.node['uuid']
@@ -72,7 +72,7 @@
self.assertRaises(lib_exc.Conflict, self.create_port, node_id=node_id,
address=address, uuid=uuid)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('65e84917-733c-40ae-ae4b-96a4adff931c')
def test_create_port_no_mandatory_field_node_id(self):
address = data_utils.rand_mac_address()
@@ -80,7 +80,7 @@
self.assertRaises(lib_exc.BadRequest, self.create_port, node_id=None,
address=address)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('bcea3476-7033-4183-acfe-e56a30809b46')
def test_create_port_no_mandatory_field_mac(self):
node_id = self.node['uuid']
@@ -88,7 +88,7 @@
self.assertRaises(lib_exc.BadRequest, self.create_port,
node_id=node_id, address=None)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('2b51cd18-fb95-458b-9780-e6257787b649')
def test_create_port_malformed_port_uuid(self):
node_id = self.node['uuid']
@@ -98,14 +98,14 @@
self.assertRaises(lib_exc.BadRequest, self.create_port,
node_id=node_id, address=address, uuid=uuid)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('583a6856-6a30-4ac4-889f-14e2adff8105')
def test_create_port_malformed_node_id(self):
address = data_utils.rand_mac_address()
self.assertRaises(lib_exc.BadRequest, self.create_port,
node_id='malformed:nodeid', address=address)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('e27f8b2e-42c6-4a43-a3cd-accff716bc5c')
def test_create_port_duplicated_mac(self):
node_id = self.node['uuid']
@@ -115,7 +115,7 @@
self.create_port, node_id=node_id,
address=address)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('8907082d-ac5e-4be3-b05f-d072ede82020')
def test_update_port_by_mac_not_allowed(self):
node_id = self.node['uuid']
@@ -132,7 +132,7 @@
self.client.update_port, address,
patch)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('df1ac70c-db9f-41d9-90f1-78cd6b905718')
def test_update_port_nonexistent(self):
node_id = self.node['uuid']
@@ -151,7 +151,7 @@
self.assertRaises(lib_exc.NotFound,
self.client.update_port, port_id, patch)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('c701e315-aa52-41ea-817c-65c5ca8ca2a8')
def test_update_port_malformed_port_uuid(self):
node_id = self.node['uuid']
@@ -165,7 +165,7 @@
patch=[{'path': '/address', 'op': 'replace',
'value': new_address}])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('f8f15803-34d6-45dc-b06f-e5e04bf1b38b')
def test_update_port_add_nonexistent_property(self):
node_id = self.node['uuid']
@@ -178,7 +178,7 @@
[{'path': '/nonexistent', ' op': 'add',
'value': 'value'}])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('898ec904-38b1-4fcb-9584-1187d4263a2a')
def test_update_port_replace_node_id_with_malformed(self):
node_id = self.node['uuid']
@@ -193,7 +193,7 @@
self.assertRaises(lib_exc.BadRequest,
self.client.update_port, port_id, patch)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('2949f30f-5f59-43fa-a6d9-4eac578afab4')
def test_update_port_replace_mac_with_duplicated(self):
node_id = self.node['uuid']
@@ -211,7 +211,7 @@
self.assertRaises(lib_exc.Conflict,
self.client.update_port, port_id, patch)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('97f6e048-6e4f-4eba-a09d-fbbc78b77a77')
def test_update_port_replace_node_id_with_nonexistent(self):
node_id = self.node['uuid']
@@ -226,7 +226,7 @@
self.assertRaises(lib_exc.BadRequest,
self.client.update_port, port_id, patch)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('375022c5-9e9e-4b11-9ca4-656729c0c9b2')
def test_update_port_replace_mac_with_malformed(self):
node_id = self.node['uuid']
@@ -242,7 +242,7 @@
self.assertRaises(lib_exc.BadRequest,
self.client.update_port, port_id, patch)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('5722b853-03fc-4854-8308-2036a1b67d85')
def test_update_port_replace_nonexistent_property(self):
node_id = self.node['uuid']
@@ -256,7 +256,7 @@
self.assertRaises(lib_exc.BadRequest,
self.client.update_port, port_id, patch)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('ae2696ca-930a-4a7f-918f-30ae97c60f56')
def test_update_port_remove_mandatory_field_mac(self):
node_id = self.node['uuid']
@@ -268,7 +268,7 @@
self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
[{'path': '/address', 'op': 'remove'}])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('5392c1f0-2071-4697-9064-ec2d63019018')
def test_update_port_remove_mandatory_field_port_uuid(self):
node_id = self.node['uuid']
@@ -280,7 +280,7 @@
self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
[{'path': '/uuid', 'op': 'remove'}])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('06b50d82-802a-47ef-b079-0a3311cf85a2')
def test_update_port_remove_nonexistent_property(self):
node_id = self.node['uuid']
@@ -292,7 +292,7 @@
self.assertRaises(lib_exc.BadRequest, self.client.update_port, port_id,
[{'path': '/nonexistent', 'op': 'remove'}])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('03d42391-2145-4a6c-95bf-63fe55eb64fd')
def test_delete_port_by_mac_not_allowed(self):
node_id = self.node['uuid']
@@ -301,7 +301,7 @@
self.create_port(node_id=node_id, address=address)
self.assertRaises(lib_exc.BadRequest, self.client.delete_port, address)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('0629e002-818e-4763-b25b-ae5e07b1cb23')
def test_update_port_mixed_ops_integrity(self):
node_id = self.node['uuid']
diff --git a/tempest/api/compute/admin/test_baremetal_nodes.py b/tempest/api/compute/admin/test_baremetal_nodes.py
index 9b88938..4d95f0a 100644
--- a/tempest/api/compute/admin/test_baremetal_nodes.py
+++ b/tempest/api/compute/admin/test_baremetal_nodes.py
@@ -33,7 +33,7 @@
cls.client = cls.os_adm.baremetal_nodes_client
cls.ironic_client = cls.os_adm.baremetal_client
- @test.attr(type=['smoke', 'baremetal'])
+ @test.attr(type=['baremetal'])
@test.idempotent_id('e475aa6e-416d-4fa4-b3af-28d5e84250fb')
def test_list_get_baremetal_nodes(self):
# Create some test nodes in Ironic directly
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 6634290..9da7901 100644
--- a/tempest/api/compute/admin/test_instance_usage_audit_log.py
+++ b/tempest/api/compute/admin/test_instance_usage_audit_log.py
@@ -14,7 +14,8 @@
# under the License.
import datetime
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api.compute import base
from tempest import test
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 ec9ad19..97d665b 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
@@ -14,8 +14,8 @@
# under the License.
import datetime
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api.compute import base
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 8a92326..d3b1f5e 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -84,10 +84,15 @@
self.volumes_client.wait_for_volume_status(volume_id, 'available')
self.volumes_client.delete_volume(volume_id)
- @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
- @testtools.skipIf(not CONF.compute_feature_enabled.live_migration,
- 'Live migration not available')
- def test_live_block_migration(self):
+ def _test_live_block_migration(self, state='ACTIVE'):
+ """Tests live block migration between two hosts.
+
+ Requires CONF.compute_feature_enabled.live_migration to be True.
+
+ :param state: The vm_state the migrated server should be in before and
+ after the live migration. Supported values are 'ACTIVE'
+ and 'PAUSED'.
+ """
# Live block migrate an instance to another host
if len(self._get_compute_hostnames()) < 2:
raise self.skipTest(
@@ -95,10 +100,33 @@
server_id = self._get_an_active_server()
actual_host = self._get_host_for_server(server_id)
target_host = self._get_host_other_than(actual_host)
+
+ if state == 'PAUSED':
+ self.admin_servers_client.pause_server(server_id)
+ self.admin_servers_client.wait_for_server_status(server_id, state)
+
self._migrate_server_to(server_id, target_host)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ self.servers_client.wait_for_server_status(server_id, state)
self.assertEqual(target_host, self._get_host_for_server(server_id))
+ @test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
+ @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
+ 'Live migration not available')
+ def test_live_block_migration(self):
+ self._test_live_block_migration()
+
+ @test.idempotent_id('1e107f21-61b2-4988-8f22-b196e938ab88')
+ @testtools.skipUnless(CONF.compute_feature_enabled.live_migration,
+ 'Live migration not available')
+ @testtools.skipUnless(CONF.compute_feature_enabled.pause,
+ 'Pause is not available.')
+ @testtools.skipUnless(CONF.compute_feature_enabled
+ .live_migrate_paused_instances,
+ 'Live migration of paused instances is not '
+ 'available.')
+ def test_live_block_migration_paused(self):
+ self._test_live_block_migration(state='PAUSED')
+
@test.idempotent_id('e19c0cc6-6720-4ed8-be83-b6603ed5c812')
@testtools.skipIf(not CONF.compute_feature_enabled.live_migration or not
CONF.compute_feature_enabled.
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index 8b571f2..01db25c 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -54,7 +54,6 @@
'instances', 'security_group_rules',
'cores', 'security_groups'))
- @test.attr(type='smoke')
@test.idempotent_id('3b0a7c8f-cf58-46b8-a60c-715a32a8ba7d')
def test_get_default_quotas(self):
# Admin can get the default resource quota set for a tenant
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 87c0008..c1fe18c 100644
--- a/tempest/api/compute/admin/test_security_group_default_rules.py
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -55,7 +55,6 @@
self.assertEqual(cidr, rule['ip_range']['cidr'])
return rule
- @test.attr(type='smoke')
@test.idempotent_id('6d880615-eec3-4d29-97c5-7a074dde239d')
def test_create_delete_security_group_default_rules(self):
# Create and delete Security Group default rule
@@ -68,7 +67,6 @@
self.adm_client.get_security_group_default_rule,
rule['id'])
- @test.attr(type='smoke')
@test.idempotent_id('4d752e0a-33a1-4c3a-b498-ff8667ca22e5')
def test_create_security_group_default_rule_without_cidr(self):
ip_protocol = 'udp'
@@ -83,7 +81,6 @@
self.assertNotEqual(0, rule['id'])
self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
- @test.attr(type='smoke')
@test.idempotent_id('29f2d218-69b0-4a95-8f3d-6bd0ef732b3a')
def test_create_security_group_default_rule_with_blank_cidr(self):
ip_protocol = 'icmp'
@@ -100,7 +97,6 @@
self.assertNotEqual(0, rule['id'])
self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
- @test.attr(type='smoke')
@test.idempotent_id('6e6de55e-9146-4ae0-89f2-3569586e0b9b')
def test_security_group_default_rules_list(self):
ip_protocol = 'tcp'
@@ -117,7 +113,6 @@
self.assertNotEqual(0, len(rules))
self.assertIn(rule, rules)
- @test.attr(type='smoke')
@test.idempotent_id('15cbb349-86b4-4f71-a048-04b7ef3f150b')
def test_default_security_group_default_rule_show(self):
ip_protocol = 'tcp'
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index 95656e8..d8679e0 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -41,7 +41,6 @@
@testtools.skipIf(CONF.service_available.neutron,
"Skipped because neutron does not support all_tenants "
"search filter.")
- @test.attr(type='smoke')
@test.services('network')
def test_list_security_groups_list_all_tenants_filter(self):
# Admin can list security groups of all tenants
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 1a84cbf..c4581e5 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -325,6 +325,15 @@
return server['id']
@classmethod
+ def delete_server(cls, server_id):
+ """Deletes an existing server and waits for it to be gone."""
+ try:
+ cls.servers_client.delete_server(server_id)
+ cls.servers_client.wait_for_server_termination(server_id)
+ except Exception:
+ LOG.exception('Failed to delete server %s' % server_id)
+
+ @classmethod
def delete_volume(cls, volume_id):
"""Deletes the given volume and waits for it to be gone."""
cls._delete_volume(cls.volumes_extensions_client, volume_id)
diff --git a/tempest/api/compute/flavors/test_flavors.py b/tempest/api/compute/flavors/test_flavors.py
index 6c71c94..c1c87f9 100644
--- a/tempest/api/compute/flavors/test_flavors.py
+++ b/tempest/api/compute/flavors/test_flavors.py
@@ -38,7 +38,6 @@
'name': flavor['name']}
self.assertIn(flavor_min_detail, flavors)
- @test.attr(type='smoke')
@test.idempotent_id('6e85fde4-b3cd-4137-ab72-ed5f418e8c24')
def test_list_flavors_with_detail(self):
# Detailed list of all flavors should contain the expected flavor
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 6555b64..54a82e9 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -108,7 +108,7 @@
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,
- '!@$%^&*()')
+ '!@$^&*()')
@test.attr(type=['negative'])
@test.idempotent_id('137aef61-39f7-44a1-8ddf-0adf82511701')
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 2968208..a92048f 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -73,7 +73,6 @@
flavor = self.flavors_client.get_flavor_details(flavor_id)
return flavor['disk']
- @test.attr(type='smoke')
@test.idempotent_id('3731d080-d4c5-4872-b41a-64d0d0021314')
def test_create_delete_image(self):
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index 7a7a363..95f49c9 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -34,14 +34,12 @@
super(ListImagesTestJSON, cls).setup_clients()
cls.client = cls.images_client
- @test.attr(type='smoke')
@test.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
def test_get_image(self):
# Returns the correct details for a single image
image = self.client.get_image(self.image_ref)
self.assertEqual(self.image_ref, image['id'])
- @test.attr(type='smoke')
@test.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
def test_list_images(self):
# The list of all images should contain the image
@@ -49,7 +47,6 @@
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
- @test.attr(type='smoke')
@test.idempotent_id('9f94cb6b-7f10-48c5-b911-a0b84d7d4cd6')
def test_list_images_with_detail(self):
# Detailed list of all images should contain the expected images
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 70394d8..ff3f25b 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -78,7 +78,6 @@
self.expected['ip_range'] = {'cidr': '0.0.0.0/0'}
self._check_expected_response(rule)
- @test.attr(type='smoke')
@test.idempotent_id('7a01873e-3c38-4f30-80be-31a043cfe2fd')
@test.services('network')
def test_security_group_rules_create_with_optional_cidr(self):
@@ -102,7 +101,6 @@
self.expected['ip_range'] = {'cidr': cidr}
self._check_expected_response(rule)
- @test.attr(type='smoke')
@test.idempotent_id('7f5d2899-7705-4d4b-8458-4505188ffab6')
@test.services('network')
def test_security_group_rules_create_with_optional_group_id(self):
@@ -167,7 +165,6 @@
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.attr(type='smoke')
@test.idempotent_id('fc5c5acf-2091-43a6-a6ae-e42760e9ffaf')
@test.services('network')
def test_security_group_rules_delete_when_peer_group_deleted(self):
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 9bf7ccb..c654172 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
@@ -37,7 +37,7 @@
super(SecurityGroupRulesNegativeTestJSON, cls).setup_clients()
cls.client = cls.security_groups_client
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('1d507e98-7951-469b-82c3-23f1e6b8c254')
@test.services('network')
def test_create_security_group_rule_with_non_existent_id(self):
@@ -52,7 +52,7 @@
self.client.create_security_group_rule,
parent_group_id, ip_protocol, from_port, to_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('2244d7e4-adb7-4ecb-9930-2d77e123ce4f')
@test.services('network')
def test_create_security_group_rule_with_invalid_id(self):
@@ -67,7 +67,7 @@
self.client.create_security_group_rule,
parent_group_id, ip_protocol, from_port, to_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('8bd56d02-3ffa-4d67-9933-b6b9a01d6089')
@test.services('network')
def test_create_security_group_rule_duplicate(self):
@@ -91,7 +91,7 @@
self.client.create_security_group_rule,
parent_group_id, ip_protocol, from_port, to_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('84c81249-9f6e-439c-9bbf-cbb0d2cddbdf')
@test.services('network')
def test_create_security_group_rule_with_invalid_ip_protocol(self):
@@ -109,7 +109,7 @@
self.client.create_security_group_rule,
parent_group_id, ip_protocol, from_port, to_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('12bbc875-1045-4f7a-be46-751277baedb9')
@test.services('network')
def test_create_security_group_rule_with_invalid_from_port(self):
@@ -126,7 +126,7 @@
self.client.create_security_group_rule,
parent_group_id, ip_protocol, from_port, to_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('ff88804d-144f-45d1-bf59-dd155838a43a')
@test.services('network')
def test_create_security_group_rule_with_invalid_to_port(self):
@@ -143,7 +143,7 @@
self.client.create_security_group_rule,
parent_group_id, ip_protocol, from_port, to_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('00296fa9-0576-496a-ae15-fbab843189e0')
@test.services('network')
def test_create_security_group_rule_with_invalid_port_range(self):
@@ -160,7 +160,7 @@
self.client.create_security_group_rule,
secgroup_id, ip_protocol, from_port, to_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('56fddcca-dbb8-4494-a0db-96e9f869527c')
@test.services('network')
def test_delete_security_group_rule_with_non_existent_id(self):
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 16e7acf..0ce26a3 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -60,7 +60,6 @@
"list" % ', '.join(m_group['name']
for m_group in deleted_sgs))
- @test.attr(type='smoke')
@test.idempotent_id('ecc0da4a-2117-48af-91af-993cca39a615')
@test.services('network')
def test_security_group_create_get_delete(self):
@@ -83,7 +82,6 @@
self.client.delete_security_group(securitygroup['id'])
self.client.wait_for_resource_deletion(securitygroup['id'])
- @test.attr(type='smoke')
@test.idempotent_id('fe4abc0d-83f5-4c50-ad11-57a1127297a2')
@test.services('network')
def test_server_security_groups(self):
@@ -127,7 +125,6 @@
self.client.delete_security_group(sg['id'])
self.client.delete_security_group(sg2['id'])
- @test.attr(type='smoke')
@test.idempotent_id('7d4e1d3c-3209-4d6d-b020-986304ebad1f')
@test.services('network')
def test_update_security_groups(self):
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 3a6b42d..2cf2e28 100644
--- a/tempest/api/compute/security_groups/test_security_groups_negative.py
+++ b/tempest/api/compute/security_groups/test_security_groups_negative.py
@@ -51,7 +51,7 @@
break
return non_exist_id
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('673eaec1-9b3e-48ed-bdf1-2786c1b9661c')
@test.services('network')
def test_security_group_get_nonexistent_group(self):
@@ -63,7 +63,7 @@
@decorators.skip_because(bug="1161411",
condition=CONF.service_available.neutron)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('1759c3cb-b0fc-44b7-86ce-c99236be911d')
@test.services('network')
def test_security_group_create_with_invalid_group_name(self):
@@ -85,7 +85,7 @@
@decorators.skip_because(bug="1161411",
condition=CONF.service_available.neutron)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('777b6f14-aca9-4758-9e84-38783cfa58bc')
@test.services('network')
def test_security_group_create_with_invalid_group_description(self):
@@ -107,7 +107,7 @@
@test.idempotent_id('9fdb4abc-6b66-4b27-b89c-eb215a956168')
@testtools.skipIf(CONF.service_available.neutron,
"Neutron allows duplicate names for security groups")
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.services('network')
def test_security_group_create_with_duplicate_name(self):
# Negative test:Security Group with duplicate name should not
@@ -120,7 +120,7 @@
self.client.create_security_group, s_name,
s_description)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('36a1629f-c6da-4a26-b8b8-55e7e5d5cd58')
@test.services('network')
def test_delete_the_default_security_group(self):
@@ -136,7 +136,7 @@
self.client.delete_security_group,
default_security_group_id)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('6727c00b-214c-4f9e-9a52-017ac3e98411')
@test.services('network')
def test_delete_nonexistent_security_group(self):
@@ -145,7 +145,7 @@
self.assertRaises(lib_exc.NotFound,
self.client.delete_security_group, non_exist_id)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('1438f330-8fa4-4aeb-8a94-37c250106d7f')
@test.services('network')
def test_delete_security_group_without_passing_id(self):
@@ -157,7 +157,7 @@
@test.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', 'smoke'])
+ @test.attr(type=['negative'])
@test.services('network')
def test_update_security_group_with_invalid_sg_id(self):
# Update security_group with invalid sg_id should fail
@@ -172,7 +172,7 @@
@test.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', 'smoke'])
+ @test.attr(type=['negative'])
@test.services('network')
def test_update_security_group_with_invalid_sg_name(self):
# Update security_group with invalid sg_name should fail
@@ -188,7 +188,7 @@
@test.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', 'smoke'])
+ @test.attr(type=['negative'])
@test.services('network')
def test_update_security_group_with_invalid_sg_des(self):
# Update security_group with invalid sg_des should fail
@@ -201,7 +201,7 @@
self.client.update_security_group,
securitygroup_id, description=s_new_des)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('27edee9c-873d-4da6-a68a-3c256efebe8f')
@test.services('network')
def test_update_non_existent_security_group(self):
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 42a61da..7ce6269 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -118,7 +118,6 @@
self.assertEqual(sorted(list1), sorted(list2))
- @test.attr(type='smoke')
@test.idempotent_id('73fe8f02-590d-4bf1-b184-e9ca81065051')
@test.services('network')
def test_create_list_show_delete_interfaces(self):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index ee756f4..9012d3d 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -43,6 +43,7 @@
@classmethod
def resource_setup(cls):
+ cls.set_validation_resources()
super(ServersTestJSON, cls).resource_setup()
cls.meta = {'hello': 'world'}
cls.accessIPv4 = '1.1.1.1'
@@ -85,7 +86,6 @@
found = any([i for i in servers if i['id'] == self.server['id']])
self.assertTrue(found)
- @test.attr(type='smoke')
@test.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
@@ -95,7 +95,7 @@
self.assertTrue(found)
@test.idempotent_id('cbc0f52f-05aa-492b-bdc1-84b575ca294b')
- @testtools.skipUnless(CONF.compute.run_ssh,
+ @testtools.skipUnless(CONF.validation.run_validation,
'Instance validation tests are disabled.')
def test_verify_created_server_vcpus(self):
# Verify that the number of vcpus reported by the instance matches
@@ -106,7 +106,7 @@
self.assertEqual(flavor['vcpus'], linux_client.get_number_of_vcpus())
@test.idempotent_id('ac1ad47f-984b-4441-9274-c9079b7a0666')
- @testtools.skipUnless(CONF.compute.run_ssh,
+ @testtools.skipUnless(CONF.validation.run_validation,
'Instance validation tests are disabled.')
def test_host_name_is_same_as_server_name(self):
# Verify the instance host name is the same as the server name
@@ -206,7 +206,7 @@
cls.client = cls.servers_client
@test.idempotent_id('b3c7bcfc-bb5b-4e22-b517-c7f686b802ca')
- @testtools.skipUnless(CONF.compute.run_ssh,
+ @testtools.skipUnless(CONF.validation.run_validation,
'Instance validation tests are disabled.')
def test_verify_created_server_ephemeral_disk(self):
# Verify that the ephemeral disk is created when creating server
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 25b2862..5374af0 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -69,10 +69,7 @@
network = cls.get_tenant_network()
if network:
- if network.get('name'):
- cls.fixed_network_name = network['name']
- else:
- cls.fixed_network_name = None
+ cls.fixed_network_name = network.get('name')
else:
cls.fixed_network_name = None
network_kwargs = fixed_network.set_networks_kwarg(network)
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 0178c9e..fd4d902 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -21,7 +21,6 @@
class ListServersNegativeTestJSON(base.BaseV2ComputeTest):
- force_tenant_isolation = True
@classmethod
def setup_clients(cls):
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index def4c47..c4cabaa 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -33,7 +33,7 @@
class ServerActionsTestJSON(base.BaseV2ComputeTest):
- run_ssh = CONF.compute.run_ssh
+ run_ssh = CONF.validation.run_validation
def setUp(self):
# NOTE(afazekas): Normally we use the same server with all test cases,
@@ -105,13 +105,11 @@
self._test_reboot_server('HARD')
@decorators.skip_because(bug="1014647")
- @test.attr(type='smoke')
@test.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')
- @test.attr(type='smoke')
@test.idempotent_id('aaa6cdf3-55a7-461a-add9-1c8596b9a07c')
def test_rebuild_server(self):
# The server should be rebuilt using the provided image and data
@@ -128,6 +126,12 @@
personality=personality,
adminPass=password)
+ # If the server was rebuilt on a different image, restore it to the
+ # original image once the test ends
+ if self.image_ref_alt != self.image_ref:
+ self.addCleanup(self.client.rebuild,
+ (self.server_id, self.image_ref))
+
# Verify the properties in the initial response are correct
self.assertEqual(self.server_id, rebuilt_server['id'])
rebuilt_image_id = rebuilt_server['image']['id']
@@ -146,8 +150,6 @@
linux_client = remote_client.RemoteClient(server, self.ssh_user,
password)
linux_client.validate_authentication()
- if self.image_ref_alt != self.image_ref:
- self.client.rebuild(self.server_id, self.image_ref)
@test.idempotent_id('30449a88-5aff-4f9b-9866-6ee9b17f906d')
def test_rebuild_server_in_stop_state(self):
@@ -179,27 +181,16 @@
self.client.wait_for_server_status(self.server_id, 'SHUTOFF')
self.client.start(self.server_id)
- def _detect_server_image_flavor(self, server_id):
- # Detects the current server image flavor ref.
- server = self.client.get_server(server_id)
- current_flavor = server['flavor']['id']
- new_flavor_ref = self.flavor_ref_alt \
- if current_flavor == self.flavor_ref else self.flavor_ref
- return current_flavor, new_flavor_ref
-
def _test_resize_server_confirm(self, stop=False):
# The server's RAM and disk space should be modified to that of
# the provided flavor
- previous_flavor_ref, new_flavor_ref = \
- self._detect_server_image_flavor(self.server_id)
-
if stop:
self.servers_client.stop(self.server_id)
self.servers_client.wait_for_server_status(self.server_id,
'SHUTOFF')
- self.client.resize(self.server_id, new_flavor_ref)
+ self.client.resize(self.server_id, self.flavor_ref_alt)
self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
self.client.confirm_resize(self.server_id)
@@ -207,23 +198,25 @@
self.client.wait_for_server_status(self.server_id, expected_status)
server = self.client.get_server(self.server_id)
- self.assertEqual(new_flavor_ref, server['flavor']['id'])
+ self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
if stop:
# NOTE(mriedem): tearDown requires the server to be started.
self.client.start(self.server_id)
+ # NOTE(jlk): Explicitly delete the server to get a new one for later
+ # tests. Avoids resize down race issues.
+ self.addCleanup(self.delete_server, self.server_id)
+
@test.idempotent_id('1499262a-9328-4eda-9068-db1ac57498d2')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
- @test.attr(type='smoke')
def test_resize_server_confirm(self):
self._test_resize_server_confirm(stop=False)
@test.idempotent_id('138b131d-66df-48c9-a171-64f45eb92962')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize not available.')
- @test.attr(type='smoke')
def test_resize_server_confirm_from_stopped(self):
self._test_resize_server_confirm(stop=True)
@@ -234,17 +227,14 @@
# The server's RAM and disk space should return to its original
# values after a resize is reverted
- previous_flavor_ref, new_flavor_ref = \
- self._detect_server_image_flavor(self.server_id)
-
- self.client.resize(self.server_id, new_flavor_ref)
+ self.client.resize(self.server_id, self.flavor_ref_alt)
self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
self.client.revert_resize(self.server_id)
self.client.wait_for_server_status(self.server_id, 'ACTIVE')
server = self.client.get_server(self.server_id)
- self.assertEqual(previous_flavor_ref, server['flavor']['id'])
+ self.assertEqual(self.flavor_ref, server['flavor']['id'])
@test.idempotent_id('b963d4f1-94b3-4c40-9e97-7b583f46e470')
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index d0dfc87..a17f581 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
+
from tempest.api.compute import base
from tempest import test
@@ -48,7 +50,7 @@
# We do not know the exact network configuration, but an instance
# should at least have a single public or private address
self.assertTrue(len(addresses) >= 1)
- for network_name, network_addresses in addresses.iteritems():
+ for network_name, network_addresses in six.iteritems(addresses):
self.assertTrue(len(network_addresses) >= 1)
for address in network_addresses:
self.assertTrue(address['addr'])
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 4b1e8f0..4e3ce47 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -77,7 +77,6 @@
self.servers_client.unrescue_server(server_id)
self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
- @test.attr(type='smoke')
@test.idempotent_id('fd032140-714c-42e4-a8fd-adcd8df06be6')
def test_rescue_unrescue_instance(self):
self.servers_client.rescue_server(
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index 86bf5fa..a6e877c 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -43,7 +43,6 @@
'instances', 'security_group_rules',
'cores', 'security_groups'))
- @test.attr(type='smoke')
@test.idempotent_id('f1ef0a97-dbbb-4cca-adc5-c9fbc4f76107')
def test_get_quotas(self):
# User can get the quota set for it's tenant
@@ -60,7 +59,6 @@
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
- @test.attr(type='smoke')
@test.idempotent_id('9bfecac7-b966-4f47-913f-1a9e2c12134a')
def test_get_default_quotas(self):
# User can get the default quota set for it's tenant
@@ -70,7 +68,6 @@
for quota in expected_quota_set:
self.assertIn(quota, quota_set.keys())
- @test.attr(type='smoke')
@test.idempotent_id('cd65d997-f7e4-4966-a7e9-d5001b674fdc')
def test_compare_tenant_quotas_with_default_quotas(self):
# Tenants are created with the default quota values
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 7f345ae..580fb84 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -85,7 +85,8 @@
self.addCleanup(self._detach, self.server['id'], self.volume['id'])
@test.idempotent_id('52e9045a-e90d-4c0d-9087-79d657faffff')
- @testtools.skipUnless(CONF.compute.run_ssh, 'SSH required for this test')
+ @testtools.skipUnless(CONF.validation.run_validation,
+ 'SSH required for this test')
def test_attach_detach_volume(self):
# Stop and Start a server with an attached volume, ensuring that
# the volume remains attached.
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 1c11128..d96dcc2 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -38,7 +38,6 @@
super(VolumesGetTestJSON, cls).setup_clients()
cls.client = cls.volumes_extensions_client
- @test.attr(type='smoke')
@test.idempotent_id('f10f25eb-9775-4d9d-9cbe-1cf54dae9d5f')
def test_volume_create_get_delete(self):
# CREATE, GET, DELETE Volume
diff --git a/tempest/api/identity/admin/v2/test_services.py b/tempest/api/identity/admin/v2/test_services.py
index aa7e3d2..de1d091 100644
--- a/tempest/api/identity/admin/v2/test_services.py
+++ b/tempest/api/identity/admin/v2/test_services.py
@@ -30,7 +30,6 @@
self.assertRaises(lib_exc.NotFound, self.client.get_service,
service_id)
- @test.attr(type='smoke')
@test.idempotent_id('84521085-c6e6-491c-9a08-ec9f70f90110')
def test_create_get_delete_service(self):
# GET Service
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 385f878..bcac853 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -40,7 +40,6 @@
self.data.users.append(user)
self.assertEqual(self.alt_user, user['name'])
- @test.attr(type='smoke')
@test.idempotent_id('89d9fdb8-15c2-4304-a429-48715d0af33d')
def test_create_user_with_enabled(self):
# Create a user with enabled : False
@@ -54,7 +53,6 @@
self.assertEqual('false', str(user['enabled']).lower())
self.assertEqual(self.alt_email, user['email'])
- @test.attr(type='smoke')
@test.idempotent_id('39d05857-e8a5-4ed4-ba83-0b52d3ab97ee')
def test_update_user(self):
# Test case to check if updating of user attributes is successful.
@@ -81,7 +79,6 @@
self.assertEqual(u_email2, updated_user['email'])
self.assertEqual('false', str(updated_user['enabled']).lower())
- @test.attr(type='smoke')
@test.idempotent_id('29ed26f4-a74e-4425-9a85-fdb49fa269d2')
def test_delete_user(self):
# Delete a user
@@ -92,7 +89,6 @@
self.alt_email)
self.client.delete_user(user['id'])
- @test.attr(type='smoke')
@test.idempotent_id('aca696c3-d645-4f45-b728-63646045beb1')
def test_user_authentication(self):
# Valid user's token is authenticated
@@ -121,7 +117,6 @@
self.data.test_tenant)
self.client.auth_provider.clear_auth()
- @test.attr(type='smoke')
@test.idempotent_id('a149c02e-e5e0-4b89-809e-7e8faf33ccda')
def test_get_users(self):
# Get a list of users and find the test user
@@ -196,7 +191,6 @@
"Failed to find user %s in fetched list" %
', '.join(m_user for m_user in missing_users))
- @test.attr(type='smoke')
@test.idempotent_id('1aeb25ac-6ec5-4d8b-97cb-7ac3567a989f')
def test_update_user_password(self):
# Test case to check if updating of user password is successful.
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 9bad8e0..98ab093 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -84,7 +84,6 @@
self.assertEqual(update_body['blob'][value2],
get_body['blob'][value2])
- @test.attr(type='smoke')
@test.idempotent_id('13202c00-0021-42a1-88d4-81b44d448aab')
def test_credentials_list_delete(self):
created_cred_ids = list()
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index 9841cc8..0b9d60e 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -10,10 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest_lib import auth
from tempest_lib.common.utils import data_utils
from tempest.api.identity import base
-from tempest import auth
from tempest import clients
from tempest import config
from tempest import manager
@@ -35,7 +35,6 @@
self.client.update_domain(domain_id, enabled=False)
self.client.delete_domain(domain_id)
- @test.attr(type='smoke')
@test.idempotent_id('d6110661-6a71-49a7-a453-b5e26640ff6d')
def test_default_project_id(self):
# create a domain
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 5af9187..79943bb 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -27,7 +27,6 @@
self.client.update_domain(domain_id, enabled=False)
self.client.delete_domain(domain_id)
- @test.attr(type='smoke')
@test.idempotent_id('8cf516ef-2114-48f1-907b-d32726c734d4')
def test_list_domains(self):
# Test to list domains
@@ -84,7 +83,6 @@
self.assertEqual(new_desc, fetched_domain['description'])
self.assertEqual('true', str(fetched_domain['enabled']).lower())
- @test.attr(type='smoke')
@test.idempotent_id('036df86e-bb5d-42c0-a7c2-66b9db3a6046')
def test_create_domain_with_disabled_status(self):
# Create domain with enabled status as false
@@ -97,7 +95,6 @@
self.assertFalse(domain['enabled'])
self.assertEqual(d_desc, domain['description'])
- @test.attr(type='smoke')
@test.idempotent_id('2abf8764-309a-4fa9-bc58-201b799817ad')
def test_create_domain_without_description(self):
# Create domain only with name
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index b366d1e..fed4dc2 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -21,7 +21,6 @@
class GroupsV3TestJSON(base.BaseIdentityV3AdminTest):
- @test.attr(type='smoke')
@test.idempotent_id('2e80343b-6c81-4ac3-88c7-452f3e9d5129')
def test_group_create_update_get(self):
name = data_utils.rand_name('Group')
@@ -70,7 +69,6 @@
group_users = self.client.list_group_users(group['id'])
self.assertEqual(len(group_users), 0)
- @test.attr(type='smoke')
@test.idempotent_id('64573281-d26a-4a52-b899-503cb0f4e4ec')
def test_list_user_groups(self):
# create a user
@@ -91,7 +89,6 @@
self.assertEqual(sorted(groups), sorted(user_groups))
self.assertEqual(2, len(user_groups))
- @test.attr(type='smoke')
@test.idempotent_id('cc9a57a5-a9ed-4f2d-a29f-4f979a06ec71')
def test_list_groups(self):
# Test to list groups
diff --git a/tempest/api/identity/admin/v3/test_policies.py b/tempest/api/identity/admin/v3/test_policies.py
index bad56f4..6c5599a 100644
--- a/tempest/api/identity/admin/v3/test_policies.py
+++ b/tempest/api/identity/admin/v3/test_policies.py
@@ -24,7 +24,6 @@
def _delete_policy(self, policy_id):
self.policy_client.delete_policy(policy_id)
- @test.attr(type='smoke')
@test.idempotent_id('1a0ad286-2d06-4123-ab0d-728893a76201')
def test_list_policies(self):
# Test to list policies
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 53aa15d..7857e11 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -89,7 +89,6 @@
roles = self.client.list_roles()
self.assertIn(role['id'], [r['id'] for r in roles])
- @test.attr(type='smoke')
@test.idempotent_id('c6b80012-fe4a-498b-9ce8-eb391c05169f')
def test_grant_list_revoke_role_to_user_on_project(self):
self.client.assign_user_role_on_project(
@@ -107,7 +106,6 @@
self.client.revoke_role_from_user_on_project(
self.project['id'], self.user_body['id'], self.role['id'])
- @test.attr(type='smoke')
@test.idempotent_id('6c9a2940-3625-43a3-ac02-5dcec62ef3bd')
def test_grant_list_revoke_role_to_user_on_domain(self):
self.client.assign_user_role_on_domain(
@@ -125,7 +123,6 @@
self.client.revoke_role_from_user_on_domain(
self.domain['id'], self.user_body['id'], self.role['id'])
- @test.attr(type='smoke')
@test.idempotent_id('cbf11737-1904-4690-9613-97bcbb3df1c4')
def test_grant_list_revoke_role_to_group_on_project(self):
# Grant role to group on project
@@ -156,7 +153,6 @@
self.client.revoke_role_from_group_on_project(
self.project['id'], self.group_body['id'], self.role['id'])
- @test.attr(type='smoke')
@test.idempotent_id('4bf8a70b-e785-413a-ad53-9f91ce02faa7')
def test_grant_list_revoke_role_to_group_on_domain(self):
self.client.assign_group_role_on_domain(
diff --git a/tempest/api/identity/admin/v3/test_services.py b/tempest/api/identity/admin/v3/test_services.py
index 886eacf..b2a75aa 100644
--- a/tempest/api/identity/admin/v3/test_services.py
+++ b/tempest/api/identity/admin/v3/test_services.py
@@ -62,7 +62,6 @@
self.assertEqual(resp2_desc, resp3_desc)
self.assertDictContainsSubset(update_service, fetched_service)
- @test.attr(type='smoke')
@test.idempotent_id('d1dcb1a1-2b6b-4da8-bbb8-5532ef6e8269')
def test_create_service_without_description(self):
# Create a service only with name and type
@@ -75,7 +74,6 @@
expected_data = {'name': name, 'type': serv_type}
self.assertDictContainsSubset(expected_data, service)
- @test.attr(type='smoke')
@test.idempotent_id('e55908e8-360e-439e-8719-c3230a3e179e')
def test_list_services(self):
# Create, List, Verify and Delete Services
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 6ac601a..41d67c7 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -22,7 +22,6 @@
class TokensV3TestJSON(base.BaseIdentityV3AdminTest):
- @test.attr(type='smoke')
@test.idempotent_id('0f9f5a5f-d5cd-4a86-8a5b-c5ded151f212')
def test_tokens(self):
# Valid user's token is authenticated
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index cafd615..3ebb90d 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -45,10 +45,11 @@
super(BaseTrustsV3Test, self).tearDown()
def create_trustor_and_roles(self):
- # Get trustor project ID, use the admin project
- self.trustor_project_name = self.client.tenant_name
- self.trustor_project_id = self.get_tenant_by_name(
- self.trustor_project_name)['id']
+ # create a project that trusts will be granted on
+ self.trustor_project_name = data_utils.rand_name(name='project-')
+ project = self.client.create_project(self.trustor_project_name,
+ domain_id='default')
+ self.trustor_project_id = project['id']
self.assertIsNotNone(self.trustor_project_id)
# Create a trustor User
@@ -61,7 +62,8 @@
description=u_desc,
password=self.trustor_password,
email=u_email,
- project_id=self.trustor_project_id)
+ project_id=self.trustor_project_id,
+ domain_id='default')
self.trustor_user_id = user['id']
# And two roles, one we'll delegate and one we won't
@@ -89,15 +91,20 @@
# Initialize a new client with the trustor credentials
creds = cred_provider.get_credentials(
+ identity_version='v3',
username=self.trustor_username,
password=self.trustor_password,
- tenant_name=self.trustor_project_name)
+ user_domain_id='default',
+ tenant_name=self.trustor_project_name,
+ project_domain_id='default')
os = clients.Manager(credentials=creds)
self.trustor_client = os.identity_v3_client
def cleanup_user_and_roles(self):
if self.trustor_user_id:
self.client.delete_user(self.trustor_user_id)
+ if self.trustor_project_id:
+ self.client.delete_project(self.trustor_project_id)
if self.delegated_role_id:
self.client.delete_role(self.delegated_role_id)
if self.not_delegated_role_id:
@@ -187,7 +194,6 @@
self.create_trustor_and_roles()
self.addCleanup(self.cleanup_user_and_roles)
- @test.attr(type='smoke')
@test.idempotent_id('5a0a91a4-baef-4a14-baba-59bf4d7fcace')
def test_trust_impersonate(self):
# Test case to check we can create, get and delete a trust
@@ -200,7 +206,6 @@
self.check_trust_roles()
- @test.attr(type='smoke')
@test.idempotent_id('ed2a8779-a7ac-49dc-afd7-30f32f936ed2')
def test_trust_noimpersonate(self):
# Test case to check we can create, get and delete a trust
@@ -213,7 +218,6 @@
self.check_trust_roles()
- @test.attr(type='smoke')
@test.idempotent_id('0ed14b66-cefd-4b5c-a964-65759453e292')
def test_trust_expire(self):
# Test case to check we can create, get and delete a trust
@@ -239,7 +243,6 @@
self.check_trust_roles()
- @test.attr(type='smoke')
@test.idempotent_id('3e48f95d-e660-4fa9-85e0-5a3d85594384')
def test_trust_expire_invalid(self):
# Test case to check we can check an invlaid expiry time
@@ -250,7 +253,6 @@
self.create_trust,
expires=expires_str)
- @test.attr(type='smoke')
@test.idempotent_id('6268b345-87ca-47c0-9ce3-37792b43403a')
def test_get_trusts_query(self):
self.create_trust()
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 832ddf0..32f80a2 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -28,6 +28,7 @@
Here we test the basic operations of images
"""
+ @test.attr(type='smoke')
@test.idempotent_id('139b765e-7f3d-4b3d-8b37-3ca3876ee318')
def test_register_upload_get_image_file(self):
@@ -69,6 +70,7 @@
body = self.client.get_image_file(image_id)
self.assertEqual(file_content, body.data)
+ @test.attr(type='smoke')
@test.idempotent_id('f848bb94-1c6e-45a4-8726-39e3a5b23535')
def test_delete_image(self):
# Deletes an image by image_id
@@ -90,6 +92,7 @@
images_id = [item['id'] for item in images]
self.assertNotIn(image_id, images_id)
+ @test.attr(type='smoke')
@test.idempotent_id('f66891a7-a35c-41a8-b590-a065c2a1caa6')
def test_update_image(self):
# Updates an image by image_id
diff --git a/tempest/api/messaging/base.py b/tempest/api/messaging/base.py
index 2ddc3fc..34ac860 100644
--- a/tempest/api/messaging/base.py
+++ b/tempest/api/messaging/base.py
@@ -116,20 +116,6 @@
return resp, body
@classmethod
- def get_single_message(cls, message_uri):
- """Wrapper utility that gets a single message."""
- resp, body = cls.client.show_single_message(message_uri)
-
- return resp, body
-
- @classmethod
- def get_multiple_messages(cls, message_uri):
- """Wrapper utility that gets multiple messages."""
- resp, body = cls.client.show_multiple_messages(message_uri)
-
- return resp, body
-
- @classmethod
def delete_messages(cls, message_uri):
"""Wrapper utility that deletes messages."""
resp, body = cls.client.delete_messages(message_uri)
diff --git a/tempest/api/network/admin/test_agent_management.py b/tempest/api/network/admin/test_agent_management.py
index be5bb1f..128398b 100644
--- a/tempest/api/network/admin/test_agent_management.py
+++ b/tempest/api/network/admin/test_agent_management.py
@@ -33,7 +33,6 @@
agents = body['agents']
cls.agent = agents[0]
- @test.attr(type='smoke')
@test.idempotent_id('9c80f04d-11f3-44a4-8738-ed2f879b0ff4')
def test_list_agent(self):
body = self.admin_client.list_agents()
@@ -46,20 +45,17 @@
agent.pop('configurations', None)
self.assertIn(self.agent, agents)
- @test.attr(type=['smoke'])
@test.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
def test_list_agents_non_admin(self):
body = self.client.list_agents()
self.assertEqual(len(body["agents"]), 0)
- @test.attr(type='smoke')
@test.idempotent_id('869bc8e8-0fda-4a30-9b71-f8a7cf58ca9f')
def test_show_agent(self):
body = self.admin_client.show_agent(self.agent['id'])
agent = body['agent']
self.assertEqual(agent['id'], self.agent['id'])
- @test.attr(type='smoke')
@test.idempotent_id('371dfc5b-55b9-4cb5-ac82-c40eadaac941')
def test_update_agent_status(self):
origin_status = self.agent['admin_state_up']
@@ -71,7 +67,6 @@
updated_status = body['agent']['admin_state_up']
self.assertEqual(origin_status, updated_status)
- @test.attr(type='smoke')
@test.idempotent_id('68a94a14-1243-46e6-83bf-157627e31556')
def test_update_agent_description(self):
self.useFixture(fixtures.LockFixture('agent_description'))
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 3b94b82..4a86aca 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -35,13 +35,11 @@
cls.cidr = cls.subnet['cidr']
cls.port = cls.create_port(cls.network)
- @test.attr(type='smoke')
@test.idempotent_id('5032b1fe-eb42-4a64-8f3b-6e189d8b5c7d')
def test_list_dhcp_agent_hosting_network(self):
self.admin_client.list_dhcp_agent_hosting_network(
self.network['id'])
- @test.attr(type='smoke')
@test.idempotent_id('30c48f98-e45d-4ffb-841c-b8aad57c7587')
def test_list_networks_hosted_by_one_dhcp(self):
body = self.admin_client.list_dhcp_agent_hosting_network(
@@ -61,7 +59,6 @@
network_ids.append(network['id'])
return network_id in network_ids
- @test.attr(type='smoke')
@test.idempotent_id('a0856713-6549-470c-a656-e97c8df9a14d')
def test_add_remove_network_from_dhcp_agent(self):
# The agent is now bound to the network, we can free the port
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index afc32da..d4e94ca 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -43,7 +43,6 @@
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
cls.port = cls.create_port(cls.network)
- @test.attr(type='smoke')
@test.idempotent_id('64f2100b-5471-4ded-b46c-ddeeeb4f231b')
def test_list_floating_ips_from_admin_and_nonadmin(self):
# Create floating ip from admin user
@@ -75,7 +74,6 @@
floating_ip_ids)
self.assertNotIn(floating_ip_alt['id'], floating_ip_ids)
- @test.attr(type='smoke')
@test.idempotent_id('32727cc3-abe2-4485-a16e-48f2d54c14f2')
def test_create_list_show_floating_ip_with_tenant_id_by_admin(self):
# Creates a floating IP
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index fca57c6..160cc06 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -81,12 +81,10 @@
cls.client.add_router_interface_with_port_id(
cls.router['id'], cls.port['id'])
- @test.attr(type='smoke')
@test.idempotent_id('b7ce6e89-e837-4ded-9b78-9ed3c9c6a45a')
def test_list_routers_on_l3_agent(self):
self.admin_client.list_routers_on_l3_agent(self.agent['id'])
- @test.attr(type='smoke')
@test.idempotent_id('9464e5e7-8625-49c3-8fd1-89c52be59d66')
def test_add_list_remove_router_on_l3_agent(self):
l3_agent_ids = list()
diff --git a/tempest/api/network/admin/test_lbaas_agent_scheduler.py b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
index c4f117b..7234348 100644
--- a/tempest/api/network/admin/test_lbaas_agent_scheduler.py
+++ b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
@@ -49,7 +49,6 @@
cls.pool = cls.create_pool(pool_name, "ROUND_ROBIN",
"HTTP", cls.subnet)
- @test.attr(type='smoke')
@test.idempotent_id('e5ea8b15-4f44-4350-963c-e0fcb533ee79')
def test_list_pools_on_lbaas_agent(self):
found = False
@@ -68,7 +67,6 @@
msg = 'Unable to find Load Balancer agent hosting pool'
self.assertTrue(found, msg)
- @test.attr(type='smoke')
@test.idempotent_id('e2745593-fd79-4b98-a262-575fd7865796')
def test_show_lbaas_agent_hosting_pool(self):
body = self.admin_client.show_lbaas_agent_hosting_pool(
diff --git a/tempest/api/network/admin/test_load_balancer_admin_actions.py b/tempest/api/network/admin/test_load_balancer_admin_actions.py
index 41f5caa..24a04be 100644
--- a/tempest/api/network/admin/test_load_balancer_admin_actions.py
+++ b/tempest/api/network/admin/test_load_balancer_admin_actions.py
@@ -50,7 +50,6 @@
cls.pool = cls.create_pool(data_utils.rand_name('pool-'),
"ROUND_ROBIN", "HTTP", cls.subnet)
- @test.attr(type='smoke')
@test.idempotent_id('6b0a20d8-4fcd-455e-b54f-ec4db5199518')
def test_create_vip_as_admin_for_another_tenant(self):
name = data_utils.rand_name('vip-')
@@ -77,7 +76,6 @@
self.assertEqual(vip['id'], show_vip['id'])
self.assertEqual(vip['name'], show_vip['name'])
- @test.attr(type='smoke')
@test.idempotent_id('74552cfc-ab78-4fb6-825b-f67bca379921')
def test_create_health_monitor_as_admin_for_another_tenant(self):
body = (
@@ -95,7 +93,6 @@
show_health_monitor = body['health_monitor']
self.assertEqual(health_monitor['id'], show_health_monitor['id'])
- @test.attr(type='smoke')
@test.idempotent_id('266a192d-3c22-46c4-a8fb-802450301e82')
def test_create_pool_from_admin_user_other_tenant(self):
body = self.admin_client.create_pool(
@@ -109,7 +106,6 @@
self.assertIsNotNone(pool['id'])
self.assertEqual(self.tenant_id, pool['tenant_id'])
- @test.attr(type='smoke')
@test.idempotent_id('158bb272-b9ed-4cfc-803c-661dac46f783')
def test_create_member_from_admin_user_other_tenant(self):
body = self.admin_client.create_member(address="10.0.9.47",
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index 86fbc54..46d6651 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest_lib.common.utils import data_utils
from tempest.api.network import base
@@ -62,7 +63,7 @@
quota_set = self.admin_client.update_quotas(tenant_id,
**new_quotas)
self.addCleanup(self.admin_client.reset_quotas, tenant_id)
- for key, value in new_quotas.iteritems():
+ for key, value in six.iteritems(new_quotas):
self.assertEqual(value, quota_set[key])
# Confirm our tenant is listed among tenants with non default quotas
@@ -76,7 +77,7 @@
# Confirm from API quotas were changed as requested for tenant
quota_set = self.admin_client.show_quotas(tenant_id)
quota_set = quota_set['quota']
- for key, value in new_quotas.iteritems():
+ for key, value in six.iteritems(new_quotas):
self.assertEqual(value, quota_set[key])
# Reset quotas to default and confirm
diff --git a/tempest/api/network/admin/test_routers_dvr.py b/tempest/api/network/admin/test_routers_dvr.py
index 48cd02b..e59be02 100644
--- a/tempest/api/network/admin/test_routers_dvr.py
+++ b/tempest/api/network/admin/test_routers_dvr.py
@@ -41,7 +41,6 @@
raise cls.skipException(msg)
cls.admin_client.delete_router(router['router']['id'])
- @test.attr(type='smoke')
@test.idempotent_id('08a2a0a8-f1e4-4b34-8e30-e522e836c44e')
def test_distributed_router_creation(self):
"""
@@ -59,7 +58,6 @@
router['router']['id'])
self.assertTrue(router['router']['distributed'])
- @test.attr(type='smoke')
@test.idempotent_id('8a0a72b4-7290-4677-afeb-b4ffe37bc352')
def test_centralized_router_creation(self):
"""
@@ -78,7 +76,6 @@
router['router']['id'])
self.assertFalse(router['router']['distributed'])
- @test.attr(type='smoke')
@test.idempotent_id('acd43596-c1fb-439d-ada8-31ad48ae3c2e')
def test_centralized_router_update_to_dvr(self):
"""
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index d2db326..5d7f00e 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -55,7 +55,6 @@
cls.ip_address = port['fixed_ips'][0]['ip_address']
cls.mac_address = port['mac_address']
- @test.attr(type='smoke')
@test.idempotent_id('86c3529b-1231-40de-803c-00e40882f043')
def test_create_list_port_with_address_pair(self):
# Create port with allowed address pair attribute
@@ -75,7 +74,6 @@
self.assertTrue(port, msg)
self._confirm_allowed_address_pair(port[0], self.ip_address)
- @test.attr(type='smoke')
def _update_port_with_address(self, address, mac_address=None, **kwargs):
# Create a port without allowed address pair
body = self.client.create_port(network_id=self.network['id'])
@@ -94,20 +92,17 @@
allowed_address_pair = body['port']['allowed_address_pairs']
self.assertEqual(allowed_address_pair, allowed_address_pairs)
- @test.attr(type='smoke')
@test.idempotent_id('9599b337-272c-47fd-b3cf-509414414ac4')
def test_update_port_with_address_pair(self):
# Update port with allowed address pair
self._update_port_with_address(self.ip_address)
- @test.attr(type='smoke')
@test.idempotent_id('4d6d178f-34f6-4bff-a01c-0a2f8fe909e4')
def test_update_port_with_cidr_address_pair(self):
# Update allowed address pair with cidr
cidr = str(netaddr.IPNetwork(CONF.network.tenant_network_cidr))
self._update_port_with_address(cidr)
- @test.attr(type='smoke')
@test.idempotent_id('b3f20091-6cd5-472b-8487-3516137df933')
def test_update_port_with_multiple_ip_mac_address_pair(self):
# Create an ip _address and mac_address through port create
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 253d779..ca08fbd 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -16,6 +16,7 @@
import netaddr
import random
+import six
from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
@@ -127,7 +128,7 @@
):
kwargs = {'ipv6_ra_mode': ra_mode,
'ipv6_address_mode': add_mode}
- kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ kwargs = {k: v for k, v in six.iteritems(kwargs) if v}
real_ip, eui_ip = self._get_ips_from_subnet(**kwargs)
self._clean_network()
self.assertEqual(eui_ip, real_ip,
@@ -203,8 +204,8 @@
real_ips = dict([(k['subnet_id'], k['ip_address'])
for k in port['fixed_ips']])
real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
- for sub in subnet_dhcp,
- subnet_slaac]
+ for sub in [subnet_dhcp,
+ subnet_slaac]]
self.client.delete_port(port['id'])
self.ports.pop()
body = self.client.list_ports()
@@ -256,8 +257,8 @@
real_ips = dict([(k['subnet_id'], k['ip_address'])
for k in port['fixed_ips']])
real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
- for sub in subnet_dhcp,
- subnet_slaac]
+ for sub in [subnet_dhcp,
+ subnet_slaac]]
self._clean_network()
self.assertTrue({real_eui_ip,
real_dhcp_ip}.issubset([eui_ip] + dhcp_ip))
@@ -284,7 +285,7 @@
):
kwargs = {'ipv6_ra_mode': ra_mode,
'ipv6_address_mode': add_mode}
- kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ kwargs = {k: v for k, v in six.iteritems(kwargs) if v}
subnet = self.create_subnet(self.network, **kwargs)
port = self.create_port(self.network)
port_ip = next(iter(port['fixed_ips']), None)['ip_address']
@@ -311,7 +312,7 @@
):
kwargs = {'ipv6_ra_mode': ra_mode,
'ipv6_address_mode': add_mode}
- kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ kwargs = {k: v for k, v in six.iteritems(kwargs) if v}
subnet = self.create_subnet(self.network, **kwargs)
ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
subnet["allocation_pools"][0]["end"])
@@ -389,7 +390,7 @@
):
kwargs = {'ipv6_ra_mode': ra_mode,
'ipv6_address_mode': add_mode}
- kwargs = {k: v for k, v in kwargs.iteritems() if v}
+ kwargs = {k: v for k, v in six.iteritems(kwargs) if v}
subnet, port = self._create_subnet_router(kwargs)
port_ip = next(iter(port['fixed_ips']), None)['ip_address']
self._clean_network()
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 1937028..72ac821 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -57,7 +57,6 @@
{'opt_value': cls.ip_server, 'opt_name': 'server-ip-address'}
]
- @test.attr(type='smoke')
@test.idempotent_id('d2c17063-3767-4a24-be4f-a23dbfa133c9')
def test_create_list_port_with_extra_dhcp_options(self):
# Create a port with Extra DHCP Options
@@ -74,7 +73,6 @@
self.assertTrue(port)
self._confirm_extra_dhcp_options(port[0], self.extra_dhcp_opts)
- @test.attr(type='smoke')
@test.idempotent_id('9a6aebf4-86ee-4f47-b07a-7f7232c55607')
def test_update_show_port_with_extra_dhcp_options(self):
# Update port with extra dhcp options
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 23223f6..57dab5f 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -121,7 +121,6 @@
self.assertIsNone(updated_floating_ip['fixed_ip_address'])
self.assertIsNone(updated_floating_ip['router_id'])
- @test.attr(type='smoke')
@test.idempotent_id('e1f6bffd-442f-4668-b30e-df13f2705e77')
def test_floating_ip_delete_port(self):
# Create a floating IP
@@ -147,7 +146,6 @@
self.assertIsNone(shown_floating_ip['fixed_ip_address'])
self.assertIsNone(shown_floating_ip['router_id'])
- @test.attr(type='smoke')
@test.idempotent_id('1bb2f731-fe5a-4b8c-8409-799ade1bed4d')
def test_floating_ip_update_different_router(self):
# Associate a floating IP to a port on a router
@@ -192,7 +190,6 @@
port_id=None)
self.assertIsNone(floating_ip['floatingip']['port_id'])
- @test.attr(type='smoke')
@test.idempotent_id('45c4c683-ea97-41ef-9c51-5e9802f2f3d7')
def test_create_update_floatingip_with_port_multiple_ip_address(self):
# Find out ips that can be used for tests
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index 824034f..8790102 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -51,7 +51,7 @@
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
cls.port = cls.create_port(cls.network)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('22996ea8-4a81-4b27-b6e1-fa5df92fa5e8')
def test_create_floatingip_with_port_ext_net_unreachable(self):
self.assertRaises(lib_exc.NotFound, self.client.create_floatingip,
@@ -60,7 +60,7 @@
fixed_ip_address=self.port['fixed_ips'][0]
['ip_address'])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('50b9aeb4-9f0b-48ee-aa31-fa955a48ff54')
def test_create_floatingip_in_private_network(self):
self.assertRaises(lib_exc.BadRequest,
@@ -70,7 +70,7 @@
fixed_ip_address=self.port['fixed_ips'][0]
['ip_address'])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('6b3b8797-6d43-4191-985c-c48b773eb429')
def test_associate_floatingip_port_ext_net_unreachable(self):
# Create floating ip
diff --git a/tempest/api/network/test_fwaas_extensions.py b/tempest/api/network/test_fwaas_extensions.py
index cecf96d..0622e87 100644
--- a/tempest/api/network/test_fwaas_extensions.py
+++ b/tempest/api/network/test_fwaas_extensions.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
@@ -145,7 +146,7 @@
def test_show_firewall_rule(self):
# show a created firewall rule
fw_rule = self.client.show_firewall_rule(self.fw_rule['id'])
- for key, value in fw_rule['firewall_rule'].iteritems():
+ for key, value in six.iteritems(fw_rule['firewall_rule']):
self.assertEqual(self.fw_rule[key], value)
@test.idempotent_id('1086dd93-a4c0-4bbb-a1bd-6d4bc62c199f')
@@ -187,7 +188,7 @@
# show a created firewall policy
fw_policy = self.client.show_firewall_policy(self.fw_policy['id'])
fw_policy = fw_policy['firewall_policy']
- for key, value in fw_policy.iteritems():
+ for key, value in six.iteritems(fw_policy):
self.assertEqual(self.fw_policy[key], value)
@test.idempotent_id('02082a03-3cdd-4789-986a-1327dd80bfb7')
@@ -216,7 +217,7 @@
firewall = self.client.show_firewall(firewall_id)
firewall = firewall['firewall']
- for key, value in firewall.iteritems():
+ for key, value in six.iteritems(firewall):
if key == 'status':
continue
self.assertEqual(created_firewall[key], value)
@@ -234,7 +235,6 @@
# Delete firewall
self.client.delete_firewall(firewall_id)
- @test.attr(type='smoke')
@test.idempotent_id('53305b4b-9897-4e01-87c0-2ae386083180')
def test_firewall_rule_insertion_position_removal_rule_from_policy(self):
# Create firewall rule
diff --git a/tempest/api/network/test_load_balancer.py b/tempest/api/network/test_load_balancer.py
index 8bd0f24..38a6fe9 100644
--- a/tempest/api/network/test_load_balancer.py
+++ b/tempest/api/network/test_load_balancer.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest_lib.common.utils import data_utils
from tempest_lib import decorators
@@ -75,7 +76,7 @@
body = create_obj(**kwargs)
obj = body[obj_name]
self.addCleanup(delete_obj, obj['id'])
- for key, value in obj.iteritems():
+ for key, value in six.iteritems(obj):
# It is not relevant to filter by all arguments. That is why
# there is a list of attr to except
if key not in attr_exceptions:
@@ -83,7 +84,6 @@
objs = [v[key] for v in body[obj_name + 's']]
self.assertIn(value, objs)
- @test.attr(type='smoke')
@test.idempotent_id('c96dbfab-4a80-4e74-a535-e950b5bedd47')
def test_list_vips(self):
# Verify the vIP exists in the list of all vIPs
@@ -91,7 +91,6 @@
vips = body['vips']
self.assertIn(self.vip['id'], [v['id'] for v in vips])
- @test.attr(type='smoke')
@test.idempotent_id('b8853f65-5089-4e69-befd-041a143427ff')
def test_list_vips_with_filter(self):
name = data_utils.rand_name('vip-')
@@ -109,7 +108,6 @@
description=data_utils.rand_name('description-'),
admin_state_up=False)
- @test.attr(type='smoke')
@test.idempotent_id('27f56083-9af9-4a48-abe9-ca1bcc6c9035')
def test_create_update_delete_pool_vip(self):
# Creates a vip
@@ -166,18 +164,16 @@
self.assertEqual('LEAST_CONNECTIONS', updated_pool['lb_method'])
self.client.delete_pool(pool['id'])
- @test.attr(type='smoke')
@test.idempotent_id('0435a95e-1d19-4d90-9e9f-3b979e9ad089')
def test_show_vip(self):
# Verifies the details of a vip
body = self.client.show_vip(self.vip['id'])
vip = body['vip']
- for key, value in vip.iteritems():
+ for key, value in six.iteritems(vip):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(self.vip[key], value)
- @test.attr(type='smoke')
@test.idempotent_id('6e7a7d31-8451-456d-b24a-e50479ce42a7')
def test_show_pool(self):
# Here we need to new pool without any dependence with vips
@@ -190,12 +186,11 @@
# Verifies the details of a pool
body = self.client.show_pool(pool['id'])
shown_pool = body['pool']
- for key, value in pool.iteritems():
+ for key, value in six.iteritems(pool):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(value, shown_pool[key])
- @test.attr(type='smoke')
@test.idempotent_id('d1ab1ffa-e06a-487f-911f-56418cb27727')
def test_list_pools(self):
# Verify the pool exists in the list of all pools
@@ -203,7 +198,6 @@
pools = body['pools']
self.assertIn(self.pool['id'], [p['id'] for p in pools])
- @test.attr(type='smoke')
@test.idempotent_id('27cc4c1a-caac-4273-b983-2acb4afaad4f')
def test_list_pools_with_filters(self):
attr_exceptions = ['status', 'vip_id', 'members', 'provider',
@@ -215,7 +209,6 @@
description=data_utils.rand_name('description-'),
admin_state_up=False)
- @test.attr(type='smoke')
@test.idempotent_id('282d0dfd-5c3a-4c9b-b39c-c99782f39193')
def test_list_members(self):
# Verify the member exists in the list of all members
@@ -223,7 +216,6 @@
members = body['members']
self.assertIn(self.member['id'], [m['id'] for m in members])
- @test.attr(type='smoke')
@test.idempotent_id('243b5126-24c6-4879-953e-7c7e32d8a57f')
def test_list_members_with_filters(self):
attr_exceptions = ['status', 'status_description']
@@ -232,7 +224,6 @@
protocol_port=80,
pool_id=self.pool['id'])
- @test.attr(type='smoke')
@test.idempotent_id('fb833ee8-9e69-489f-b540-a409762b78b2')
def test_create_update_delete_member(self):
# Creates a member
@@ -248,18 +239,16 @@
# Verification of member delete
self.client.delete_member(member['id'])
- @test.attr(type='smoke')
@test.idempotent_id('893cd71f-a7dd-4485-b162-f6ab9a534914')
def test_show_member(self):
# Verifies the details of a member
body = self.client.show_member(self.member['id'])
member = body['member']
- for key, value in member.iteritems():
+ for key, value in six.iteritems(member):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(self.member[key], value)
- @test.attr(type='smoke')
@test.idempotent_id('8e5822c5-68a4-4224-8d6c-a617741ebc2d')
def test_list_health_monitors(self):
# Verify the health monitor exists in the list of all health monitors
@@ -268,7 +257,6 @@
self.assertIn(self.health_monitor['id'],
[h['id'] for h in health_monitors])
- @test.attr(type='smoke')
@test.idempotent_id('49bac58a-511c-4875-b794-366698211d25')
def test_list_health_monitors_with_filters(self):
attr_exceptions = ['status', 'status_description', 'pools']
@@ -276,7 +264,6 @@
delay=5, max_retries=4, type="TCP",
timeout=2)
- @test.attr(type='smoke')
@test.idempotent_id('e8ce05c4-d554-4d1e-a257-ad32ce134bb5')
def test_create_update_delete_health_monitor(self):
# Creates a health_monitor
@@ -294,7 +281,6 @@
# Verification of health_monitor delete
body = self.client.delete_health_monitor(health_monitor['id'])
- @test.attr(type='smoke')
@test.idempotent_id('d3e1aebc-06c2-49b3-9816-942af54012eb')
def test_create_health_monitor_http_type(self):
hm_type = "HTTP"
@@ -307,7 +293,6 @@
health_monitor['id'])
self.assertEqual(hm_type, health_monitor['type'])
- @test.attr(type='smoke')
@test.idempotent_id('0eff9f67-90fb-4bb1-b4ed-c5fda99fff0c')
def test_update_health_monitor_http_method(self):
body = self.client.create_health_monitor(delay=4,
@@ -327,18 +312,16 @@
self.assertEqual("/home/user", updated_health_monitor['url_path'])
self.assertEqual("290", updated_health_monitor['expected_codes'])
- @test.attr(type='smoke')
@test.idempotent_id('08e126ab-1407-483f-a22e-b11cc032ca7c')
def test_show_health_monitor(self):
# Verifies the details of a health_monitor
body = self.client.show_health_monitor(self.health_monitor['id'])
health_monitor = body['health_monitor']
- for key, value in health_monitor.iteritems():
+ for key, value in six.iteritems(health_monitor):
# 'status' should not be confirmed in api tests
if key != 'status':
self.assertEqual(self.health_monitor[key], value)
- @test.attr(type='smoke')
@test.idempotent_id('87f7628e-8918-493d-af50-0602845dbb5b')
def test_associate_disassociate_health_monitor_with_pool(self):
# Verify that a health monitor can be associated with a pool
@@ -364,7 +347,6 @@
self.assertNotIn(pool['id'],
[p['pool_id'] for p in health_monitor['pools']])
- @test.attr(type='smoke')
@test.idempotent_id('525fc7dc-be24-408d-938d-822e9783e027')
def test_get_lb_pool_stats(self):
# Verify the details of pool stats
@@ -375,7 +357,6 @@
self.assertIn("active_connections", stats)
self.assertIn("bytes_out", stats)
- @test.attr(type='smoke')
@test.idempotent_id('66236be2-5121-4047-8cde-db4b83b110a5')
def test_update_list_of_health_monitors_associated_with_pool(self):
(self.client.associate_health_monitor_with_pool
@@ -390,7 +371,6 @@
(self.client.disassociate_health_monitor_with_pool
(self.health_monitor['id'], self.pool['id']))
- @test.attr(type='smoke')
@test.idempotent_id('44ec9b40-b501-41e2-951f-4fc673b15ac0')
def test_update_admin_state_up_of_pool(self):
self.client.update_pool(self.pool['id'],
@@ -399,7 +379,6 @@
pool = body['pool']
self.assertFalse(pool['admin_state_up'])
- @test.attr(type='smoke')
@test.idempotent_id('466a9d4c-37c6-4ea2-b807-133437beb48c')
def test_show_vip_associated_with_pool(self):
body = self.client.show_pool(self.pool['id'])
@@ -409,7 +388,6 @@
self.assertEqual(self.vip['name'], vip['name'])
self.assertEqual(self.vip['id'], vip['id'])
- @test.attr(type='smoke')
@test.idempotent_id('7b97694e-69d0-4151-b265-e1052a465aa8')
def test_show_members_associated_with_pool(self):
body = self.client.show_pool(self.pool['id'])
@@ -420,7 +398,6 @@
self.assertEqual(member_id, body['member']['id'])
self.assertIsNotNone(body['member']['admin_state_up'])
- @test.attr(type='smoke')
@test.idempotent_id('73ed6f27-595b-4b2c-969c-dbdda6b8ab34')
def test_update_pool_related_to_member(self):
# Create new pool
@@ -441,7 +418,6 @@
body = self.client.update_member(self.member['id'],
pool_id=self.pool['id'])
- @test.attr(type='smoke')
@test.idempotent_id('cf63f071-bbe3-40ba-97a0-a33e11923162')
def test_update_member_weight(self):
self.client.update_member(self.member['id'],
diff --git a/tempest/api/network/test_metering_extensions.py b/tempest/api/network/test_metering_extensions.py
index 7935e5b..68bc3cd 100644
--- a/tempest/api/network/test_metering_extensions.py
+++ b/tempest/api/network/test_metering_extensions.py
@@ -67,7 +67,6 @@
id=metering_label_rule_id))
self.assertEqual(len(rules['metering_label_rules']), 0)
- @test.attr(type='smoke')
@test.idempotent_id('e2fb2f8c-45bf-429a-9f17-171c70444612')
def test_list_metering_labels(self):
# Verify label filtering
@@ -75,7 +74,6 @@
metering_labels = body['metering_labels']
self.assertEqual(0, len(metering_labels))
- @test.attr(type='smoke')
@test.idempotent_id('ec8e15ff-95d0-433b-b8a6-b466bddb1e50')
def test_create_delete_metering_label_with_filters(self):
# Creates a label
@@ -92,7 +90,6 @@
id=metering_label['id']))
self.assertEqual(len(labels['metering_labels']), 1)
- @test.attr(type='smoke')
@test.idempotent_id('30abb445-0eea-472e-bd02-8649f54a5968')
def test_show_metering_label(self):
# Verifies the details of a label
@@ -105,7 +102,6 @@
self.assertEqual(self.metering_label['description'],
metering_label['description'])
- @test.attr(type='smoke')
@test.idempotent_id('cc832399-6681-493b-9d79-0202831a1281')
def test_list_metering_label_rules(self):
# Verify rule filtering
@@ -113,7 +109,6 @@
metering_label_rules = body['metering_label_rules']
self.assertEqual(0, len(metering_label_rules))
- @test.attr(type='smoke')
@test.idempotent_id('f4d547cd-3aee-408f-bf36-454f8825e045')
def test_create_delete_metering_label_rule_with_filters(self):
# Creates a rule
@@ -132,7 +127,6 @@
id=metering_label_rule['id']))
self.assertEqual(len(rules['metering_label_rules']), 1)
- @test.attr(type='smoke')
@test.idempotent_id('b7354489-96ea-41f3-9452-bace120fb4a7')
def test_show_metering_label_rule(self):
# Verifies the details of a rule
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index f85e8cf..5e3e374 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -15,6 +15,7 @@
import itertools
import netaddr
+import six
from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
@@ -162,7 +163,7 @@
**kwargs)
compare_args_full = dict(gateway_ip=gateway, cidr=cidr,
mask_bits=mask_bits, **kwargs)
- compare_args = dict((k, v) for k, v in compare_args_full.iteritems()
+ compare_args = dict((k, v) for k, v in six.iteritems(compare_args_full)
if v is not None)
if 'dns_nameservers' in set(subnet).intersection(compare_args):
@@ -207,7 +208,6 @@
for key in ['id', 'name']:
self.assertEqual(network[key], self.network[key])
- @test.attr(type='smoke')
@test.idempotent_id('867819bb-c4b6-45f7-acf9-90edcf70aa5e')
def test_show_network_fields(self):
# Verify specific fields of a network
@@ -228,7 +228,6 @@
if network['id'] == self.network['id']]
self.assertNotEmpty(networks, "Created network not found in the list")
- @test.attr(type='smoke')
@test.idempotent_id('6ae6d24f-9194-4869-9c85-c313cb20e080')
def test_list_networks_fields(self):
# Verify specific fields of the networks
@@ -250,7 +249,6 @@
self.assertIn(key, subnet)
self.assertEqual(subnet[key], self.subnet[key])
- @test.attr(type='smoke')
@test.idempotent_id('270fff0b-8bfc-411f-a184-1e8fd35286f0')
def test_show_subnet_fields(self):
# Verify specific fields of a subnet
@@ -271,7 +269,6 @@
if subnet['id'] == self.subnet['id']]
self.assertNotEmpty(subnets, "Created subnet not found in the list")
- @test.attr(type='smoke')
@test.idempotent_id('842589e3-9663-46b0-85e4-7f01273b0412')
def test_list_subnets_fields(self):
# Verify specific fields of subnets
@@ -290,7 +287,6 @@
except lib_exc.NotFound:
pass
- @test.attr(type='smoke')
@test.idempotent_id('f04f61a9-b7f3-4194-90b2-9bcf660d1bfe')
def test_delete_network_with_subnet(self):
# Creates a network
@@ -316,41 +312,34 @@
# it from the list.
self.subnets.pop()
- @test.attr(type='smoke')
@test.idempotent_id('d2d596e2-8e76-47a9-ac51-d4648009f4d3')
def test_create_delete_subnet_without_gateway(self):
self._create_verify_delete_subnet()
- @test.attr(type='smoke')
@test.idempotent_id('9393b468-186d-496d-aa36-732348cd76e7')
def test_create_delete_subnet_with_gw(self):
self._create_verify_delete_subnet(
**self.subnet_dict(['gateway']))
- @test.attr(type='smoke')
@test.idempotent_id('bec949c4-3147-4ba6-af5f-cd2306118404')
def test_create_delete_subnet_with_allocation_pools(self):
self._create_verify_delete_subnet(
**self.subnet_dict(['allocation_pools']))
- @test.attr(type='smoke')
@test.idempotent_id('8217a149-0c6c-4cfb-93db-0486f707d13f')
def test_create_delete_subnet_with_gw_and_allocation_pools(self):
self._create_verify_delete_subnet(**self.subnet_dict(
['gateway', 'allocation_pools']))
- @test.attr(type='smoke')
@test.idempotent_id('d830de0a-be47-468f-8f02-1fd996118289')
def test_create_delete_subnet_with_host_routes_and_dns_nameservers(self):
self._create_verify_delete_subnet(
**self.subnet_dict(['host_routes', 'dns_nameservers']))
- @test.attr(type='smoke')
@test.idempotent_id('94ce038d-ff0a-4a4c-a56b-09da3ca0b55d')
def test_create_delete_subnet_with_dhcp_enabled(self):
self._create_verify_delete_subnet(enable_dhcp=True)
- @test.attr(type='smoke')
@test.idempotent_id('3d3852eb-3009-49ec-97ac-5ce83b73010a')
def test_update_subnet_gw_dns_host_routes_dhcp(self):
network = self.create_network()
@@ -384,7 +373,6 @@
self._compare_resource_attrs(updated_subnet, kwargs)
- @test.attr(type='smoke')
@test.idempotent_id('a4d9ec4c-0306-4111-a75c-db01a709030b')
def test_create_delete_subnet_all_attributes(self):
self._create_verify_delete_subnet(
@@ -547,7 +535,6 @@
class NetworksIpV6TestJSON(NetworksTestJSON):
_ip_version = 6
- @test.attr(type='smoke')
@test.idempotent_id('e41a4888-65a6-418c-a095-f7c2ef4ad59a')
def test_create_delete_subnet_with_gw(self):
net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
@@ -558,7 +545,6 @@
# Verifies Subnet GW in IPv6
self.assertEqual(subnet['gateway_ip'], gateway)
- @test.attr(type='smoke')
@test.idempotent_id('ebb4fd95-524f-46af-83c1-0305b239338f')
def test_create_delete_subnet_with_default_gw(self):
net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
@@ -569,7 +555,6 @@
# Verifies Subnet GW in IPv6
self.assertEqual(subnet['gateway_ip'], gateway_ip)
- @test.attr(type='smoke')
@test.idempotent_id('a9653883-b2a4-469b-8c3c-4518430a7e55')
def test_create_list_subnet_with_no_gw64_one_network(self):
name = data_utils.rand_name('network-')
@@ -608,7 +593,6 @@
raise cls.skipException("IPv6 extended attributes for "
"subnets not available")
- @test.attr(type='smoke')
@test.idempotent_id('da40cd1b-a833-4354-9a85-cd9b8a3b74ca')
def test_create_delete_subnet_with_v6_attributes_stateful(self):
self._create_verify_delete_subnet(
@@ -616,14 +600,12 @@
ipv6_ra_mode='dhcpv6-stateful',
ipv6_address_mode='dhcpv6-stateful')
- @test.attr(type='smoke')
@test.idempotent_id('176b030f-a923-4040-a755-9dc94329e60c')
def test_create_delete_subnet_with_v6_attributes_slaac(self):
self._create_verify_delete_subnet(
ipv6_ra_mode='slaac',
ipv6_address_mode='slaac')
- @test.attr(type='smoke')
@test.idempotent_id('7d410310-8c86-4902-adf9-865d08e31adb')
def test_create_delete_subnet_with_v6_attributes_stateless(self):
self._create_verify_delete_subnet(
@@ -650,7 +632,6 @@
self.client.delete_network,
slaac_network['id'])
- @test.attr(type='smoke')
@test.idempotent_id('88554555-ebf8-41ef-9300-4926d45e06e9')
def test_create_delete_slaac_subnet_with_ports(self):
"""Test deleting subnet with SLAAC ports
@@ -661,7 +642,6 @@
"""
self._test_delete_subnet_with_ports("slaac")
- @test.attr(type='smoke')
@test.idempotent_id('2de6ab5a-fcf0-4144-9813-f91a940291f1')
def test_create_delete_stateless_subnet_with_ports(self):
"""Test deleting subnet with DHCPv6 stateless ports
diff --git a/tempest/api/network/test_networks_negative.py b/tempest/api/network/test_networks_negative.py
index d246d38..ae530c2 100644
--- a/tempest/api/network/test_networks_negative.py
+++ b/tempest/api/network/test_networks_negative.py
@@ -23,35 +23,35 @@
class NetworksNegativeTestJSON(base.BaseNetworkTest):
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('9293e937-824d-42d2-8d5b-e985ea67002a')
def test_show_non_existent_network(self):
non_exist_id = data_utils.rand_name('network')
self.assertRaises(lib_exc.NotFound, self.client.show_network,
non_exist_id)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('d746b40c-5e09-4043-99f7-cba1be8b70df')
def test_show_non_existent_subnet(self):
non_exist_id = data_utils.rand_name('subnet')
self.assertRaises(lib_exc.NotFound, self.client.show_subnet,
non_exist_id)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('a954861d-cbfd-44e8-b0a9-7fab111f235d')
def test_show_non_existent_port(self):
non_exist_id = data_utils.rand_name('port')
self.assertRaises(lib_exc.NotFound, self.client.show_port,
non_exist_id)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('98bfe4e3-574e-4012-8b17-b2647063de87')
def test_update_non_existent_network(self):
non_exist_id = data_utils.rand_name('network')
self.assertRaises(lib_exc.NotFound, self.client.update_network,
non_exist_id, name="new_name")
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('03795047-4a94-4120-a0a1-bd376e36fd4e')
def test_delete_non_existent_network(self):
non_exist_id = data_utils.rand_name('network')
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 953b268..7b6b25b 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -130,7 +130,6 @@
custom_matchers.MatchesDictExceptForKeys
(port, excluded_keys=['extra_dhcp_opts']))
- @test.attr(type='smoke')
@test.idempotent_id('45fcdaf2-dab0-4c13-ac6c-fcddfb579dbd')
def test_show_port_fields(self):
# Verify specific fields of a port
@@ -151,7 +150,6 @@
if port['id'] == self.port['id']]
self.assertNotEmpty(ports, "Created port not found in the list")
- @test.attr(type='smoke')
@test.idempotent_id('5ad01ed0-0e6e-4c5d-8194-232801b15c72')
def test_port_list_filter_by_router_id(self):
# Create a router
@@ -174,7 +172,6 @@
self.assertEqual(ports[0]['id'], port['port']['id'])
self.assertEqual(ports[0]['device_id'], router['id'])
- @test.attr(type='smoke')
@test.idempotent_id('ff7f117f-f034-4e0e-abff-ccef05c454b4')
def test_list_ports_fields(self):
# Verify specific fields of ports
@@ -186,7 +183,6 @@
for port in ports:
self.assertEqual(sorted(fields), sorted(port.keys()))
- @test.attr(type='smoke')
@test.idempotent_id('63aeadd4-3b49-427f-a3b1-19ca81f06270')
def test_create_update_port_with_second_ip(self):
# Create a network with two subnets
@@ -267,20 +263,17 @@
for security_group in security_groups_list:
self.assertIn(security_group, port_show['security_groups'])
- @test.attr(type='smoke')
@test.idempotent_id('58091b66-4ff4-4cc1-a549-05d60c7acd1a')
def test_update_port_with_security_group_and_extra_attributes(self):
self._update_port_with_security_groups(
[data_utils.rand_name('secgroup')])
- @test.attr(type='smoke')
@test.idempotent_id('edf6766d-3d40-4621-bc6e-2521a44c257d')
def test_update_port_with_two_security_groups_and_extra_attributes(self):
self._update_port_with_security_groups(
[data_utils.rand_name('secgroup'),
data_utils.rand_name('secgroup')])
- @test.attr(type='smoke')
@test.idempotent_id('13e95171-6cbd-489c-9d7c-3f9c58215c18')
def test_create_show_delete_port_user_defined_mac(self):
# Create a port for a legal mac
@@ -326,7 +319,6 @@
cls.tenant = cls.identity_client.get_tenant_by_name(
CONF.identity.tenant_name)
- @test.attr(type='smoke')
@test.idempotent_id('8e8569c1-9ac7-44db-8bc1-f5fb2814f29b')
def test_create_port_binding_ext_attr(self):
post_body = {"network_id": self.network['id'],
@@ -338,7 +330,6 @@
self.assertIsNotNone(host_id)
self.assertEqual(self.host_id, host_id)
- @test.attr(type='smoke')
@test.idempotent_id('6f6c412c-711f-444d-8502-0ac30fbf5dd5')
def test_update_port_binding_ext_attr(self):
post_body = {"network_id": self.network['id']}
@@ -352,7 +343,6 @@
self.assertIsNotNone(host_id)
self.assertEqual(self.host_id, host_id)
- @test.attr(type='smoke')
@test.idempotent_id('1c82a44a-6c6e-48ff-89e1-abe7eaf8f9f8')
def test_list_ports_binding_ext_attr(self):
# Create a new port
@@ -378,7 +368,6 @@
'%s' % (port['id'], ports_list))
self.assertEqual(self.host_id, listed_port[0]['binding:host_id'])
- @test.attr(type='smoke')
@test.idempotent_id('b54ac0ff-35fc-4c79-9ca3-c7dbd4ea4f13')
def test_show_port_binding_ext_attr(self):
body = self.admin_client.create_port(network_id=self.network['id'])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 7c0ab7f..35072b4 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -14,6 +14,7 @@
# under the License.
import netaddr
+import six
from tempest_lib.common.utils import data_utils
from tempest.api.network import base_routers as base
@@ -83,7 +84,6 @@
create_body['router']['id'])
self.assertEqual(show_body['router']['name'], updated_name)
- @test.attr(type='smoke')
@test.idempotent_id('e54dd3a3-4352-4921-b09d-44369ae17397')
def test_create_router_setting_tenant_id(self):
# Test creating router from admin user setting tenant_id.
@@ -103,7 +103,6 @@
@test.idempotent_id('847257cc-6afd-4154-b8fb-af49f5670ce8')
@test.requires_ext(extension='ext-gw-mode', service='network')
- @test.attr(type='smoke')
def test_create_router_with_default_snat_value(self):
# Create a router with default snat rule
name = data_utils.rand_name('router')
@@ -115,7 +114,6 @@
@test.idempotent_id('ea74068d-09e9-4fd7-8995-9b6a1ace920f')
@test.requires_ext(extension='ext-gw-mode', service='network')
- @test.attr(type='smoke')
def test_create_router_with_snat_explicit(self):
name = data_utils.rand_name('snat-router')
# Create a router enabling snat attributes
@@ -179,7 +177,7 @@
self.assertIsNone(actual_ext_gw_info)
return
# Verify only keys passed in exp_ext_gw_info
- for k, v in exp_ext_gw_info.iteritems():
+ for k, v in six.iteritems(exp_ext_gw_info):
self.assertEqual(v, actual_ext_gw_info[k])
def _verify_gateway_port(self, router_id):
@@ -196,7 +194,6 @@
self.assertIn(public_subnet_id,
map(lambda x: x['subnet_id'], fixed_ips))
- @test.attr(type='smoke')
@test.idempotent_id('6cc285d8-46bf-4f36-9b1a-783e3008ba79')
def test_update_router_set_gateway(self):
router = self._create_router(data_utils.rand_name('router-'))
@@ -212,7 +209,6 @@
@test.idempotent_id('b386c111-3b21-466d-880c-5e72b01e1a33')
@test.requires_ext(extension='ext-gw-mode', service='network')
- @test.attr(type='smoke')
def test_update_router_set_gateway_with_snat_explicit(self):
router = self._create_router(data_utils.rand_name('router-'))
self.admin_client.update_router_with_snat_gw_info(
@@ -228,7 +224,6 @@
@test.idempotent_id('96536bc7-8262-4fb2-9967-5c46940fa279')
@test.requires_ext(extension='ext-gw-mode', service='network')
- @test.attr(type='smoke')
def test_update_router_set_gateway_without_snat(self):
router = self._create_router(data_utils.rand_name('router-'))
self.admin_client.update_router_with_snat_gw_info(
@@ -242,7 +237,6 @@
'enable_snat': False})
self._verify_gateway_port(router['id'])
- @test.attr(type='smoke')
@test.idempotent_id('ad81b7ee-4f81-407b-a19c-17e623f763e8')
def test_update_router_unset_gateway(self):
router = self._create_router(
@@ -258,7 +252,6 @@
@test.idempotent_id('f2faf994-97f4-410b-a831-9bc977b64374')
@test.requires_ext(extension='ext-gw-mode', service='network')
- @test.attr(type='smoke')
def test_update_router_reset_gateway_without_snat(self):
router = self._create_router(
data_utils.rand_name('router-'),
@@ -276,7 +269,6 @@
@test.idempotent_id('c86ac3a8-50bd-4b00-a6b8-62af84a0765c')
@test.requires_ext(extension='extraroute', service='network')
- @test.attr(type='smoke')
def test_update_extra_route(self):
self.network = self.create_network()
self.name = self.network['name']
@@ -309,7 +301,6 @@
def _delete_extra_routes(self, router_id):
self.client.delete_extra_routes(router_id)
- @test.attr(type='smoke')
@test.idempotent_id('a8902683-c788-4246-95c7-ad9c6d63a4d9')
def test_update_router_admin_state(self):
self.router = self._create_router(data_utils.rand_name('router-'))
@@ -362,7 +353,6 @@
msg = "DVR extension not enabled."
raise cls.skipException(msg)
- @test.attr(type='smoke')
@test.idempotent_id('141297aa-3424-455d-aa8d-f2d95731e00a')
def test_create_distributed_router(self):
name = data_utils.rand_name('router')
@@ -373,7 +363,6 @@
self.admin_client)
self.assertTrue(create_body['router']['distributed'])
- @test.attr(type='smoke')
@test.idempotent_id('644d7a4a-01a1-4b68-bb8d-0c0042cb1729')
def test_convert_centralized_router(self):
router = self._create_router(data_utils.rand_name('router'))
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 4149be3..d2afcba 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -43,7 +43,7 @@
if cls._ip_version == 4 else
CONF.network.tenant_network_v6_cidr)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('37a94fc0-a834-45b9-bd23-9a81d2fd1e22')
def test_router_add_gateway_invalid_network_returns_404(self):
self.assertRaises(lib_exc.NotFound,
@@ -52,7 +52,7 @@
external_gateway_info={
'network_id': self.router['id']})
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('11836a18-0b15-4327-a50b-f0d9dc66bddd')
def test_router_add_gateway_net_not_external_returns_400(self):
alt_network = self.create_network(
@@ -65,7 +65,7 @@
external_gateway_info={
'network_id': alt_network['id']})
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('957751a3-3c68-4fa2-93b6-eb52ea10db6e')
def test_add_router_interfaces_on_overlapping_subnets_returns_400(self):
network01 = self.create_network(
@@ -81,7 +81,7 @@
self.router['id'],
subnet02['id'])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('04df80f9-224d-47f5-837a-bf23e33d1c20')
def test_router_remove_interface_in_use_returns_409(self):
self.client.add_router_interface_with_subnet_id(
@@ -90,21 +90,21 @@
self.client.delete_router,
self.router['id'])
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('c2a70d72-8826-43a7-8208-0209e6360c47')
def test_show_non_existent_router_returns_404(self):
router = data_utils.rand_name('non_exist_router')
self.assertRaises(lib_exc.NotFound, self.client.show_router,
router)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('b23d1569-8b0c-4169-8d4b-6abd34fad5c7')
def test_update_non_existent_router_returns_404(self):
router = data_utils.rand_name('non_exist_router')
self.assertRaises(lib_exc.NotFound, self.client.update_router,
router, name="new_name")
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('c7edc5ad-d09d-41e6-a344-5c0c31e2e3e4')
def test_delete_non_existent_router_returns_404(self):
router = data_utils.rand_name('non_exist_router')
@@ -132,7 +132,7 @@
cls.network = cls.create_network()
cls.subnet = cls.create_subnet(cls.network)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('4990b055-8fc7-48ab-bba7-aa28beaad0b9')
def test_router_create_tenant_distributed_returns_forbidden(self):
self.assertRaises(lib_exc.Forbidden,
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 71e1beb..05f0de4 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -141,7 +141,6 @@
self.assertIn(rule_create_body['security_group_rule']['id'],
rule_list)
- @test.attr(type='smoke')
@test.idempotent_id('87dfbcf9-1849-43ea-b1e4-efa3eeae9f71')
def test_create_security_group_rule_with_additional_args(self):
"""Verify security group rule with additional arguments works.
@@ -160,7 +159,6 @@
port_range_min,
port_range_max)
- @test.attr(type='smoke')
@test.idempotent_id('c9463db8-b44d-4f52-b6c0-8dbda99f26ce')
def test_create_security_group_rule_with_icmp_type_code(self):
"""Verify security group rule for icmp protocol works.
@@ -181,7 +179,6 @@
self.ethertype, protocol,
icmp_type, icmp_code)
- @test.attr(type='smoke')
@test.idempotent_id('c2ed2deb-7a0c-44d8-8b4c-a5825b5c310b')
def test_create_security_group_rule_with_remote_group_id(self):
# Verify creating security group rule with remote_group_id works
@@ -200,7 +197,6 @@
port_range_max,
remote_group_id=remote_id)
- @test.attr(type='smoke')
@test.idempotent_id('16459776-5da2-4634-bce4-4b55ee3ec188')
def test_create_security_group_rule_with_remote_ip_prefix(self):
# Verify creating security group rule with remote_ip_prefix works
@@ -218,7 +214,6 @@
port_range_max,
remote_ip_prefix=ip_prefix)
- @test.attr(type='smoke')
@test.idempotent_id('0a307599-6655-4220-bebc-fd70c64f2290')
def test_create_security_group_rule_with_protocol_integer_value(self):
# Verify creating security group rule with the
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index ce6253b..f80ea59 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -157,7 +157,7 @@
direction='ingress', ethertype=self.ethertype)
self.assertIn(msg, str(ex))
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('2323061e-9fbf-4eb0-b547-7e8fafc90849')
def test_create_additional_default_security_group_fails(self):
# Create security group named 'default', it should be failed.
@@ -166,7 +166,7 @@
self.client.create_security_group,
name=name)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('8fde898f-ce88-493b-adc9-4e4692879fc5')
def test_create_duplicate_security_group_rule_fails(self):
# Create duplicate security group rule, it should fail.
@@ -191,7 +191,7 @@
protocol='tcp', direction='ingress', ethertype=self.ethertype,
port_range_min=min_port, port_range_max=max_port)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('be308db6-a7cf-4d5c-9baf-71bafd73f35e')
def test_create_security_group_rule_with_non_existent_security_group(self):
# Create security group rules with not existing security group.
diff --git a/tempest/api/network/test_service_type_management.py b/tempest/api/network/test_service_type_management.py
index 085ad73..ad1ecc4 100644
--- a/tempest/api/network/test_service_type_management.py
+++ b/tempest/api/network/test_service_type_management.py
@@ -26,7 +26,6 @@
raise cls.skipException(msg)
@decorators.skip_because(bug="1400370")
- @test.attr(type='smoke')
@test.idempotent_id('2cbbeea9-f010-40f6-8df5-4eaa0c918ea6')
def test_service_provider_list(self):
body = self.client.list_service_providers()
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
index 4ab69e0..9fe2a56 100644
--- a/tempest/api/network/test_vpnaas_extensions.py
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
@@ -82,7 +83,7 @@
def _assertExpected(self, expected, actual):
# Check if not expected keys/values exists in actual response body
- for key, value in expected.iteritems():
+ for key, value in six.iteritems(expected):
self.assertIn(key, actual)
self.assertEqual(value, actual[key])
@@ -103,7 +104,6 @@
body = self.client.show_network(self.network['id'])
return body['network']['tenant_id']
- @test.attr(type='smoke')
@test.idempotent_id('14311574-0737-4e53-ac05-f7ae27742eed')
def test_admin_create_ipsec_policy_for_tenant(self):
tenant_id = self._get_tenant_id()
@@ -121,7 +121,6 @@
ipsecpolicies = [policy['id'] for policy in body['ipsecpolicies']]
self.assertIn(ipsecpolicy['id'], ipsecpolicies)
- @test.attr(type='smoke')
@test.idempotent_id('b62acdc6-0c53-4d84-84aa-859b22b79799')
def test_admin_create_vpn_service_for_tenant(self):
tenant_id = self._get_tenant_id()
@@ -147,7 +146,6 @@
vpn_services = [vs['id'] for vs in body['vpnservices']]
self.assertIn(vpnservice['id'], vpn_services)
- @test.attr(type='smoke')
@test.idempotent_id('58cc4a1c-443b-4f39-8fb6-c19d39f343ab')
def test_admin_create_ike_policy_for_tenant(self):
tenant_id = self._get_tenant_id()
@@ -168,7 +166,6 @@
ikepolicies = [ikp['id'] for ikp in body['ikepolicies']]
self.assertIn(ikepolicy['id'], ikepolicies)
- @test.attr(type='smoke')
@test.idempotent_id('de5bb04c-3a1f-46b1-b329-7a8abba5c7f1')
def test_list_vpn_services(self):
# Verify the VPN service exists in the list of all VPN services
@@ -176,7 +173,6 @@
vpnservices = body['vpnservices']
self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
- @test.attr(type='smoke')
@test.idempotent_id('aacb13b1-fdc7-41fd-bab2-32621aee1878')
def test_create_update_delete_vpn_service(self):
# Creates a VPN service and sets up deletion
@@ -203,7 +199,6 @@
# But precondition is that current state of vpnservice
# should be "ACTIVE" not "PENDING*"
- @test.attr(type='smoke')
@test.idempotent_id('0dedfc1d-f8ee-4e2a-bfd4-7997b9dc17ff')
def test_show_vpn_service(self):
# Verifies the details of a vpn service
@@ -220,7 +215,6 @@
"PENDING_UPDATE", "PENDING_DELETE"]
self.assertIn(vpnservice['status'], valid_status)
- @test.attr(type='smoke')
@test.idempotent_id('e0fb6200-da3d-4869-8340-a8c1956ca618')
def test_list_ike_policies(self):
# Verify the ike policy exists in the list of all IKE policies
@@ -228,7 +222,6 @@
ikepolicies = body['ikepolicies']
self.assertIn(self.ikepolicy['id'], [i['id'] for i in ikepolicies])
- @test.attr(type='smoke')
@test.idempotent_id('d61f29a5-160c-487d-bc0d-22e32e731b44')
def test_create_update_delete_ike_policy(self):
# Creates a IKE policy
@@ -253,7 +246,7 @@
# Confirm that update was successful by verifying using 'show'
body = self.client.show_ikepolicy(ikepolicy['id'])
ike_policy = body['ikepolicy']
- for key, value in new_ike.iteritems():
+ for key, value in six.iteritems(new_ike):
self.assertIn(key, ike_policy)
self.assertEqual(value, ike_policy[key])
@@ -263,7 +256,6 @@
ikepolicies = [ikp['id'] for ikp in body['ikepolicies']]
self.assertNotIn(ike_policy['id'], ikepolicies)
- @test.attr(type='smoke')
@test.idempotent_id('b5fcf3a3-9407-452d-b8a8-e7c6c32baea8')
def test_show_ike_policy(self):
# Verifies the details of a ike policy
@@ -286,7 +278,6 @@
self.assertEqual(self.ikepolicy['ike_version'],
ikepolicy['ike_version'])
- @test.attr(type='smoke')
@test.idempotent_id('19ea0a2f-add9-44be-b732-ffd8a7b42f37')
def test_list_ipsec_policies(self):
# Verify the ipsec policy exists in the list of all ipsec policies
@@ -294,7 +285,6 @@
ipsecpolicies = body['ipsecpolicies']
self.assertIn(self.ipsecpolicy['id'], [i['id'] for i in ipsecpolicies])
- @test.attr(type='smoke')
@test.idempotent_id('9c1701c9-329a-4e5d-930a-1ead1b3f86ad')
def test_create_update_delete_ipsec_policy(self):
# Creates an ipsec policy
@@ -321,7 +311,6 @@
self.assertRaises(lib_exc.NotFound,
self.client.delete_ipsecpolicy, ipsecpolicy['id'])
- @test.attr(type='smoke')
@test.idempotent_id('601f8a05-9d3c-4539-a400-1c4b3a21b03b')
def test_show_ipsec_policy(self):
# Verifies the details of an ipsec policy
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index 524454e..a11b407 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -77,7 +77,7 @@
cls.delete_containers([cls.container_name])
super(AccountQuotasNegativeTest, cls).resource_cleanup()
- @test.attr(type=["negative", "smoke"])
+ @test.attr(type=["negative"])
@test.idempotent_id('d1dc5076-555e-4e6d-9697-28f1fe976324')
@test.requires_ext(extension='account_quotas', service='object')
def test_user_modify_quota(self):
@@ -95,7 +95,7 @@
self.account_client.create_account_metadata,
{"Quota-Bytes": "100"})
- @test.attr(type=["negative", "smoke"])
+ @test.attr(type=["negative"])
@decorators.skip_because(bug="1310597")
@test.idempotent_id('cf9e21f5-3aa4-41b1-9462-28ac550d8d3f')
@test.requires_ext(extension='account_quotas', service='object')
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index 44b24d5..c28a3e0 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -62,7 +62,6 @@
for container_name in self.containers:
self.assertIn(container_name, container_list)
- @test.attr(type='smoke')
@test.idempotent_id('884ec421-fbad-4fcc-916b-0580f2699565')
def test_list_no_containers(self):
# List request to empty account
@@ -91,7 +90,6 @@
self.assertEqual(len(container_list), 0)
- @test.attr(type='smoke')
@test.idempotent_id('1c7efa35-e8a2-4b0b-b5ff-862c7fd83704')
def test_list_containers_with_format_json(self):
# list containers setting format parameter to 'json'
@@ -104,7 +102,6 @@
self.assertTrue([c['count'] for c in container_list])
self.assertTrue([c['bytes'] for c in container_list])
- @test.attr(type='smoke')
@test.idempotent_id('4477b609-1ca6-4d4b-b25d-ad3f01086089')
def test_list_containers_with_format_xml(self):
# list containers setting format parameter to 'xml'
@@ -120,7 +117,6 @@
self.assertEqual(container_list.find(".//count").tag, 'count')
self.assertEqual(container_list.find(".//bytes").tag, 'bytes')
- @test.attr(type='smoke')
@test.idempotent_id('6eb04a6a-4860-4e31-ba91-ea3347d76b58')
@testtools.skipIf(
not CONF.object_storage_feature_enabled.discoverability,
@@ -130,7 +126,6 @@
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
- @test.attr(type='smoke')
@test.idempotent_id('5cfa4ab2-4373-48dd-a41f-a532b12b08b2')
def test_list_containers_with_limit(self):
# list containers one of them, half of them then all of them
@@ -142,7 +137,6 @@
self.assertEqual(len(container_list), limit)
- @test.attr(type='smoke')
@test.idempotent_id('638f876d-6a43-482a-bbb3-0840bca101c6')
def test_list_containers_with_marker(self):
# list containers using marker param
@@ -163,7 +157,6 @@
self.assertEqual(len(container_list), self.containers_count / 2 - 1)
- @test.attr(type='smoke')
@test.idempotent_id('5ca164e4-7bde-43fa-bafb-913b53b9e786')
def test_list_containers_with_end_marker(self):
# list containers using end_marker param
@@ -182,7 +175,6 @@
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), self.containers_count / 2)
- @test.attr(type='smoke')
@test.idempotent_id('ac8502c2-d4e4-4f68-85a6-40befea2ef5e')
def test_list_containers_with_marker_and_end_marker(self):
# list containers combining marker and end_marker param
@@ -193,7 +185,6 @@
self.assertHeaders(resp, 'Account', 'GET')
self.assertEqual(len(container_list), self.containers_count - 2)
- @test.attr(type='smoke')
@test.idempotent_id('f7064ae8-dbcc-48da-b594-82feef6ea5af')
def test_list_containers_with_limit_and_marker(self):
# list containers combining marker and limit param
@@ -208,7 +199,6 @@
self.assertTrue(len(container_list) <= limit, str(container_list))
- @test.attr(type='smoke')
@test.idempotent_id('888a3f0e-7214-4806-8e50-5e0c9a69bb5e')
def test_list_containers_with_limit_and_end_marker(self):
# list containers combining limit and end_marker param
@@ -221,7 +211,6 @@
self.assertEqual(len(container_list),
min(limit, self.containers_count / 2))
- @test.attr(type='smoke')
@test.idempotent_id('8cf98d9c-e3a0-4e44-971b-c87656fdddbd')
def test_list_containers_with_limit_and_marker_and_end_marker(self):
# list containers combining limit, marker and end_marker param
@@ -251,7 +240,6 @@
self.assertIn('x-account-meta-test-account-meta2', resp)
self.account_client.delete_account_metadata(metadata)
- @test.attr(type='smoke')
@test.idempotent_id('b904c2e3-24c2-4dba-ad7d-04e90a761be5')
def test_list_no_account_metadata(self):
# list no account metadata
@@ -259,7 +247,6 @@
self.assertHeaders(resp, 'Account', 'HEAD')
self.assertNotIn('x-account-meta-', str(resp))
- @test.attr(type='smoke')
@test.idempotent_id('e2a08b5f-3115-4768-a3ee-d4287acd6c08')
def test_update_account_metadata_with_create_metadata(self):
# add metadata to account
@@ -274,7 +261,6 @@
self.account_client.delete_account_metadata(metadata)
- @test.attr(type='smoke')
@test.idempotent_id('9f60348d-c46f-4465-ae06-d51dbd470953')
def test_update_account_metadata_with_delete_matadata(self):
# delete metadata from account
@@ -286,7 +272,6 @@
resp, _ = self.account_client.list_account_metadata()
self.assertNotIn('x-account-meta-test-account-meta1', resp)
- @test.attr(type='smoke')
@test.idempotent_id('64fd53f3-adbd-4639-af54-436e4982dbfb')
def test_update_account_metadata_with_create_matadata_key(self):
# if the value of metadata is not set, the metadata is not
@@ -298,7 +283,6 @@
resp, _ = self.account_client.list_account_metadata()
self.assertNotIn('x-account-meta-test-account-meta1', resp)
- @test.attr(type='smoke')
@test.idempotent_id('d4d884d3-4696-4b85-bc98-4f57c4dd2bf1')
def test_update_account_metadata_with_delete_matadata_key(self):
# Although the value of metadata is not set, the feature of
@@ -312,7 +296,6 @@
resp, _ = self.account_client.list_account_metadata()
self.assertNotIn('x-account-meta-test-account-meta1', resp)
- @test.attr(type='smoke')
@test.idempotent_id('8e5fc073-59b9-42ee-984a-29ed11b2c749')
def test_update_account_metadata_with_create_and_delete_metadata(self):
# Send a request adding and deleting metadata requests simultaneously
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index eaf5bf0..25dac6b 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -44,7 +44,6 @@
self.delete_containers([self.container_name])
super(ObjectTestACLs, self).tearDown()
- @test.attr(type='smoke')
@test.idempotent_id('a3270f3f-7640-4944-8448-c7ea783ea5b6')
def test_read_object_with_rights(self):
# attempt to read object using authorized user
@@ -70,7 +69,6 @@
self.container_name, object_name)
self.assertHeaders(resp, 'Object', 'GET')
- @test.attr(type='smoke')
@test.idempotent_id('aa58bfa5-40d9-4bc3-82b4-d07f4a9e392a')
def test_write_object_with_rights(self):
# attempt to write object using authorized user
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index 2d43b74..31c301a 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -126,7 +126,7 @@
self.object_client.delete_object,
self.container_name, object_name)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('9ed01334-01e9-41ea-87ea-e6f465582823')
def test_read_object_without_rights(self):
# attempt to read object using non-authorized user
@@ -150,7 +150,7 @@
self.object_client.get_object,
self.container_name, object_name)
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('a3a585a7-d8cf-4b65-a1a0-edc2b1204f85')
def test_write_object_without_rights(self):
# attempt to write object using non-authorized user
@@ -171,7 +171,7 @@
self.container_name,
object_name, 'data', headers={})
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('8ba512ad-aa6e-444e-b882-2906a0ea2052')
def test_write_object_without_write_rights(self):
# attempt to write object using non-authorized user
@@ -196,7 +196,7 @@
self.container_name,
object_name, 'data', headers={})
- @test.attr(type=['negative', 'smoke'])
+ @test.attr(type=['negative'])
@test.idempotent_id('b4e366f8-f185-47ab-b789-df4416f9ecdb')
def test_delete_object_without_write_rights(self):
# attempt to delete object using non-authorized user
diff --git a/tempest/api/object_storage/test_container_services.py b/tempest/api/object_storage/test_container_services.py
index 9f2adfe..0f107f5 100644
--- a/tempest/api/object_storage/test_container_services.py
+++ b/tempest/api/object_storage/test_container_services.py
@@ -55,7 +55,6 @@
self.containers.append(container_name)
self.assertHeaders(resp, 'Container', 'PUT')
- @test.attr(type='smoke')
@test.idempotent_id('49f866ed-d6af-4395-93e7-4187eb56d322')
def test_create_container_overwrite(self):
# overwrite container with the same name
@@ -66,7 +65,6 @@
resp, _ = self.container_client.create_container(container_name)
self.assertHeaders(resp, 'Container', 'PUT')
- @test.attr(type='smoke')
@test.idempotent_id('c2ac4d59-d0f5-40d5-ba19-0635056d48cd')
def test_create_container_with_metadata_key(self):
# create container with the blank value of metadata
@@ -84,7 +82,6 @@
# in the server
self.assertNotIn('x-container-meta-test-container-meta', resp)
- @test.attr(type='smoke')
@test.idempotent_id('e1e8df32-7b22-44e1-aa08-ccfd8d446b58')
def test_create_container_with_metadata_value(self):
# create container with metadata value
@@ -103,7 +100,6 @@
self.assertEqual(resp['x-container-meta-test-container-meta'],
metadata['test-container-meta'])
- @test.attr(type='smoke')
@test.idempotent_id('24d16451-1c0c-4e4f-b59c-9840a3aba40e')
def test_create_container_with_remove_metadata_key(self):
# create container with the blank value of remove metadata
@@ -124,7 +120,6 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta', resp)
- @test.attr(type='smoke')
@test.idempotent_id('8a21ebad-a5c7-4e29-b428-384edc8cd156')
def test_create_container_with_remove_metadata_value(self):
# create container with remove metadata
@@ -143,7 +138,6 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta', resp)
- @test.attr(type='smoke')
@test.idempotent_id('95d3a249-b702-4082-a2c4-14bb860cf06a')
def test_delete_container(self):
# create a container
@@ -165,7 +159,6 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual(object_name, object_list.strip('\n'))
- @test.attr(type='smoke')
@test.idempotent_id('4646ac2d-9bfb-4c7d-a3c5-0f527402b3df')
def test_list_container_contents_with_no_object(self):
# get empty container contents list
@@ -176,7 +169,6 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual('', object_list.strip('\n'))
- @test.attr(type='smoke')
@test.idempotent_id('fe323a32-57b9-4704-a996-2e68f83b09bc')
def test_list_container_contents_with_delimiter(self):
# get container contents list using delimiter param
@@ -191,7 +183,6 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual(object_name.split('/')[0], object_list.strip('/\n'))
- @test.attr(type='smoke')
@test.idempotent_id('55b4fa5c-e12e-4ca9-8fcf-a79afe118522')
def test_list_container_contents_with_end_marker(self):
# get container contents list using end_marker param
@@ -205,7 +196,6 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual(object_name, object_list.strip('\n'))
- @test.attr(type='smoke')
@test.idempotent_id('196f5034-6ab0-4032-9da9-a937bbb9fba9')
def test_list_container_contents_with_format_json(self):
# get container contents list using format_json param
@@ -225,7 +215,6 @@
self.assertTrue([c['content_type'] for c in object_list])
self.assertTrue([c['last_modified'] for c in object_list])
- @test.attr(type='smoke')
@test.idempotent_id('655a53ca-4d15-408c-a377-f4c6dbd0a1fa')
def test_list_container_contents_with_format_xml(self):
# get container contents list using format_xml param
@@ -250,7 +239,6 @@
self.assertEqual(object_list.find(".//last_modified").tag,
'last_modified')
- @test.attr(type='smoke')
@test.idempotent_id('297ec38b-2b61-4ff4-bcd1-7fa055e97b61')
def test_list_container_contents_with_limit(self):
# get container contents list using limit param
@@ -264,7 +252,6 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual(object_name, object_list.strip('\n'))
- @test.attr(type='smoke')
@test.idempotent_id('c31ddc63-2a58-4f6b-b25c-94d2937e6867')
def test_list_container_contents_with_marker(self):
# get container contents list using marker param
@@ -278,7 +265,6 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual(object_name, object_list.strip('\n'))
- @test.attr(type='smoke')
@test.idempotent_id('58ca6cc9-6af0-408d-aaec-2a6a7b2f0df9')
def test_list_container_contents_with_path(self):
# get container contents list using path param
@@ -293,7 +279,6 @@
self.assertHeaders(resp, 'Container', 'GET')
self.assertEqual(object_name, object_list.strip('\n'))
- @test.attr(type='smoke')
@test.idempotent_id('77e742c7-caf2-4ec9-8aa4-f7d509a3344c')
def test_list_container_contents_with_prefix(self):
# get container contents list using prefix param
@@ -325,7 +310,6 @@
self.assertIn('x-container-meta-name', resp)
self.assertEqual(resp['x-container-meta-name'], metadata['name'])
- @test.attr(type='smoke')
@test.idempotent_id('a2faf936-6b13-4f8d-92a2-c2278355821e')
def test_list_no_container_metadata(self):
# HEAD container without metadata
@@ -336,7 +320,6 @@
self.assertHeaders(resp, 'Container', 'HEAD')
self.assertNotIn('x-container-meta-', str(resp))
- @test.attr(type='smoke')
@test.idempotent_id('cf19bc0b-7e16-4a5a-aaed-cb0c2fe8deef')
def test_update_container_metadata_with_create_and_delete_matadata(self):
# Send one request of adding and deleting metadata
@@ -360,7 +343,6 @@
self.assertEqual(resp['x-container-meta-test-container-meta2'],
metadata_2['test-container-meta2'])
- @test.attr(type='smoke')
@test.idempotent_id('2ae5f295-4bf1-4e04-bfad-21e54b62cec5')
def test_update_container_metadata_with_create_metadata(self):
# update container metadata using add metadata
@@ -378,7 +360,6 @@
self.assertEqual(resp['x-container-meta-test-container-meta1'],
metadata['test-container-meta1'])
- @test.attr(type='smoke')
@test.idempotent_id('3a5ce7d4-6e4b-47d0-9d87-7cd42c325094')
def test_update_container_metadata_with_delete_metadata(self):
# update container metadata using delete metadata
@@ -397,7 +378,6 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta1', resp)
- @test.attr(type='smoke')
@test.idempotent_id('31f40a5f-6a52-4314-8794-cd89baed3040')
def test_update_container_metadata_with_create_matadata_key(self):
# update container metadata with a blenk value of metadata
@@ -413,7 +393,6 @@
container_name)
self.assertNotIn('x-container-meta-test-container-meta1', resp)
- @test.attr(type='smoke')
@test.idempotent_id('a2e36378-6f1f-43f4-840a-ffd9cfd61914')
def test_update_container_metadata_with_delete_metadata_key(self):
# update container metadata with a blank value of matadata
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 6a524ca..b02f178 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -88,6 +88,7 @@
for meta_key in not_in_meta:
self.assertNotIn('x-object-meta-' + meta_key, resp)
+ @test.attr(type='smoke')
@test.idempotent_id('5b4ce26f-3545-46c9-a2ba-5754358a4c62')
def test_create_object(self):
# create object
@@ -384,7 +385,6 @@
object_name)
self.assertNotIn('x-object-meta-test-meta1', resp)
- @test.attr(type='smoke')
@test.idempotent_id('f726174b-2ded-4708-bff7-729d12ce1f84')
def test_update_object_metadata_with_create_and_remove_metadata(self):
# creation and deletion of metadata with one request
@@ -412,7 +412,6 @@
self.assertIn('x-object-meta-test-meta2', resp)
self.assertEqual(resp['x-object-meta-test-meta2'], 'Meta2')
- @test.attr(type='smoke')
@test.idempotent_id('08854588-6449-4bb7-8cca-f2e1040f5e6f')
def test_update_object_metadata_with_x_object_manifest(self):
# update object metadata with x_object_manifest
@@ -459,7 +458,6 @@
self.assertIn('x-object-meta-test-meta', resp)
self.assertEqual(resp['x-object-meta-test-meta'], '')
- @test.attr(type='smoke')
@test.idempotent_id('9a88dca4-b684-425b-806f-306cd0e57e42')
def test_update_object_metadata_with_x_remove_object_metakey(self):
# update object metadata with a blank value of remove metadata
@@ -503,7 +501,6 @@
self.assertIn('x-object-meta-test-meta', resp)
self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
- @test.attr(type='smoke')
@test.idempotent_id('170fb90e-f5c3-4b1f-ae1b-a18810821172')
def test_list_no_object_metadata(self):
# get empty list of object metadata
@@ -515,7 +512,6 @@
self.assertHeaders(resp, 'Object', 'HEAD')
self.assertNotIn('x-object-meta-', str(resp))
- @test.attr(type='smoke')
@test.idempotent_id('23a3674c-d6de-46c3-86af-ff92bfc8a3da')
def test_list_object_metadata_with_x_object_manifest(self):
# get object metadata with x_object_manifest
@@ -570,7 +566,6 @@
self.assertEqual(body, data)
- @test.attr(type='smoke')
@test.idempotent_id('005f9bf6-e06d-41ec-968e-96c78e0b1d82')
def test_get_object_with_metadata(self):
# get object with metadata
@@ -590,7 +585,6 @@
self.assertEqual(resp['x-object-meta-test-meta'], 'Meta')
self.assertEqual(body, data)
- @test.attr(type='smoke')
@test.idempotent_id('05a1890e-7db9-4a6c-90a8-ce998a2bddfa')
def test_get_object_with_range(self):
# get object with range
@@ -609,7 +603,6 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data[rand_num - 3: rand_num])
- @test.attr(type='smoke')
@test.idempotent_id('11b4515b-7ba7-4ca8-8838-357ded86fc10')
def test_get_object_with_x_object_manifest(self):
# get object with x_object_manifest
@@ -653,7 +646,6 @@
self.assertEqual(''.join(data_segments), body)
- @test.attr(type='smoke')
@test.idempotent_id('c05b4013-e4de-47af-be84-e598062b16fc')
def test_get_object_with_if_match(self):
# get object with if_match
@@ -674,7 +666,6 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.attr(type='smoke')
@test.idempotent_id('be133639-e5d2-4313-9b1f-2d59fc054a16')
def test_get_object_with_if_modified_since(self):
# get object with if_modified_since
@@ -717,7 +708,6 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.attr(type='smoke')
@test.idempotent_id('0aa1201c-10aa-467a-bee7-63cbdd463152')
def test_get_object_with_if_unmodified_since(self):
# get object with if_unmodified_since
@@ -733,7 +723,6 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.attr(type='smoke')
@test.idempotent_id('94587078-475f-48f9-a40f-389c246e31cd')
def test_get_object_with_x_newest(self):
# get object with x_newest
@@ -747,7 +736,6 @@
self.assertHeaders(resp, 'Object', 'GET')
self.assertEqual(body, data)
- @test.attr(type='smoke')
@test.idempotent_id('1a9ab572-1b66-4981-8c21-416e2a5e6011')
def test_copy_object_in_same_container(self):
# create source object
@@ -774,7 +762,6 @@
dst_object_name)
self.assertEqual(body, src_data)
- @test.attr(type='smoke')
@test.idempotent_id('2248abba-415d-410b-9c30-22dff9cd6e67')
def test_copy_object_to_itself(self):
# change the content type of an existing object
@@ -796,7 +783,6 @@
object_name)
self.assertEqual(resp['content-type'], metadata['content-type'])
- @test.attr(type='smoke')
@test.idempotent_id('06f90388-2d0e-40aa-934c-e9a8833e958a')
def test_copy_object_2d_way(self):
# create source object
@@ -823,7 +809,6 @@
# check data
self._check_copied_obj(dst_object_name, src_data)
- @test.attr(type='smoke')
@test.idempotent_id('aa467252-44f3-472a-b5ae-5b57c3c9c147')
def test_copy_object_across_containers(self):
# create a container to use as asource container
@@ -864,7 +849,6 @@
self.assertIn(actual_meta_key, resp)
self.assertEqual(resp[actual_meta_key], meta_value)
- @test.attr(type='smoke')
@test.idempotent_id('5a9e2cc6-85b6-46fc-916d-0cbb7a88e5fd')
def test_copy_object_with_x_fresh_metadata(self):
# create source object
@@ -885,7 +869,6 @@
# check that destination object does NOT have any object-meta
self._check_copied_obj(dst_object_name, data, not_in_meta=["src"])
- @test.attr(type='smoke')
@test.idempotent_id('a28a8b99-e701-4d7e-9d84-3b66f121460b')
def test_copy_object_with_x_object_metakey(self):
# create source object
@@ -908,7 +891,6 @@
# check destination object
self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
- @test.attr(type='smoke')
@test.idempotent_id('edabedca-24c3-4322-9b70-d6d9f942a074')
def test_copy_object_with_x_object_meta(self):
# create source object
@@ -1027,7 +1009,6 @@
self.delete_containers([self.container_name])
super(PublicObjectTest, self).tearDown()
- @test.attr(type='smoke')
@test.idempotent_id('07c9cf95-c0d4-4b49-b9c8-0ef2c9b27193')
def test_access_public_container_object_without_using_creds(self):
# make container public-readable and access an object in it object
@@ -1066,7 +1047,6 @@
self.assertEqual(body, data)
- @test.attr(type='smoke')
@test.idempotent_id('54e2a2fe-42dc-491b-8270-8e4217dd4cdc')
def test_access_public_object_with_another_user_creds(self):
# make container public-readable and access an object in it using
diff --git a/tempest/api/object_storage/test_object_version.py b/tempest/api/object_storage/test_object_version.py
index cd2d3c3..923166a 100644
--- a/tempest/api/object_storage/test_object_version.py
+++ b/tempest/api/object_storage/test_object_version.py
@@ -45,7 +45,6 @@
header_value = resp.get('x-versions-location', 'Missing Header')
self.assertEqual(header_value, versioned)
- @test.attr(type='smoke')
@test.idempotent_id('a151e158-dcbf-4a1f-a1e7-46cd65895a6f')
@testtools.skipIf(
not CONF.object_storage_feature_enabled.object_versioning,
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 787d58e..b8047b2 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -100,14 +100,12 @@
super(VolumeMultiBackendV2Test, cls).resource_cleanup()
- @test.attr(type='smoke')
@test.idempotent_id('c1a41f3f-9dad-493e-9f09-3ff197d477cc')
def test_backend_name_reporting(self):
# get volume id which created by type without prefix
volume_id = self.volume_id_list_without_prefix[0]
self._test_backend_name_reporting_by_volume_id(volume_id)
- @test.attr(type='smoke')
@test.idempotent_id('f38e647f-ab42-4a31-a2e7-ca86a6485215')
def test_backend_name_reporting_with_prefix(self):
# get volume id which created by type with prefix
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 814b46d..24c7c63 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import six
from tempest_lib.common.utils import data_utils
from tempest.api.volume import base
@@ -57,7 +58,7 @@
**new_quota_set)
cleanup_quota_set = dict(
- (k, v) for k, v in default_quota_set.iteritems()
+ (k, v) for k, v in six.iteritems(default_quota_set)
if k in QUOTA_KEYS)
self.addCleanup(self.quotas_client.update_quota_set,
self.demo_tenant_id, **cleanup_quota_set)
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 048b02c..ea9864e 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -31,14 +31,12 @@
def _delete_volume_type(self, volume_type_id):
self.volume_types_client.delete_volume_type(volume_type_id)
- @test.attr(type='smoke')
@test.idempotent_id('9d9b28e3-1b2e-4483-a2cc-24aa0ea1de54')
def test_volume_type_list(self):
# List Volume types.
body = self.volume_types_client.list_volume_types()
self.assertIsInstance(body, list)
- @test.attr(type='smoke')
@test.idempotent_id('c03cc62c-f4e9-4623-91ec-64ce2f9c1260')
def test_volume_crud_with_volume_type_and_extra_specs(self):
# Create/update/get/delete volume with volume_type and extra spec.
@@ -89,7 +87,6 @@
'The fetched Volume is different '
'from the created Volume')
- @test.attr(type='smoke')
@test.idempotent_id('4e955c3b-49db-4515-9590-0c99f8e471ad')
def test_volume_type_create_get_delete(self):
# Create/get volume type.
@@ -122,7 +119,6 @@
'The fetched Volume_type is different '
'from the created Volume_type')
- @test.attr(type='smoke')
@test.idempotent_id('7830abd0-ff99-4793-a265-405684a54d46')
def test_volume_type_encryption_create_get_delete(self):
# Create/get/delete encryption type.
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 1cbba58..2feb062 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -33,7 +33,6 @@
cls.volume_types_client.delete_volume_type(cls.volume_type['id'])
super(VolumeTypesExtraSpecsV2Test, cls).resource_cleanup()
- @test.attr(type='smoke')
@test.idempotent_id('b42923e9-0452-4945-be5b-d362ae533e60')
def test_volume_type_extra_specs_list(self):
# List Volume types extra specs.
@@ -65,7 +64,6 @@
self.assertEqual(extra_spec['spec2'], body['spec2'],
"Volume type extra spec incorrectly updated")
- @test.attr(type='smoke')
@test.idempotent_id('d4772798-601f-408a-b2a5-29e8a59d1220')
def test_volume_type_extra_spec_create_get_delete(self):
# Create/Get/Delete volume type extra spec.
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index 2d830c8..8b85da3 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -38,7 +38,6 @@
cls.volume = cls.create_volume()
- @test.attr(type='smoke')
@test.idempotent_id('a66eb488-8ee1-47d4-8e9f-575a095728c6')
def test_volume_backup_create_get_detailed_list_restore_delete(self):
# Create backup
diff --git a/tempest/api/volume/test_qos.py b/tempest/api/volume/test_qos.py
index edece79..863a698 100644
--- a/tempest/api/volume/test_qos.py
+++ b/tempest/api/volume/test_qos.py
@@ -89,7 +89,6 @@
"""
self._create_delete_test_qos_with_given_consumer('back-end')
- @test.attr(type='smoke')
@test.idempotent_id('f88d65eb-ea0d-487d-af8d-71f4011575a4')
def test_create_delete_qos_with_both_consumer(self):
"""Tests the creation and deletion of QoS specs
@@ -98,7 +97,6 @@
"""
self._create_delete_test_qos_with_given_consumer('both')
- @test.attr(type='smoke')
@test.idempotent_id('7aa214cc-ac1a-4397-931f-3bb2e83bb0fd')
def test_get_qos(self):
"""Tests the detail of a given qos-specs"""
@@ -106,14 +104,12 @@
self.assertEqual(self.qos_name, body['name'])
self.assertEqual(self.qos_consumer, body['consumer'])
- @test.attr(type='smoke')
@test.idempotent_id('75e04226-bcf7-4595-a34b-fdf0736f38fc')
def test_list_qos(self):
"""Tests the list of all qos-specs"""
body = self.volume_qos_client.list_qos()
self.assertIn(self.created_qos, body)
- @test.attr(type='smoke')
@test.idempotent_id('ed00fd85-4494-45f2-8ceb-9e2048919aed')
def test_set_unset_qos_key(self):
"""Test the addition of a specs key to qos-specs"""
@@ -133,7 +129,6 @@
body = self.volume_qos_client.show_qos(self.created_qos['id'])
self.assertNotIn(keys[0], body['specs'])
- @test.attr(type='smoke')
@test.idempotent_id('1dd93c76-6420-485d-a771-874044c416ac')
def test_associate_disassociate_qos(self):
"""Test the following operations :
diff --git a/tempest/auth.py b/tempest/auth.py
deleted file mode 100644
index 113ad69..0000000
--- a/tempest/auth.py
+++ /dev/null
@@ -1,659 +0,0 @@
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-# 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 abc
-import copy
-import datetime
-import exceptions
-import re
-import urlparse
-
-from oslo_log import log as logging
-import six
-
-from tempest.services.identity.v2.json import token_client as json_v2id
-from tempest.services.identity.v3.json import token_client as json_v3id
-
-
-LOG = logging.getLogger(__name__)
-
-
-@six.add_metaclass(abc.ABCMeta)
-class AuthProvider(object):
- """
- Provide authentication
- """
-
- def __init__(self, credentials):
- """
- :param credentials: credentials for authentication
- """
- if self.check_credentials(credentials):
- self.credentials = credentials
- else:
- raise TypeError("Invalid credentials")
- self.cache = None
- self.alt_auth_data = None
- self.alt_part = None
-
- def __str__(self):
- return "Creds :{creds}, cached auth data: {cache}".format(
- creds=self.credentials, cache=self.cache)
-
- @abc.abstractmethod
- def _decorate_request(self, filters, method, url, headers=None, body=None,
- auth_data=None):
- """
- Decorate request with authentication data
- """
- return
-
- @abc.abstractmethod
- def _get_auth(self):
- return
-
- @abc.abstractmethod
- def _fill_credentials(self, auth_data_body):
- return
-
- def fill_credentials(self):
- """
- Fill credentials object with data from auth
- """
- auth_data = self.get_auth()
- self._fill_credentials(auth_data[1])
- return self.credentials
-
- @classmethod
- def check_credentials(cls, credentials):
- """
- Verify credentials are valid.
- """
- return isinstance(credentials, Credentials) and credentials.is_valid()
-
- @property
- def auth_data(self):
- return self.get_auth()
-
- @auth_data.deleter
- def auth_data(self):
- self.clear_auth()
-
- def get_auth(self):
- """
- Returns auth from cache if available, else auth first
- """
- if self.cache is None or self.is_expired(self.cache):
- self.set_auth()
- return self.cache
-
- def set_auth(self):
- """
- Forces setting auth, ignores cache if it exists.
- Refills credentials
- """
- self.cache = self._get_auth()
- self._fill_credentials(self.cache[1])
-
- def clear_auth(self):
- """
- Can be called to clear the access cache so that next request
- will fetch a new token and base_url.
- """
- self.cache = None
- self.credentials.reset()
-
- @abc.abstractmethod
- def is_expired(self, auth_data):
- return
-
- def auth_request(self, method, url, headers=None, body=None, filters=None):
- """
- Obtains auth data and decorates a request with that.
- :param method: HTTP method of the request
- :param url: relative URL of the request (path)
- :param headers: HTTP headers of the request
- :param body: HTTP body in case of POST / PUT
- :param filters: select a base URL out of the catalog
- :returns a Tuple (url, headers, body)
- """
- orig_req = dict(url=url, headers=headers, body=body)
-
- auth_url, auth_headers, auth_body = self._decorate_request(
- filters, method, url, headers, body)
- auth_req = dict(url=auth_url, headers=auth_headers, body=auth_body)
-
- # Overwrite part if the request if it has been requested
- if self.alt_part is not None:
- if self.alt_auth_data is not None:
- alt_url, alt_headers, alt_body = self._decorate_request(
- filters, method, url, headers, body,
- auth_data=self.alt_auth_data)
- alt_auth_req = dict(url=alt_url, headers=alt_headers,
- body=alt_body)
- auth_req[self.alt_part] = alt_auth_req[self.alt_part]
-
- else:
- # If alt auth data is None, skip auth in the requested part
- auth_req[self.alt_part] = orig_req[self.alt_part]
-
- # Next auth request will be normal, unless otherwise requested
- self.reset_alt_auth_data()
-
- return auth_req['url'], auth_req['headers'], auth_req['body']
-
- def reset_alt_auth_data(self):
- """
- Configure auth provider to provide valid authentication data
- """
- self.alt_part = None
- self.alt_auth_data = None
-
- def set_alt_auth_data(self, request_part, auth_data):
- """
- Configure auth provider to provide alt authentication data
- on a part of the *next* auth_request. If credentials are None,
- set invalid data.
- :param request_part: request part to contain invalid auth: url,
- headers, body
- :param auth_data: alternative auth_data from which to get the
- invalid data to be injected
- """
- self.alt_part = request_part
- self.alt_auth_data = auth_data
-
- @abc.abstractmethod
- def base_url(self, filters, auth_data=None):
- """
- Extracts the base_url based on provided filters
- """
- return
-
-
-class KeystoneAuthProvider(AuthProvider):
-
- token_expiry_threshold = datetime.timedelta(seconds=60)
-
- def __init__(self, credentials, auth_url,
- disable_ssl_certificate_validation=None,
- ca_certs=None, trace_requests=None):
- super(KeystoneAuthProvider, self).__init__(credentials)
- self.dsvm = disable_ssl_certificate_validation
- self.ca_certs = ca_certs
- self.trace_requests = trace_requests
- self.auth_client = self._auth_client(auth_url)
-
- def _decorate_request(self, filters, method, url, headers=None, body=None,
- auth_data=None):
- if auth_data is None:
- auth_data = self.auth_data
- token, _ = auth_data
- base_url = self.base_url(filters=filters, auth_data=auth_data)
- # build authenticated request
- # returns new request, it does not touch the original values
- _headers = copy.deepcopy(headers) if headers is not None else {}
- _headers['X-Auth-Token'] = str(token)
- if url is None or url == "":
- _url = base_url
- else:
- # Join base URL and url, and remove multiple contiguous slashes
- _url = "/".join([base_url, url])
- parts = [x for x in urlparse.urlparse(_url)]
- parts[2] = re.sub("/{2,}", "/", parts[2])
- _url = urlparse.urlunparse(parts)
- # no change to method or body
- return str(_url), _headers, body
-
- @abc.abstractmethod
- def _auth_client(self):
- return
-
- @abc.abstractmethod
- def _auth_params(self):
- return
-
- def _get_auth(self):
- # Bypasses the cache
- auth_func = getattr(self.auth_client, 'get_token')
- auth_params = self._auth_params()
-
- # returns token, auth_data
- token, auth_data = auth_func(**auth_params)
- return token, auth_data
-
- def get_token(self):
- return self.auth_data[0]
-
-
-class KeystoneV2AuthProvider(KeystoneAuthProvider):
-
- EXPIRY_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
-
- def _auth_client(self, auth_url):
- return json_v2id.TokenClientJSON(
- auth_url, disable_ssl_certificate_validation=self.dsvm,
- ca_certs=self.ca_certs, trace_requests=self.trace_requests)
-
- def _auth_params(self):
- return dict(
- user=self.credentials.username,
- password=self.credentials.password,
- tenant=self.credentials.tenant_name,
- auth_data=True)
-
- def _fill_credentials(self, auth_data_body):
- tenant = auth_data_body['token']['tenant']
- user = auth_data_body['user']
- if self.credentials.tenant_name is None:
- self.credentials.tenant_name = tenant['name']
- if self.credentials.tenant_id is None:
- self.credentials.tenant_id = tenant['id']
- if self.credentials.username is None:
- self.credentials.username = user['name']
- if self.credentials.user_id is None:
- self.credentials.user_id = user['id']
-
- def base_url(self, filters, auth_data=None):
- """
- Filters can be:
- - service: compute, image, etc
- - region: the service region
- - endpoint_type: adminURL, publicURL, internalURL
- - api_version: replace catalog version with this
- - skip_path: take just the base URL
- """
- if auth_data is None:
- auth_data = self.auth_data
- token, _auth_data = auth_data
- service = filters.get('service')
- region = filters.get('region')
- endpoint_type = filters.get('endpoint_type', 'publicURL')
-
- if service is None:
- raise exceptions.EndpointNotFound("No service provided")
-
- _base_url = None
- for ep in _auth_data['serviceCatalog']:
- if ep["type"] == service:
- for _ep in ep['endpoints']:
- if region is not None and _ep['region'] == region:
- _base_url = _ep.get(endpoint_type)
- if not _base_url:
- # No region matching, use the first
- _base_url = ep['endpoints'][0].get(endpoint_type)
- break
- if _base_url is None:
- raise exceptions.EndpointNotFound(service)
-
- parts = urlparse.urlparse(_base_url)
- if filters.get('api_version', None) is not None:
- path = "/" + filters['api_version']
- noversion_path = "/".join(parts.path.split("/")[2:])
- if noversion_path != "":
- path += "/" + noversion_path
- _base_url = _base_url.replace(parts.path, path)
- if filters.get('skip_path', None) is not None and parts.path != '':
- _base_url = _base_url.replace(parts.path, "/")
-
- return _base_url
-
- def is_expired(self, auth_data):
- _, access = auth_data
- expiry = datetime.datetime.strptime(access['token']['expires'],
- self.EXPIRY_DATE_FORMAT)
- return expiry - self.token_expiry_threshold <= \
- datetime.datetime.utcnow()
-
-
-class KeystoneV3AuthProvider(KeystoneAuthProvider):
-
- EXPIRY_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
-
- def _auth_client(self, auth_url):
- return json_v3id.V3TokenClientJSON(
- auth_url, disable_ssl_certificate_validation=self.dsvm,
- ca_certs=self.ca_certs, trace_requests=self.trace_requests)
-
- def _auth_params(self):
- return dict(
- user_id=self.credentials.user_id,
- username=self.credentials.username,
- password=self.credentials.password,
- project_id=self.credentials.project_id,
- project_name=self.credentials.project_name,
- user_domain_id=self.credentials.user_domain_id,
- user_domain_name=self.credentials.user_domain_name,
- project_domain_id=self.credentials.project_domain_id,
- project_domain_name=self.credentials.project_domain_name,
- domain_id=self.credentials.domain_id,
- domain_name=self.credentials.domain_name,
- auth_data=True)
-
- def _fill_credentials(self, auth_data_body):
- # project or domain, depending on the scope
- project = auth_data_body.get('project', None)
- domain = auth_data_body.get('domain', None)
- # user is always there
- user = auth_data_body['user']
- # Set project fields
- if project is not None:
- if self.credentials.project_name is None:
- self.credentials.project_name = project['name']
- if self.credentials.project_id is None:
- self.credentials.project_id = project['id']
- if self.credentials.project_domain_id is None:
- self.credentials.project_domain_id = project['domain']['id']
- if self.credentials.project_domain_name is None:
- self.credentials.project_domain_name = \
- project['domain']['name']
- # Set domain fields
- if domain is not None:
- if self.credentials.domain_id is None:
- self.credentials.domain_id = domain['id']
- if self.credentials.domain_name is None:
- self.credentials.domain_name = domain['name']
- # Set user fields
- if self.credentials.username is None:
- self.credentials.username = user['name']
- if self.credentials.user_id is None:
- self.credentials.user_id = user['id']
- if self.credentials.user_domain_id is None:
- self.credentials.user_domain_id = user['domain']['id']
- if self.credentials.user_domain_name is None:
- self.credentials.user_domain_name = user['domain']['name']
-
- def base_url(self, filters, auth_data=None):
- """
- Filters can be:
- - service: compute, image, etc
- - region: the service region
- - endpoint_type: adminURL, publicURL, internalURL
- - api_version: replace catalog version with this
- - skip_path: take just the base URL
- """
- if auth_data is None:
- auth_data = self.auth_data
- token, _auth_data = auth_data
- service = filters.get('service')
- region = filters.get('region')
- endpoint_type = filters.get('endpoint_type', 'public')
-
- if service is None:
- raise exceptions.EndpointNotFound("No service provided")
-
- if 'URL' in endpoint_type:
- endpoint_type = endpoint_type.replace('URL', '')
- _base_url = None
- catalog = _auth_data['catalog']
- # Select entries with matching service type
- service_catalog = [ep for ep in catalog if ep['type'] == service]
- if len(service_catalog) > 0:
- service_catalog = service_catalog[0]['endpoints']
- else:
- # No matching service
- raise exceptions.EndpointNotFound(service)
- # Filter by endpoint type (interface)
- filtered_catalog = [ep for ep in service_catalog if
- ep['interface'] == endpoint_type]
- if len(filtered_catalog) == 0:
- # No matching type, keep all and try matching by region at least
- filtered_catalog = service_catalog
- # Filter by region
- filtered_catalog = [ep for ep in filtered_catalog if
- ep['region'] == region]
- if len(filtered_catalog) == 0:
- # No matching region, take the first endpoint
- filtered_catalog = [service_catalog[0]]
- # There should be only one match. If not take the first.
- _base_url = filtered_catalog[0].get('url', None)
- if _base_url is None:
- raise exceptions.EndpointNotFound(service)
-
- parts = urlparse.urlparse(_base_url)
- if filters.get('api_version', None) is not None:
- path = "/" + filters['api_version']
- noversion_path = "/".join(parts.path.split("/")[2:])
- if noversion_path != "":
- path += "/" + noversion_path
- _base_url = _base_url.replace(parts.path, path)
- if filters.get('skip_path', None) is not None:
- _base_url = _base_url.replace(parts.path, "/")
-
- return _base_url
-
- def is_expired(self, auth_data):
- _, access = auth_data
- expiry = datetime.datetime.strptime(access['expires_at'],
- self.EXPIRY_DATE_FORMAT)
- return expiry - self.token_expiry_threshold <= \
- datetime.datetime.utcnow()
-
-
-def is_identity_version_supported(identity_version):
- return identity_version in IDENTITY_VERSION
-
-
-def get_credentials(auth_url, fill_in=True, identity_version='v2',
- disable_ssl_certificate_validation=None, ca_certs=None,
- trace_requests=None, **kwargs):
- """
- Builds a credentials object based on the configured auth_version
-
- :param auth_url (string): Full URI of the OpenStack Identity API(Keystone)
- which is used to fetch the token from Identity service.
- :param fill_in (boolean): obtain a token and fill in all credential
- details provided by the identity service. When fill_in is not
- specified, credentials are not validated. Validation can be invoked
- by invoking ``is_valid()``
- :param identity_version (string): identity API version is used to
- select the matching auth provider and credentials class
- :param disable_ssl_certificate_validation: whether to enforce SSL
- certificate validation in SSL API requests to the auth system
- :param ca_certs: CA certificate bundle for validation of certificates
- in SSL API requests to the auth system
- :param trace_requests: trace in log API requests to the auth system
- :param kwargs (dict): Dict of credential key/value pairs
-
- Examples:
-
- Returns credentials from the provided parameters:
- >>> get_credentials(username='foo', password='bar')
-
- Returns credentials including IDs:
- >>> get_credentials(username='foo', password='bar', fill_in=True)
- """
- if not is_identity_version_supported(identity_version):
- raise exceptions.InvalidIdentityVersion(
- identity_version=identity_version)
-
- credential_class, auth_provider_class = IDENTITY_VERSION.get(
- identity_version)
-
- creds = credential_class(**kwargs)
- # Fill in the credentials fields that were not specified
- if fill_in:
- dsvm = disable_ssl_certificate_validation
- auth_provider = auth_provider_class(
- creds, auth_url, disable_ssl_certificate_validation=dsvm,
- ca_certs=ca_certs, trace_requests=trace_requests)
- creds = auth_provider.fill_credentials()
- return creds
-
-
-class Credentials(object):
- """
- Set of credentials for accessing OpenStack services
-
- ATTRIBUTES: list of valid class attributes representing credentials.
- """
-
- ATTRIBUTES = []
-
- def __init__(self, **kwargs):
- """
- Enforce the available attributes at init time (only).
- Additional attributes can still be set afterwards if tests need
- to do so.
- """
- self._initial = kwargs
- self._apply_credentials(kwargs)
-
- def _apply_credentials(self, attr):
- for key in attr.keys():
- if key in self.ATTRIBUTES:
- setattr(self, key, attr[key])
- else:
- raise exceptions.InvalidCredentials
-
- def __str__(self):
- """
- Represent only attributes included in self.ATTRIBUTES
- """
- _repr = dict((k, getattr(self, k)) for k in self.ATTRIBUTES)
- return str(_repr)
-
- def __eq__(self, other):
- """
- Credentials are equal if attributes in self.ATTRIBUTES are equal
- """
- return str(self) == str(other)
-
- def __getattr__(self, key):
- # If an attribute is set, __getattr__ is not invoked
- # If an attribute is not set, and it is a known one, return None
- if key in self.ATTRIBUTES:
- return None
- else:
- raise AttributeError
-
- def __delitem__(self, key):
- # For backwards compatibility, support dict behaviour
- if key in self.ATTRIBUTES:
- delattr(self, key)
- else:
- raise AttributeError
-
- def get(self, item, default):
- # In this patch act as dict for backward compatibility
- try:
- return getattr(self, item)
- except AttributeError:
- return default
-
- def get_init_attributes(self):
- return self._initial.keys()
-
- def is_valid(self):
- raise NotImplementedError
-
- def reset(self):
- # First delete all known attributes
- for key in self.ATTRIBUTES:
- if getattr(self, key) is not None:
- delattr(self, key)
- # Then re-apply initial setup
- self._apply_credentials(self._initial)
-
-
-class KeystoneV2Credentials(Credentials):
-
- ATTRIBUTES = ['username', 'password', 'tenant_name', 'user_id',
- 'tenant_id']
-
- def is_valid(self):
- """
- Minimum set of valid credentials, are username and password.
- Tenant is optional.
- """
- return None not in (self.username, self.password)
-
-
-class KeystoneV3Credentials(Credentials):
- """
- Credentials suitable for the Keystone Identity V3 API
- """
-
- ATTRIBUTES = ['domain_id', 'domain_name', 'password', 'username',
- 'project_domain_id', 'project_domain_name', 'project_id',
- 'project_name', 'tenant_id', 'tenant_name', 'user_domain_id',
- 'user_domain_name', 'user_id']
-
- def __setattr__(self, key, value):
- parent = super(KeystoneV3Credentials, self)
- # for tenant_* set both project and tenant
- if key == 'tenant_id':
- parent.__setattr__('project_id', value)
- elif key == 'tenant_name':
- parent.__setattr__('project_name', value)
- # for project_* set both project and tenant
- if key == 'project_id':
- parent.__setattr__('tenant_id', value)
- elif key == 'project_name':
- parent.__setattr__('tenant_name', value)
- # for *_domain_* set both user and project if not set yet
- if key == 'user_domain_id':
- if self.project_domain_id is None:
- parent.__setattr__('project_domain_id', value)
- if key == 'project_domain_id':
- if self.user_domain_id is None:
- parent.__setattr__('user_domain_id', value)
- if key == 'user_domain_name':
- if self.project_domain_name is None:
- parent.__setattr__('project_domain_name', value)
- if key == 'project_domain_name':
- if self.user_domain_name is None:
- parent.__setattr__('user_domain_name', value)
- # support domain_name coming from config
- if key == 'domain_name':
- parent.__setattr__('user_domain_name', value)
- parent.__setattr__('project_domain_name', value)
- # finally trigger default behaviour for all attributes
- parent.__setattr__(key, value)
-
- def is_valid(self):
- """
- Valid combinations of v3 credentials (excluding token, scope)
- - User id, password (optional domain)
- - User name, password and its domain id/name
- For the scope, valid combinations are:
- - None
- - Project id (optional domain)
- - Project name and its domain id/name
- - Domain id
- - Domain name
- """
- valid_user_domain = any(
- [self.user_domain_id is not None,
- self.user_domain_name is not None])
- valid_project_domain = any(
- [self.project_domain_id is not None,
- self.project_domain_name is not None])
- valid_user = any(
- [self.user_id is not None,
- self.username is not None and valid_user_domain])
- valid_project_scope = any(
- [self.project_name is None and self.project_id is None,
- self.project_id is not None,
- self.project_name is not None and valid_project_domain])
- valid_domain_scope = any(
- [self.domain_id is None and self.domain_name is None,
- self.domain_id or self.domain_name])
- return all([self.password is not None,
- valid_user,
- valid_project_scope and valid_domain_scope])
-
-
-IDENTITY_VERSION = {'v2': (KeystoneV2Credentials, KeystoneV2AuthProvider),
- 'v3': (KeystoneV3Credentials, KeystoneV3AuthProvider)}
diff --git a/tempest/cli/README.rst b/tempest/cli/README.rst
deleted file mode 100644
index bc18084..0000000
--- a/tempest/cli/README.rst
+++ /dev/null
@@ -1,50 +0,0 @@
-.. _cli_field_guide:
-
-Tempest Field Guide to CLI tests
-================================
-
-
-What are these tests?
----------------------
-The cli tests test the various OpenStack command line interface tools
-to ensure that they minimally function. The current scope is read only
-operations on a cloud that are hard to test via unit tests.
-
-
-Why are these tests in tempest?
--------------------------------
-These tests exist here because it is extremely difficult to build a
-functional enough environment in the python-\*client unit tests to
-provide this kind of testing. Because we already put up a cloud in the
-gate with devstack + tempest it was decided it was better to have
-these as a side tree in tempest instead of another QA effort which
-would split review time.
-
-
-Scope of these tests
---------------------
-This should stay limited to the scope of testing the cli. Functional
-testing of the cloud should be elsewhere, this is about exercising the
-cli code.
-
-
-Example of a good test
-----------------------
-Tests should be isolated to a single command in one of the python
-clients.
-
-Tests should not modify the cloud.
-
-If a test is validating the cli for bad data, it should do it with
-assertRaises.
-
-A reasonable example of an existing test is as follows::
-
- def test_admin_list(self):
- self.nova('list')
- self.nova('list', params='--all-tenants 1')
- self.nova('list', params='--all-tenants 0')
- self.assertRaises(subprocess.CalledProcessError,
- self.nova,
- 'list',
- params='--all-tenants bad')
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
deleted file mode 100644
index 6733204..0000000
--- a/tempest/cli/__init__.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import functools
-
-from tempest_lib.cli import base
-from tempest_lib.cli import output_parser
-import testtools
-
-from tempest.common import credentials
-from tempest import config
-from tempest import exceptions
-from tempest.openstack.common import versionutils
-from tempest import test
-
-
-CONF = config.CONF
-
-
-def check_client_version(client, version):
- """Checks if the client's version is compatible with the given version
-
- @param client: The client to check.
- @param version: The version to compare against.
- @return: True if the client version is compatible with the given version
- parameter, False otherwise.
- """
- current_version = base.execute(client, '', params='--version',
- merge_stderr=True, cli_dir=CONF.cli.cli_dir)
-
- if not current_version.strip():
- raise exceptions.TempestException('"%s --version" output was empty' %
- client)
-
- return versionutils.is_compatible(version, current_version,
- same_major=False)
-
-
-def min_client_version(*args, **kwargs):
- """A decorator to skip tests if the client used isn't of the right version.
-
- @param client: The client command to run. For python-novaclient, this is
- 'nova', for python-cinderclient this is 'cinder', etc.
- @param version: The minimum version required to run the CLI test.
- """
- def decorator(func):
- @functools.wraps(func)
- def wrapper(*func_args, **func_kwargs):
- if not check_client_version(kwargs['client'], kwargs['version']):
- msg = "requires %s client version >= %s" % (kwargs['client'],
- kwargs['version'])
- raise testtools.TestCase.skipException(msg)
- return func(*func_args, **func_kwargs)
- return wrapper
- return decorator
-
-
-class ClientTestBase(test.BaseTestCase):
-
- @classmethod
- def skip_checks(cls):
- super(ClientTestBase, cls).skip_checks()
- if not CONF.identity_feature_enabled.api_v2:
- raise cls.skipException("CLI clients rely on identity v2 API, "
- "which is configured as not available")
-
- @classmethod
- def resource_setup(cls):
- if not CONF.cli.enabled:
- msg = "cli testing disabled"
- raise cls.skipException(msg)
- super(ClientTestBase, cls).resource_setup()
- cls.isolated_creds = credentials.get_isolated_credentials(cls.__name__)
- cls.creds = cls.isolated_creds.get_admin_creds()
-
- def _get_clients(self):
- clients = base.CLIClient(self.creds.username,
- self.creds.password,
- self.creds.tenant_name,
- CONF.identity.uri, CONF.cli.cli_dir)
- return clients
-
- # TODO(mtreinish): The following code is basically copied from tempest-lib.
- # The base cli test class in tempest-lib 0.0.1 doesn't work as a mixin like
- # is needed here. The code below should be removed when tempest-lib
- # provides a way to provide this functionality
- def setUp(self):
- super(ClientTestBase, self).setUp()
- self.clients = self._get_clients()
- self.parser = output_parser
-
- def assertTableStruct(self, items, field_names):
- """Verify that all items has keys listed in field_names.
-
- :param items: items to assert are field names in the output table
- :type items: list
- :param field_names: field names from the output table of the cmd
- :type field_names: list
- """
- for item in items:
- for field in field_names:
- self.assertIn(field, item)
-
- def assertFirstLineStartsWith(self, lines, beginning):
- """Verify that the first line starts with a string
-
- :param lines: strings for each line of output
- :type lines: list
- :param beginning: verify this is at the beginning of the first line
- :type beginning: string
- """
- self.assertTrue(lines[0].startswith(beginning),
- msg=('Beginning of first line has invalid content: %s'
- % lines[:3]))
diff --git a/tempest/cli/simple_read_only/README.txt b/tempest/cli/simple_read_only/README.txt
deleted file mode 100644
index ca5fa2f..0000000
--- a/tempest/cli/simple_read_only/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-This directory consists of simple read only python client tests.
diff --git a/tempest/cli/simple_read_only/__init__.py b/tempest/cli/simple_read_only/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/heat_templates/heat_minimal.yaml b/tempest/cli/simple_read_only/heat_templates/heat_minimal.yaml
deleted file mode 100644
index 7dcda39..0000000
--- a/tempest/cli/simple_read_only/heat_templates/heat_minimal.yaml
+++ /dev/null
@@ -1,18 +0,0 @@
-HeatTemplateFormatVersion: '2012-12-12'
-Description: Minimal template to test validation
-Parameters:
- InstanceImage:
- Description: Glance image name
- Type: String
- InstanceType:
- Description: Nova instance type
- Type: String
- Default: m1.small
- AllowedValues: [m1.tiny, m1.small, m1.medium, m1.large, m1.nano, m1.xlarge, m1.micro]
- ConstraintDescription: must be a valid nova instance type.
-Resources:
- InstanceResource:
- Type: OS::Nova::Server
- Properties:
- flavor: {Ref: InstanceType}
- image: {Ref: InstanceImage}
diff --git a/tempest/cli/simple_read_only/heat_templates/heat_minimal_hot.yaml b/tempest/cli/simple_read_only/heat_templates/heat_minimal_hot.yaml
deleted file mode 100644
index 4657bfc..0000000
--- a/tempest/cli/simple_read_only/heat_templates/heat_minimal_hot.yaml
+++ /dev/null
@@ -1,19 +0,0 @@
-heat_template_version: 2013-05-23
-description: A minimal HOT test template
-parameters:
- instance_image:
- description: Glance image name
- type: string
- instance_type:
- description: Nova instance type
- type: string
- default: m1.small
- constraints:
- - allowed_values: [m1.small, m1.medium, m1.large]
- description: instance_type must be one of m1.small, m1.medium or m1.large
-resources:
- instance:
- type: OS::Nova::Server
- properties:
- image: { get_param: instance_image }
- flavor: { get_param: instance_type }
diff --git a/tempest/cli/simple_read_only/image/__init__.py b/tempest/cli/simple_read_only/image/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/image/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/image/test_glance.py b/tempest/cli/simple_read_only/image/test_glance.py
deleted file mode 100644
index e38ca48..0000000
--- a/tempest/cli/simple_read_only/image/test_glance.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import re
-
-from oslo_log import log as logging
-from tempest_lib import exceptions
-
-from tempest import cli
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyGlanceClientTest(cli.ClientTestBase):
- """Basic, read-only tests for Glance CLI client.
-
- Checks return values and output of read-only commands.
- These tests do not presume any content, nor do they create
- their own. They only verify the structure of output if present.
- """
-
- @classmethod
- def resource_setup(cls):
- if not CONF.service_available.glance:
- msg = ("%s skipped as Glance is not available" % cls.__name__)
- raise cls.skipException(msg)
- super(SimpleReadOnlyGlanceClientTest, cls).resource_setup()
-
- def glance(self, *args, **kwargs):
- return self.clients.glance(*args,
- endpoint_type=CONF.image.endpoint_type,
- **kwargs)
-
- @test.idempotent_id('c6bd9bf9-717f-4458-8d74-05b682ea7adf')
- def test_glance_fake_action(self):
- self.assertRaises(exceptions.CommandFailed,
- self.glance,
- 'this-does-not-exist')
-
- @test.idempotent_id('72bcdaf3-11cd-48cb-bb8e-62b329acc1ef')
- def test_glance_image_list(self):
- out = self.glance('image-list')
- endpoints = self.parser.listing(out)
- self.assertTableStruct(endpoints, [
- 'ID', 'Name', 'Disk Format', 'Container Format',
- 'Size', 'Status'])
-
- @test.idempotent_id('965d294c-8772-4899-ba33-26ee23406135')
- def test_glance_member_list(self):
- tenant_name = '--tenant-id %s' % CONF.identity.admin_tenant_name
- out = self.glance('member-list',
- params=tenant_name)
- endpoints = self.parser.listing(out)
- self.assertTableStruct(endpoints,
- ['Image ID', 'Member ID', 'Can Share'])
-
- @test.idempotent_id('43b80ee5-4297-47f3-ab4c-6f81b9c6edb3')
- def test_glance_help(self):
- help_text = self.glance('help')
- lines = help_text.split('\n')
- self.assertFirstLineStartsWith(lines, 'usage: glance')
-
- commands = []
- cmds_start = lines.index('Positional arguments:')
- cmds_end = lines.index('Optional arguments:')
- command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
- for line in lines[cmds_start:cmds_end]:
- match = command_pattern.match(line)
- if match:
- commands.append(match.group(1))
- commands = set(commands)
- wanted_commands = set(('image-create', 'image-delete', 'help',
- 'image-download', 'image-show', 'image-update',
- 'member-create', 'member-delete',
- 'member-list', 'image-list'))
- self.assertFalse(wanted_commands - commands)
-
- # Optional arguments:
-
- @test.idempotent_id('3b2359ea-3719-4b47-81e5-44a042572b11')
- def test_glance_version(self):
- self.glance('', flags='--version')
-
- @test.idempotent_id('1a52d3bd-3edf-4d67-b3da-999a5d9e0c5e')
- def test_glance_debug_list(self):
- self.glance('image-list', flags='--debug')
-
- @test.idempotent_id('6f42b076-f9a7-4e2b-a729-579f53e7814e')
- def test_glance_timeout(self):
- self.glance('image-list', flags='--timeout %d' % CONF.cli.timeout)
diff --git a/tempest/cli/simple_read_only/orchestration/__init__.py b/tempest/cli/simple_read_only/orchestration/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/orchestration/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/orchestration/test_heat.py b/tempest/cli/simple_read_only/orchestration/test_heat.py
deleted file mode 100644
index 8defe51..0000000
--- a/tempest/cli/simple_read_only/orchestration/test_heat.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# 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 json
-import os
-
-from oslo_log import log as logging
-import yaml
-
-import tempest.cli
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyHeatClientTest(tempest.cli.ClientTestBase):
- """Basic, read-only tests for Heat CLI client.
-
- Basic smoke test for the heat CLI commands which do not require
- creating or modifying stacks.
- """
-
- @classmethod
- def resource_setup(cls):
- if (not CONF.service_available.heat):
- msg = ("Skipping all Heat cli tests because it is "
- "not available")
- raise cls.skipException(msg)
- super(SimpleReadOnlyHeatClientTest, cls).resource_setup()
- cls.heat_template_path = os.path.join(os.path.dirname(
- os.path.dirname(os.path.realpath(__file__))),
- 'heat_templates/heat_minimal.yaml')
-
- def heat(self, *args, **kwargs):
- return self.clients.heat(
- *args, endpoint_type=CONF.orchestration.endpoint_type, **kwargs)
-
- @test.idempotent_id('0ae034bb-ce35-45e8-b7aa-3e339cd3140f')
- def test_heat_stack_list(self):
- self.heat('stack-list')
-
- @test.idempotent_id('a360d069-7250-4aed-9721-0a6f2db7c3fa')
- def test_heat_stack_list_debug(self):
- self.heat('stack-list', flags='--debug')
-
- @test.idempotent_id('e1b7c177-5ab4-4d3f-8a26-ea01ebbd2b8c')
- def test_heat_resource_template_fmt_default(self):
- ret = self.heat('resource-template OS::Nova::Server')
- self.assertIn('Type: OS::Nova::Server', ret)
-
- @test.idempotent_id('93f82f76-aab2-4910-9359-11cf48f2a46b')
- def test_heat_resource_template_fmt_arg_short_yaml(self):
- ret = self.heat('resource-template -F yaml OS::Nova::Server')
- self.assertIn('Type: OS::Nova::Server', ret)
- self.assertIsInstance(yaml.safe_load(ret), dict)
-
- @test.idempotent_id('7356a98c-e14d-43f0-8c25-c9f7daa0aafa')
- def test_heat_resource_template_fmt_arg_long_json(self):
- ret = self.heat('resource-template --format json OS::Nova::Server')
- self.assertIn('"Type": "OS::Nova::Server"', ret)
- self.assertIsInstance(json.loads(ret), dict)
-
- @test.idempotent_id('2fd99d20-beff-4667-b42e-de9095f671d7')
- def test_heat_resource_type_list(self):
- ret = self.heat('resource-type-list')
- rsrc_types = self.parser.listing(ret)
- self.assertTableStruct(rsrc_types, ['resource_type'])
-
- @test.idempotent_id('62f60dbf-d139-4698-b230-a09fb531d643')
- def test_heat_resource_type_show(self):
- rsrc_schema = self.heat('resource-type-show OS::Nova::Server')
- # resource-type-show returns a json resource schema
- self.assertIsInstance(json.loads(rsrc_schema), dict)
-
- @test.idempotent_id('6ca16ff7-9d5f-4448-a8c2-4cecc7b5ba3a')
- def test_heat_template_validate_yaml(self):
- ret = self.heat('template-validate -f %s' % self.heat_template_path)
- # On success template-validate returns a json representation
- # of the template parameters
- self.assertIsInstance(json.loads(ret), dict)
-
- @test.idempotent_id('35241014-16ea-4cb6-ad3e-4ee5f41446de')
- def test_heat_template_validate_hot(self):
- ret = self.heat('template-validate -f %s' % self.heat_template_path)
- self.assertIsInstance(json.loads(ret), dict)
-
- @test.idempotent_id('34d43e0a-36dc-4ea8-9b85-0189e3de89d8')
- def test_heat_help(self):
- self.heat('help')
-
- @tempest.cli.min_client_version(client='heat', version='0.2.7')
- @test.idempotent_id('c122c08b-839d-49d1-afd1-bc546b2d18d3')
- def test_heat_bash_completion(self):
- self.heat('bash-completion')
-
- @test.idempotent_id('1b045e12-2fa0-4895-9282-00668428dfbe')
- def test_heat_help_cmd(self):
- # Check requesting help for a specific command works
- help_text = self.heat('help resource-template')
- lines = help_text.split('\n')
- self.assertFirstLineStartsWith(lines, 'usage: heat resource-template')
-
- @test.idempotent_id('c7837f8f-d0a8-47fd-b75b-14ba3e3fa9a2')
- def test_heat_version(self):
- self.heat('', flags='--version')
diff --git a/tempest/cli/simple_read_only/volume/__init__.py b/tempest/cli/simple_read_only/volume/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/volume/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/volume/test_cinder.py b/tempest/cli/simple_read_only/volume/test_cinder.py
deleted file mode 100644
index cb29cc8..0000000
--- a/tempest/cli/simple_read_only/volume/test_cinder.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import logging
-import re
-
-from tempest_lib import exceptions
-import testtools
-
-from tempest import cli
-from tempest import clients
-from tempest import config
-from tempest import test
-
-
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyCinderClientTest(cli.ClientTestBase):
- """Basic, read-only tests for Cinder CLI client.
-
- Checks return values and output of read-only commands.
- These tests do not presume any content, nor do they create
- their own. They only verify the structure of output if present.
- """
-
- @classmethod
- def resource_setup(cls):
- if not CONF.service_available.cinder:
- msg = ("%s skipped as Cinder is not available" % cls.__name__)
- raise cls.skipException(msg)
- super(SimpleReadOnlyCinderClientTest, cls).resource_setup()
- id_cl = clients.AdminManager().identity_client
- tenant = id_cl.get_tenant_by_name(CONF.identity.admin_tenant_name)
- cls.admin_tenant_id = tenant['id']
-
- def cinder(self, *args, **kwargs):
- return self.clients.cinder(*args,
- endpoint_type=CONF.volume.endpoint_type,
- **kwargs)
-
- @test.idempotent_id('229bc6dc-d804-4668-b753-b590caf63061')
- def test_cinder_fake_action(self):
- self.assertRaises(exceptions.CommandFailed,
- self.cinder,
- 'this-does-not-exist')
-
- @test.idempotent_id('77140216-14db-4fc5-a246-e2a587e9e99b')
- def test_cinder_absolute_limit_list(self):
- roles = self.parser.listing(self.cinder('absolute-limits'))
- self.assertTableStruct(roles, ['Name', 'Value'])
-
- @test.idempotent_id('2206b9ce-1a36-4a0a-a129-e5afc7cee1dd')
- def test_cinder_backup_list(self):
- backup_list = self.parser.listing(self.cinder('backup-list'))
- self.assertTableStruct(backup_list, ['ID', 'Volume ID', 'Status',
- 'Name', 'Size', 'Object Count',
- 'Container'])
-
- @test.idempotent_id('c7f50346-cd99-4e0b-953f-796ff5f47295')
- def test_cinder_extra_specs_list(self):
- extra_specs_list = self.parser.listing(self.cinder('extra-specs-list'))
- self.assertTableStruct(extra_specs_list, ['ID', 'Name', 'extra_specs'])
-
- @test.idempotent_id('9de694cb-b40b-442c-a30c-5f9873e144f7')
- def test_cinder_volumes_list(self):
- list = self.parser.listing(self.cinder('list'))
- self.assertTableStruct(list, ['ID', 'Status', 'Name', 'Size',
- 'Volume Type', 'Bootable',
- 'Attached to'])
- self.cinder('list', params='--all-tenants 1')
- self.cinder('list', params='--all-tenants 0')
- self.assertRaises(exceptions.CommandFailed,
- self.cinder,
- 'list',
- params='--all-tenants bad')
-
- @test.idempotent_id('56f7c15c-ee82-4f23-bbe8-ce99b66da493')
- def test_cinder_quota_class_show(self):
- """This CLI can accept and string as param."""
- roles = self.parser.listing(self.cinder('quota-class-show',
- params='abc'))
- self.assertTableStruct(roles, ['Property', 'Value'])
-
- @test.idempotent_id('a919a811-b7f0-47a7-b4e5-f3eb674dd200')
- def test_cinder_quota_defaults(self):
- """This CLI can accept and string as param."""
- roles = self.parser.listing(self.cinder('quota-defaults',
- params=self.admin_tenant_id))
- self.assertTableStruct(roles, ['Property', 'Value'])
-
- @test.idempotent_id('18166673-ffa8-4df3-b60c-6375532288bc')
- def test_cinder_quota_show(self):
- """This CLI can accept and string as param."""
- roles = self.parser.listing(self.cinder('quota-show',
- params=self.admin_tenant_id))
- self.assertTableStruct(roles, ['Property', 'Value'])
-
- @test.idempotent_id('b2c66ed9-ca96-4dc4-94cc-8083e664e516')
- def test_cinder_rate_limits(self):
- rate_limits = self.parser.listing(self.cinder('rate-limits'))
- self.assertTableStruct(rate_limits, ['Verb', 'URI', 'Value', 'Remain',
- 'Unit', 'Next_Available'])
-
- @test.idempotent_id('7a19955b-807c-481a-a2ee-9d76733eac28')
- @testtools.skipUnless(CONF.volume_feature_enabled.snapshot,
- 'Volume snapshot not available.')
- def test_cinder_snapshot_list(self):
- snapshot_list = self.parser.listing(self.cinder('snapshot-list'))
- self.assertTableStruct(snapshot_list, ['ID', 'Volume ID', 'Status',
- 'Name', 'Size'])
-
- @test.idempotent_id('6e54ecd9-7ba9-490d-8e3b-294b67139e73')
- def test_cinder_type_list(self):
- type_list = self.parser.listing(self.cinder('type-list'))
- self.assertTableStruct(type_list, ['ID', 'Name'])
-
- @test.idempotent_id('2c363583-24a0-4980-b9cb-b50c0d241e82')
- def test_cinder_list_extensions(self):
- roles = self.parser.listing(self.cinder('list-extensions'))
- self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated'])
-
- @test.idempotent_id('691bd6df-30ad-4be7-927b-a02d62aaa38a')
- def test_cinder_credentials(self):
- credentials = self.parser.listing(self.cinder('credentials'))
- self.assertTableStruct(credentials, ['User Credentials', 'Value'])
-
- @test.idempotent_id('5c6d71a3-4904-4a3a-aec9-7fd4aa830e95')
- def test_cinder_availability_zone_list(self):
- zone_list = self.parser.listing(self.cinder('availability-zone-list'))
- self.assertTableStruct(zone_list, ['Name', 'Status'])
-
- @test.idempotent_id('9b0fd5a6-f955-42b9-a42f-6f542a80b9a3')
- def test_cinder_endpoints(self):
- out = self.cinder('endpoints')
- tables = self.parser.tables(out)
- for table in tables:
- headers = table['headers']
- self.assertTrue(2 >= len(headers))
- self.assertEqual('Value', headers[1])
-
- @test.idempotent_id('301b5ae1-9591-4e9f-999c-d525a9bdf822')
- def test_cinder_service_list(self):
- service_list = self.parser.listing(self.cinder('service-list'))
- self.assertTableStruct(service_list, ['Binary', 'Host', 'Zone',
- 'Status', 'State', 'Updated_at'])
-
- @test.idempotent_id('7260ae52-b462-461e-9048-36d0bccf92c6')
- def test_cinder_transfer_list(self):
- transfer_list = self.parser.listing(self.cinder('transfer-list'))
- self.assertTableStruct(transfer_list, ['ID', 'Volume ID', 'Name'])
-
- @test.idempotent_id('0976dea8-14f3-45a9-8495-3617fc4fbb13')
- def test_cinder_bash_completion(self):
- self.cinder('bash-completion')
-
- @test.idempotent_id('b7c00361-be80-4512-8735-5f98fc54f2a9')
- def test_cinder_qos_list(self):
- qos_list = self.parser.listing(self.cinder('qos-list'))
- self.assertTableStruct(qos_list, ['ID', 'Name', 'Consumer', 'specs'])
-
- @test.idempotent_id('2e92dc6e-22b5-4d94-abfc-b543b0c50a89')
- def test_cinder_encryption_type_list(self):
- encrypt_list = self.parser.listing(self.cinder('encryption-type-list'))
- self.assertTableStruct(encrypt_list, ['Volume Type ID', 'Provider',
- 'Cipher', 'Key Size',
- 'Control Location'])
-
- @test.idempotent_id('0ee6cb4c-8de6-4811-a7be-7f4bb75b80cc')
- def test_admin_help(self):
- help_text = self.cinder('help')
- lines = help_text.split('\n')
- self.assertFirstLineStartsWith(lines, 'usage: cinder')
-
- commands = []
- cmds_start = lines.index('Positional arguments:')
- cmds_end = lines.index('Optional arguments:')
- command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
- for line in lines[cmds_start:cmds_end]:
- match = command_pattern.match(line)
- if match:
- commands.append(match.group(1))
- commands = set(commands)
- wanted_commands = set(('absolute-limits', 'list', 'help',
- 'quota-show', 'type-list', 'snapshot-list'))
- self.assertFalse(wanted_commands - commands)
-
- # Optional arguments:
-
- @test.idempotent_id('2fd6f530-183c-4bda-8918-1e59e36c26b9')
- def test_cinder_version(self):
- self.cinder('', flags='--version')
-
- @test.idempotent_id('306bac51-c443-4426-a6cf-583a953fcd68')
- def test_cinder_debug_list(self):
- self.cinder('list', flags='--debug')
-
- @test.idempotent_id('6d97fcd2-5dd1-429d-af70-030c949d86cd')
- def test_cinder_retries_list(self):
- self.cinder('list', flags='--retries 3')
-
- @test.idempotent_id('95a2850c-35b4-4159-bb93-51647a5ad232')
- def test_cinder_region_list(self):
- region = CONF.volume.region
- if not region:
- region = CONF.identity.region
- self.cinder('list', flags='--os-region-name ' + region)
diff --git a/tempest/clients.py b/tempest/clients.py
index e1b6eab..9f6a9bb 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -16,10 +16,13 @@
import copy
from oslo_log import log as logging
+from tempest_lib.services.identity.v2.token_client import TokenClientJSON
+from tempest_lib.services.identity.v3.token_client import V3TokenClientJSON
from tempest.common import cred_provider
from tempest.common import negative_rest_client
from tempest import config
+from tempest import exceptions
from tempest import manager
from tempest.services.baremetal.v1.json.baremetal_client import \
BaremetalClientJSON
@@ -77,7 +80,6 @@
DatabaseVersionsClientJSON
from tempest.services.identity.v2.json.identity_client import \
IdentityClientJSON
-from tempest.services.identity.v2.json.token_client import TokenClientJSON
from tempest.services.identity.v3.json.credentials_client import \
CredentialsClientJSON
from tempest.services.identity.v3.json.endpoints_client import \
@@ -88,7 +90,6 @@
from tempest.services.identity.v3.json.region_client import RegionClientJSON
from tempest.services.identity.v3.json.service_client import \
ServiceClientJSON
-from tempest.services.identity.v3.json.token_client import V3TokenClientJSON
from tempest.services.image.v1.json.image_client import ImageClientJSON
from tempest.services.image.v2.json.image_client import ImageClientV2JSON
from tempest.services.messaging.json.messaging_client import \
@@ -343,11 +344,22 @@
self.credentials_client = CredentialsClientJSON(self.auth_provider,
**params)
# Token clients do not use the catalog. They only need default_params.
- self.token_client = TokenClientJSON(CONF.identity.uri,
- **self.default_params)
+ # They read auth_url, so they should only be set if the corresponding
+ # API version is marked as enabled
+ if CONF.identity_feature_enabled.api_v2:
+ if CONF.identity.uri:
+ self.token_client = TokenClientJSON(
+ CONF.identity.uri, **self.default_params)
+ else:
+ msg = 'Identity v2 API enabled, but no identity.uri set'
+ raise exceptions.InvalidConfiguration(msg)
if CONF.identity_feature_enabled.api_v3:
- self.token_v3_client = V3TokenClientJSON(CONF.identity.uri_v3,
- **self.default_params)
+ if CONF.identity.uri_v3:
+ self.token_v3_client = V3TokenClientJSON(
+ CONF.identity.uri_v3, **self.default_params)
+ else:
+ msg = 'Identity v3 API enabled, but no identity.uri_v3 set'
+ raise exceptions.InvalidConfiguration(msg)
def _set_volume_clients(self):
params = {
diff --git a/tempest/cmd/account_generator.py b/tempest/cmd/account_generator.py
new file mode 100755
index 0000000..0a48b8d
--- /dev/null
+++ b/tempest/cmd/account_generator.py
@@ -0,0 +1,266 @@
+#!/usr/bin/env python
+
+# Copyright 2015 Mirantis, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# 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 argparse
+import os
+
+from oslo_log import log as logging
+import yaml
+
+from tempest import config
+from tempest import exceptions
+from tempest.services.identity.v2.json import identity_client
+import tempest_lib.auth
+from tempest_lib.common.utils import data_utils
+import tempest_lib.exceptions
+
+LOG = None
+CONF = config.CONF
+
+
+def setup_logging():
+ global LOG
+ logging.setup(CONF, __name__)
+ LOG = logging.getLogger(__name__)
+
+
+def keystone_admin(opts):
+ _creds = tempest_lib.auth.KeystoneV2Credentials(
+ username=opts.os_username,
+ password=opts.os_password,
+ tenant_name=opts.os_tenant_name)
+ auth_params = {
+ 'disable_ssl_certificate_validation':
+ CONF.identity.disable_ssl_certificate_validation,
+ 'ca_certs': CONF.identity.ca_certificates_file,
+ 'trace_requests': CONF.debug.trace_requests
+ }
+ _auth = tempest_lib.auth.KeystoneV2AuthProvider(
+ _creds, CONF.identity.uri, **auth_params)
+ params = {
+ 'disable_ssl_certificate_validation':
+ CONF.identity.disable_ssl_certificate_validation,
+ 'ca_certs': CONF.identity.ca_certificates_file,
+ 'trace_requests': CONF.debug.trace_requests,
+ 'build_interval': CONF.compute.build_interval,
+ 'build_timeout': CONF.compute.build_timeout
+ }
+ return identity_client.IdentityClientJSON(
+ _auth,
+ CONF.identity.catalog_type,
+ CONF.identity.region,
+ endpoint_type='adminURL',
+ **params
+ )
+
+
+def create_resources(opts, resources):
+ admin = keystone_admin(opts)
+ roles = admin.list_roles()
+ for u in resources['users']:
+ u['role_ids'] = []
+ for r in u.get('roles', ()):
+ try:
+ role = filter(lambda r_: r_['name'] == r, roles)[0]
+ u['role_ids'] += [role['id']]
+ except IndexError:
+ raise exceptions.TempestException(
+ "Role: %s - doesn't exist" % r
+ )
+ existing = [x['name'] for x in admin.list_tenants()]
+ for tenant in resources['tenants']:
+ if tenant not in existing:
+ admin.create_tenant(tenant)
+ else:
+ LOG.warn("Tenant '%s' already exists in this environment" % tenant)
+ LOG.info('Tenants created')
+ for u in resources['users']:
+ try:
+ tenant = admin.get_tenant_by_name(u['tenant'])
+ except tempest_lib.exceptions.NotFound:
+ LOG.error("Tenant: %s - not found" % u['tenant'])
+ continue
+ while True:
+ try:
+ admin.get_user_by_username(tenant['id'], u['name'])
+ except tempest_lib.exceptions.NotFound:
+ admin.create_user(
+ u['name'], u['pass'], tenant['id'],
+ "%s@%s" % (u['name'], tenant['id']),
+ enabled=True)
+ break
+ else:
+ LOG.warn("User '%s' already exists in this environment. "
+ "New name generated" % u['name'])
+ u['name'] = random_user_name(opts.tag, u['prefix'])
+
+ LOG.info('Users created')
+ for u in resources['users']:
+ try:
+ tenant = admin.get_tenant_by_name(u['tenant'])
+ except tempest_lib.exceptions.NotFound:
+ LOG.error("Tenant: %s - not found" % u['tenant'])
+ continue
+ try:
+ user = admin.get_user_by_username(tenant['id'],
+ u['name'])
+ except tempest_lib.exceptions.NotFound:
+ LOG.error("User: %s - not found" % u['user'])
+ continue
+ for r in u['role_ids']:
+ try:
+ admin.assign_user_role(tenant['id'], user['id'], r)
+ except tempest_lib.exceptions.Conflict:
+ # don't care if it's already assigned
+ pass
+ LOG.info('Roles assigned')
+ LOG.info('Resources deployed successfully!')
+
+
+def random_user_name(tag, prefix):
+ if tag:
+ return data_utils.rand_name('-'.join((tag, prefix)))
+ else:
+ return data_utils.rand_name(prefix)
+
+
+def generate_resources(opts):
+ spec = [{'number': 1,
+ 'prefix': 'primary',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.operator_role])},
+ {'number': 1,
+ 'prefix': 'alt',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.operator_role])},
+ {'number': 1,
+ 'prefix': 'swift_admin',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.object_storage.operator_role,
+ CONF.object_storage.reseller_admin_role])},
+ {'number': 1,
+ 'prefix': 'stack_owner',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.orchestration.stack_owner_role])},
+ ]
+ if opts.admin:
+ spec.append({
+ 'number': 1,
+ 'prefix': 'admin',
+ 'roles': (CONF.auth.tempest_roles +
+ [CONF.identity.admin_role])
+ })
+ resources = {'tenants': [],
+ 'users': []}
+ for count in range(opts.concurrency):
+ for user_group in spec:
+ users = [random_user_name(opts.tag, user_group['prefix'])
+ for _ in range(user_group['number'])]
+ for user in users:
+ tenant = '-'.join((user, 'tenant'))
+ resources['tenants'].append(tenant)
+ resources['users'].append({
+ 'tenant': tenant,
+ 'name': user,
+ 'pass': data_utils.rand_name(),
+ 'prefix': user_group['prefix'],
+ 'roles': user_group['roles']
+ })
+ return resources
+
+
+def dump_accounts(opts, resources):
+ accounts = []
+ for user in resources['users']:
+ accounts.append({
+ 'username': user['name'],
+ 'tenant_name': user['tenant'],
+ 'password': user['pass'],
+ 'roles': user['roles']
+ })
+ if os.path.exists(opts.accounts):
+ os.rename(opts.accounts, '.'.join((opts.accounts, 'bak')))
+ with open(opts.accounts, 'w') as f:
+ yaml.dump(accounts, f, default_flow_style=False)
+ LOG.info('%s generated successfully!' % opts.accounts)
+
+
+def get_options():
+ usage_string = ('account_generator [-h] <ARG> ...\n\n'
+ 'To see help on specific argument, do:\n'
+ 'account_generator <ARG> -h')
+ parser = argparse.ArgumentParser(
+ description='Create accounts.yaml file for concurrent test runs. '
+ 'One primary user, one alt user, '
+ 'one swift admin, one stack owner '
+ 'and one admin (optionally) will be created '
+ 'for each concurrent thread.',
+ formatter_class=argparse.ArgumentDefaultsHelpFormatter,
+ usage=usage_string
+ )
+
+ parser.add_argument('-c', '--config-file',
+ metavar='/etc/tempest.conf',
+ help='path to tempest config file')
+ parser.add_argument('--os-username',
+ metavar='<auth-user-name>',
+ default=os.environ.get('OS_USERNAME'),
+ help='User should have permitions '
+ 'to create new user accounts and '
+ 'tenants. Defaults to env[OS_USERNAME].')
+ parser.add_argument('--os-password',
+ metavar='<auth-password>',
+ default=os.environ.get('OS_PASSWORD'),
+ help='Defaults to env[OS_PASSWORD].')
+ parser.add_argument('--os-tenant-name',
+ metavar='<auth-tenant-name>',
+ default=os.environ.get('OS_TENANT_NAME'),
+ help='Defaults to env[OS_TENANT_NAME].')
+ parser.add_argument('--tag',
+ default='',
+ required=False,
+ dest='tag',
+ help='Resources tag')
+ parser.add_argument('-r', '--concurrency',
+ default=1,
+ type=int,
+ required=True,
+ dest='concurrency',
+ help='Concurrency count')
+ parser.add_argument('--with-admin',
+ action='store_true',
+ dest='admin',
+ help='Create admin in every tenant')
+ parser.add_argument('accounts',
+ metavar='accounts_file.yaml',
+ help='Output accounts yaml file')
+
+ opts = parser.parse_args()
+ if opts.config_file:
+ config.CONF.set_config_path(opts.config_file)
+ return opts
+
+
+def main(opts=None):
+ if not opts:
+ opts = get_options()
+ setup_logging()
+ resources = generate_resources(opts)
+ create_resources(opts, resources)
+ dump_accounts(opts, resources)
+
+if __name__ == "__main__":
+ main()
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 1ad12eb..eb6f143 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -343,6 +343,44 @@
self.data['volumes'] = vols
+class VolumeQuotaService(BaseService):
+ def __init__(self, manager, **kwargs):
+ super(VolumeQuotaService, self).__init__(kwargs)
+ self.client = manager.volume_quotas_client
+
+ def delete(self):
+ client = self.client
+ try:
+ client.delete_quota_set(self.tenant_id)
+ except Exception as e:
+ LOG.exception("Delete Volume Quotas exception: %s" % e)
+ pass
+
+ def dry_run(self):
+ quotas = self.client.show_quota_usage(self.tenant_id)
+ self.data['volume_quotas'] = quotas
+
+
+class NovaQuotaService(BaseService):
+ def __init__(self, manager, **kwargs):
+ super(NovaQuotaService, self).__init__(kwargs)
+ self.client = manager.quotas_client
+ self.limits_client = manager.limits_client
+
+ def delete(self):
+ client = self.client
+ try:
+ client.delete_quota_set(self.tenant_id)
+ except Exception as e:
+ LOG.exception("Delete Quotas exception: %s" % e)
+ pass
+
+ def dry_run(self):
+ client = self.limits_client
+ quotas = client.get_absolute_limits()
+ self.data['compute_quotas'] = quotas
+
+
# Begin network service classes
class NetworkService(BaseService):
def __init__(self, manager, **kwargs):
@@ -667,7 +705,7 @@
self.data['pools'] = pools
-class NetworMeteringLabelRuleService(NetworkService):
+class NetworkMeteringLabelRuleService(NetworkService):
def list(self):
client = self.client
@@ -692,7 +730,7 @@
self.data['rules'] = rules
-class NetworMeteringLabelService(NetworkService):
+class NetworkMeteringLabelService(NetworkService):
def list(self):
client = self.client
@@ -1052,6 +1090,7 @@
tenant_services.append(ServerGroupService)
if not IS_NEUTRON:
tenant_services.append(FloatingIpService)
+ tenant_services.append(NovaQuotaService)
if IS_HEAT:
tenant_services.append(StackService)
if IS_NEUTRON:
@@ -1068,8 +1107,8 @@
tenant_services.append(NetworkVipService)
tenant_services.append(NetworkPoolService)
if test.is_extension_enabled('metering', 'network'):
- tenant_services.append(NetworMeteringLabelRuleService)
- tenant_services.append(NetworMeteringLabelService)
+ tenant_services.append(NetworkMeteringLabelRuleService)
+ tenant_services.append(NetworkMeteringLabelService)
tenant_services.append(NetworkRouterService)
tenant_services.append(NetworkFloatingIpService)
tenant_services.append(NetworkPortService)
@@ -1078,6 +1117,7 @@
if IS_CINDER:
tenant_services.append(SnapshotService)
tenant_services.append(VolumeService)
+ tenant_services.append(VolumeQuotaService)
return tenant_services
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index f84771f..4e2af76 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -114,10 +114,11 @@
import netaddr
from oslo_log import log as logging
from oslo_utils import timeutils
+import six
+from tempest_lib import auth
from tempest_lib import exceptions as lib_exc
import yaml
-import tempest.auth
from tempest import config
from tempest.services.compute.json import flavors_client
from tempest.services.compute.json import floating_ips_client
@@ -175,7 +176,7 @@
}
object_storage_params.update(default_params)
- _creds = tempest.auth.KeystoneV2Credentials(
+ _creds = auth.KeystoneV2Credentials(
username=user,
password=pw,
tenant_name=tenant)
@@ -185,7 +186,7 @@
'ca_certs': CONF.identity.ca_certificates_file,
'trace_requests': CONF.debug.trace_requests
}
- _auth = tempest.auth.KeystoneV2AuthProvider(
+ _auth = auth.KeystoneV2AuthProvider(
_creds, CONF.identity.uri, **auth_provider_params)
self.identity = identity_client.IdentityClientJSON(
_auth,
@@ -416,7 +417,7 @@
that things like tenantId didn't drift across versions.
"""
LOG.info("checking users")
- for name, user in self.users.iteritems():
+ for name, user in six.iteritems(self.users):
client = keystone_admin()
found = client.identity.get_user(user['id'])
self.assertEqual(found['name'], user['name'])
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index f1965bc..f51d9aa 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -94,7 +94,7 @@
versions = map(lambda x: x['id'], body['versions']['values'])
else:
versions = map(lambda x: x['id'], body['versions'])
- return versions
+ return list(versions)
def verify_keystone_api_versions(os, update):
@@ -175,6 +175,7 @@
else:
extensions = map(lambda x: x['alias'], resp)
+ extensions = list(extensions)
if not results.get(service):
results[service] = {}
extensions_opt = get_enabled_extensions(service)
@@ -335,25 +336,28 @@
CONF_PARSER.optionxform = str
CONF_PARSER.readfp(conf_file)
icreds = credentials.get_isolated_credentials('verify_tempest_config')
- os = clients.Manager(icreds.get_primary_creds())
- services = check_service_availability(os, update)
- results = {}
- for service in ['nova', 'cinder', 'neutron', 'swift']:
- if service not in services:
- continue
- results = verify_extensions(os, service, results)
+ try:
+ os = clients.Manager(icreds.get_primary_creds())
+ services = check_service_availability(os, update)
+ results = {}
+ for service in ['nova', 'cinder', 'neutron', 'swift']:
+ if service not in services:
+ continue
+ results = verify_extensions(os, service, results)
- # Verify API versions of all services in the keystone catalog and keystone
- # itself.
- services.append('keystone')
- for service in services:
- verify_api_versions(os, service, update)
+ # Verify API versions of all services in the keystone catalog and
+ # keystone itself.
+ services.append('keystone')
+ for service in services:
+ verify_api_versions(os, service, update)
- display_results(results, update, replace)
- if update:
- conf_file.close()
- CONF_PARSER.write(outfile)
- outfile.close()
+ display_results(results, update, replace)
+ if update:
+ conf_file.close()
+ CONF_PARSER.write(outfile)
+ outfile.close()
+ finally:
+ icreds.clear_isolated_creds()
if __name__ == "__main__":
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 93c8bcf..650faf1 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -17,6 +17,7 @@
from oslo_concurrency import lockutils
from oslo_log import log as logging
+import six
import yaml
from tempest import clients
@@ -75,7 +76,7 @@
if 'resources' in account:
resources = account.pop('resources')
temp_hash = hashlib.md5()
- temp_hash.update(str(account))
+ temp_hash.update(six.text_type(account).encode('utf-8'))
temp_hash_key = temp_hash.hexdigest()
hash_dict['creds'][temp_hash_key] = account
for role in roles:
@@ -244,17 +245,19 @@
def get_creds_by_roles(self, roles, force_new=False):
roles = list(set(roles))
- exist_creds = self.isolated_creds.get(str(roles), None)
+ exist_creds = self.isolated_creds.get(six.text_type(roles).encode(
+ 'utf-8'), None)
# The force kwarg is used to allocate an additional set of creds with
# the same role list. The index used for the previously allocation
# in the isolated_creds dict will be moved.
if exist_creds and not force_new:
return exist_creds
elif exist_creds and force_new:
- new_index = str(roles) + '-' + str(len(self.isolated_creds))
+ new_index = six.text_type(roles).encode('utf-8') + '-' + \
+ six.text_type(len(self.isolated_creds)).encode('utf-8')
self.isolated_creds[new_index] = exist_creds
net_creds = self._get_creds(roles=roles)
- self.isolated_creds[str(roles)] = net_creds
+ self.isolated_creds[six.text_type(roles).encode('utf-8')] = net_creds
return net_creds
def clear_isolated_creds(self):
@@ -283,8 +286,11 @@
net_clients = clients.Manager(credentials=credential)
compute_network_client = net_clients.networks_client
net_name = self.hash_dict['networks'].get(hash, None)
- network = fixed_network.get_network_from_name(
- net_name, compute_network_client)
+ try:
+ network = fixed_network.get_network_from_name(
+ net_name, compute_network_client)
+ except exceptions.InvalidConfiguration:
+ network = {}
net_creds.set_resources(network=network)
return net_creds
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 3223027..461097f 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -16,8 +16,8 @@
from oslo_log import log as logging
import six
+from tempest_lib import auth
-from tempest import auth
from tempest import config
from tempest import exceptions
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 298a94e..839088c 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -14,6 +14,7 @@
import re
+import six
from testtools import helpers
@@ -121,7 +122,7 @@
"""
def match(self, actual):
- for key, value in actual.iteritems():
+ for key, value in six.iteritems(actual):
if key in ('content-length', 'x-account-bytes-used',
'x-account-container-count', 'x-account-object-count',
'x-container-bytes-used', 'x-container-object-count')\
diff --git a/tempest/common/fixed_network.py b/tempest/common/fixed_network.py
index 1557474..2c6e334 100644
--- a/tempest/common/fixed_network.py
+++ b/tempest/common/fixed_network.py
@@ -17,6 +17,7 @@
from tempest_lib import exceptions as lib_exc
from tempest import config
+from tempest import exceptions
CONF = config.CONF
@@ -29,51 +30,59 @@
:param str name: the name of the network to use
:param NetworksClientJSON compute_networks_client: The network client
object to use for making the network lists api request
- :return: The full dictionary for the network in question, unless the
- network for the supplied name can not be found. In which case a dict
- with just the name will be returned.
+ :return: The full dictionary for the network in question
:rtype: dict
+ :raises InvalidConfiguration: If the name provided is invalid, the networks
+ list returns a 404, there are no found networks, or the found network
+ is invalid
"""
caller = misc_utils.find_test_caller()
+
if not name:
- network = {'name': name}
+ raise exceptions.InvalidConfiguration()
+
+ try:
+ networks = compute_networks_client.list_networks(name=name)
+ except lib_exc.NotFound:
+ # In case of nova network, if the fixed_network_name is not
+ # owned by the tenant, and the network client is not an admin
+ # one, list_networks will not find it
+ msg = ('Unable to find network %s. '
+ 'Starting instance without specifying a network.' %
+ name)
+ if caller:
+ msg = '(%s) %s' % (caller, msg)
+ LOG.info(msg)
+ raise exceptions.InvalidConfiguration()
+
+ # Check that a network exists, else raise an InvalidConfigurationException
+ if len(networks) == 1:
+ network = sorted(networks)[0]
+ elif len(networks) > 1:
+ msg = ("Network with name: %s had multiple matching networks in the "
+ "list response: %s\n Unable to specify a single network" % (
+ name, networks))
+ if caller:
+ msg = '(%s) %s' % (caller, msg)
+ LOG.warn(msg)
+ raise exceptions.InvalidConfiguration()
else:
- try:
- resp = compute_networks_client.list_networks(name=name)
- if isinstance(resp, list):
- networks = resp
- elif isinstance(resp, dict):
- networks = resp['networks']
- else:
- raise lib_exc.NotFound()
- if len(networks) > 0:
- network = networks[0]
- else:
- msg = "Network with name: %s not found" % name
- if caller:
- LOG.warn('(%s) %s' % (caller, msg))
- else:
- LOG.warn(msg)
- raise lib_exc.NotFound()
- # To be consistent with network isolation, add name is only
- # label is available
- name = network.get('name', network.get('label'))
- if name:
- network['name'] = name
- else:
- raise lib_exc.NotFound()
- except lib_exc.NotFound:
- # In case of nova network, if the fixed_network_name is not
- # owned by the tenant, and the network client is not an admin
- # one, list_networks will not find it
- msg = ('Unable to find network %s. '
- 'Starting instance without specifying a network.' %
- name)
- if caller:
- LOG.info('(%s) %s' % (caller, msg))
- else:
- LOG.info(msg)
- network = {'name': name}
+ msg = "Network with name: %s not found" % name
+ if caller:
+ msg = '(%s) %s' % (caller, msg)
+ LOG.warn(msg)
+ raise exceptions.InvalidConfiguration()
+ # To be consistent between neutron and nova network always use name even
+ # if label is used in the api response. If neither is present than then
+ # the returned network is invalid.
+ name = network.get('name') or network.get('label')
+ if not name:
+ msg = "Network found from list doesn't contain a valid name or label"
+ if caller:
+ msg = '(%s) %s' % (caller, msg)
+ LOG.warn(msg)
+ raise exceptions.InvalidConfiguration()
+ network['name'] = name
return network
@@ -97,16 +106,17 @@
msg = ('No valid network provided or created, defaulting to '
'fixed_network_name')
if caller:
- LOG.debug('(%s) %s' % (caller, msg))
- else:
- LOG.debug(msg)
- network = get_network_from_name(fixed_network_name,
- compute_networks_client)
+ msg = '(%s) %s' % (caller, msg)
+ LOG.debug(msg)
+ try:
+ network = get_network_from_name(fixed_network_name,
+ compute_networks_client)
+ except exceptions.InvalidConfiguration:
+ network = {}
msg = ('Found network %s available for tenant' % network)
if caller:
- LOG.info('(%s) %s' % (caller, msg))
- else:
- LOG.info(msg)
+ msg = '(%s) %s' % (caller, msg)
+ LOG.info(msg)
return network
diff --git a/tempest/common/generator/base_generator.py b/tempest/common/generator/base_generator.py
index f81f405..3e09300 100644
--- a/tempest/common/generator/base_generator.py
+++ b/tempest/common/generator/base_generator.py
@@ -17,8 +17,8 @@
import functools
import jsonschema
-
from oslo_log import log as logging
+import six
LOG = logging.getLogger(__name__)
@@ -122,7 +122,7 @@
if schema_type == 'object':
properties = schema["properties"]
- for attribute, definition in properties.iteritems():
+ for attribute, definition in six.iteritems(properties):
current_path = copy.copy(path)
if path is not None:
current_path.append(attribute)
diff --git a/tempest/common/generator/valid_generator.py b/tempest/common/generator/valid_generator.py
index 0c63bf5..2213b4a 100644
--- a/tempest/common/generator/valid_generator.py
+++ b/tempest/common/generator/valid_generator.py
@@ -14,6 +14,7 @@
# under the License.
from oslo_log import log as logging
+import six
import tempest.common.generator.base_generator as base
@@ -51,7 +52,7 @@
@base.simple_generator
def generate_valid_object(self, schema):
obj = {}
- for k, v in schema["properties"].iteritems():
+ for k, v in six.iteritems(schema["properties"]):
obj[k] = self.generate_valid(v)
return obj
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 1f85872..fee1467 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -413,7 +413,7 @@
if not self.isolated_creds:
return
self._clear_isolated_net_resources()
- for creds in self.isolated_creds.itervalues():
+ for creds in six.itervalues(self.isolated_creds):
try:
self.creds_client.delete_user(creds.user_id)
except lib_exc.NotFound:
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
deleted file mode 100644
index d0e484c..0000000
--- a/tempest/common/ssh.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import select
-import socket
-import time
-import warnings
-
-from oslo_log import log as logging
-import six
-from six import moves
-
-from tempest import exceptions
-
-
-with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- import paramiko
-
-
-LOG = logging.getLogger(__name__)
-
-
-class Client(object):
-
- def __init__(self, host, username, password=None, timeout=300, pkey=None,
- channel_timeout=10, look_for_keys=False, key_filename=None):
- self.host = host
- self.username = username
- self.password = password
- if isinstance(pkey, six.string_types):
- pkey = paramiko.RSAKey.from_private_key(
- moves.cStringIO(str(pkey)))
- self.pkey = pkey
- self.look_for_keys = look_for_keys
- self.key_filename = key_filename
- self.timeout = int(timeout)
- self.channel_timeout = float(channel_timeout)
- self.buf_size = 1024
-
- def _get_ssh_connection(self, sleep=1.5, backoff=1):
- """Returns an ssh connection to the specified host."""
- bsleep = sleep
- ssh = paramiko.SSHClient()
- ssh.set_missing_host_key_policy(
- paramiko.AutoAddPolicy())
- _start_time = time.time()
- if self.pkey is not None:
- LOG.info("Creating ssh connection to '%s' as '%s'"
- " with public key authentication",
- self.host, self.username)
- else:
- LOG.info("Creating ssh connection to '%s' as '%s'"
- " with password %s",
- self.host, self.username, str(self.password))
- attempts = 0
- while True:
- try:
- ssh.connect(self.host, username=self.username,
- password=self.password,
- look_for_keys=self.look_for_keys,
- key_filename=self.key_filename,
- timeout=self.channel_timeout, pkey=self.pkey)
- LOG.info("ssh connection to %s@%s successfuly created",
- self.username, self.host)
- return ssh
- except (socket.error,
- paramiko.SSHException) as e:
- if self._is_timed_out(_start_time):
- LOG.exception("Failed to establish authenticated ssh"
- " connection to %s@%s after %d attempts",
- self.username, self.host, attempts)
- raise exceptions.SSHTimeout(host=self.host,
- user=self.username,
- password=self.password)
- bsleep += backoff
- attempts += 1
- LOG.warning("Failed to establish authenticated ssh"
- " connection to %s@%s (%s). Number attempts: %s."
- " Retry after %d seconds.",
- self.username, self.host, e, attempts, bsleep)
- time.sleep(bsleep)
-
- def _is_timed_out(self, start_time):
- return (time.time() - self.timeout) > start_time
-
- def exec_command(self, cmd):
- """
- Execute the specified command on the server.
-
- Note that this method is reading whole command outputs to memory, thus
- shouldn't be used for large outputs.
-
- :returns: data read from standard output of the command.
- :raises: SSHExecCommandFailed if command returns nonzero
- status. The exception contains command status stderr content.
- """
- ssh = self._get_ssh_connection()
- transport = ssh.get_transport()
- channel = transport.open_session()
- channel.fileno() # Register event pipe
- channel.exec_command(cmd)
- channel.shutdown_write()
- out_data = []
- err_data = []
- poll = select.poll()
- poll.register(channel, select.POLLIN)
- start_time = time.time()
-
- while True:
- ready = poll.poll(self.channel_timeout)
- if not any(ready):
- if not self._is_timed_out(start_time):
- continue
- raise exceptions.TimeoutException(
- "Command: '{0}' executed on host '{1}'.".format(
- cmd, self.host))
- if not ready[0]: # If there is nothing to read.
- continue
- out_chunk = err_chunk = None
- if channel.recv_ready():
- out_chunk = channel.recv(self.buf_size)
- out_data += out_chunk,
- if channel.recv_stderr_ready():
- err_chunk = channel.recv_stderr(self.buf_size)
- err_data += err_chunk,
- if channel.closed and not err_chunk and not out_chunk:
- break
- exit_status = channel.recv_exit_status()
- if 0 != exit_status:
- raise exceptions.SSHExecCommandFailed(
- command=cmd, exit_status=exit_status,
- strerror=''.join(err_data))
- return ''.join(out_data)
-
- def test_connection_auth(self):
- """Raises an exception when we can not connect to server via ssh."""
- connection = self._get_ssh_connection()
- connection.close()
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 29fb493..bedff1f 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -15,8 +15,8 @@
import time
import six
+from tempest_lib.common import ssh
-from tempest.common import ssh
from tempest import config
from tempest import exceptions
diff --git a/tempest/common/validation_resources.py b/tempest/common/validation_resources.py
new file mode 100644
index 0000000..d370ebc
--- /dev/null
+++ b/tempest/common/validation_resources.py
@@ -0,0 +1,113 @@
+# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from oslo_log import log as logging
+
+from tempest import config
+from tempest_lib.common.utils import data_utils
+from tempest_lib import exceptions as lib_exc
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+def create_ssh_security_group(os, add_rule=False):
+ security_group_client = os.security_groups_client
+ sg_name = data_utils.rand_name('securitygroup-')
+ sg_description = data_utils.rand_name('description-')
+ security_group = \
+ security_group_client.create_security_group(sg_name, sg_description)
+ if add_rule:
+ security_group_client.create_security_group_rule(security_group['id'],
+ 'tcp', 22, 22)
+ security_group_client.create_security_group_rule(security_group['id'],
+ 'icmp', -1, -1)
+ LOG.debug("SSH Validation resource security group with tcp and icmp "
+ "rules %s created"
+ % sg_name)
+ return security_group
+
+
+def create_validation_resources(os, validation_resources=None):
+ # Create and Return the validation resources required to validate a VM
+ validation_data = {}
+ if validation_resources:
+ if validation_resources['keypair']:
+ keypair_name = data_utils.rand_name('keypair')
+ validation_data['keypair'] = \
+ os.keypairs_client.create_keypair(keypair_name)
+ LOG.debug("Validation resource key %s created" % keypair_name)
+ add_rule = False
+ if validation_resources['security_group']:
+ if validation_resources['security_group_rules']:
+ add_rule = True
+ validation_data['security_group'] = \
+ create_ssh_security_group(os, add_rule)
+ if validation_resources['floating_ip']:
+ floating_client = os.floating_ips_client
+ validation_data['floating_ip'] = \
+ floating_client.create_floating_ip()
+ return validation_data
+
+
+def clear_validation_resources(os, validation_data=None):
+ # Cleanup the vm validation resources
+ has_exception = None
+ if validation_data:
+ if 'keypair' in validation_data:
+ keypair_client = os.keypairs_client
+ keypair_name = validation_data['keypair']['name']
+ try:
+ keypair_client.delete_keypair(keypair_name)
+ except lib_exc.NotFound:
+ LOG.warn("Keypair %s is not found when attempting to delete"
+ % keypair_name)
+ except Exception as exc:
+ LOG.exception('Exception raised while deleting key %s'
+ % keypair_name)
+ if not has_exception:
+ has_exception = exc
+ if 'security_group' in validation_data:
+ security_group_client = os.security_groups_client
+ sec_id = validation_data['security_group']['id']
+ try:
+ security_group_client.delete_security_group(sec_id)
+ security_group_client.wait_for_resource_deletion(sec_id)
+ except lib_exc.NotFound:
+ LOG.warn("Security group %s is not found when attempting to "
+ " delete" % sec_id)
+ except lib_exc.Conflict as exc:
+ LOG.exception('Conflict while deleting security '
+ 'group %s VM might not be deleted ' % sec_id)
+ if not has_exception:
+ has_exception = exc
+ except Exception as exc:
+ LOG.exception('Exception raised while deleting security '
+ 'group %s ' % sec_id)
+ if not has_exception:
+ has_exception = exc
+ if 'floating_ip' in validation_data:
+ floating_client = os.floating_ips_client
+ fip_id = validation_data['floating_ip']['id']
+ try:
+ floating_client.delete_floating_ip(fip_id)
+ except lib_exc.NotFound:
+ LOG.warn('Floating ip %s not found while attempting to delete'
+ % fip_id)
+ except Exception as exc:
+ LOG.exception('Exception raised while deleting ip %s '
+ % fip_id)
+ if not has_exception:
+ has_exception = exc
+ if has_exception:
+ raise has_exception
diff --git a/tempest/config.py b/tempest/config.py
index bcbe41f..3f3e7e7 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -195,9 +195,6 @@
help="Timeout in seconds to wait for an instance to build. "
"Other services that do not define build_timeout will "
"inherit this value."),
- cfg.BoolOpt('run_ssh',
- default=False,
- help="Should the tests ssh to instances?"),
cfg.StrOpt('ssh_auth_method',
default='keypair',
help="Auth method used for authenticate to the instance. "
@@ -249,7 +246,7 @@
cfg.StrOpt('network_for_ssh',
default='public',
help="Network used for SSH connections. Ignored if "
- "use_floatingip_for_ssh=true or run_ssh=false."),
+ "use_floatingip_for_ssh=true or run_validation=false."),
cfg.IntOpt('ip_version_for_ssh',
default=4,
help="IP version used for SSH connections."),
@@ -335,6 +332,13 @@
help="Does the test environment block migration support "
"cinder iSCSI volumes. Note, libvirt doesn't support this, "
"see https://bugs.launchpad.net/nova/+bug/1398999"),
+ # TODO(gilliard): Remove live_migrate_paused_instances at juno-eol.
+ cfg.BoolOpt('live_migrate_paused_instances',
+ default=False,
+ help="Does the test system allow live-migration of paused "
+ "instances? Note, this is more than just the ANDing of "
+ "paused and live_migrate, but all 3 should be set to True "
+ "to run those tests"),
cfg.BoolOpt('vnc_console',
default=False,
help='Enable VNC console. This configuration value should '
@@ -551,6 +555,12 @@
title='SSH Validation options')
ValidationGroup = [
+ cfg.BoolOpt('run_validation',
+ default=False,
+ help='Enable ssh on created servers and creation of additional'
+ ' validation resources to enable remote access',
+ deprecated_opts=[cfg.DeprecatedOpt('run_ssh',
+ group='compute')]),
cfg.StrOpt('connect_method',
default='floating',
choices=['fixed', 'floating'],
@@ -1091,25 +1101,6 @@
help="Timeout for unprovisioning an Ironic node.")
]
-cli_group = cfg.OptGroup(name='cli', title="cli Configuration Options")
-
-CLIGroup = [
- cfg.BoolOpt('enabled',
- default=True,
- help="enable cli tests"),
- cfg.StrOpt('cli_dir',
- default='/usr/local/bin',
- help="directory where python client binaries are located"),
- cfg.BoolOpt('has_manage',
- default=True,
- help=("Whether the tempest run location has access to the "
- "*-manage commands. In a pure blackbox environment "
- "it will not.")),
- cfg.IntOpt('timeout',
- default=15,
- help="Number of seconds to wait on a CLI timeout"),
-]
-
negative_group = cfg.OptGroup(name='negative', title="Negative Test Options")
NegativeGroup = [
@@ -1148,7 +1139,6 @@
(debug_group, DebugGroup),
(baremetal_group, BaremetalGroup),
(input_scenario_group, InputScenarioGroup),
- (cli_group, CLIGroup),
(negative_group, NegativeGroup)
]
@@ -1212,7 +1202,6 @@
self.debug = _CONF.debug
self.baremetal = _CONF.baremetal
self.input_scenario = _CONF['input-scenario']
- self.cli = _CONF.cli
self.negative = _CONF.negative
_CONF.set_default('domain_name', self.identity.admin_domain_name,
group='identity')
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 09f7016..15617c6 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -128,17 +128,6 @@
message = "Got identity error"
-class SSHTimeout(TempestException):
- message = ("Connection to the %(host)s via SSH timed out.\n"
- "User: %(user)s, Password: %(password)s")
-
-
-class SSHExecCommandFailed(TempestException):
- """Raised when remotely executed command returns nonzero status."""
- message = ("Command '%(command)s', exit status: %(exit_status)d, "
- "Error:\n%(strerror)s")
-
-
class ServerUnreachable(TempestException):
message = "The server is not reachable via the configured network"
diff --git a/tempest/manager.py b/tempest/manager.py
index 025ce65..c39d3e5 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -13,7 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest import auth
+from tempest_lib import auth
+
from tempest.common import cred_provider
from tempest import config
from tempest import exceptions
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 13ceccc..50aa261 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -309,7 +309,7 @@
linux_client.validate_authentication()
except Exception:
LOG.exception('Initializing SSH connection to %s failed' % ip)
- # If we don't explicitely set for which servers we want to
+ # If we don't explicitly set for which servers we want to
# log the console output then all the servers will be logged.
# See the definition of _log_console_output()
self._log_console_output(log_console_of_servers)
@@ -380,7 +380,7 @@
def _log_net_info(self, exc):
# network debug is called as part of ssh init
- if not isinstance(exc, exceptions.SSHTimeout):
+ if not isinstance(exc, lib_exc.SSHTimeout):
LOG.debug('Network information on a devstack host')
def create_server_snapshot(self, server, name=None):
@@ -740,7 +740,7 @@
# The target login is assumed to have been configured for
# key-based authentication by cloud-init.
try:
- for net_name, ip_addresses in server['addresses'].iteritems():
+ for net_name, ip_addresses in six.iteritems(server['addresses']):
for ip_address in ip_addresses:
self.check_vm_connectivity(ip_address['addr'],
username,
@@ -765,7 +765,7 @@
def ping_remote():
try:
source.ping_host(dest)
- except exceptions.SSHExecCommandFailed:
+ except lib_exc.SSHExecCommandFailed:
LOG.warn('Failed to ping IP: %s via a ssh connection from: %s.'
% (dest, source.ssh_client.host))
return not should_succeed
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index 612a5a2..e54c25a 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -126,8 +126,9 @@
self.boot_instance()
self.validate_ports()
self.verify_connectivity()
- floating_ip = self.add_floating_ip()
- self.verify_connectivity(ip=floating_ip)
+ if CONF.compute.ssh_connect_method == 'floating':
+ floating_ip = self.add_floating_ip()
+ self.verify_connectivity(ip=floating_ip)
vm_client = self.get_remote_client(self.instance)
diff --git a/tempest/scenario/test_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 5aec01f..eb018eb 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import HTMLParser
-import urllib
-import urllib2
+from six.moves import html_parser as HTMLParser
+from six.moves.urllib import parse
+from six.moves.urllib import request
from tempest import config
from tempest.scenario import manager
@@ -68,11 +68,11 @@
super(TestDashboardBasicOps, cls).setup_credentials()
def check_login_page(self):
- response = urllib2.urlopen(CONF.dashboard.dashboard_url)
+ response = request.urlopen(CONF.dashboard.dashboard_url)
self.assertIn("id_username", response.read())
def user_login(self, username, password):
- self.opener = urllib2.build_opener(urllib2.HTTPCookieProcessor())
+ self.opener = request.build_opener(request.HTTPCookieProcessor())
response = self.opener.open(CONF.dashboard.dashboard_url).read()
# Grab the CSRF token and default region
@@ -80,14 +80,14 @@
parser.feed(response)
# Prepare login form request
- req = urllib2.Request(CONF.dashboard.login_url)
+ req = request.Request(CONF.dashboard.login_url)
req.add_header('Content-type', 'application/x-www-form-urlencoded')
req.add_header('Referer', CONF.dashboard.dashboard_url)
params = {'username': username,
'password': password,
'region': parser.region,
'csrfmiddlewaretoken': parser.csrf_token}
- self.opener.open(req, urllib.urlencode(params))
+ self.opener.open(req, parse.urlencode(params))
def check_home_page(self):
response = self.opener.open(CONF.dashboard.dashboard_url)
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 8f37d74..691c7c9 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -16,7 +16,9 @@
import tempfile
import time
-import urllib2
+
+import six
+from six.moves.urllib import request as urllib2
from tempest.common import commands
from tempest import config
@@ -158,7 +160,7 @@
1. SSH to the instance
2. Start two http backends listening on ports 80 and 88 respectively
"""
- for server_id, ip in self.server_ips.iteritems():
+ for server_id, ip in six.iteritems(self.server_ips):
private_key = self.servers_keypairs[server_id]['private_key']
server_name = self.servers_client.get_server(server_id)['name']
username = config.scenario.ssh_user
@@ -238,7 +240,7 @@
but with different ports to listen on.
"""
- for server_id, ip in self.server_fixed_ips.iteritems():
+ for server_id, ip in six.iteritems(self.server_fixed_ips):
if len(self.server_fixed_ips) == 1:
member1 = self._create_member(address=ip,
protocol_port=self.port1,
@@ -307,7 +309,7 @@
except urllib2.HTTPError:
continue
# Assert that each member of the pool gets balanced at least once
- for member, counter in counters.iteritems():
+ for member, counter in six.iteritems(counters):
self.assertGreater(counter, 0, 'Member %s never balanced' % member)
@test.idempotent_id('c0c6f1ca-603b-4509-9c0f-2c63f0d838ee')
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index b97ad0b..3274ce8 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -407,7 +407,6 @@
@test.idempotent_id('1546850e-fbaa-42f5-8b5f-03d8a6a95f15')
@testtools.skipIf(CONF.baremetal.driver_enabled,
'Baremetal relies on a shared physical network.')
- @test.attr(type='smoke')
@test.services('compute', 'network')
def test_connectivity_between_vms_on_different_networks(self):
"""
@@ -456,7 +455,6 @@
@testtools.skipIf(CONF.network.port_vnic_type in ['direct', 'macvtap'],
'NIC hotplug not supported for '
'vnic_type direct or macvtap')
- @test.attr(type='smoke')
@test.services('compute', 'network')
def test_hotplug_nic(self):
"""
@@ -477,7 +475,6 @@
@testtools.skipIf(CONF.baremetal.driver_enabled,
'Router state cannot be altered on a shared baremetal '
'network')
- @test.attr(type='smoke')
@test.services('compute', 'network')
def test_update_router_admin_state(self):
"""
@@ -510,7 +507,6 @@
'network isolation not available for baremetal nodes')
@testtools.skipUnless(CONF.scenario.dhcp_client,
"DHCP client is not available.")
- @test.attr(type='smoke')
@test.services('compute', 'network')
def test_subnet_details(self):
"""Tests that subnet's extra configuration details are affecting
@@ -593,7 +589,6 @@
@testtools.skipUnless(CONF.network_feature_enabled.port_admin_state_change,
"Changing a port's admin state is not supported "
"by the test environment")
- @test.attr(type='smoke')
@test.services('compute', 'network')
def test_update_instance_port_admin_state(self):
"""
@@ -625,7 +620,6 @@
@testtools.skipUnless(CONF.compute_feature_enabled.preserve_ports,
'Preserving ports on instance delete may not be '
'supported in the version of Nova being tested.')
- @test.attr(type='smoke')
@test.services('compute', 'network')
def test_preserve_preexisting_port(self):
"""Tests that a pre-existing port provided on server boot is not
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 16ff848..6e67c4b 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -16,6 +16,7 @@
import netaddr
from oslo_log import log as logging
+import six
from tempest import config
from tempest.scenario import manager
@@ -93,7 +94,7 @@
@staticmethod
def define_server_ips(srv):
- for net_name, nics in srv['addresses'].iteritems():
+ for net_name, nics in six.iteritems(srv['addresses']):
for nic in nics:
if nic['version'] == 6:
srv['accessIPv6'] = nic['addr']
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 37d4844..8ec10c7 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -437,7 +437,6 @@
subnet_id = tenant.subnet.id
self.assertIn((subnet_id, server_ip, mac_addr), port_detail_list)
- @test.attr(type='smoke')
@test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
@test.services('compute', 'network')
def test_cross_tenant_traffic(self):
@@ -459,7 +458,6 @@
self._log_console_output(servers=tenant.servers)
raise
- @test.attr(type='smoke')
@test.idempotent_id('63163892-bbf6-4249-aa12-d5ea1f8f421b')
@test.services('compute', 'network')
def test_in_tenant_traffic(self):
@@ -474,7 +472,6 @@
self._log_console_output(servers=tenant.servers)
raise
- @test.attr(type='smoke')
@test.idempotent_id('f4d556d7-1526-42ad-bafb-6bebf48568f6')
@test.services('compute', 'network')
def test_port_update_new_security_group(self):
@@ -526,7 +523,6 @@
self._log_console_output(servers=tenant.servers)
raise
- @test.attr(type='smoke')
@test.idempotent_id('d2f77418-fcc4-439d-b935-72eca704e293')
@test.services('compute', 'network')
def test_multiple_security_groups(self):
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index e093f43..b795775 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -56,7 +56,7 @@
image=self.image_ref, flavor=self.flavor_ref
)
)
- self.run_ssh = CONF.compute.run_ssh and \
+ self.run_ssh = CONF.validation.run_validation and \
self.image_utils.is_sshable_image(self.image_ref)
self.ssh_user = self.image_utils.ssh_user(self.image_ref)
LOG.debug('Starting test for i:{image}, f:{flavor}. '
@@ -95,6 +95,7 @@
private_key=self.keypair['private_key'])
@test.idempotent_id('7fff3fb3-91d8-4fd0-bd7d-0204f1f180ba')
+ @test.attr(type='smoke')
@test.services('compute', 'network')
def test_server_basicops(self):
self.add_keypair()
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 5bc24ea..177697b 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -73,11 +73,9 @@
volume_id=vol_id,
force=True,
display_name=snap_name)
- self.addCleanup_with_wait(
- waiter_callable=self.snapshots_client.wait_for_resource_deletion,
- thing_id=snap['id'], thing_id_param='id',
- cleanup_callable=self.delete_wrapper,
- cleanup_args=[self.snapshots_client.delete_snapshot, snap['id']])
+ self.addCleanup(
+ self.snapshots_client.wait_for_resource_deletion, snap['id'])
+ self.addCleanup(self.snapshots_client.delete_snapshot, snap['id'])
self.snapshots_client.wait_for_snapshot_status(snap['id'], 'available')
self.assertEqual(snap_name, snap['display_name'])
return snap
@@ -134,6 +132,7 @@
self.assertEqual(expected, actual)
@test.idempotent_id('557cd2c2-4eb8-4dce-98be-f86765ff311b')
+ @test.attr(type='smoke')
@test.services('compute', 'volume', 'image')
def test_volume_boot_pattern(self):
keypair = self.create_keypair()
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index 6c00d09..e5613d6 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -23,7 +23,7 @@
import testtools
from tempest import clients
-from tempest.common import cred_provider
+from tempest.common import credentials
from tempest import config
from tempest import exceptions
@@ -41,7 +41,17 @@
self.non_ssh_image_pattern = \
CONF.input_scenario.non_ssh_image_regex
# Setup clients
- os = clients.Manager()
+ network_resources = {
+ 'network': False,
+ 'router': False,
+ 'subnet': False,
+ 'dhcp': False,
+ }
+ self.isolated_creds = credentials.get_isolated_credentials(
+ name='ScenarioImageUtils',
+ identity_version=CONF.identity.auth_version,
+ network_resources=network_resources)
+ os = clients.Manager(self.isolated_creds.get_primary_creds())
self.images_client = os.images_client
self.flavors_client = os.flavors_client
@@ -100,8 +110,17 @@
digit=string.digits)
def __init__(self):
- os = clients.Manager(
- cred_provider.get_configured_credentials('user', fill_in=False))
+ network_resources = {
+ 'network': False,
+ 'router': False,
+ 'subnet': False,
+ 'dhcp': False,
+ }
+ self.isolated_creds = credentials.get_isolated_credentials(
+ name='InputScenarioUtils',
+ identity_version=CONF.identity.auth_version,
+ network_resources=network_resources)
+ os = clients.Manager(self.isolated_creds.get_primary_creds())
self.images_client = os.images_client
self.flavors_client = os.flavors_client
self.image_pattern = CONF.input_scenario.image_regex
@@ -162,7 +181,7 @@
scenario_utils = InputScenarioUtils()
scenario_flavor = scenario_utils.scenario_flavors
scenario_image = scenario_utils.scenario_images
- except exceptions.InvalidConfiguration:
+ except (exceptions.InvalidConfiguration, TypeError):
return standard_tests
for test in testtools.iterate_tests(standard_tests):
setattr(test, 'scenarios', testscenarios.multiply_scenarios(
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index 4c6a5bf..1461198 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -12,9 +12,9 @@
import functools
import json
-import urllib
import six
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index 403437d..c69e483 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -13,7 +13,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import agents as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/baremetal_nodes_client.py b/tempest/services/compute/json/baremetal_nodes_client.py
index e4a4e88..fa2d7f4 100644
--- a/tempest/services/compute/json/baremetal_nodes_client.py
+++ b/tempest/services/compute/json/baremetal_nodes_client.py
@@ -13,7 +13,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute import baremetal_nodes as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 2de43cf..80cbe4d 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -14,7 +14,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute import flavors_access as schema_access
from tempest.api_schema.response.compute import flavors_extra_specs \
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 5bad527..9568a5e 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -14,8 +14,8 @@
# under the License.
import json
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index 088e695..287482f 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -13,7 +13,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import hosts as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 1223fef..5462efc 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -14,8 +14,8 @@
# under the License.
import json
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import images as schema
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index a65b655..009992c 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -13,7 +13,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute import migrations as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index d8c8d63..2855e13 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -14,8 +14,8 @@
# under the License.
import json
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import security_groups as schema
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index c9ba2c3..1af1b37 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -16,8 +16,8 @@
import json
import time
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import servers as schema
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index fc2274d..e2d959b 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -15,7 +15,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute import services as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index ff6e7a2..b7e2b2a 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -14,7 +14,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import tenant_usages as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index ba5921e..4d7a7aa 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -15,8 +15,8 @@
import json
import time
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import volumes as schema
diff --git a/tempest/services/database/json/limits_client.py b/tempest/services/database/json/limits_client.py
index ae758bc..f99ceaa 100644
--- a/tempest/services/database/json/limits_client.py
+++ b/tempest/services/database/json/limits_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import urllib
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index aa2fef7..0db9c6a 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import urllib
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/identity/v2/json/token_client.py b/tempest/services/identity/v2/json/token_client.py
deleted file mode 100644
index e61ac84..0000000
--- a/tempest/services/identity/v2/json/token_client.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright 2015 NEC Corporation. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import json
-from tempest_lib.common import rest_client
-from tempest_lib import exceptions as lib_exc
-
-from tempest.common import service_client
-from tempest import exceptions
-
-
-class TokenClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_url, disable_ssl_certificate_validation=None,
- ca_certs=None, trace_requests=None):
- dscv = disable_ssl_certificate_validation
- super(TokenClientJSON, self).__init__(
- None, None, None, disable_ssl_certificate_validation=dscv,
- ca_certs=ca_certs, trace_requests=trace_requests)
-
- # Normalize URI to ensure /tokens is in it.
- if 'tokens' not in auth_url:
- auth_url = auth_url.rstrip('/') + '/tokens'
-
- self.auth_url = auth_url
-
- def auth(self, user, password, tenant=None):
- creds = {
- 'auth': {
- 'passwordCredentials': {
- 'username': user,
- 'password': password,
- },
- }
- }
-
- if tenant:
- creds['auth']['tenantName'] = tenant
-
- body = json.dumps(creds)
- resp, body = self.post(self.auth_url, body=body)
- self.expected_success(200, resp.status)
-
- return service_client.ResponseBody(resp, body['access'])
-
- def auth_token(self, token_id, tenant=None):
- creds = {
- 'auth': {
- 'token': {
- 'id': token_id,
- },
- }
- }
-
- if tenant:
- creds['auth']['tenantName'] = tenant
-
- body = json.dumps(creds)
- resp, body = self.post(self.auth_url, body=body)
- self.expected_success(200, resp.status)
-
- return service_client.ResponseBody(resp, body['access'])
-
- def request(self, method, url, extra_headers=False, headers=None,
- body=None):
- """A simple HTTP request interface."""
- if headers is None:
- headers = self.get_headers(accept_type="json")
- elif extra_headers:
- try:
- headers.update(self.get_headers(accept_type="json"))
- except (ValueError, TypeError):
- headers = self.get_headers(accept_type="json")
-
- resp, resp_body = self.raw_request(url, method,
- headers=headers, body=body)
- self._log_request(method, url, resp)
-
- if resp.status in [401, 403]:
- resp_body = json.loads(resp_body)
- raise lib_exc.Unauthorized(resp_body['error']['message'])
- elif resp.status not in [200, 201]:
- raise exceptions.IdentityError(
- 'Unexpected status code {0}'.format(resp.status))
-
- if isinstance(resp_body, str):
- resp_body = json.loads(resp_body)
- return resp, resp_body
-
- def get_token(self, user, password, tenant, auth_data=False):
- """
- Returns (token id, token data) for supplied credentials
- """
- body = self.auth(user, password, tenant)
-
- if auth_data:
- return body['token']['id'], body
- else:
- return body['token']['id']
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index bc90fd1..f3d02a8 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -14,7 +14,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/region_client.py b/tempest/services/identity/v3/json/region_client.py
index faaf43c..02df354 100644
--- a/tempest/services/identity/v3/json/region_client.py
+++ b/tempest/services/identity/v3/json/region_client.py
@@ -14,7 +14,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/token_client.py b/tempest/services/identity/v3/json/token_client.py
deleted file mode 100644
index 3e37403..0000000
--- a/tempest/services/identity/v3/json/token_client.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright 2015 NEC Corporation. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import json
-from tempest_lib.common import rest_client
-from tempest_lib import exceptions as lib_exc
-
-from tempest.common import service_client
-from tempest import exceptions
-
-
-class V3TokenClientJSON(rest_client.RestClient):
-
- def __init__(self, auth_url, disable_ssl_certificate_validation=None,
- ca_certs=None, trace_requests=None):
- dscv = disable_ssl_certificate_validation
- super(V3TokenClientJSON, self).__init__(
- None, None, None, disable_ssl_certificate_validation=dscv,
- ca_certs=ca_certs, trace_requests=trace_requests)
- if not auth_url:
- raise exceptions.InvalidConfiguration('you must specify a v3 uri '
- 'if using the v3 identity '
- 'api')
- if 'auth/tokens' not in auth_url:
- auth_url = auth_url.rstrip('/') + '/auth/tokens'
-
- self.auth_url = auth_url
-
- def auth(self, user_id=None, username=None, password=None, project_id=None,
- project_name=None, user_domain_id=None, user_domain_name=None,
- project_domain_id=None, project_domain_name=None, domain_id=None,
- domain_name=None, token=None):
- """
- :param user_id: user id
- :param username: user name
- :param user_domain_id: the user domain id
- :param user_domain_name: the user domain name
- :param project_domain_id: the project domain id
- :param project_domain_name: the project domain name
- :param domain_id: a domain id to scope to
- :param domain_name: a domain name to scope to
- :param project_id: a project id to scope to
- :param project_name: a project name to scope to
- :param token: a token to re-scope.
-
- Accepts different combinations of credentials.
- Sample sample valid combinations:
- - token
- - token, project_name, project_domain_id
- - user_id, password
- - username, password, user_domain_id
- - username, password, project_name, user_domain_id, project_domain_id
- Validation is left to the server side.
- """
- creds = {
- 'auth': {
- 'identity': {
- 'methods': [],
- }
- }
- }
- id_obj = creds['auth']['identity']
- if token:
- id_obj['methods'].append('token')
- id_obj['token'] = {
- 'id': token
- }
-
- if (user_id or username) and password:
- id_obj['methods'].append('password')
- id_obj['password'] = {
- 'user': {
- 'password': password,
- }
- }
- if user_id:
- id_obj['password']['user']['id'] = user_id
- else:
- id_obj['password']['user']['name'] = username
-
- _domain = None
- if user_domain_id is not None:
- _domain = dict(id=user_domain_id)
- elif user_domain_name is not None:
- _domain = dict(name=user_domain_name)
- if _domain:
- id_obj['password']['user']['domain'] = _domain
-
- if (project_id or project_name):
- _project = dict()
-
- if project_id:
- _project['id'] = project_id
- elif project_name:
- _project['name'] = project_name
-
- if project_domain_id is not None:
- _project['domain'] = {'id': project_domain_id}
- elif project_domain_name is not None:
- _project['domain'] = {'name': project_domain_name}
-
- creds['auth']['scope'] = dict(project=_project)
- elif domain_id:
- creds['auth']['scope'] = dict(domain={'id': domain_id})
- elif domain_name:
- creds['auth']['scope'] = dict(domain={'name': domain_name})
-
- body = json.dumps(creds)
- resp, body = self.post(self.auth_url, body=body)
- self.expected_success(201, resp.status)
- return service_client.ResponseBody(resp, body)
-
- def request(self, method, url, extra_headers=False, headers=None,
- body=None):
- """A simple HTTP request interface."""
- if headers is None:
- # Always accept 'json', for xml token client too.
- # Because XML response is not easily
- # converted to the corresponding JSON one
- headers = self.get_headers(accept_type="json")
- elif extra_headers:
- try:
- headers.update(self.get_headers(accept_type="json"))
- except (ValueError, TypeError):
- headers = self.get_headers(accept_type="json")
-
- resp, resp_body = self.raw_request(url, method,
- headers=headers, body=body)
- self._log_request(method, url, resp)
-
- if resp.status in [401, 403]:
- resp_body = json.loads(resp_body)
- raise lib_exc.Unauthorized(resp_body['error']['message'])
- elif resp.status not in [200, 201, 204]:
- raise exceptions.IdentityError(
- 'Unexpected status code {0}'.format(resp.status))
-
- return resp, json.loads(resp_body)
-
- def get_token(self, **kwargs):
- """
- Returns (token id, token data) for supplied credentials
- """
-
- auth_data = kwargs.pop('auth_data', False)
-
- if not (kwargs.get('user_domain_id') or
- kwargs.get('user_domain_name')):
- kwargs['user_domain_name'] = 'Default'
-
- if not (kwargs.get('project_domain_id') or
- kwargs.get('project_domain_name')):
- kwargs['project_domain_name'] = 'Default'
-
- body = self.auth(**kwargs)
-
- token = body.response.get('x-subject-token')
- if auth_data:
- return token, body['token']
- else:
- return token
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index ec7900b..5e442fa 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -18,9 +18,10 @@
import json
import os
import time
-import urllib
from oslo_log import log as logging
+import six
+from six.moves.urllib import parse as urllib
from tempest_lib.common.utils import misc as misc_utils
from tempest_lib import exceptions as lib_exc
@@ -54,7 +55,7 @@
def _image_meta_from_headers(self, headers):
meta = {'properties': {}}
- for key, value in headers.iteritems():
+ for key, value in six.iteritems(headers):
if key.startswith('x-image-meta-property-'):
_key = key[22:]
meta['properties'][_key] = value
@@ -80,11 +81,11 @@
copy_from = fields_copy.pop('copy_from', None)
if copy_from is not None:
headers['x-glance-api-copy-from'] = copy_from
- for key, value in fields_copy.pop('properties', {}).iteritems():
+ for key, value in six.iteritems(fields_copy.pop('properties', {})):
headers['x-image-meta-property-%s' % key] = str(value)
- for key, value in fields_copy.pop('api', {}).iteritems():
+ for key, value in six.iteritems(fields_copy.pop('api', {})):
headers['x-glance-api-property-%s' % key] = str(value)
- for key, value in fields_copy.iteritems():
+ for key, value in six.iteritems(fields_copy):
headers['x-image-meta-%s' % key] = str(value)
return headers
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 6b04144..aff8e85 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -14,9 +14,9 @@
# under the License.
import json
-import urllib
import jsonschema
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.common import glance_http
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
index 483ba93..5f6c32a 100644
--- a/tempest/services/messaging/json/messaging_client.py
+++ b/tempest/services/messaging/json/messaging_client.py
@@ -14,9 +14,10 @@
# limitations under the License.
import json
-import urllib
import uuid
+from six.moves.urllib import parse as urllib
+
from tempest.api_schema.response.messaging.v1 import queues as queues_schema
from tempest.common import service_client
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 53645a5..e93cc47 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -12,8 +12,8 @@
import json
import time
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib.common.utils import misc
from tempest_lib import exceptions as lib_exc
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index af00eff..dece763 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -14,9 +14,10 @@
# under the License.
import json
-import urllib
from xml.etree import ElementTree as etree
+from six.moves.urllib import parse as urllib
+
from tempest.common import service_client
diff --git a/tempest/services/object_storage/container_client.py b/tempest/services/object_storage/container_client.py
index ed74de4..8e225b0 100644
--- a/tempest/services/object_storage/container_client.py
+++ b/tempest/services/object_storage/container_client.py
@@ -14,9 +14,10 @@
# under the License.
import json
-import urllib
from xml.etree import ElementTree as etree
+from six.moves.urllib import parse as urllib
+
from tempest.common import service_client
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index 3466c8a..2265587 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import urllib
-
+import six
from six.moves import http_client as httplib
from six.moves.urllib import parse as urlparse
@@ -36,7 +35,7 @@
headers[str(key)] = metadata[key]
url = "%s/%s" % (str(container), str(object_name))
if params:
- url += '?%s' % urllib.urlencode(params)
+ url += '?%s' % urlparse.urlencode(params)
resp, body = self.put(url, data, headers)
self.expected_success(201, resp.status)
@@ -52,7 +51,7 @@
"""Delete storage object."""
url = "%s/%s" % (str(container), str(object_name))
if params:
- url += '?%s' % urllib.urlencode(params)
+ url += '?%s' % urlparse.urlencode(params)
resp, body = self.delete(url, headers={})
self.expected_success([200, 204], resp.status)
return resp, body
@@ -234,7 +233,7 @@
headers = {}
if hasattr(contents, 'read'):
conn.putrequest('PUT', path)
- for header, value in headers.iteritems():
+ for header, value in six.iteritems(headers):
conn.putheader(header, value)
if 'Content-Length' not in headers:
if 'Transfer-Encoding' not in headers:
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index debf39b..4d443d3 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -16,8 +16,8 @@
import json
import re
import time
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.common import service_client
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 0c01908..554f574 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -13,9 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import urllib
-
from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/volume/json/admin/volume_hosts_client.py b/tempest/services/volume/json/admin/volume_hosts_client.py
index 1cd92b7..1dfabaf 100644
--- a/tempest/services/volume/json/admin/volume_hosts_client.py
+++ b/tempest/services/volume/json/admin/volume_hosts_client.py
@@ -14,7 +14,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index 5092afc..cbab3f0 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -12,9 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import urllib
-
from oslo_serialization import jsonutils
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/volume/json/admin/volume_services_client.py b/tempest/services/volume/json/admin/volume_services_client.py
index 1c4433f..94792e0 100644
--- a/tempest/services/volume/json/admin/volume_services_client.py
+++ b/tempest/services/volume/json/admin/volume_services_client.py
@@ -14,7 +14,8 @@
# under the License.
import json
-import urllib
+
+from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index 9366984..2436d88 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -14,8 +14,8 @@
# under the License.
import json
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.common import service_client
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index 2140c62..cfa02bd 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -12,9 +12,9 @@
import json
import time
-import urllib
from oslo_log import log as logging
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.common import service_client
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index a82291a..9a08bbd 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -15,8 +15,8 @@
import json
import time
-import urllib
+from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.common import service_client
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 62e60d6..3f8e537 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -19,12 +19,13 @@
from oslo_log import log as logging
from oslo_utils import importutils
+import six
from six import moves
+from tempest_lib.common import ssh
from tempest_lib.common.utils import data_utils
from tempest import clients
from tempest.common import isolated_creds
-from tempest.common import ssh
from tempest import config
from tempest import exceptions
from tempest.stress import cleanup
@@ -171,7 +172,7 @@
test_run = test_obj(manager, max_runs, stop_on_error)
kwargs = test.get('kwargs', {})
- test_run.setUp(**dict(kwargs.iteritems()))
+ test_run.setUp(**dict(six.iteritems(kwargs)))
LOG.debug("calling Target Object %s" %
test_run.__class__.__name__)
diff --git a/tempest/test.py b/tempest/test.py
index ed8d12c..ab5a353 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -34,6 +34,7 @@
from tempest.common import credentials
from tempest.common import fixed_network
import tempest.common.generator.valid_generator as valid
+import tempest.common.validation_resources as vresources
from tempest import config
from tempest import exceptions
@@ -231,6 +232,8 @@
# NOTE(andreaf) credentials holds a list of the credentials to be allocated
# at class setup time. Credential types can be 'primary', 'alt' or 'admin'
credentials = []
+ # Resources required to validate a server using ssh
+ validation_resources = {}
network_resources = {}
# NOTE(sdague): log_format is defined inline here instead of using the oslo
@@ -264,7 +267,7 @@
etype, cls.__name__))
cls.tearDownClass()
try:
- raise etype, value, trace
+ six.reraise(etype, value, trace)
finally:
del trace # to avoid circular refs
@@ -302,7 +305,7 @@
# the first one
if re_raise and etype is not None:
try:
- raise etype, value, trace
+ six.reraise(etype, value, trace)
finally:
del trace # to avoid circular refs
@@ -367,7 +370,12 @@
def resource_setup(cls):
"""Class level resource setup for test cases.
"""
- pass
+ if hasattr(cls, "os"):
+ cls.validation_resources = vresources.create_validation_resources(
+ cls.os, cls.validation_resources)
+ else:
+ LOG.warn("Client manager not found, validation resources not"
+ " created")
@classmethod
def resource_cleanup(cls):
@@ -375,7 +383,14 @@
Resource cleanup must be able to handle the case of partially setup
resources, in case a failure during `resource_setup` should happen.
"""
- pass
+ if cls.validation_resources:
+ if hasattr(cls, "os"):
+ vresources.clear_validation_resources(cls.os,
+ cls.validation_resources)
+ cls.validation_resources = {}
+ else:
+ LOG.warn("Client manager not found, validation resources not"
+ " deleted")
def setUp(self):
super(BaseTestCase, self).setUp()
@@ -476,10 +491,49 @@
"""
Clears isolated creds if set
"""
- if hasattr(cls, '_cred_provider'):
+ if hasattr(cls, '_creds_provider'):
cls._creds_provider.clear_isolated_creds()
@classmethod
+ def set_validation_resources(cls, keypair=None, floating_ip=None,
+ security_group=None,
+ security_group_rules=None):
+ """Specify which ssh server validation resources should be created.
+ Each of the argument must be set to either None, True or False, with
+ None - use default from config (security groups and security group
+ rules get created when set to None)
+ False - Do not create the validation resource
+ True - create the validation resource
+
+ @param keypair
+ @param security_group
+ @param security_group_rules
+ @param floating_ip
+ """
+ if not CONF.validation.run_validation:
+ return
+ if keypair is None:
+ if CONF.validation.auth_method.lower() == "keypair":
+ keypair = True
+ else:
+ keypair = False
+ if floating_ip is None:
+ if CONF.validation.connect_method.lower() == "floating":
+ floating_ip = True
+ else:
+ floating_ip = False
+ if security_group is None:
+ security_group = True
+ if security_group_rules is None:
+ security_group_rules = True
+ if not cls.validation_resources:
+ cls.validation_resources = {
+ 'keypair': keypair,
+ 'security_group': security_group,
+ 'security_group_rules': security_group_rules,
+ 'floating_ip': floating_ip}
+
+ @classmethod
def set_network_resources(cls, network=False, router=False, subnet=False,
dhcp=False):
"""Specify which network resources should be created
diff --git a/tempest/test_discover/test_discover.py b/tempest/test_discover/test_discover.py
index 3fbb8e1..4a4b43a 100644
--- a/tempest/test_discover/test_discover.py
+++ b/tempest/test_discover/test_discover.py
@@ -25,7 +25,7 @@
suite = unittest.TestSuite()
base_path = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0]
base_path = os.path.split(base_path)[0]
- for test_dir in ['./tempest/api', './tempest/cli', './tempest/scenario',
+ for test_dir in ['./tempest/api', './tempest/scenario',
'./tempest/thirdparty']:
if not pattern:
suite.addTests(loader.discover(test_dir, top_level_dir=base_path))
diff --git a/tempest/tests/cli/__init__.py b/tempest/tests/cli/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/tests/cli/__init__.py
+++ /dev/null
diff --git a/tempest/tests/cli/test_cli.py b/tempest/tests/cli/test_cli.py
deleted file mode 100644
index 8f18dfc..0000000
--- a/tempest/tests/cli/test_cli.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2014 IBM Corp.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import mock
-from tempest_lib.cli import base as cli_base
-import testtools
-
-from tempest import cli
-from tempest import config
-from tempest import exceptions
-from tempest.tests import base
-from tempest.tests import fake_config
-
-
-class TestMinClientVersion(base.TestCase):
- """Tests for the min_client_version decorator.
- """
-
- def setUp(self):
- super(TestMinClientVersion, self).setUp()
- self.useFixture(fake_config.ConfigFixture())
- self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
-
- def _test_min_version(self, required, installed, expect_skip):
-
- @cli.min_client_version(client='nova', version=required)
- def fake(self, expect_skip):
- if expect_skip:
- # If we got here, the decorator didn't raise a skipException as
- # expected so we need to fail.
- self.fail('Should not have gotten past the decorator.')
-
- with mock.patch.object(cli_base, 'execute',
- return_value=installed) as mock_cmd:
- if expect_skip:
- self.assertRaises(testtools.TestCase.skipException, fake,
- self, expect_skip)
- else:
- fake(self, expect_skip)
- mock_cmd.assert_called_once_with('nova', '', params='--version',
- cli_dir='/usr/local/bin',
- merge_stderr=True)
-
- def test_min_client_version(self):
- # required, installed, expect_skip
- cases = (('2.17.0', '2.17.0', False),
- ('2.17.0', '2.18.0', False),
- ('2.18.0', '2.17.0', True))
-
- for case in cases:
- self._test_min_version(*case)
-
- @mock.patch.object(cli_base, 'execute', return_value=' ')
- def test_check_client_version_empty_output(self, mock_execute):
- # Tests that an exception is raised if the command output is empty.
- self.assertRaises(exceptions.TempestException,
- cli.check_client_version, 'nova', '2.18.0')
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index b4048ba..596e811 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -20,13 +20,14 @@
from oslo_concurrency import lockutils
from oslo_config import cfg
from oslotest import mockpatch
+import six
+from tempest_lib import auth
+from tempest_lib.services.identity.v2 import token_client
-from tempest import auth
from tempest.common import accounts
from tempest.common import cred_provider
from tempest import config
from tempest import exceptions
-from tempest.services.identity.v2.json import token_client
from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests import fake_http
@@ -79,7 +80,7 @@
hash_list = []
for account in accounts_list:
hash = hashlib.md5()
- hash.update(str(account))
+ hash.update(six.text_type(account).encode('utf-8'))
temp_hash = hash.hexdigest()
hash_list.append(temp_hash)
return hash_list
@@ -106,7 +107,8 @@
def test_create_hash_file_previous_file(self):
# Emulate the lock existing on the filesystem
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
- with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+ with mock.patch('six.moves.builtins.open', mock.mock_open(),
+ create=True):
test_account_class = accounts.Accounts('v2', 'test_name')
res = test_account_class._create_hash_file('12345')
self.assertFalse(res, "_create_hash_file should return False if the "
@@ -115,7 +117,8 @@
def test_create_hash_file_no_previous_file(self):
# Emulate the lock not existing on the filesystem
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
- with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+ with mock.patch('six.moves.builtins.open', mock.mock_open(),
+ create=True):
test_account_class = accounts.Accounts('v2', 'test_name')
res = test_account_class._create_hash_file('12345')
self.assertTrue(res, "_create_hash_file should return True if the "
@@ -129,7 +132,7 @@
mkdir_mock = self.useFixture(mockpatch.Patch('os.mkdir'))
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
test_account_class = accounts.Accounts('v2', 'test_name')
- with mock.patch('__builtin__.open', mock.mock_open(),
+ with mock.patch('six.moves.builtins.open', mock.mock_open(),
create=True) as open_mock:
test_account_class._get_free_hash(hash_list)
lock_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
@@ -148,7 +151,8 @@
# Emulate all lcoks in list are in use
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
test_account_class = accounts.Accounts('v2', 'test_name')
- with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+ with mock.patch('six.moves.builtins.open', mock.mock_open(),
+ create=True):
self.assertRaises(exceptions.InvalidConfiguration,
test_account_class._get_free_hash, hash_list)
@@ -167,7 +171,7 @@
return True
self.stubs.Set(os.path, 'isfile', _fake_is_file)
- with mock.patch('__builtin__.open', mock.mock_open(),
+ with mock.patch('six.moves.builtins.open', mock.mock_open(),
create=True) as open_mock:
test_account_class._get_free_hash(hash_list)
lock_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
@@ -265,7 +269,7 @@
'tempest.common.accounts.read_accounts_yaml',
return_value=self.test_accounts))
test_accounts_class = accounts.Accounts('v2', 'test_name')
- hashes = test_accounts_class.hash_dict['creds'].keys()
+ hashes = list(test_accounts_class.hash_dict['creds'].keys())
admin_hashes = test_accounts_class.hash_dict['roles'][
cfg.CONF.identity.admin_role]
temp_hash = hashes[0]
diff --git a/tempest/tests/common/test_admin_available.py b/tempest/tests/common/test_admin_available.py
index 4e3aa4c..5c69c5e 100644
--- a/tempest/tests/common/test_admin_available.py
+++ b/tempest/tests/common/test_admin_available.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo.config import cfg
+from oslo_config import cfg
from oslotest import mockpatch
from tempest.common import credentials
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
index 76430ac..ed3f931 100644
--- a/tempest/tests/common/test_cred_provider.py
+++ b/tempest/tests/common/test_cred_provider.py
@@ -13,21 +13,21 @@
# under the License.
from oslo_config import cfg
+from tempest_lib import auth
+from tempest_lib import exceptions as lib_exc
+from tempest_lib.services.identity.v2 import token_client as v2_client
+from tempest_lib.services.identity.v3 import token_client as v3_client
-from tempest import auth
+
from tempest.common import cred_provider
from tempest.common import tempest_fixtures as fixtures
from tempest import config
-from tempest.services.identity.v2.json import token_client as v2_client
-from tempest.services.identity.v3.json import token_client as v3_client
+from tempest.tests import base
from tempest.tests import fake_config
from tempest.tests import fake_identity
-# Note(andreaf): once credentials tests move to tempest-lib, I will copy the
-# parts of them required by these here.
-from tempest.tests import test_credentials as test_creds
-class ConfiguredV2CredentialsTests(test_creds.CredentialsTests):
+class ConfiguredV2CredentialsTests(base.TestCase):
attributes = {
'username': 'fake_username',
'password': 'fake_password',
@@ -46,6 +46,23 @@
self.stubs.Set(self.tokenclient_class, 'raw_request',
self.identity_response)
+ def _get_credentials(self, attributes=None):
+ if attributes is None:
+ attributes = self.attributes
+ return self.credentials_class(**attributes)
+
+ def _check(self, credentials, credentials_class, filled):
+ # Check the right version of credentials has been returned
+ self.assertIsInstance(credentials, credentials_class)
+ # Check the id attributes are filled in
+ attributes = [x for x in credentials.ATTRIBUTES if (
+ '_id' in x and x != 'domain_id')]
+ for attr in attributes:
+ if filled:
+ self.assertIsNotNone(getattr(credentials, attr))
+ else:
+ self.assertIsNone(getattr(credentials, attr))
+
def _verify_credentials(self, credentials_class, filled=True,
identity_version=None):
for ctype in cred_provider.CREDENTIAL_TYPES:
@@ -58,6 +75,15 @@
identity_version=identity_version)
self._check(creds, credentials_class, filled)
+ def test_create(self):
+ creds = self._get_credentials()
+ self.assertEqual(self.attributes, creds._initial)
+
+ def test_create_invalid_attr(self):
+ self.assertRaises(lib_exc.InvalidCredentials,
+ self._get_credentials,
+ attributes=dict(invalid='fake'))
+
def test_get_configured_credentials(self):
self.useFixture(fixtures.LockFixture('auth_version'))
self._verify_credentials(credentials_class=self.credentials_class)
diff --git a/tempest/tests/common/utils/test_file_utils.py b/tempest/tests/common/utils/test_file_utils.py
index 605e82a..937aefa 100644
--- a/tempest/tests/common/utils/test_file_utils.py
+++ b/tempest/tests/common/utils/test_file_utils.py
@@ -22,7 +22,8 @@
class TestFileUtils(base.TestCase):
def test_have_effective_read_path(self):
- with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+ with mock.patch('six.moves.builtins.open', mock.mock_open(),
+ create=True):
result = file_utils.have_effective_read_access('fake_path')
self.assertTrue(result)
diff --git a/tempest/tests/fake_credentials.py b/tempest/tests/fake_credentials.py
deleted file mode 100644
index 649d51d..0000000
--- a/tempest/tests/fake_credentials.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-# 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 import auth
-
-
-class FakeCredentials(auth.Credentials):
-
- def is_valid(self):
- return True
-
-
-class FakeKeystoneV2Credentials(auth.KeystoneV2Credentials):
-
- def __init__(self):
- creds = dict(
- username='fake_username',
- password='fake_password',
- tenant_name='fake_tenant_name'
- )
- super(FakeKeystoneV2Credentials, self).__init__(**creds)
-
-
-class FakeKeystoneV3Credentials(auth.KeystoneV3Credentials):
- """
- Fake credentials suitable for the Keystone Identity V3 API
- """
-
- def __init__(self):
- creds = dict(
- username='fake_username',
- password='fake_password',
- user_domain_name='fake_domain_name',
- project_name='fake_tenant_name',
- project_domain_name='fake_domain_name'
- )
- super(FakeKeystoneV3Credentials, self).__init__(**creds)
-
-
-class FakeKeystoneV3DomainCredentials(auth.KeystoneV3Credentials):
- """
- Fake credentials suitable for the Keystone Identity V3 API, with no scope
- """
-
- def __init__(self):
- creds = dict(
- username='fake_username',
- password='fake_password',
- user_domain_name='fake_domain_name'
- )
- super(FakeKeystoneV3DomainCredentials, self).__init__(**creds)
diff --git a/tempest/tests/negative/test_negative_generators.py b/tempest/tests/negative/test_negative_generators.py
index 2fa6933..78fd80d 100644
--- a/tempest/tests/negative/test_negative_generators.py
+++ b/tempest/tests/negative/test_negative_generators.py
@@ -17,6 +17,7 @@
import jsonschema
import mock
+import six
from tempest.common.generator import base_generator
from tempest.common.generator import negative_generator
@@ -101,11 +102,11 @@
class fake_test_class(object):
def __init__(self, scenario):
- for k, v in scenario.iteritems():
+ for k, v in six.iteritems(scenario):
setattr(self, k, v)
def _validate_result(self, valid_schema, invalid_schema):
- for k, v in valid_schema.iteritems():
+ for k, v in six.iteritems(valid_schema):
self.assertTrue(k in invalid_schema)
def test_generator_mandatory_functions(self):
diff --git a/tempest/tests/stress/test_stress.py b/tempest/tests/stress/test_stress.py
index 3a7b436..16f1ac7 100644
--- a/tempest/tests/stress/test_stress.py
+++ b/tempest/tests/stress/test_stress.py
@@ -33,7 +33,7 @@
cmd = ' '.join([cmd, param])
LOG.info("running: '%s'" % cmd)
cmd_str = cmd
- cmd = shlex.split(cmd.encode('utf-8'))
+ cmd = shlex.split(cmd)
result = ''
result_err = ''
try:
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
deleted file mode 100644
index eb63b30..0000000
--- a/tempest/tests/test_auth.py
+++ /dev/null
@@ -1,411 +0,0 @@
-# Copyright 2014 IBM Corp.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-import datetime
-
-from oslotest import mockpatch
-
-from tempest import auth
-from tempest import exceptions
-from tempest.services.identity.v2.json import token_client as v2_client
-from tempest.services.identity.v3.json import token_client as v3_client
-from tempest.tests import base
-from tempest.tests import fake_credentials
-from tempest.tests import fake_http
-from tempest.tests import fake_identity
-
-
-def fake_get_credentials(fill_in=True, identity_version='v2', **kwargs):
- return fake_credentials.FakeCredentials()
-
-
-class BaseAuthTestsSetUp(base.TestCase):
- _auth_provider_class = None
- credentials = fake_credentials.FakeCredentials()
-
- def _auth(self, credentials, auth_url, **params):
- """
- returns auth method according to keystone
- """
- return self._auth_provider_class(credentials, auth_url, **params)
-
- def setUp(self):
- super(BaseAuthTestsSetUp, self).setUp()
- self.fake_http = fake_http.fake_httplib2(return_type=200)
- self.stubs.Set(auth, 'get_credentials', fake_get_credentials)
- self.auth_provider = self._auth(self.credentials,
- fake_identity.FAKE_AUTH_URL)
-
-
-class TestBaseAuthProvider(BaseAuthTestsSetUp):
- """
- This tests auth.AuthProvider class which is base for the other so we
- obviously don't test not implemented method or the ones which strongly
- depends on them.
- """
-
- class FakeAuthProviderImpl(auth.AuthProvider):
- def _decorate_request():
- pass
-
- def _fill_credentials():
- pass
-
- def _get_auth():
- pass
-
- def base_url():
- pass
-
- def is_expired():
- pass
-
- _auth_provider_class = FakeAuthProviderImpl
-
- def _auth(self, credentials, auth_url, **params):
- """
- returns auth method according to keystone
- """
- return self._auth_provider_class(credentials, **params)
-
- def test_check_credentials_bad_type(self):
- self.assertFalse(self.auth_provider.check_credentials([]))
-
- def test_auth_data_property_when_cache_exists(self):
- self.auth_provider.cache = 'foo'
- self.useFixture(mockpatch.PatchObject(self.auth_provider,
- 'is_expired',
- return_value=False))
- self.assertEqual('foo', getattr(self.auth_provider, 'auth_data'))
-
- def test_delete_auth_data_property_through_deleter(self):
- self.auth_provider.cache = 'foo'
- del self.auth_provider.auth_data
- self.assertIsNone(self.auth_provider.cache)
-
- def test_delete_auth_data_property_through_clear_auth(self):
- self.auth_provider.cache = 'foo'
- self.auth_provider.clear_auth()
- self.assertIsNone(self.auth_provider.cache)
-
- def test_set_and_reset_alt_auth_data(self):
- self.auth_provider.set_alt_auth_data('foo', 'bar')
- self.assertEqual(self.auth_provider.alt_part, 'foo')
- self.assertEqual(self.auth_provider.alt_auth_data, 'bar')
-
- self.auth_provider.reset_alt_auth_data()
- self.assertIsNone(self.auth_provider.alt_part)
- self.assertIsNone(self.auth_provider.alt_auth_data)
-
- def test_auth_class(self):
- self.assertRaises(TypeError,
- auth.AuthProvider,
- fake_credentials.FakeCredentials)
-
-
-class TestKeystoneV2AuthProvider(BaseAuthTestsSetUp):
- _endpoints = fake_identity.IDENTITY_V2_RESPONSE['access']['serviceCatalog']
- _auth_provider_class = auth.KeystoneV2AuthProvider
- credentials = fake_credentials.FakeKeystoneV2Credentials()
-
- def setUp(self):
- super(TestKeystoneV2AuthProvider, self).setUp()
- self.stubs.Set(v2_client.TokenClientJSON, 'raw_request',
- fake_identity._fake_v2_response)
- self.target_url = 'test_api'
-
- def _get_fake_alt_identity(self):
- return fake_identity.ALT_IDENTITY_V2_RESPONSE['access']
-
- def _get_result_url_from_endpoint(self, ep, endpoint_type='publicURL',
- replacement=None):
- if replacement:
- return ep[endpoint_type].replace('v2', replacement)
- return ep[endpoint_type]
-
- def _get_token_from_fake_identity(self):
- return fake_identity.TOKEN
-
- def _get_from_fake_identity(self, attr):
- access = fake_identity.IDENTITY_V2_RESPONSE['access']
- if attr == 'user_id':
- return access['user']['id']
- elif attr == 'tenant_id':
- return access['token']['tenant']['id']
-
- def _test_request_helper(self, filters, expected):
- url, headers, body = self.auth_provider.auth_request('GET',
- self.target_url,
- filters=filters)
-
- self.assertEqual(expected['url'], url)
- self.assertEqual(expected['token'], headers['X-Auth-Token'])
- self.assertEqual(expected['body'], body)
-
- def _auth_data_with_expiry(self, date_as_string):
- token, access = self.auth_provider.auth_data
- access['token']['expires'] = date_as_string
- return token, access
-
- def test_request(self):
- filters = {
- 'service': 'compute',
- 'endpoint_type': 'publicURL',
- 'region': 'FakeRegion'
- }
-
- url = self._get_result_url_from_endpoint(
- self._endpoints[0]['endpoints'][1]) + '/' + self.target_url
-
- expected = {
- 'body': None,
- 'url': url,
- 'token': self._get_token_from_fake_identity(),
- }
- self._test_request_helper(filters, expected)
-
- def test_request_with_alt_auth_cleans_alt(self):
- self.auth_provider.set_alt_auth_data(
- 'body',
- (fake_identity.ALT_TOKEN, self._get_fake_alt_identity()))
- self.test_request()
- # Assert alt auth data is clear after it
- self.assertIsNone(self.auth_provider.alt_part)
- self.assertIsNone(self.auth_provider.alt_auth_data)
-
- def test_request_with_alt_part_without_alt_data(self):
- """
- Assert that when alt_part is defined, the corresponding original
- request element is kept the same.
- """
- filters = {
- 'service': 'compute',
- 'endpoint_type': 'publicURL',
- 'region': 'fakeRegion'
- }
- self.auth_provider.set_alt_auth_data('url', None)
-
- url, headers, body = self.auth_provider.auth_request('GET',
- self.target_url,
- filters=filters)
-
- self.assertEqual(url, self.target_url)
- self.assertEqual(self._get_token_from_fake_identity(),
- headers['X-Auth-Token'])
- self.assertEqual(body, None)
-
- def test_request_with_bad_service(self):
- filters = {
- 'service': 'BAD_SERVICE',
- 'endpoint_type': 'publicURL',
- 'region': 'fakeRegion'
- }
- self.assertRaises(exceptions.EndpointNotFound,
- self.auth_provider.auth_request, 'GET',
- self.target_url, filters=filters)
-
- def test_request_without_service(self):
- filters = {
- 'service': None,
- 'endpoint_type': 'publicURL',
- 'region': 'fakeRegion'
- }
- self.assertRaises(exceptions.EndpointNotFound,
- self.auth_provider.auth_request, 'GET',
- self.target_url, filters=filters)
-
- def test_check_credentials_missing_attribute(self):
- for attr in ['username', 'password']:
- cred = copy.copy(self.credentials)
- del cred[attr]
- self.assertFalse(self.auth_provider.check_credentials(cred))
-
- def test_fill_credentials(self):
- self.auth_provider.fill_credentials()
- creds = self.auth_provider.credentials
- for attr in ['user_id', 'tenant_id']:
- self.assertEqual(self._get_from_fake_identity(attr),
- getattr(creds, attr))
-
- def _test_base_url_helper(self, expected_url, filters,
- auth_data=None):
-
- url = self.auth_provider.base_url(filters, auth_data)
- self.assertEqual(url, expected_url)
-
- def test_base_url(self):
- self.filters = {
- 'service': 'compute',
- 'endpoint_type': 'publicURL',
- 'region': 'FakeRegion'
- }
- expected = self._get_result_url_from_endpoint(
- self._endpoints[0]['endpoints'][1])
- self._test_base_url_helper(expected, self.filters)
-
- def test_base_url_to_get_admin_endpoint(self):
- self.filters = {
- 'service': 'compute',
- 'endpoint_type': 'adminURL',
- 'region': 'FakeRegion'
- }
- expected = self._get_result_url_from_endpoint(
- self._endpoints[0]['endpoints'][1], endpoint_type='adminURL')
- self._test_base_url_helper(expected, self.filters)
-
- def test_base_url_unknown_region(self):
- """
- Assure that if the region is unknow the first endpoint is returned.
- """
- self.filters = {
- 'service': 'compute',
- 'endpoint_type': 'publicURL',
- 'region': 'AintNoBodyKnowThisRegion'
- }
- expected = self._get_result_url_from_endpoint(
- self._endpoints[0]['endpoints'][0])
- self._test_base_url_helper(expected, self.filters)
-
- def test_base_url_with_non_existent_service(self):
- self.filters = {
- 'service': 'BAD_SERVICE',
- 'endpoint_type': 'publicURL',
- 'region': 'FakeRegion'
- }
- self.assertRaises(exceptions.EndpointNotFound,
- self._test_base_url_helper, None, self.filters)
-
- def test_base_url_without_service(self):
- self.filters = {
- 'endpoint_type': 'publicURL',
- 'region': 'FakeRegion'
- }
- self.assertRaises(exceptions.EndpointNotFound,
- self._test_base_url_helper, None, self.filters)
-
- def test_base_url_with_api_version_filter(self):
- self.filters = {
- 'service': 'compute',
- 'endpoint_type': 'publicURL',
- 'region': 'FakeRegion',
- 'api_version': 'v12'
- }
- expected = self._get_result_url_from_endpoint(
- self._endpoints[0]['endpoints'][1], replacement='v12')
- self._test_base_url_helper(expected, self.filters)
-
- def test_base_url_with_skip_path_filter(self):
- self.filters = {
- 'service': 'compute',
- 'endpoint_type': 'publicURL',
- 'region': 'FakeRegion',
- 'skip_path': True
- }
- expected = 'http://fake_url/'
- self._test_base_url_helper(expected, self.filters)
-
- def test_token_not_expired(self):
- expiry_data = datetime.datetime.utcnow() + datetime.timedelta(days=1)
- auth_data = self._auth_data_with_expiry(
- expiry_data.strftime(self.auth_provider.EXPIRY_DATE_FORMAT))
- self.assertFalse(self.auth_provider.is_expired(auth_data))
-
- def test_token_expired(self):
- expiry_data = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
- auth_data = self._auth_data_with_expiry(
- expiry_data.strftime(self.auth_provider.EXPIRY_DATE_FORMAT))
- self.assertTrue(self.auth_provider.is_expired(auth_data))
-
- def test_token_not_expired_to_be_renewed(self):
- expiry_data = datetime.datetime.utcnow() + \
- self.auth_provider.token_expiry_threshold / 2
- auth_data = self._auth_data_with_expiry(
- expiry_data.strftime(self.auth_provider.EXPIRY_DATE_FORMAT))
- self.assertTrue(self.auth_provider.is_expired(auth_data))
-
-
-class TestKeystoneV3AuthProvider(TestKeystoneV2AuthProvider):
- _endpoints = fake_identity.IDENTITY_V3_RESPONSE['token']['catalog']
- _auth_provider_class = auth.KeystoneV3AuthProvider
- credentials = fake_credentials.FakeKeystoneV3Credentials()
-
- def setUp(self):
- super(TestKeystoneV3AuthProvider, self).setUp()
- self.stubs.Set(v3_client.V3TokenClientJSON, 'raw_request',
- fake_identity._fake_v3_response)
-
- def _get_fake_alt_identity(self):
- return fake_identity.ALT_IDENTITY_V3['token']
-
- def _get_result_url_from_endpoint(self, ep, replacement=None):
- if replacement:
- return ep['url'].replace('v3', replacement)
- return ep['url']
-
- def _auth_data_with_expiry(self, date_as_string):
- token, access = self.auth_provider.auth_data
- access['expires_at'] = date_as_string
- return token, access
-
- def _get_from_fake_identity(self, attr):
- token = fake_identity.IDENTITY_V3_RESPONSE['token']
- if attr == 'user_id':
- return token['user']['id']
- elif attr == 'project_id':
- return token['project']['id']
- elif attr == 'user_domain_id':
- return token['user']['domain']['id']
- elif attr == 'project_domain_id':
- return token['project']['domain']['id']
-
- def test_check_credentials_missing_attribute(self):
- # reset credentials to fresh ones
- self.credentials.reset()
- for attr in ['username', 'password', 'user_domain_name',
- 'project_domain_name']:
- cred = copy.copy(self.credentials)
- del cred[attr]
- self.assertFalse(self.auth_provider.check_credentials(cred),
- "Credentials should be invalid without %s" % attr)
-
- def test_check_domain_credentials_missing_attribute(self):
- # reset credentials to fresh ones
- self.credentials.reset()
- domain_creds = fake_credentials.FakeKeystoneV3DomainCredentials()
- for attr in ['username', 'password', 'user_domain_name']:
- cred = copy.copy(domain_creds)
- del cred[attr]
- self.assertFalse(self.auth_provider.check_credentials(cred),
- "Credentials should be invalid without %s" % attr)
-
- def test_fill_credentials(self):
- self.auth_provider.fill_credentials()
- creds = self.auth_provider.credentials
- for attr in ['user_id', 'project_id', 'user_domain_id',
- 'project_domain_id']:
- self.assertEqual(self._get_from_fake_identity(attr),
- getattr(creds, attr))
-
- # Overwrites v2 test
- def test_base_url_to_get_admin_endpoint(self):
- self.filters = {
- 'service': 'compute',
- 'endpoint_type': 'admin',
- 'region': 'MiddleEarthRegion'
- }
- expected = self._get_result_url_from_endpoint(
- self._endpoints[0]['endpoints'][2])
- self._test_base_url_helper(expected, self.filters)
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
deleted file mode 100644
index bf44d11..0000000
--- a/tempest/tests/test_credentials.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# Copyright 2014 Hewlett-Packard Development Company, L.P.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import copy
-
-from tempest import auth
-from tempest import exceptions
-from tempest.services.identity.v2.json import token_client as v2_client
-from tempest.services.identity.v3.json import token_client as v3_client
-from tempest.tests import base
-from tempest.tests import fake_identity
-
-
-class CredentialsTests(base.TestCase):
- attributes = {}
- credentials_class = auth.Credentials
-
- def _get_credentials(self, attributes=None):
- if attributes is None:
- attributes = self.attributes
- return self.credentials_class(**attributes)
-
- def _check(self, credentials, credentials_class, filled):
- # Check the right version of credentials has been returned
- self.assertIsInstance(credentials, credentials_class)
- # Check the id attributes are filled in
- attributes = [x for x in credentials.ATTRIBUTES if (
- '_id' in x and x != 'domain_id')]
- for attr in attributes:
- if filled:
- self.assertIsNotNone(getattr(credentials, attr))
- else:
- self.assertIsNone(getattr(credentials, attr))
-
- def test_create(self):
- creds = self._get_credentials()
- self.assertEqual(self.attributes, creds._initial)
-
- def test_create_invalid_attr(self):
- self.assertRaises(exceptions.InvalidCredentials,
- self._get_credentials,
- attributes=dict(invalid='fake'))
-
- def test_is_valid(self):
- creds = self._get_credentials()
- self.assertRaises(NotImplementedError, creds.is_valid)
-
-
-class KeystoneV2CredentialsTests(CredentialsTests):
- attributes = {
- 'username': 'fake_username',
- 'password': 'fake_password',
- 'tenant_name': 'fake_tenant_name'
- }
-
- identity_response = fake_identity._fake_v2_response
- credentials_class = auth.KeystoneV2Credentials
- tokenclient_class = v2_client.TokenClientJSON
- identity_version = 'v2'
-
- def setUp(self):
- super(KeystoneV2CredentialsTests, self).setUp()
- self.stubs.Set(self.tokenclient_class, 'raw_request',
- self.identity_response)
-
- def _verify_credentials(self, credentials_class, creds_dict, filled=True):
- creds = auth.get_credentials(fake_identity.FAKE_AUTH_URL,
- fill_in=filled,
- identity_version=self.identity_version,
- **creds_dict)
- self._check(creds, credentials_class, filled)
-
- def test_get_credentials(self):
- self._verify_credentials(credentials_class=self.credentials_class,
- creds_dict=self.attributes)
-
- def test_get_credentials_not_filled(self):
- self._verify_credentials(credentials_class=self.credentials_class,
- creds_dict=self.attributes,
- filled=False)
-
- def test_is_valid(self):
- creds = self._get_credentials()
- self.assertTrue(creds.is_valid())
-
- def _test_is_not_valid(self, ignore_key):
- creds = self._get_credentials()
- for attr in self.attributes.keys():
- if attr == ignore_key:
- continue
- temp_attr = getattr(creds, attr)
- delattr(creds, attr)
- self.assertFalse(creds.is_valid(),
- "Credentials should be invalid without %s" % attr)
- setattr(creds, attr, temp_attr)
-
- def test_is_not_valid(self):
- # NOTE(mtreinish): A KeystoneV2 credential object is valid without
- # a tenant_name. So skip that check. See tempest.auth for the valid
- # credential requirements
- self._test_is_not_valid('tenant_name')
-
- def test_reset_all_attributes(self):
- creds = self._get_credentials()
- initial_creds = copy.deepcopy(creds)
- set_attr = creds.__dict__.keys()
- missing_attr = set(creds.ATTRIBUTES).difference(set_attr)
- # Set all unset attributes, then reset
- for attr in missing_attr:
- setattr(creds, attr, 'fake' + attr)
- creds.reset()
- # Check reset credentials are same as initial ones
- self.assertEqual(creds, initial_creds)
-
- def test_reset_single_attribute(self):
- creds = self._get_credentials()
- initial_creds = copy.deepcopy(creds)
- set_attr = creds.__dict__.keys()
- missing_attr = set(creds.ATTRIBUTES).difference(set_attr)
- # Set one unset attributes, then reset
- for attr in missing_attr:
- setattr(creds, attr, 'fake' + attr)
- creds.reset()
- # Check reset credentials are same as initial ones
- self.assertEqual(creds, initial_creds)
-
-
-class KeystoneV3CredentialsTests(KeystoneV2CredentialsTests):
- attributes = {
- 'username': 'fake_username',
- 'password': 'fake_password',
- 'project_name': 'fake_project_name',
- 'user_domain_name': 'fake_domain_name'
- }
-
- credentials_class = auth.KeystoneV3Credentials
- identity_response = fake_identity._fake_v3_response
- tokenclient_class = v3_client.V3TokenClientJSON
- identity_version = 'v3'
-
- def test_is_not_valid(self):
- # NOTE(mtreinish) For a Keystone V3 credential object a project name
- # is not required to be valid, so we skip that check. See tempest.auth
- # for the valid credential requirements
- self._test_is_not_valid('project_name')
-
- def test_synced_attributes(self):
- attributes = self.attributes
- # Create V3 credentials with tenant instead of project, and user_domain
- for attr in ['project_id', 'user_domain_id']:
- attributes[attr] = 'fake_' + attr
- creds = self._get_credentials(attributes)
- self.assertEqual(creds.project_name, creds.tenant_name)
- self.assertEqual(creds.project_id, creds.tenant_id)
- self.assertEqual(creds.user_domain_name, creds.project_domain_name)
- self.assertEqual(creds.user_domain_id, creds.project_domain_id)
- # Replace user_domain with project_domain
- del attributes['user_domain_name']
- del attributes['user_domain_id']
- del attributes['project_name']
- del attributes['project_id']
- for attr in ['project_domain_name', 'project_domain_id',
- 'tenant_name', 'tenant_id']:
- attributes[attr] = 'fake_' + attr
- self.assertEqual(creds.tenant_name, creds.project_name)
- self.assertEqual(creds.tenant_id, creds.project_id)
- self.assertEqual(creds.project_domain_name, creds.user_domain_name)
- self.assertEqual(creds.project_domain_id, creds.user_domain_id)
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index b132f60..7850ee4 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -137,7 +137,7 @@
resp, body = self.client.raw_request('PUT', '/images', body=req_body)
self.assertEqual(200, resp.status)
self.assertEqual('fake_response_body', body.read())
- httplib.HTTPConnection.send.assert_call_count(req_body.len)
+ httplib.HTTPConnection.send.assert_call_count(req_body.tell())
def test_get_connection_class_for_https(self):
conn_class = self.client.get_connection_class('https')
diff --git a/tempest/tests/test_list_tests.py b/tempest/tests/test_list_tests.py
index 19e4c9c..38d4c5c 100644
--- a/tempest/tests/test_list_tests.py
+++ b/tempest/tests/test_list_tests.py
@@ -14,6 +14,7 @@
import os
import re
+import six
import subprocess
from tempest.tests import base
@@ -32,7 +33,7 @@
self.assertEqual(0, p.returncode,
"test discovery failed, one or more files cause an "
"error on import %s" % ids)
- ids = ids.split('\n')
+ ids = six.text_type(ids).split('\n')
for test_id in ids:
if re.match('(\w+\.){3}\w+', test_id):
if not test_id.startswith('tempest.'):
diff --git a/tempest/tests/test_ssh.py b/tempest/tests/test_ssh.py
deleted file mode 100644
index aaacaab..0000000
--- a/tempest/tests/test_ssh.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# Copyright 2014 OpenStack Foundation
-#
-# 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 contextlib
-import socket
-import time
-
-import mock
-import testtools
-
-from tempest.common import ssh
-from tempest import exceptions
-from tempest.tests import base
-
-
-class TestSshClient(base.TestCase):
-
- def test_pkey_calls_paramiko_RSAKey(self):
- with contextlib.nested(
- mock.patch('paramiko.RSAKey.from_private_key'),
- mock.patch('six.moves.cStringIO')) as (rsa_mock, cs_mock):
- cs_mock.return_value = mock.sentinel.csio
- pkey = 'mykey'
- ssh.Client('localhost', 'root', pkey=pkey)
- rsa_mock.assert_called_once_with(mock.sentinel.csio)
- cs_mock.assert_called_once_with('mykey')
- rsa_mock.reset_mock()
- cs_mock.reset_mock()
- pkey = mock.sentinel.pkey
- # Shouldn't call out to load a file from RSAKey, since
- # a sentinel isn't a basestring...
- ssh.Client('localhost', 'root', pkey=pkey)
- self.assertEqual(0, rsa_mock.call_count)
- self.assertEqual(0, cs_mock.call_count)
-
- def _set_ssh_connection_mocks(self):
- client_mock = mock.MagicMock()
- client_mock.connect.return_value = True
- return (self.patch('paramiko.SSHClient'),
- self.patch('paramiko.AutoAddPolicy'),
- client_mock)
-
- def test_get_ssh_connection(self):
- c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks()
- s_mock = self.patch('time.sleep')
-
- c_mock.return_value = client_mock
- aa_mock.return_value = mock.sentinel.aa
-
- # Test normal case for successful connection on first try
- client = ssh.Client('localhost', 'root', timeout=2)
- client._get_ssh_connection(sleep=1)
-
- aa_mock.assert_called_once_with()
- client_mock.set_missing_host_key_policy.assert_called_once_with(
- mock.sentinel.aa)
- expected_connect = [mock.call(
- 'localhost',
- username='root',
- pkey=None,
- key_filename=None,
- look_for_keys=False,
- timeout=10.0,
- password=None
- )]
- self.assertEqual(expected_connect, client_mock.connect.mock_calls)
- self.assertEqual(0, s_mock.call_count)
-
- def test_get_ssh_connection_two_attemps(self):
- c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks()
-
- c_mock.return_value = client_mock
- client_mock.connect.side_effect = [
- socket.error,
- mock.MagicMock()
- ]
-
- client = ssh.Client('localhost', 'root', timeout=1)
- start_time = int(time.time())
- client._get_ssh_connection(sleep=1)
- end_time = int(time.time())
- self.assertLess((end_time - start_time), 4)
- self.assertGreater((end_time - start_time), 1)
-
- def test_get_ssh_connection_timeout(self):
- c_mock, aa_mock, client_mock = self._set_ssh_connection_mocks()
-
- c_mock.return_value = client_mock
- client_mock.connect.side_effect = [
- socket.error,
- socket.error,
- socket.error,
- ]
-
- client = ssh.Client('localhost', 'root', timeout=2)
- start_time = int(time.time())
- with testtools.ExpectedException(exceptions.SSHTimeout):
- client._get_ssh_connection()
- end_time = int(time.time())
- self.assertLess((end_time - start_time), 5)
- self.assertGreaterEqual((end_time - start_time), 2)
-
- def test_exec_command(self):
- gsc_mock = self.patch('tempest.common.ssh.Client._get_ssh_connection')
- ito_mock = self.patch('tempest.common.ssh.Client._is_timed_out')
- select_mock = self.patch('select.poll')
-
- client_mock = mock.MagicMock()
- tran_mock = mock.MagicMock()
- chan_mock = mock.MagicMock()
- poll_mock = mock.MagicMock()
-
- def reset_mocks():
- gsc_mock.reset_mock()
- ito_mock.reset_mock()
- select_mock.reset_mock()
- poll_mock.reset_mock()
- client_mock.reset_mock()
- tran_mock.reset_mock()
- chan_mock.reset_mock()
-
- select_mock.return_value = poll_mock
- gsc_mock.return_value = client_mock
- ito_mock.return_value = True
- client_mock.get_transport.return_value = tran_mock
- tran_mock.open_session.return_value = chan_mock
- poll_mock.poll.side_effect = [
- [0, 0, 0]
- ]
-
- # Test for a timeout condition immediately raised
- client = ssh.Client('localhost', 'root', timeout=2)
- with testtools.ExpectedException(exceptions.TimeoutException):
- client.exec_command("test")
-
- chan_mock.fileno.assert_called_once_with()
- chan_mock.exec_command.assert_called_once_with("test")
- chan_mock.shutdown_write.assert_called_once_with()
-
- SELECT_POLLIN = 1
- poll_mock.register.assert_called_once_with(chan_mock, SELECT_POLLIN)
- poll_mock.poll.assert_called_once_with(10)
-
- # Test for proper reading of STDOUT and STDERROR and closing
- # of all file descriptors.
-
- reset_mocks()
-
- select_mock.return_value = poll_mock
- gsc_mock.return_value = client_mock
- ito_mock.return_value = False
- client_mock.get_transport.return_value = tran_mock
- tran_mock.open_session.return_value = chan_mock
- poll_mock.poll.side_effect = [
- [1, 0, 0]
- ]
- closed_prop = mock.PropertyMock(return_value=True)
- type(chan_mock).closed = closed_prop
- chan_mock.recv_exit_status.return_value = 0
- chan_mock.recv.return_value = ''
- chan_mock.recv_stderr.return_value = ''
-
- client = ssh.Client('localhost', 'root', timeout=2)
- client.exec_command("test")
-
- chan_mock.fileno.assert_called_once_with()
- chan_mock.exec_command.assert_called_once_with("test")
- chan_mock.shutdown_write.assert_called_once_with()
-
- SELECT_POLLIN = 1
- poll_mock.register.assert_called_once_with(chan_mock, SELECT_POLLIN)
- poll_mock.poll.assert_called_once_with(10)
- chan_mock.recv_ready.assert_called_once_with()
- chan_mock.recv.assert_called_once_with(1024)
- chan_mock.recv_stderr_ready.assert_called_once_with()
- chan_mock.recv_stderr.assert_called_once_with(1024)
- chan_mock.recv_exit_status.assert_called_once_with()
- closed_prop.assert_called_once_with()
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index fd8718f..47e6abd 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -15,6 +15,7 @@
import mock
from oslo_config import cfg
from oslotest import mockpatch
+from tempest_lib.services.identity.v2 import token_client as json_token_client
from tempest.common import isolated_creds
from tempest.common import service_client
@@ -22,7 +23,6 @@
from tempest import exceptions
from tempest.services.identity.v2.json import identity_client as \
json_iden_client
-from tempest.services.identity.v2.json import token_client as json_token_client
from tempest.services.network.json import network_client as json_network_client
from tempest.tests import base
from tempest.tests import fake_config
@@ -196,6 +196,7 @@
# Assert that the role creation is called with the 2 specified roles
self.assertEqual(len(calls), 2)
args = map(lambda x: x[1], calls)
+ args = list(args)
self.assertIn(('1234', '1234', '1234'), args)
self.assertIn(('1234', '1234', '12345'), args)
self.assertEqual(role_creds.username, 'fake_role_user')
@@ -237,6 +238,7 @@
calls = user_mock.mock_calls
self.assertEqual(len(calls), 3)
args = map(lambda x: x[1][0], calls)
+ args = list(args)
self.assertIn('1234', args)
self.assertIn('12345', args)
self.assertIn('123456', args)
@@ -244,6 +246,7 @@
calls = tenant_mock.mock_calls
self.assertEqual(len(calls), 3)
args = map(lambda x: x[1][0], calls)
+ args = list(args)
self.assertIn('1234', args)
self.assertIn('12345', args)
self.assertIn('123456', args)
@@ -381,6 +384,7 @@
calls = remove_secgroup_mock.mock_calls
self.assertEqual(len(calls), 3)
args = map(lambda x: x[1][0], calls)
+ args = list(args)
self.assertIn('v2.0/security-groups/sg-1234', args)
self.assertIn('v2.0/security-groups/sg-12345', args)
self.assertIn('v2.0/security-groups/sg-123456', args)
@@ -388,6 +392,7 @@
calls = remove_router_interface_mock.mock_calls
self.assertEqual(len(calls), 3)
args = map(lambda x: x[1], calls)
+ args = list(args)
self.assertIn(('1234', '1234'), args)
self.assertIn(('12345', '12345'), args)
self.assertIn(('123456', '123456'), args)
@@ -395,6 +400,7 @@
calls = net_mock.mock_calls
self.assertEqual(len(calls), 3)
args = map(lambda x: x[1][0], calls)
+ args = list(args)
self.assertIn('1234', args)
self.assertIn('12345', args)
self.assertIn('123456', args)
@@ -402,6 +408,7 @@
calls = subnet_mock.mock_calls
self.assertEqual(len(calls), 3)
args = map(lambda x: x[1][0], calls)
+ args = list(args)
self.assertIn('1234', args)
self.assertIn('12345', args)
self.assertIn('123456', args)
@@ -409,6 +416,7 @@
calls = router_mock.mock_calls
self.assertEqual(len(calls), 3)
args = map(lambda x: x[1][0], calls)
+ args = list(args)
self.assertIn('1234', args)
self.assertIn('12345', args)
self.assertIn('123456', args)
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index 4485972..1ff4dee 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -252,9 +252,9 @@
except exception.BotoServerError as exc:
error_msg = excMatcher.match(exc)
if error_msg is not None:
- raise self.failureException, error_msg
+ raise self.failureException(error_msg)
else:
- raise self.failureException, "BotoServerError not raised"
+ raise self.failureException("BotoServerError not raised")
@classmethod
def resource_cleanup(cls):
diff --git a/test-requirements.txt b/test-requirements.txt
index 76ae521..32f33bc 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,9 +5,9 @@
# needed for doc build
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
python-subunit>=0.0.18
-oslosphinx>=2.5.0,<2.6.0 # Apache-2.0
+oslosphinx>=2.5.0 # Apache-2.0
mox>=0.5.3
mock>=1.0
coverage>=3.6
-oslotest>=1.5.1,<1.6.0 # Apache-2.0
-stevedore>=1.3.0,<1.4.0 # Apache-2.0
+oslotest>=1.5.1 # Apache-2.0
+stevedore>=1.3.0 # Apache-2.0
diff --git a/tox.ini b/tox.ini
index ef98e90..2d2ed38 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,5 +1,5 @@
[tox]
-envlist = pep8,py27
+envlist = pep8,py27,py34
minversion = 1.6
skipsdist = True
@@ -47,7 +47,7 @@
# See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
commands =
find . -type f -name "*.pyc" -delete
- bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
+ bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty)) {posargs}'
[testenv:full-serial]
sitepackages = {[tempestenv]sitepackages}
@@ -57,7 +57,7 @@
# See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
commands =
find . -type f -name "*.pyc" -delete
- bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
+ bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty)) {posargs}'
[testenv:heat-slow]
sitepackages = {[tempestenv]sitepackages}
@@ -83,7 +83,7 @@
deps = {[tempestenv]deps}
commands =
find . -type f -name "*.pyc" -delete
- bash tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])((smoke)|(^tempest\.scenario)) {posargs}'
+ bash tools/pretty_tox.sh '\[.*\bsmoke\b.*\] {posargs}'
[testenv:smoke-serial]
sitepackages = {[tempestenv]sitepackages}
@@ -94,7 +94,7 @@
# job would fail if we moved it to parallel.
commands =
find . -type f -name "*.pyc" -delete
- bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])((smoke)|(^tempest\.scenario)) {posargs}'
+ bash tools/pretty_tox_serial.sh '\[.*\bsmoke\b.*\] {posargs}'
[testenv:stress]
sitepackages = {[tempestenv]sitepackages}