Merge "Prevent error in _parse_resp when nullable list"
diff --git a/HACKING.rst b/HACKING.rst
index c0a857c..dbb758b 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -22,6 +22,7 @@
- [T112] Check that tempest.lib should not import local tempest code
- [T113] Check that tests use data_utils.rand_uuid() instead of uuid.uuid4()
- [T114] Check that tempest.lib does not use tempest config
+- [T115] Check that admin tests should exist under admin path
- [N322] Method's default argument shouldn't be mutable
Test Data/Configuration
@@ -232,9 +233,9 @@
and xml version of the same test class there could still be a race between
methods.
-- The rand_name() function from tempest.common.utils.data_utils should be used
- anywhere a resource is created with a name. Static naming should be avoided
- to prevent resource conflicts.
+- The rand_name() function from tempest.lib.common.utils.data_utils should be
+ used anywhere a resource is created with a name. Static naming should be
+ avoided to prevent resource conflicts.
- If the execution of a set of tests is required to be serialized then locking
can be used to perform this. See AggregatesAdminTest in
diff --git a/doc/source/conf.py b/doc/source/conf.py
index f11d96a..b9e22b5 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -155,8 +155,7 @@
git_cmd = ["git", "log", "--pretty=format:'%ad, commit %h'", "--date=local",
"-n1"]
try:
- html_last_updated_fmt = str(
- subprocess.Popen(git_cmd, stdout=subprocess.PIPE).communicate()[0])
+ html_last_updated_fmt = subprocess.check_output(git_cmd).decode('utf-8')
except Exception:
warnings.warn('Cannot get last updated time from git repository. '
'Not setting "html_last_updated_fmt".')
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 2314222..4accd94 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -52,8 +52,7 @@
#. ``uri_v3``
The ``auth_version`` option is used to tell Tempest whether it should be using
-keystone's v2 or v3 api for communicating with keystone. (except for the
-identity api tests which will test a specific version) The two uri options are
+keystone's v2 or v3 api for communicating with keystone. The two uri options are
used to tell Tempest the url of the keystone endpoint. The ``uri`` option is
used for keystone v2 request and ``uri_v3`` is used for keystone v3. You want to
ensure that which ever version you set for ``auth_version`` has its uri option
diff --git a/doc/source/index.rst b/doc/source/index.rst
index c4affd2..f562850 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -24,8 +24,8 @@
field_guide/scenario
field_guide/unit_tests
-For users
-=========
+Users Guide
+===========
Tempest Configuration Guide
---------------------------
@@ -48,8 +48,8 @@
workspace
run
-For developers
-==============
+Developers Guide
+================
Development
-----------
diff --git a/doc/source/write_tests.rst b/doc/source/write_tests.rst
index 2363fa6..4e3bfa2 100644
--- a/doc/source/write_tests.rst
+++ b/doc/source/write_tests.rst
@@ -178,16 +178,16 @@
+-------------------+---------------------+
| Credentials Entry | Manager Variable |
+===================+=====================+
-| primary | cls.os |
+| primary | cls.os_primary |
+-------------------+---------------------+
-| admin | cls.os_adm |
+| admin | cls.os_admin |
+-------------------+---------------------+
| alt | cls.os_alt |
+-------------------+---------------------+
| [$label, $role] | cls.os_roles_$label |
+-------------------+---------------------+
-By default cls.os is available since it is allocated in the base tempest test
+By default cls.os_primary is available since it is allocated in the base tempest test
class (located in tempest/test.py). If your TestCase inherits from a different
direct parent class (it'll still inherit from the BaseTestCase, just not
directly) be sure to check if that class overrides allocated credentials.
@@ -270,13 +270,13 @@
class TestExampleCase(test.BaseTestCase):
def test_example_create_server(self):
- self.os.servers_client.create_server(...)
+ self.os_primary.servers_client.create_server(...)
-is all you need to do. As described previously, in the above example the ``self.os``
-is created automatically because the base test class sets the ``credentials``
-attribute to allocate a primary credential set and initializes the client
-manager as ``self.os``. This same access pattern can be used for all of the
-clients in Tempest.
+is all you need to do. As described previously, in the above example the
+``self.os_primary`` is created automatically because the base test class sets the
+``credentials`` attribute to allocate a primary credential set and initializes
+the client manager as ``self.os_primary``. This same access pattern can be used
+for all of the clients in Tempest.
Credentials Objects
-------------------
@@ -293,7 +293,7 @@
class TestExampleCase(test.BaseTestCase):
def test_example_create_server(self):
- credentials = self.os.credentials
+ credentials = self.os_primary.credentials
The credentials object provides access to all of the credential information you
would need to make API requests. For example, building off the previous
@@ -304,7 +304,7 @@
class TestExampleCase(test.BaseTestCase):
def test_example_create_server(self):
- credentials = self.os.credentials
+ credentials = self.os_primary.credentials
username = credentials.username
user_id = credentials.user_id
password = credentials.password
diff --git a/releasenotes/notes/add-floating-ip-config-option-e5774bf77702ce9f.yaml b/releasenotes/notes/add-floating-ip-config-option-e5774bf77702ce9f.yaml
new file mode 100644
index 0000000..8221d78
--- /dev/null
+++ b/releasenotes/notes/add-floating-ip-config-option-e5774bf77702ce9f.yaml
@@ -0,0 +1,5 @@
+---
+features:
+ - A new config option in the network-feature-enabled section, floating_ips,
+ to specify whether floating ips are available in the cloud under test. By
+ default this is set to True.
diff --git a/releasenotes/notes/use-cinder-v3-client-for-verify_tempest_config-2bf3d817b0070064.yaml b/releasenotes/notes/use-cinder-v3-client-for-verify_tempest_config-2bf3d817b0070064.yaml
new file mode 100644
index 0000000..1c8fa77
--- /dev/null
+++ b/releasenotes/notes/use-cinder-v3-client-for-verify_tempest_config-2bf3d817b0070064.yaml
@@ -0,0 +1,6 @@
+---
+upgrade:
+ - verify_tempest_config command starts using extension_client of
+ cinder v2 API only, because cinder v3 API is current and v2 and
+ v1 are deprecated and v3 extension API is the same as v2. Then
+ we can reuse the v2 client for v3 API also.
diff --git a/requirements.txt b/requirements.txt
index 26e1f02..9f57ee1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,7 +9,7 @@
netaddr!=0.7.16,>=0.7.13 # BSD
testrepository>=0.0.18 # Apache-2.0/BSD
oslo.concurrency>=3.8.0 # Apache-2.0
-oslo.config>=3.22.0 # Apache-2.0
+oslo.config>=4.0.0 # Apache-2.0
oslo.log>=3.22.0 # Apache-2.0
oslo.serialization>=1.10.0 # Apache-2.0
oslo.utils>=3.20.0 # Apache-2.0
diff --git a/tempest/api/compute/admin/test_agents.py b/tempest/api/compute/admin/test_agents.py
index 31976ec..69cbfb5 100644
--- a/tempest/api/compute/admin/test_agents.py
+++ b/tempest/api/compute/admin/test_agents.py
@@ -86,8 +86,7 @@
body = self.client.create_agent(**self.params_agent)['agent']
self.addCleanup(self.client.delete_agent, body['agent_id'])
agents = self.client.list_agents()['agents']
- self.assertGreater(len(agents), 0,
- 'Cannot get any agents.(%s)' % agents)
+ self.assertNotEmpty(agents, 'Cannot get any agents.(%s)' % agents)
self.assertIn(body['agent_id'], map(lambda x: x['agent_id'], agents))
@decorators.idempotent_id('eabadde4-3cd7-4ec4-a4b5-5a936d2d4408')
@@ -105,8 +104,7 @@
agent_id_xen = agent_xen['agent_id']
agents = (self.client.list_agents(hypervisor=agent_xen['hypervisor'])
['agents'])
- self.assertGreater(len(agents), 0,
- 'Cannot get any agents.(%s)' % agents)
+ self.assertNotEmpty(agents, 'Cannot get any agents.(%s)' % agents)
self.assertIn(agent_id_xen, map(lambda x: x['agent_id'], agents))
self.assertNotIn(body['agent_id'], map(lambda x: x['agent_id'],
agents))
diff --git a/tempest/api/compute/admin/test_auto_allocate_network.py b/tempest/api/compute/admin/test_auto_allocate_network.py
index c4db5e3..ba8a214 100644
--- a/tempest/api/compute/admin/test_auto_allocate_network.py
+++ b/tempest/api/compute/admin/test_auto_allocate_network.py
@@ -151,7 +151,7 @@
"""Tests that no networking is allocated for the server."""
# create the server with no networking
server, _ = compute.create_test_server(
- self.os, networks='none', wait_until='ACTIVE')
+ self.os_primary, networks='none', wait_until='ACTIVE')
self.addCleanup(self.delete_server, server['id'])
# get the server ips
addresses = self.servers_client.list_addresses(
@@ -176,7 +176,7 @@
# - Third request sees net1 and net2 for the tenant and fails with a
# NetworkAmbiguous 400 error.
_, servers = compute.create_test_server(
- self.os, networks='auto', wait_until='ACTIVE',
+ self.os_primary, networks='auto', wait_until='ACTIVE',
min_count=3)
server_nets = set()
for server in servers:
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index 50dec28..bbd39b6 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -29,10 +29,10 @@
def test_get_availability_zone_list(self):
# List of availability zone
availability_zone = self.client.list_availability_zones()
- self.assertGreater(len(availability_zone['availabilityZoneInfo']), 0)
+ self.assertNotEmpty(availability_zone['availabilityZoneInfo'])
@decorators.idempotent_id('ef726c58-530f-44c2-968c-c7bed22d5b8c')
def test_get_availability_zone_list_detail(self):
# List of availability zones and available services
availability_zone = self.client.list_availability_zones(detail=True)
- self.assertGreater(len(availability_zone['availabilityZoneInfo']), 0)
+ self.assertNotEmpty(availability_zone['availabilityZoneInfo'])
diff --git a/tempest/api/compute/admin/test_delete_server.py b/tempest/api/compute/admin/test_delete_server.py
index 2569161..83444b9 100644
--- a/tempest/api/compute/admin/test_delete_server.py
+++ b/tempest/api/compute/admin/test_delete_server.py
@@ -29,7 +29,7 @@
def setup_clients(cls):
super(DeleteServersAdminTestJSON, cls).setup_clients()
cls.non_admin_client = cls.servers_client
- cls.admin_client = cls.os_adm.servers_client
+ cls.admin_client = cls.os_admin.servers_client
@decorators.idempotent_id('99774678-e072-49d1-9d2a-49a59bc56063')
def test_delete_server_while_in_error_state(self):
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 5a38acc..2c236ec 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -50,7 +50,7 @@
flavor_access = (self.admin_flavors_client.list_flavor_access(
flavor['id'])['flavor_access'])
- self.assertEqual(len(flavor_access), 0, str(flavor_access))
+ self.assertEmpty(flavor_access)
@decorators.idempotent_id('59e622f6-bdf6-45e3-8ba8-fedad905a6b4')
def test_flavor_access_add_remove(self):
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index 056b4bd..496f119 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -73,7 +73,7 @@
self.client.delete_floating_ips_bulk, self.ip_range)
self.assertEqual(self.ip_range, body['ip_range'])
ips_list = self.client.list_floating_ips_bulk()['floating_ip_info']
- self.assertNotEqual(0, len(ips_list))
+ self.assertNotEmpty(ips_list)
for ip in netaddr.IPNetwork(self.ip_range).iter_hosts():
self.assertIn(str(ip), map(lambda x: x['address'], ips_list))
body = (self.client.delete_floating_ips_bulk(self.ip_range)
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index 8e2f6ed..0e1e7ed 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -36,7 +36,7 @@
hosts = self.client.list_hosts()['hosts']
host = hosts[0]
hosts = self.client.list_hosts(zone=host['zone'])['hosts']
- self.assertGreaterEqual(len(hosts), 1)
+ self.assertNotEmpty(hosts)
self.assertIn(host, hosts)
@decorators.idempotent_id('9af3c171-fbf4-4150-a624-22109733c2a6')
@@ -44,26 +44,26 @@
# If send the request with a blank zone, the request will be successful
# and it will return all the hosts list
hosts = self.client.list_hosts(zone='')['hosts']
- self.assertNotEqual(0, len(hosts))
+ self.assertNotEmpty(hosts)
@decorators.idempotent_id('c6ddbadb-c94e-4500-b12f-8ffc43843ff8')
def test_list_hosts_with_nonexistent_zone(self):
# If send the request with a nonexistent zone, the request will be
# successful and no hosts will be returned
hosts = self.client.list_hosts(zone='xxx')['hosts']
- self.assertEqual(0, len(hosts))
+ self.assertEmpty(hosts)
@decorators.idempotent_id('38adbb12-aee2-4498-8aec-329c72423aa4')
def test_show_host_detail(self):
hosts = self.client.list_hosts()['hosts']
hosts = [host for host in hosts if host['service'] == 'compute']
- self.assertGreaterEqual(len(hosts), 1)
+ self.assertNotEmpty(hosts)
for host in hosts:
hostname = host['host_name']
resources = self.client.show_host(hostname)['host']
- self.assertGreaterEqual(len(resources), 1)
+ self.assertNotEmpty(resources)
host_resource = resources[0]['resource']
self.assertIsNotNone(host_resource)
self.assertIsNotNone(host_resource['cpu'])
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 4544267..0db802c 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -31,7 +31,7 @@
return hypers
def assertHypervisors(self, hypers):
- self.assertGreater(len(hypers), 0, "No hypervisors found: %s" % hypers)
+ self.assertNotEmpty(hypers, "No hypervisors found: %s" % hypers)
@decorators.idempotent_id('7f0ceacd-c64d-4e96-b8ee-d02943142cc5')
def test_get_hypervisor_list(self):
@@ -52,7 +52,7 @@
self.assertHypervisors(hypers)
details = self.client.show_hypervisor(hypers[0]['id'])['hypervisor']
- self.assertGreater(len(details), 0)
+ self.assertNotEmpty(details)
self.assertEqual(details['hypervisor_hostname'],
hypers[0]['hypervisor_hostname'])
@@ -65,14 +65,14 @@
hostname = hypers[0]['hypervisor_hostname']
hypervisors = (self.client.list_servers_on_hypervisor(hostname)
['hypervisors'])
- self.assertGreater(len(hypervisors), 0)
+ self.assertNotEmpty(hypervisors)
@decorators.idempotent_id('797e4f28-b6e0-454d-a548-80cc77c00816')
def test_get_hypervisor_stats(self):
# Verify the stats of the all hypervisor
stats = (self.client.show_hypervisor_statistics()
['hypervisor_statistics'])
- self.assertGreater(len(stats), 0)
+ self.assertNotEmpty(stats)
@decorators.idempotent_id('91a50d7d-1c2b-4f24-b55a-a1fe20efca70')
def test_get_hypervisor_uptime(self):
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index af87287..431e823 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -47,7 +47,7 @@
@decorators.idempotent_id('51e663d0-6b89-4817-a465-20aca0667d03')
def test_show_hypervisor_with_non_admin_user(self):
hypers = self._list_hypervisors()
- self.assertGreater(len(hypers), 0)
+ self.assertNotEmpty(hypers)
self.assertRaises(
lib_exc.Forbidden,
@@ -58,7 +58,7 @@
@decorators.idempotent_id('2a0a3938-832e-4859-95bf-1c57c236b924')
def test_show_servers_with_non_admin_user(self):
hypers = self._list_hypervisors()
- self.assertGreater(len(hypers), 0)
+ self.assertNotEmpty(hypers)
self.assertRaises(
lib_exc.Forbidden,
@@ -96,7 +96,7 @@
@decorators.idempotent_id('6c3461f9-c04c-4e2a-bebb-71dc9cb47df2')
def test_get_hypervisor_uptime_with_non_admin_user(self):
hypers = self._list_hypervisors()
- self.assertGreater(len(hypers), 0)
+ self.assertNotEmpty(hypers)
self.assertRaises(
lib_exc.Forbidden,
@@ -131,7 +131,7 @@
@decorators.idempotent_id('5b6a6c79-5dc1-4fa5-9c58-9c8085948e74')
def test_search_hypervisor_with_non_admin_user(self):
hypers = self._list_hypervisors()
- self.assertGreater(len(hypers), 0)
+ self.assertNotEmpty(hypers)
self.assertRaises(
lib_exc.Forbidden,
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
index 0ea0a78..acb0d90 100644
--- a/tempest/api/compute/admin/test_networks.py
+++ b/tempest/api/compute/admin/test_networks.py
@@ -62,4 +62,4 @@
self.assertIn(configured_network, [x['label'] for x in networks])
else:
network_labels = [x['label'] for x in networks]
- self.assertGreaterEqual(len(network_labels), 1)
+ self.assertNotEmpty(network_labels)
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 6c7cde2..f2f3b57 100644
--- a/tempest/api/compute/admin/test_security_group_default_rules.py
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -111,7 +111,7 @@
rule['id'])
rules = (self.adm_client.list_security_group_default_rules()
['security_group_default_rules'])
- self.assertNotEqual(0, len(rules))
+ self.assertNotEmpty(rules)
self.assertIn(rule, rules)
@decorators.idempotent_id('15cbb349-86b4-4f71-a048-04b7ef3f150b')
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index a492b43..789049b 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -133,7 +133,7 @@
# self.create_test_server() here as this method creates the server
# in the "primary" (i.e non-admin) tenant.
test_server, _ = compute.create_test_server(
- self.os_adm, wait_until="ACTIVE", name=name, **network_kwargs)
+ self.os_admin, wait_until="ACTIVE", name=name, **network_kwargs)
self.addCleanup(self.client.delete_server, test_server['id'])
server = self.client.show_server(test_server['id'])['server']
self.assertEqual(server['status'], 'ACTIVE')
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index 1dfc13e..f3eb597 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -29,13 +29,13 @@
@decorators.idempotent_id('5be41ef4-53d1-41cc-8839-5c2a48a1b283')
def test_list_services(self):
services = self.client.list_services()['services']
- self.assertNotEqual(0, len(services))
+ self.assertNotEmpty(services)
@decorators.idempotent_id('f345b1ec-bc6e-4c38-a527-3ca2bc00bef5')
def test_get_service_by_service_binary_name(self):
binary_name = 'nova-compute'
services = self.client.list_services(binary=binary_name)['services']
- self.assertNotEqual(0, len(services))
+ self.assertNotEmpty(services)
for service in services:
self.assertEqual(binary_name, service['binary'])
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index 38bb5ec..201670a 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -48,7 +48,7 @@
host_name = services[0]['host']
services = self.client.list_services(host=host_name,
binary='xxx')['services']
- self.assertEqual(0, len(services))
+ self.assertEmpty(services)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('64e7e7fb-69e8-4cb6-a71d-8d5eb0c98655')
@@ -57,4 +57,4 @@
binary_name = services[0]['binary']
services = self.client.list_services(host='xxx',
binary=binary_name)['services']
- self.assertEqual(0, len(services))
+ self.assertEmpty(services)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 141b9f3..d893446 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -204,7 +204,7 @@
kwargs['name'] = data_utils.rand_name(cls.__name__ + "-server")
tenant_network = cls.get_tenant_network()
body, servers = compute.create_test_server(
- cls.os,
+ cls.os_primary,
validatable,
validation_resources=cls.validation_resources,
tenant_network=tenant_network,
@@ -350,7 +350,7 @@
@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)
+ cls._delete_volume(cls.volumes_client, volume_id)
@classmethod
def get_server_ip(cls, server):
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions.py b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
index 2769245..faa7b5d 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -30,6 +30,12 @@
floating_ip = None
@classmethod
+ def skip_checks(cls):
+ super(FloatingIPsTestJSON, cls).skip_checks()
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
+
+ @classmethod
def setup_clients(cls):
super(FloatingIPsTestJSON, cls).setup_clients()
cls.client = cls.floating_ips_client
diff --git a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
index 96983b0..483bd95 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions_negative.py
@@ -28,6 +28,12 @@
class FloatingIPsNegativeTestJSON(base.BaseFloatingIPsTest):
@classmethod
+ def skip_checks(cls):
+ super(FloatingIPsNegativeTestJSON, cls).skip_checks()
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
+
+ @classmethod
def setup_clients(cls):
super(FloatingIPsNegativeTestJSON, cls).setup_clients()
cls.client = cls.floating_ips_client
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 71f5f13..913b992 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -24,6 +24,12 @@
class FloatingIPDetailsTestJSON(base.BaseV2ComputeTest):
@classmethod
+ def skip_checks(cls):
+ super(FloatingIPDetailsTestJSON, cls).skip_checks()
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
+
+ @classmethod
def setup_clients(cls):
super(FloatingIPDetailsTestJSON, cls).setup_clients()
cls.client = cls.floating_ips_client
@@ -52,7 +58,7 @@
# Positive test:Should return the list of floating IPs
body = self.client.list_floating_ips()['floating_ips']
floating_ips = body
- self.assertNotEqual(0, len(floating_ips),
+ self.assertNotEmpty(floating_ips,
"Expected floating IPs. Got zero.")
for i in range(3):
self.assertIn(self.floating_ip[i], floating_ips)
@@ -84,5 +90,5 @@
def test_list_floating_ip_pools(self):
# Positive test:Should return the list of floating IP Pools
floating_ip_pools = self.pools_client.list_floating_ip_pools()
- self.assertNotEqual(0, len(floating_ip_pools['floating_ip_pools']),
+ self.assertNotEmpty(floating_ip_pools['floating_ip_pools'],
"Expected floating IP Pools. Got zero.")
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
index 9d70bf7..b5bbb8c 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips_negative.py
@@ -26,6 +26,12 @@
class FloatingIPDetailsNegativeTestJSON(base.BaseV2ComputeTest):
@classmethod
+ def skip_checks(cls):
+ super(FloatingIPDetailsNegativeTestJSON, cls).skip_checks()
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
+
+ @classmethod
def setup_clients(cls):
super(FloatingIPDetailsNegativeTestJSON, cls).setup_clients()
cls.client = cls.floating_ips_client
diff --git a/tempest/api/compute/limits/test_absolute_limits.py b/tempest/api/compute/limits/test_absolute_limits.py
index 58352bd..0585fec 100644
--- a/tempest/api/compute/limits/test_absolute_limits.py
+++ b/tempest/api/compute/limits/test_absolute_limits.py
@@ -42,6 +42,6 @@
# check whether all expected elements exist
missing_elements =\
[ele for ele in expected_elements if ele not in absolute_limits]
- self.assertEqual(0, len(missing_elements),
+ self.assertEmpty(missing_elements,
"Failed to find element %s in absolute limits list"
% ', '.join(ele for ele in missing_elements))
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 3378ef8..b568f7d 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -186,4 +186,4 @@
rules = (self.security_groups_client.show_security_group(sg1_id)
['security_group']['rules'])
# The group1 has no rules because group2 has deleted
- self.assertEqual(0, len(rules))
+ self.assertEmpty(rules)
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index e50b29a..65d5042 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -49,7 +49,6 @@
cls.subnets_client = cls.os_primary.subnets_client
cls.ports_client = cls.os_primary.ports_client
- # TODO(mriedem): move this into a common waiters utility module
def wait_for_port_detach(self, port_id):
"""Waits for the port's device_id to be unset.
@@ -264,7 +263,8 @@
# create two servers
_, servers = compute.create_test_server(
- self.os, tenant_network=network, wait_until='ACTIVE', min_count=2)
+ self.os_primary, tenant_network=network,
+ wait_until='ACTIVE', min_count=2)
# add our cleanups for the servers since we bypassed the base class
for server in servers:
self.addCleanup(self.delete_server, server['id'])
diff --git a/tempest/api/compute/servers/test_availability_zone.py b/tempest/api/compute/servers/test_availability_zone.py
index 82e74ed..36828d6 100644
--- a/tempest/api/compute/servers/test_availability_zone.py
+++ b/tempest/api/compute/servers/test_availability_zone.py
@@ -29,4 +29,4 @@
def test_get_availability_zone_list_with_non_admin_user(self):
# List of availability zone with non-administrator user
availability_zone = self.client.list_availability_zones()
- self.assertGreater(len(availability_zone['availabilityZoneInfo']), 0)
+ self.assertNotEmpty(availability_zone['availabilityZoneInfo'])
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 1ad153a..921b7da 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -142,7 +142,7 @@
# Verify only the expected number of servers are returned
params = {'limit': 0}
servers = self.client.list_servers(**params)
- self.assertEqual(0, len(servers['servers']))
+ self.assertEmpty(servers['servers'])
@decorators.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
def test_list_servers_filter_by_exceed_limit(self):
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 3e32c2d..6c9b287 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -84,12 +84,6 @@
servers = body['servers']
self.assertEmpty(servers)
- @decorators.idempotent_id('12c80a9f-2dec-480e-882b-98ba15757659')
- def test_list_servers_by_limits(self):
- # List servers by specifying limits
- body = self.client.list_servers(limit=1)
- self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
-
@decorators.attr(type=['negative'])
@decorators.idempotent_id('d47c17fb-eebd-4287-8e95-f20a7e627b18')
def test_list_servers_by_limits_greater_than_actual_count(self):
@@ -128,7 +122,7 @@
# Return an empty list when a date in the future is passed
changes_since = {'changes-since': '2051-01-01T12:34:00Z'}
body = self.client.list_servers(**changes_since)
- self.assertEqual(0, len(body['servers']))
+ self.assertEmpty(body['servers'])
@decorators.attr(type=['negative'])
@decorators.idempotent_id('93055106-2d34-46fe-af68-d9ddbf7ee570')
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index 7cbb513..059454d 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -24,7 +24,7 @@
def test_multiple_create(self):
tenant_network = self.get_tenant_network()
body, servers = compute.create_test_server(
- self.os,
+ self.os_primary,
wait_until='ACTIVE',
min_count=2,
tenant_network=tenant_network)
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 76b9c44..6f072b2 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -531,6 +531,10 @@
self.client.unshelve_server(self.server_id)
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+ images = self.compute_images_client.list_images(**params)['images']
+ msg = ('After unshelve, shelved image is not deleted.')
+ self.assertEmpty(images, msg)
+
@decorators.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
def test_stop_start_server(self):
self.client.stop_server(self.server_id)
diff --git a/tempest/api/compute/servers/test_server_addresses.py b/tempest/api/compute/servers/test_server_addresses.py
index 92b1ff1..022ceba 100644
--- a/tempest/api/compute/servers/test_server_addresses.py
+++ b/tempest/api/compute/servers/test_server_addresses.py
@@ -48,9 +48,9 @@
# We do not know the exact network configuration, but an instance
# should at least have a single public or private address
- self.assertGreaterEqual(len(addresses), 1)
+ self.assertNotEmpty(addresses)
for network_addresses in addresses.values():
- self.assertGreaterEqual(len(network_addresses), 1)
+ self.assertNotEmpty(network_addresses)
for address in network_addresses:
self.assertTrue(address['addr'])
self.assertTrue(address['version'])
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 83151b3..b0ef3bc 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -65,6 +65,8 @@
@decorators.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
@testtools.skipUnless(CONF.network.public_network_id,
'The public_network_id option must be specified.')
+ @testtools.skipUnless(CONF.network_feature_enabled.floating_ips,
+ "Floating ips are not available")
def test_rescued_vm_associate_dissociate_floating_ip(self):
# Association of floating IP to a rescued vm
floating_ip_body = self.floating_ips_client.create_floating_ip(
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 610121b..6b625d9 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -58,7 +58,7 @@
output = self.client.list_virtual_interfaces(self.server['id'])
self.assertIsNotNone(output)
virt_ifaces = output
- self.assertNotEqual(0, len(virt_ifaces['virtual_interfaces']),
+ self.assertNotEmpty(virt_ifaces['virtual_interfaces'],
'Expected virtual interfaces, got 0 '
'interfaces.')
for virt_iface in virt_ifaces['virtual_interfaces']:
diff --git a/tempest/api/compute/volumes/test_volume_snapshots.py b/tempest/api/compute/volumes/test_volume_snapshots.py
index 2f3a06e..0f436eb 100644
--- a/tempest/api/compute/volumes/test_volume_snapshots.py
+++ b/tempest/api/compute/volumes/test_volume_snapshots.py
@@ -27,6 +27,11 @@
class VolumesSnapshotsTestJSON(base.BaseV2ComputeTest):
+ # These tests will fail with a 404 starting from microversion 2.36. For
+ # more information, see:
+ # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ max_microversion = '2.35'
+
@classmethod
def skip_checks(cls):
super(VolumesSnapshotsTestJSON, cls).skip_checks()
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 43c837a..01cfb5f 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -16,7 +16,6 @@
from testtools import matchers
from tempest.api.compute import base
-from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
@@ -27,6 +26,11 @@
class VolumesGetTestJSON(base.BaseV2ComputeTest):
+ # These tests will fail with a 404 starting from microversion 2.36. For
+ # more information, see:
+ # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ max_microversion = '2.35'
+
@classmethod
def skip_checks(cls):
super(VolumesGetTestJSON, cls).skip_checks()
@@ -37,7 +41,7 @@
@classmethod
def setup_clients(cls):
super(VolumesGetTestJSON, cls).setup_clients()
- cls.client = cls.volumes_extensions_client
+ cls.volumes_client = cls.volumes_extensions_client
@decorators.idempotent_id('f10f25eb-9775-4d9d-9cbe-1cf54dae9d5f')
def test_volume_create_get_delete(self):
@@ -45,22 +49,19 @@
v_name = data_utils.rand_name(self.__class__.__name__ + '-Volume')
metadata = {'Type': 'work'}
# Create volume
- volume = self.client.create_volume(size=CONF.volume.volume_size,
- display_name=v_name,
- metadata=metadata)['volume']
+ volume = self.create_volume(size=CONF.volume.volume_size,
+ display_name=v_name,
+ metadata=metadata)
self.assertIn('id', volume)
- self.addCleanup(self.delete_volume, volume['id'])
self.assertIn('displayName', volume)
self.assertEqual(volume['displayName'], v_name,
"The created volume name is not equal "
"to the requested name")
self.assertIsNotNone(volume['id'],
"Field volume id is empty or not found.")
- # Wait for Volume status to become ACTIVE
- waiters.wait_for_volume_resource_status(self.client, volume['id'],
- 'available')
# GET Volume
- fetched_volume = self.client.show_volume(volume['id'])['volume']
+ fetched_volume = self.volumes_client.show_volume(
+ volume['id'])['volume']
# Verification of details of fetched Volume
self.assertEqual(v_name,
fetched_volume['displayName'],
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 0d8214f..b2aebe7 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -27,6 +27,11 @@
# If you are running a Devstack environment, ensure that the
# VOLUME_BACKING_FILE_SIZE is at least 4G in your localrc
+ # These tests will fail with a 404 starting from microversion 2.36. For
+ # more information, see:
+ # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ max_microversion = '2.35'
+
@classmethod
def skip_checks(cls):
super(VolumesTestJSON, cls).skip_checks()
diff --git a/tempest/api/compute/volumes/test_volumes_negative.py b/tempest/api/compute/volumes/test_volumes_negative.py
index 80db1be..87f7d8a 100644
--- a/tempest/api/compute/volumes/test_volumes_negative.py
+++ b/tempest/api/compute/volumes/test_volumes_negative.py
@@ -24,6 +24,11 @@
class VolumesNegativeTest(base.BaseV2ComputeTest):
+ # These tests will fail with a 404 starting from microversion 2.36. For
+ # more information, see:
+ # https://developer.openstack.org/api-ref/compute/#volume-extension-os-volumes-os-snapshots-deprecated
+ max_microversion = '2.35'
+
@classmethod
def skip_checks(cls):
super(VolumesNegativeTest, cls).skip_checks()
diff --git a/tempest/api/identity/admin/v2/test_endpoints.py b/tempest/api/identity/admin/v2/test_endpoints.py
index db32f5a..59fc4d8 100644
--- a/tempest/api/identity/admin/v2/test_endpoints.py
+++ b/tempest/api/identity/admin/v2/test_endpoints.py
@@ -62,7 +62,7 @@
# Asserting LIST endpoints
missing_endpoints =\
[e for e in self.setup_endpoints if e not in fetched_endpoints]
- self.assertEqual(0, len(missing_endpoints),
+ self.assertEmpty(missing_endpoints,
"Failed to find endpoint %s in fetched list" %
', '.join(str(e) for e in missing_endpoints))
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index 2711a2d..0d98af5 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -141,7 +141,7 @@
# verifying the user Id in the list
missing_users =\
[user for user in user_ids if user not in fetched_user_ids]
- self.assertEqual(0, len(missing_users),
+ self.assertEmpty(missing_users,
"Failed to find user %s in fetched list" %
', '.join(m_user for m_user in missing_users))
@@ -169,7 +169,7 @@
# verifying the user Id in the list
missing_users = [missing_user for missing_user in user_ids
if missing_user not in fetched_user_ids]
- self.assertEqual(0, len(missing_users),
+ self.assertEmpty(missing_users,
"Failed to find user %s in fetched list" %
', '.join(m_user for m_user in missing_users))
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 75e877a..15b2008 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -107,6 +107,6 @@
fetched_cred_ids.append(i['id'])
missing_creds = [c for c in created_cred_ids
if c not in fetched_cred_ids]
- self.assertEqual(0, len(missing_creds),
+ self.assertEmpty(missing_creds,
"Failed to find cred %s in fetched list" %
', '.join(m_cred for m_cred in missing_creds))
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index cddba53..9fe978c 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -57,7 +57,7 @@
fetched_ids.append(d['id'])
missing_doms = [d for d in self.setup_domains
if d['id'] not in fetched_ids]
- self.assertEqual(0, len(missing_doms))
+ self.assertEmpty(missing_doms)
@decorators.idempotent_id('c6aee07b-4981-440c-bb0b-eb598f58ffe9')
def test_list_domains_filter_by_name(self):
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 09f92e2..b1ae2aa 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -64,7 +64,7 @@
# Asserting LIST endpoints
missing_endpoints =\
[e for e in self.setup_endpoints if e not in fetched_endpoints]
- self.assertEqual(0, len(missing_endpoints),
+ self.assertEmpty(missing_endpoints,
"Failed to find endpoint %s in fetched list" %
', '.join(str(e) for e in missing_endpoints))
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index bcbf6b6..47a3580 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -93,7 +93,7 @@
fetched_ids = [u['id'] for u in body]
missing_users = [u['id'] for u in self.users
if u['id'] not in fetched_ids]
- self.assertEqual(0, len(missing_users),
+ self.assertEmpty(missing_users,
"Failed to find user %s in fetched list" %
', '.join(m_user for m_user in missing_users))
diff --git a/tempest/api/identity/admin/v3/test_oauth_consumers.py b/tempest/api/identity/admin/v3/test_oauth_consumers.py
index f06fb8f..970ead3 100644
--- a/tempest/api/identity/admin/v3/test_oauth_consumers.py
+++ b/tempest/api/identity/admin/v3/test_oauth_consumers.py
@@ -14,7 +14,7 @@
# under the License.
from tempest.api.identity import base
-from tempest.common.utils import data_utils
+from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions as exceptions
diff --git a/tempest/api/identity/admin/v3/test_policies.py b/tempest/api/identity/admin/v3/test_policies.py
index 730d469..960e2cb 100644
--- a/tempest/api/identity/admin/v3/test_policies.py
+++ b/tempest/api/identity/admin/v3/test_policies.py
@@ -41,7 +41,7 @@
for p in body:
fetched_ids.append(p['id'])
missing_pols = [p for p in policy_ids if p not in fetched_ids]
- self.assertEqual(0, len(missing_pols))
+ self.assertEmpty(missing_pols)
@decorators.attr(type='smoke')
@decorators.idempotent_id('e544703a-2f03-4cf2-9b0f-350782fdb0d3')
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index ac550a7..d00e408 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -98,7 +98,7 @@
missing_regions =\
[e for e in self.setup_regions if e not in fetched_regions]
# Asserting List Regions response
- self.assertEqual(0, len(missing_regions),
+ self.assertEmpty(missing_regions,
"Failed to find region %s in fetched list" %
', '.join(str(e) for e in missing_regions))
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 8c5e63b..1acc67d 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -145,7 +145,7 @@
@decorators.idempotent_id('08ed85ce-2ba8-4864-b442-bcc61f16ae89')
def test_get_available_project_scopes(self):
- manager_project_id = self.manager.credentials.project_id
+ manager_project_id = self.os_primary.credentials.project_id
admin_user_id = self.os_admin.credentials.user_id
admin_role_id = self.get_role_by_name(CONF.identity.admin_role)['id']
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 751962f..409d4f8 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -131,7 +131,7 @@
missing_projects =\
[p for p in assigned_project_ids
if p not in fetched_project_ids]
- self.assertEqual(0, len(missing_projects),
+ self.assertEmpty(missing_projects,
"Failed to find project %s in fetched list" %
', '.join(m_project for m_project
in missing_projects))
diff --git a/tempest/api/identity/v3/test_tokens.py b/tempest/api/identity/v3/test_tokens.py
index c9d7a4d..042c821 100644
--- a/tempest/api/identity/v3/test_tokens.py
+++ b/tempest/api/identity/v3/test_tokens.py
@@ -54,15 +54,13 @@
self.assertEqual(subject_id, user_id)
else:
# Expect a user ID, but don't know what it will be.
- self.assertGreaterEqual(len(subject_id), 0,
- 'Expected user ID in token.')
+ self.assertIsNotNone(subject_id, 'Expected user ID in token.')
subject_name = resp['user']['name']
if username:
self.assertEqual(subject_name, username)
else:
# Expect a user name, but don't know what it will be.
- self.assertGreaterEqual(len(subject_name), 0,
- 'Expected user name in token.')
+ self.assertIsNotNone(subject_name, 'Expected user name in token.')
self.assertEqual(resp['methods'][0], 'password')
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index 4902316..bf2e510 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -54,6 +54,6 @@
self.alt_tenant_id)
body = self.image_member_client.list_image_members(image_id)
members = body['members']
- self.assertEqual(0, len(members), str(members))
+ self.assertEmpty(members)
self.assertRaises(
lib_exc.NotFound, self.alt_img_cli.show_image, image_id)
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index b341ab7..76723f4 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -43,7 +43,8 @@
else:
msg = ("The container format and the disk format don't match. "
"Container format: %(container)s, Disk format: %(disk)s." %
- {'container': container_format, 'disk': disk_format})
+ {'container': container_format, 'disk':
+ CONF.image.disk_formats})
raise exceptions.InvalidConfiguration(msg)
else:
disk_format = CONF.image.disk_formats[0]
diff --git a/tempest/api/network/admin/test_agent_management.py b/tempest/api/network/admin/test_agent_management.py
index 6389489..7304db9 100644
--- a/tempest/api/network/admin/test_agent_management.py
+++ b/tempest/api/network/admin/test_agent_management.py
@@ -49,7 +49,7 @@
@decorators.idempotent_id('e335be47-b9a1-46fd-be30-0874c0b751e6')
def test_list_agents_non_admin(self):
body = self.agents_client.list_agents()
- self.assertEqual(len(body["agents"]), 0)
+ self.assertEmpty(body["agents"])
@decorators.idempotent_id('869bc8e8-0fda-4a30-9b71-f8a7cf58ca9f')
def test_show_agent(self):
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index c83dd7f..4d41e33 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -10,11 +10,16 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from tempest.api.network import base
+from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
+CONF = config.CONF
+
class ExternalNetworksTestJSON(base.BaseAdminNetworkTest):
@@ -91,6 +96,8 @@
self.assertFalse(show_net['router:external'])
@decorators.idempotent_id('82068503-2cf2-4ed4-b3be-ecb89432e4bb')
+ @testtools.skipUnless(CONF.network_feature_enabled.floating_ips,
+ 'Floating ips are not availabled')
def test_delete_external_networks_with_floating_ip(self):
# Verifies external network can be deleted while still holding
# (unassociated) floating IPs
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 11f520a..7ee819e 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -34,6 +34,8 @@
if not CONF.network.public_network_id:
msg = "The public_network_id option must be specified."
raise cls.skipException(msg)
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
@classmethod
def setup_clients(cls):
diff --git a/tempest/api/network/admin/test_metering_extensions.py b/tempest/api/network/admin/test_metering_extensions.py
index 3f94868..21a7ab4 100644
--- a/tempest/api/network/admin/test_metering_extensions.py
+++ b/tempest/api/network/admin/test_metering_extensions.py
@@ -74,7 +74,7 @@
# Asserting that the label is not found in list after deletion
labels = self.admin_metering_labels_client.list_metering_labels(
id=metering_label_id)
- self.assertEqual(len(labels['metering_labels']), 0)
+ self.assertEmpty(labels['metering_labels'])
def _delete_metering_label_rule(self, metering_label_rule_id):
client = self.admin_metering_label_rules_client
@@ -89,7 +89,7 @@
# Verify label filtering
body = self.admin_metering_labels_client.list_metering_labels(id=33)
metering_labels = body['metering_labels']
- self.assertEqual(0, len(metering_labels))
+ self.assertEmpty(metering_labels)
@decorators.idempotent_id('ec8e15ff-95d0-433b-b8a6-b466bddb1e50')
def test_create_delete_metering_label_with_filters(self):
@@ -126,7 +126,7 @@
# Verify rule filtering
body = client.list_metering_label_rules(id=33)
metering_label_rules = body['metering_label_rules']
- self.assertEqual(0, len(metering_label_rules))
+ self.assertEmpty(metering_label_rules)
@decorators.idempotent_id('f4d547cd-3aee-408f-bf36-454f8825e045')
def test_create_delete_metering_label_rule_with_filters(self):
diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py
index ec8d260..07c4157 100644
--- a/tempest/api/network/admin/test_routers.py
+++ b/tempest/api/network/admin/test_routers.py
@@ -134,7 +134,7 @@
self.assertEqual(len(list_body['ports']), 1)
gw_port = list_body['ports'][0]
fixed_ips = gw_port['fixed_ips']
- self.assertGreaterEqual(len(fixed_ips), 1)
+ self.assertNotEmpty(fixed_ips)
# Assert that all of the IPs from the router gateway port
# are allocated from a valid public subnet.
public_net_body = self.admin_networks_client.show_network(
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index f0f92ac..c799b15 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -49,6 +49,8 @@
if not CONF.network.public_network_id:
msg = "The public_network_id option must be specified."
raise cls.skipException(msg)
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
index f5830ab..5ca17fe 100644
--- a/tempest/api/network/test_floating_ips_negative.py
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -40,6 +40,8 @@
if not CONF.network.public_network_id:
msg = "The public_network_id option must be specified."
raise cls.skipException(msg)
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index d78cd1e..128544b 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -156,7 +156,7 @@
self.assertEqual(len(list_body['ports']), 1)
gw_port = list_body['ports'][0]
fixed_ips = gw_port['fixed_ips']
- self.assertGreaterEqual(len(fixed_ips), 1)
+ self.assertNotEmpty(fixed_ips)
# Assert that all of the IPs from the router gateway port
# are allocated from a valid public subnet.
public_net_body = self.admin_networks_client.show_network(
diff --git a/tempest/api/object_storage/test_account_services.py b/tempest/api/object_storage/test_account_services.py
index e54b6e7..811e530 100644
--- a/tempest/api/object_storage/test_account_services.py
+++ b/tempest/api/object_storage/test_account_services.py
@@ -101,7 +101,7 @@
# Check only the format of common headers with custom matcher
self.assertThat(resp, custom_matchers.AreAllWellFormatted())
- self.assertEqual(len(container_list), 0)
+ self.assertEmpty(container_list)
@decorators.idempotent_id('1c7efa35-e8a2-4b0b-b5ff-862c7fd83704')
def test_list_containers_with_format_json(self):
@@ -162,7 +162,7 @@
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
- self.assertEqual(len(container_list), 0)
+ self.assertEmpty(container_list)
params = {'marker': self.containers[self.containers_count // 2]}
resp, container_list = \
@@ -182,7 +182,7 @@
resp, container_list = \
self.account_client.list_account_containers(params=params)
self.assertHeaders(resp, 'Account', 'GET')
- self.assertEqual(len(container_list), 0)
+ self.assertEmpty(container_list)
params = {'end_marker': self.containers[self.containers_count // 2]}
resp, container_list = \
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 21ea6ae..e9d2de0 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -414,7 +414,7 @@
self.container_name,
object_name)
self.assertIn('x-object-manifest', resp)
- self.assertNotEqual(len(resp['x-object-manifest']), 0)
+ self.assertNotEmpty(resp['x-object-manifest'])
@decorators.idempotent_id('0dbbe89c-6811-4d84-a2df-eca2bdd40c0e')
def test_update_object_metadata_with_x_object_metakey(self):
@@ -521,10 +521,10 @@
self.assertTrue(resp['etag'].endswith('\"'))
self.assertTrue(resp['etag'].strip('\"').isalnum())
self.assertTrue(re.match("^\d+\.?\d*\Z", resp['x-timestamp']))
- self.assertNotEqual(len(resp['content-type']), 0)
+ self.assertNotEmpty(resp['content-type'])
self.assertTrue(re.match("^tx[0-9a-f]{21}-[0-9a-f]{10}.*",
resp['x-trans-id']))
- self.assertNotEqual(len(resp['date']), 0)
+ self.assertNotEmpty(resp['date'])
self.assertEqual(resp['accept-ranges'], 'bytes')
self.assertEqual(resp['x-object-manifest'],
'%s/%s' % (self.container_name, object_name))
@@ -613,10 +613,10 @@
self.assertTrue(resp['etag'].endswith('\"'))
self.assertTrue(resp['etag'].strip('\"').isalnum())
self.assertTrue(re.match("^\d+\.?\d*\Z", resp['x-timestamp']))
- self.assertNotEqual(len(resp['content-type']), 0)
+ self.assertNotEmpty(resp['content-type'])
self.assertTrue(re.match("^tx[0-9a-f]{21}-[0-9a-f]{10}.*",
resp['x-trans-id']))
- self.assertNotEqual(len(resp['date']), 0)
+ self.assertNotEmpty(resp['date'])
self.assertEqual(resp['accept-ranges'], 'bytes')
self.assertEqual(resp['x-object-manifest'],
'%s/%s' % (self.container_name, object_name))
diff --git a/tempest/api/volume/admin/test_snapshot_manage.py b/tempest/api/volume/admin/test_snapshot_manage.py
index a2d5fb1..9f96194 100644
--- a/tempest/api/volume/admin/test_snapshot_manage.py
+++ b/tempest/api/volume/admin/test_snapshot_manage.py
@@ -18,6 +18,7 @@
from tempest.api.volume import base
from tempest.common import waiters
from tempest import config
+from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
CONF = config.CONF
@@ -56,11 +57,19 @@
# Verify snapshot does not exist in snapshot list
self.assertNotIn(snapshot['id'], snapshot_list)
+ name = data_utils.rand_name(self.__class__.__name__ +
+ '-Managed-Snapshot')
+ description = data_utils.rand_name(self.__class__.__name__ +
+ '-Managed-Snapshot-Description')
+ metadata = {"manage-snap-meta1": "value1",
+ "manage-snap-meta2": "value2",
+ "manage-snap-meta3": "value3"}
+
# Manage the snapshot
snapshot_ref = '_snapshot-%s' % snapshot['id']
new_snapshot = self.admin_snapshot_manage_client.manage_snapshot(
- volume_id=volume['id'],
- ref={'source-name': snapshot_ref})['snapshot']
+ volume_id=volume['id'], ref={'source-name': snapshot_ref},
+ name=name, description=description, metadata=metadata)['snapshot']
self.addCleanup(self.delete_snapshot, new_snapshot['id'],
self.admin_snapshots_client)
@@ -70,4 +79,10 @@
'available')
# Verify the managed snapshot has the expected parent volume
- self.assertEqual(new_snapshot['volume_id'], volume['id'])
+ # and the expected field values.
+ new_snap_info = self.admin_snapshots_client.show_snapshot(
+ new_snapshot['id'])['snapshot']
+ self.assertEqual(volume['id'], new_snap_info['volume_id'])
+ self.assertEqual(name, new_snap_info['name'])
+ self.assertEqual(description, new_snap_info['description'])
+ self.assertEqual(metadata, new_snap_info['metadata'])
diff --git a/tempest/api/volume/admin/test_volume_pools.py b/tempest/api/volume/admin/test_volume_pools.py
index 60a3bda..d389c26 100644
--- a/tempest/api/volume/admin/test_volume_pools.py
+++ b/tempest/api/volume/admin/test_volume_pools.py
@@ -22,7 +22,7 @@
class VolumePoolsAdminTestsJSON(base.BaseVolumeAdminTest):
def _assert_pools(self, with_detail=False):
- cinder_pools = self.admin_volume_client.show_pools(
+ cinder_pools = self.admin_scheduler_stats_client.list_pools(
detail=with_detail)['pools']
self.assertIn('name', cinder_pools[0])
if with_detail:
diff --git a/tempest/api/volume/admin/test_volume_quota_classes.py b/tempest/api/volume/admin/test_volume_quota_classes.py
index 016d87a..f551575 100644
--- a/tempest/api/volume/admin/test_volume_quota_classes.py
+++ b/tempest/api/volume/admin/test_volume_quota_classes.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import random
+
from oslo_log import log as logging
from testtools import matchers
@@ -53,31 +55,41 @@
LOG.debug("Get the current default quota class values")
body = self.admin_quota_classes_client.show_quota_class_set(
'default')['quota_class_set']
- body.pop('id')
- # Restore the defaults when the test is done
- self.addCleanup(self._restore_default_quotas, body.copy())
+ # Note(jeremyZ) Only include specified quota keys to avoid the conflict
+ # that other tests may create/delete volume types or update volume
+ # type's default quotas in concurrency running.
+ update_kwargs = {key: body[key] for key in body if key in QUOTA_KEYS}
- # Increment some of the values for updating the default quota class.
- # For safety, only items with value >= 0 will be updated, and items
- # with value < 0 (-1 means unlimited) will be ignored.
- for quota, default in body.items():
+ # Restore the defaults when the test is done.
+ self.addCleanup(self._restore_default_quotas, update_kwargs.copy())
+
+ # Note(jeremyZ) Increment some of the values for updating the default
+ # quota class. For safety, only items with value >= 0 will be updated,
+ # and items with value < 0 (-1 means unlimited) will be ignored.
+ for quota, default in update_kwargs.items():
if default >= 0:
- body[quota] = default + 1
+ update_kwargs[quota] = default + 1
+
+ # Create a volume type for updating default quotas class.
+ volume_type_name = self.create_volume_type()['name']
+ for key in ['volumes', 'snapshots', 'gigabytes']:
+ update_kwargs['%s_%s' % (key, volume_type_name)] = \
+ random.randint(1, 10)
LOG.debug("Update limits for the default quota class set")
update_body = self.admin_quota_classes_client.update_quota_class_set(
- 'default', **body)['quota_class_set']
+ 'default', **update_kwargs)['quota_class_set']
self.assertThat(update_body.items(),
- matchers.ContainsAll(body.items()))
+ matchers.ContainsAll(update_kwargs.items()))
- # Verify current project's default quotas
+ # Verify current project's default quotas.
default_quotas = self.admin_quotas_client.show_default_quota_set(
- self.os_adm.credentials.tenant_id)['quota_set']
+ self.os_admin.credentials.tenant_id)['quota_set']
self.assertThat(default_quotas.items(),
- matchers.ContainsAll(body.items()))
+ matchers.ContainsAll(update_kwargs.items()))
- # Verify a new project's default quotas
+ # Verify a new project's default quotas.
project_name = data_utils.rand_name('quota_class_tenant')
description = data_utils.rand_name('desc_')
project_id = self.identity_utils.create_project(
@@ -86,4 +98,4 @@
default_quotas = self.admin_quotas_client.show_default_quota_set(
project_id)['quota_set']
self.assertThat(default_quotas.items(),
- matchers.ContainsAll(body.items()))
+ matchers.ContainsAll(update_kwargs.items()))
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 4aab9c1..293af81 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -41,13 +41,13 @@
def test_list_services(self):
services = (self.admin_volume_services_client.list_services()
['services'])
- self.assertNotEqual(0, len(services))
+ self.assertNotEmpty(services)
@decorators.idempotent_id('63a3e1ca-37ee-4983-826d-83276a370d25')
def test_get_service_by_service_binary_name(self):
services = (self.admin_volume_services_client.list_services(
binary=self.binary_name)['services'])
- self.assertNotEqual(0, len(services))
+ self.assertNotEmpty(services)
for service in services:
self.assertEqual(self.binary_name, service['binary'])
@@ -76,7 +76,7 @@
services = (self.admin_volume_services_client.list_services(
host=hostname, binary='cinder-volume')['services'])
- self.assertNotEqual(0, len(services),
+ self.assertNotEmpty(services,
'cinder-volume not found on host %s' % hostname)
self.assertEqual(hostname, _get_host(services[0]['host']))
self.assertEqual('cinder-volume', services[0]['binary'])
@@ -87,6 +87,6 @@
services = (self.admin_volume_services_client.list_services(
host=self.host_name, binary=self.binary_name))['services']
- self.assertNotEqual(0, len(services))
+ self.assertNotEmpty(services)
self.assertEqual(self.host_name, _get_host(services[0]['host']))
self.assertEqual(self.binary_name, services[0]['binary'])
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index ac717f8..af1024c 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -57,8 +57,6 @@
"to the requested name")
self.assertIsNotNone(volume['id'],
"Field volume id is empty or not found.")
- waiters.wait_for_volume_resource_status(self.volumes_client,
- volume['id'], 'available')
# Update volume with new volume_type
self.volumes_client.retype_volume(volume['id'],
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index acff7cd..b81a477 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -70,7 +70,7 @@
@test.services('compute')
def test_force_detach_volume(self):
# Create a server and a volume
- server_id = self.create_server(wait_until='ACTIVE')['id']
+ server_id = self.create_server()['id']
volume_id = self.create_volume()['id']
# Attach volume
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 3f33c7b..8d66156 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -217,16 +217,17 @@
cls.snapshots_client.wait_for_resource_deletion,
snapshot)
- def create_server(self, **kwargs):
+ def create_server(self, wait_until='ACTIVE', **kwargs):
name = kwargs.pop(
'name',
data_utils.rand_name(self.__class__.__name__ + '-instance'))
tenant_network = self.get_tenant_network()
body, _ = compute.create_test_server(
- self.os,
+ self.os_primary,
tenant_network=tenant_network,
name=name,
+ wait_until=wait_until,
**kwargs)
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
diff --git a/tempest/api/volume/test_availability_zone.py b/tempest/api/volume/test_availability_zone.py
index 666efdf..d0a87db 100644
--- a/tempest/api/volume/test_availability_zone.py
+++ b/tempest/api/volume/test_availability_zone.py
@@ -30,4 +30,4 @@
# List of availability zone
availability_zone = (self.client.list_availability_zones()
['availabilityZoneInfo'])
- self.assertGreater(len(availability_zone), 0)
+ self.assertNotEmpty(availability_zone)
diff --git a/tempest/api/volume/test_volume_absolute_limits.py b/tempest/api/volume/test_volume_absolute_limits.py
index 870b9f0..4018468 100644
--- a/tempest/api/volume/test_volume_absolute_limits.py
+++ b/tempest/api/volume/test_volume_absolute_limits.py
@@ -24,7 +24,7 @@
# NOTE(zhufl): This inherits from BaseVolumeAdminTest because
# it requires force_tenant_isolation=True, which need admin
# credentials to create non-admin users for the tests.
-class AbsoluteLimitsTests(base.BaseVolumeAdminTest):
+class AbsoluteLimitsTests(base.BaseVolumeAdminTest): # noqa
# avoid existing volumes of pre-defined tenant
force_tenant_isolation = True
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 5a192ac..2c13a3c 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -13,8 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-from testtools import matchers
-
from tempest.api.volume import base
from tempest.common import waiters
from tempest.lib import decorators
@@ -56,7 +54,7 @@
# List volume transfers, the result should be greater than
# or equal to 1
body = self.client.list_volume_transfers()['transfers']
- self.assertThat(len(body), matchers.GreaterThan(0))
+ self.assertNotEmpty(body)
# Accept a volume transfer by alt_tenant
body = self.alt_client.accept_volume_transfer(
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 0e7f1e9..8541c6d 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -38,7 +38,7 @@
@test.services('compute')
def test_attach_detach_volume_to_instance(self):
# Create a server
- server = self.create_server(wait_until='ACTIVE')
+ server = self.create_server()
# Volume is attached and detached successfully from an instance
self.volumes_client.attach_volume(self.volume['id'],
instance_uuid=server['id'],
@@ -69,7 +69,7 @@
@test.services('compute')
def test_get_volume_attachment(self):
# Create a server
- server = self.create_server(wait_until='ACTIVE')
+ server = self.create_server()
# Verify that a volume's attachment information is retrieved
self.volumes_client.attach_volume(self.volume['id'],
instance_uuid=server['id'],
diff --git a/tempest/api/volume/test_volumes_backup.py b/tempest/api/volume/test_volumes_backup.py
index 5ad209c..da4324a 100644
--- a/tempest/api/volume/test_volumes_backup.py
+++ b/tempest/api/volume/test_volumes_backup.py
@@ -108,7 +108,7 @@
volume = self.create_volume()
self.addCleanup(self.volumes_client.delete_volume,
volume['id'])
- server = self.create_server(wait_until='ACTIVE')
+ server = self.create_server()
# Attach volume to instance
self.attach_volume(server['id'], volume['id'])
# Create backup using force flag
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index fc3bcab..4e19e62 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -170,7 +170,7 @@
@decorators.idempotent_id('f5e56b0a-5d02-43c1-a2a7-c9b792c2e3f6')
@test.services('compute')
def test_attach_volumes_with_nonexistent_volume_id(self):
- server = self.create_server(wait_until='ACTIVE')
+ server = self.create_server()
self.assertRaises(lib_exc.NotFound,
self.volumes_client.attach_volume,
@@ -261,7 +261,7 @@
params = {'name': v_name}
fetched_volume = self.volumes_client.list_volumes(
params=params)['volumes']
- self.assertEqual(0, len(fetched_volume))
+ self.assertEmpty(fetched_volume)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('9ca17820-a0e7-4cbd-a7fa-f4468735e359')
@@ -271,7 +271,7 @@
fetched_volume = \
self.volumes_client.list_volumes(
detail=True, params=params)['volumes']
- self.assertEqual(0, len(fetched_volume))
+ self.assertEmpty(fetched_volume)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('143b279b-7522-466b-81be-34a87d564a7c')
@@ -279,7 +279,7 @@
params = {'status': 'null'}
fetched_volume = self.volumes_client.list_volumes(
params=params)['volumes']
- self.assertEqual(0, len(fetched_volume))
+ self.assertEmpty(fetched_volume)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('ba94b27b-be3f-496c-a00e-0283b373fa75')
@@ -288,7 +288,7 @@
fetched_volume = \
self.volumes_client.list_volumes(detail=True,
params=params)['volumes']
- self.assertEqual(0, len(fetched_volume))
+ self.assertEmpty(fetched_volume)
@decorators.attr(type=['negative'])
@decorators.idempotent_id('5b810c91-0ad1-47ce-aee8-615f789be78f')
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 99918eb..44c1def 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -39,7 +39,7 @@
@test.services('compute')
def test_snapshot_create_delete_with_volume_in_use(self):
# Create a test instance
- server = self.create_server(wait_until='ACTIVE')
+ server = self.create_server()
self.attach_volume(server['id'], self.volume_origin['id'])
# Snapshot a volume which attached to an instance with force=False
@@ -65,7 +65,7 @@
snapshot1 = self.create_snapshot(self.volume_origin['id'])
# Create a server and attach it
- server = self.create_server(wait_until='ACTIVE')
+ server = self.create_server()
self.attach_volume(server['id'], self.volume_origin['id'])
# Now that the volume is attached, create another snapshots
diff --git a/tempest/clients.py b/tempest/clients.py
index 4baa31d..7b6cc19 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -41,8 +41,7 @@
_, identity_uri = get_auth_provider_class(credentials)
super(Manager, self).__init__(
credentials=credentials, identity_uri=identity_uri, scope=scope,
- region=CONF.identity.region,
- client_parameters=self._prepare_configuration())
+ region=CONF.identity.region)
# TODO(andreaf) When clients are initialised without the right
# parameters available, the calls below will trigger a KeyError.
# We should catch that and raise a better error.
@@ -62,35 +61,6 @@
build_timeout=CONF.orchestration.build_timeout,
**self.default_params)
- def _prepare_configuration(self):
- """Map values from CONF into Manager parameters
-
- This uses `config.service_client_config` for all services to collect
- most configuration items needed to init the clients.
- """
- # NOTE(andreaf) Once all service clients in Tempest are migrated
- # to tempest.lib, their configuration will be picked up from the
- # registry, and this method will become redundant.
-
- configuration = {}
-
- # Setup the parameters for all Tempest services which are not in lib.
- # NOTE(andreaf) Since client.py is an internal module of Tempest,
- # it doesn't have to consider plugin configuration.
- for service in clients._tempest_internal_modules():
- try:
- # NOTE(andreaf) Use the unversioned service name to fetch
- # the configuration since configuration is not versioned.
- service_for_config = service.split('.')[0]
- if service_for_config not in configuration:
- configuration[service_for_config] = (
- config.service_client_config(service_for_config))
- except lib_exc.UnknownServiceClient:
- LOG.warning(
- 'Could not load configuration for service %s', service)
-
- return configuration
-
def _set_network_clients(self):
self.network_agents_client = self.network.AgentsClient()
self.network_extensions_client = self.network.ExtensionsClient()
@@ -296,8 +266,10 @@
self.volume_v2.TransfersClient()
def _set_object_storage_clients(self):
- # Mandatory parameters (always defined)
- params = self.parameters['object-storage']
+ # NOTE(andreaf) Load configuration from config. Once object storage
+ # is in lib, configuration will be pulled directly from the registry
+ # and this will not be required anymore.
+ params = config.service_client_config('object-storage')
self.account_client = object_storage.AccountClient(self.auth_provider,
**params)
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 0a1881c..6b81e0d 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -167,15 +167,13 @@
def get_extension_client(os, service):
extensions_client = {
'nova': os.extensions_client,
- 'cinder': os.volumes_extension_client,
'neutron': os.network_extensions_client,
'swift': os.capabilities_client,
+ # NOTE: Cinder v3 API is current and v2 and v1 are deprecated.
+ # V3 extension API is the same as v2, so we reuse the v2 client
+ # for v3 API also.
+ 'cinder': os.volumes_v2_extension_client,
}
- # NOTE (e0ne): Use Cinder API v2 by default because v1 is deprecated
- if CONF.volume_feature_enabled.api_v2:
- extensions_client['cinder'] = os.volumes_v2_extension_client
- else:
- extensions_client['cinder'] = os.volumes_extension_client
if service not in extensions_client:
print('No tempest extensions client for %s' % service)
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 9319d2a..99a628e 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -64,10 +64,14 @@
# Show header line too
selected.append(l)
# lsblk lists disk type in a column right-aligned with TYPE
- elif pos > 0 and l[pos:pos + 4] == "disk":
+ elif pos is not None and pos > 0 and l[pos:pos + 4] == "disk":
selected.append(l)
- return "\n".join(selected)
+ if selected:
+ return "\n".join(selected)
+ else:
+ msg = "'TYPE' column is requred but the output doesn't have it: "
+ raise tempest.lib.exceptions.TempestException(msg + output)
def get_boot_time(self):
cmd = 'cut -f1 -d. /proc/uptime'
@@ -89,12 +93,12 @@
def get_nic_name_by_mac(self, address):
cmd = "ip -o link | awk '/%s/ {print $2}'" % address
nic = self.exec_command(cmd)
- return nic.strip().strip(":").lower()
+ return nic.strip().strip(":").split('@')[0].lower()
def get_nic_name_by_ip(self, address):
cmd = "ip -o addr | awk '/%s/ {print $2}'" % address
nic = self.exec_command(cmd)
- return nic.strip().strip(":").lower()
+ return nic.strip().strip(":").split('@')[0].lower()
def get_dns_servers(self):
cmd = 'cat /etc/resolv.conf'
diff --git a/tempest/common/validation_resources.py b/tempest/common/validation_resources.py
index b15796f..9e83a07 100644
--- a/tempest/common/validation_resources.py
+++ b/tempest/common/validation_resources.py
@@ -80,10 +80,23 @@
validation_data['security_group'] = \
create_ssh_security_group(os, add_rule)
if validation_resources['floating_ip']:
- floating_client = os.compute_floating_ips_client
- validation_data.update(
- floating_client.create_floating_ip(
- pool=CONF.network.floating_network_name))
+ if CONF.service_available.neutron:
+ floatingip = os.floating_ips_client.create_floatingip(
+ floating_network_id=CONF.network.public_network_id)
+ # validation_resources['floating_ip'] has historically looked
+ # like a compute API POST /os-floating-ips response, so we need
+ # to mangle it a bit for a Neutron response with different
+ # fields.
+ validation_data['floating_ip'] = floatingip['floatingip']
+ validation_data['floating_ip']['ip'] = (
+ floatingip['floatingip']['floating_ip_address'])
+ else:
+ # NOTE(mriedem): The os-floating-ips compute API was deprecated
+ # in the 2.36 microversion. Any tests for CRUD operations on
+ # floating IPs using the compute API should be capped at 2.35.
+ validation_data.update(
+ os.compute_floating_ips_client.create_floating_ip(
+ pool=CONF.network.floating_network_name))
return validation_data
diff --git a/tempest/config.py b/tempest/config.py
index a2e0877..989d53a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -647,6 +647,9 @@
cfg.BoolOpt('port_security',
default=False,
help="Does the test environment support port security?"),
+ cfg.BoolOpt('floating_ips',
+ default=True,
+ help='Does the test environment support floating_ips')
]
validation_group = cfg.OptGroup(name='validation',
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 4123ae5..067da09 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -273,6 +273,27 @@
yield(0, msg)
+def dont_put_admin_tests_on_nonadmin_path(logical_line, physical_line,
+ filename):
+ """Check admin tests should exist under admin path
+
+ T115
+ """
+
+ if 'tempest/api/' not in filename:
+ return
+
+ if pep8.noqa(physical_line):
+ return
+
+ if not re.match('class .*Test.*\(.*Admin.*\):', logical_line):
+ return
+
+ if not re.match('.\/tempest\/api\/.*\/admin\/.*', filename):
+ msg = 'T115: All admin tests should exist under admin path.'
+ yield(0, msg)
+
+
def factory(register):
register(import_no_clients_in_api_and_scenario_tests)
register(scenario_tests_need_service_tags)
@@ -287,3 +308,4 @@
register(dont_import_local_tempest_into_lib)
register(dont_use_config_in_tempest_lib)
register(use_rand_uuid_instead_of_uuid4)
+ register(dont_put_admin_tests_on_nonadmin_path)
diff --git a/tempest/lib/api_schema/response/compute/v2_13/__init__.py b/tempest/lib/api_schema/response/compute/v2_13/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_13/__init__.py
diff --git a/tempest/lib/api_schema/response/compute/v2_13/servers.py b/tempest/lib/api_schema/response/compute/v2_13/servers.py
new file mode 100644
index 0000000..a90f3e4
--- /dev/null
+++ b/tempest/lib/api_schema/response/compute/v2_13/servers.py
@@ -0,0 +1,34 @@
+# Copyright 2017 NTT Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import copy
+
+from tempest.lib.api_schema.response.compute.v2_1 import servers
+
+
+common_server_group = copy.deepcopy(servers.common_server_group)
+common_server_group['properties']['project_id'] = {'type': 'string'}
+common_server_group['properties']['user_id'] = {'type': 'string'}
+common_server_group['required'].append('project_id')
+common_server_group['required'].append('user_id')
+
+create_show_server_group = copy.deepcopy(servers.create_show_server_group)
+create_show_server_group['response_body']['properties'][
+ 'server_group'] = common_server_group
+
+delete_server_group = copy.deepcopy(servers.delete_server_group)
+
+list_server_groups = copy.deepcopy(servers.list_server_groups)
+list_server_groups['response_body']['properties']['server_groups'][
+ 'items'] = common_server_group
diff --git a/tempest/lib/common/ssh.py b/tempest/lib/common/ssh.py
index 657c0c1..d4ec6ad 100644
--- a/tempest/lib/common/ssh.py
+++ b/tempest/lib/common/ssh.py
@@ -84,10 +84,6 @@
ssh.set_missing_host_key_policy(
paramiko.AutoAddPolicy())
_start_time = time.time()
- if self.proxy_client is not None:
- proxy_chan = self._get_proxy_channel()
- else:
- proxy_chan = None
if self.pkey is not None:
LOG.info("Creating ssh connection to '%s:%d' as '%s'"
" with public key authentication",
@@ -98,6 +94,10 @@
self.host, self.port, self.username, str(self.password))
attempts = 0
while True:
+ if self.proxy_client is not None:
+ proxy_chan = self._get_proxy_channel()
+ else:
+ proxy_chan = None
try:
ssh.connect(self.host, port=self.port, username=self.username,
password=self.password,
diff --git a/tempest/lib/services/compute/server_groups_client.py b/tempest/lib/services/compute/server_groups_client.py
index 3a935b4..03cd645 100644
--- a/tempest/lib/services/compute/server_groups_client.py
+++ b/tempest/lib/services/compute/server_groups_client.py
@@ -17,12 +17,17 @@
from oslo_serialization import jsonutils as json
from tempest.lib.api_schema.response.compute.v2_1 import servers as schema
+from tempest.lib.api_schema.response.compute.v2_13 import servers as schemav213
from tempest.lib.common import rest_client
from tempest.lib.services.compute import base_compute_client
class ServerGroupsClient(base_compute_client.BaseComputeClient):
+ schema_versions_info = [
+ {'min': None, 'max': '2.12', 'schema': schema},
+ {'min': '2.13', 'max': None, 'schema': schemav213}]
+
def create_server_group(self, **kwargs):
"""Create the server group.
@@ -34,12 +39,14 @@
resp, body = self.post('os-server-groups', post_body)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.create_show_server_group, resp, body)
return rest_client.ResponseBody(resp, body)
def delete_server_group(self, server_group_id):
"""Delete the given server-group."""
resp, body = self.delete("os-server-groups/%s" % server_group_id)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.delete_server_group, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -47,6 +54,7 @@
"""List the server-groups."""
resp, body = self.get("os-server-groups")
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.list_server_groups, resp, body)
return rest_client.ResponseBody(resp, body)
@@ -54,5 +62,6 @@
"""Get the details of given server_group."""
resp, body = self.get("os-server-groups/%s" % server_group_id)
body = json.loads(body)
+ schema = self.get_schema(self.schema_versions_info)
self.validate_response(schema.create_show_server_group, resp, body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/identity/v3/services_client.py b/tempest/lib/services/identity/v3/services_client.py
index 17b0f24..7bbe850 100644
--- a/tempest/lib/services/identity/v3/services_client.py
+++ b/tempest/lib/services/identity/v3/services_client.py
@@ -76,7 +76,7 @@
url = 'services'
if params:
url += '?%s' % urllib.urlencode(params)
- resp, body = self.get('services')
+ resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/lib/services/volume/v2/types_client.py b/tempest/lib/services/volume/v2/types_client.py
index 5d30615..af4fd8c 100644
--- a/tempest/lib/services/volume/v2/types_client.py
+++ b/tempest/lib/services/volume/v2/types_client.py
@@ -41,7 +41,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/block-storage/v2/#list-volume-types
+ https://developer.openstack.org/api-ref/block-storage/v2/#list-all-volume-types-for-v2
"""
url = 'types'
if params:
@@ -57,7 +57,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/block-storage/v2/#show-volume-type-details
+ https://developer.openstack.org/api-ref/block-storage/v2/#show-volume-type-details-for-v2
"""
url = "types/%s" % volume_type_id
resp, body = self.get(url)
@@ -70,7 +70,7 @@
For a full list of available parameters, please refer to the official
API reference:
- http://developer.openstack.org/api-ref/block-storage/v2/#create-volume-type
+ https://developer.openstack.org/api-ref/block-storage/v2/#create-volume-type-for-v2
"""
post_body = json.dumps({'volume_type': kwargs})
resp, body = self.post('types', post_body)
diff --git a/tempest/lib/services/volume/v2/volumes_client.py b/tempest/lib/services/volume/v2/volumes_client.py
index 8b5c96f..f4e7c6a 100644
--- a/tempest/lib/services/volume/v2/volumes_client.py
+++ b/tempest/lib/services/volume/v2/volumes_client.py
@@ -321,7 +321,7 @@
self.expected_success(200, resp.status)
return rest_client.ResponseBody(resp, body)
- @removals.remove(message="use show_pools from tempest.lib.services."
+ @removals.remove(message="use list_pools from tempest.lib.services."
"volume.v2.scheduler_stats_client")
def show_pools(self, detail=False):
# List all the volumes pools (hosts)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index ef4506c..f25ab1d 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -47,40 +47,40 @@
def setup_clients(cls):
super(ScenarioTest, cls).setup_clients()
# Clients (in alphabetical order)
- cls.flavors_client = cls.manager.flavors_client
+ cls.flavors_client = cls.os_primary.flavors_client
cls.compute_floating_ips_client = (
- cls.manager.compute_floating_ips_client)
+ cls.os_primary.compute_floating_ips_client)
if CONF.service_available.glance:
# Check if glance v1 is available to determine which client to use.
if CONF.image_feature_enabled.api_v1:
- cls.image_client = cls.manager.image_client
+ cls.image_client = cls.os_primary.image_client
elif CONF.image_feature_enabled.api_v2:
- cls.image_client = cls.manager.image_client_v2
+ cls.image_client = cls.os_primary.image_client_v2
else:
raise lib_exc.InvalidConfiguration(
'Either api_v1 or api_v2 must be True in '
'[image-feature-enabled].')
# Compute image client
- cls.compute_images_client = cls.manager.compute_images_client
- cls.keypairs_client = cls.manager.keypairs_client
+ cls.compute_images_client = cls.os_primary.compute_images_client
+ cls.keypairs_client = cls.os_primary.keypairs_client
# Nova security groups client
cls.compute_security_groups_client = (
- cls.manager.compute_security_groups_client)
+ cls.os_primary.compute_security_groups_client)
cls.compute_security_group_rules_client = (
- cls.manager.compute_security_group_rules_client)
- cls.servers_client = cls.manager.servers_client
- cls.interface_client = cls.manager.interfaces_client
+ cls.os_primary.compute_security_group_rules_client)
+ cls.servers_client = cls.os_primary.servers_client
+ cls.interface_client = cls.os_primary.interfaces_client
# Neutron network client
- cls.networks_client = cls.manager.networks_client
- cls.ports_client = cls.manager.ports_client
- cls.routers_client = cls.manager.routers_client
- cls.subnets_client = cls.manager.subnets_client
- cls.floating_ips_client = cls.manager.floating_ips_client
- cls.security_groups_client = cls.manager.security_groups_client
+ cls.networks_client = cls.os_primary.networks_client
+ cls.ports_client = cls.os_primary.ports_client
+ cls.routers_client = cls.os_primary.routers_client
+ cls.subnets_client = cls.os_primary.subnets_client
+ cls.floating_ips_client = cls.os_primary.floating_ips_client
+ cls.security_groups_client = cls.os_primary.security_groups_client
cls.security_group_rules_client = (
- cls.manager.security_group_rules_client)
- cls.volumes_client = cls.manager.volumes_v2_client
- cls.snapshots_client = cls.manager.snapshots_v2_client
+ cls.os_primary.security_group_rules_client)
+ cls.volumes_client = cls.os_primary.volumes_v2_client
+ cls.snapshots_client = cls.os_primary.snapshots_v2_client
# ## Test functions library
#
@@ -133,7 +133,7 @@
# Needed for the cross_tenant_traffic test:
if clients is None:
- clients = self.manager
+ clients = self.os_primary
if name is None:
name = data_utils.rand_name(self.__class__.__name__ + "-server")
@@ -195,7 +195,7 @@
tenant_network = self.get_tenant_network()
- body, servers = compute.create_test_server(
+ body, _ = compute.create_test_server(
clients,
tenant_network=tenant_network,
wait_until=wait_until,
@@ -741,7 +741,7 @@
:returns: True if subnet with cidr already exist in tenant
False else
"""
- cidr_in_use = self.admin_manager.subnets_client.list_subnets(
+ cidr_in_use = self.os_admin.subnets_client.list_subnets(
tenant_id=tenant_id, cidr=cidr)['subnets']
return len(cidr_in_use) != 0
@@ -790,7 +790,7 @@
return subnet
def _get_server_port_id_and_ip4(self, server, ip_addr=None):
- ports = self.admin_manager.ports_client.list_ports(
+ ports = self.os_admin.ports_client.list_ports(
device_id=server['id'], fixed_ip=ip_addr)['ports']
# A port can have more than one IP address in some cases.
# If the network is dual-stack (IPv4 + IPv6), this port is associated
@@ -811,7 +811,7 @@
if inactive:
LOG.warning("Instance has ports that are not ACTIVE: %s", inactive)
- self.assertNotEqual(0, len(port_map),
+ self.assertNotEmpty(port_map,
"No IPv4 addresses found in: %s" % ports)
self.assertEqual(len(port_map), 1,
"Found multiple IPv4 addresses: %s. "
@@ -820,9 +820,9 @@
return port_map[0]
def _get_network_by_name(self, network_name):
- net = self.admin_manager.networks_client.list_networks(
+ net = self.os_admin.networks_client.list_networks(
name=network_name)['networks']
- self.assertNotEqual(len(net), 0,
+ self.assertNotEmpty(net,
"Unable to get network by name: %s" % network_name)
return net[0]
@@ -1029,7 +1029,7 @@
if sg['tenant_id'] == tenant_id and sg['name'] == 'default'
]
msg = "No default security group for tenant %s." % (tenant_id)
- self.assertGreater(len(sgs), 0, msg)
+ self.assertNotEmpty(sgs, msg)
return sgs[0]
def _create_security_group_rule(self, secgroup=None,
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 8408a1e..25227be 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -36,8 +36,8 @@
def setup_clients(cls):
super(TestAggregatesBasicOps, cls).setup_clients()
# Use admin client by default
- cls.aggregates_client = cls.admin_manager.aggregates_client
- cls.hosts_client = cls.admin_manager.hosts_client
+ cls.aggregates_client = cls.os_admin.aggregates_client
+ cls.hosts_client = cls.os_admin.hosts_client
def _create_aggregate(self, **kwargs):
aggregate = (self.aggregates_client.create_aggregate(**kwargs)
@@ -52,7 +52,7 @@
def _get_host_name(self):
hosts = self.hosts_client.list_hosts()['hosts']
- self.assertGreaterEqual(len(hosts), 1)
+ self.assertNotEmpty(hosts)
computes = [x for x in hosts if x['service'] == 'compute']
return computes[0]['host_name']
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 5fee801..eae1056 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -103,6 +103,8 @@
@decorators.idempotent_id('bdbb5441-9204-419d-a225-b4fdbfb1a1a8')
@testtools.skipUnless(CONF.network.public_network_id,
'The public_network_id option must be specified.')
+ @testtools.skipUnless(CONF.network_feature_enabled.floating_ips,
+ 'Floating ips are not available')
@test.services('compute', 'volume', 'image', 'network')
def test_minimum_basic_scenario(self):
image = self.glance_image_create()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index c2fc1a7..c8add8b 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -48,6 +48,8 @@
msg = ('Either project_networks_reachable must be "true", or '
'public_network_id must be defined.')
raise cls.skipException(msg)
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
@classmethod
def setup_credentials(cls):
@@ -60,7 +62,7 @@
if test.is_extension_enabled('security-group', 'network'):
security_group = self._create_security_group()
security_groups = [{'name': security_group['name']}]
- network, subnet, router = self.create_networks()
+ network, _, _ = self.create_networks()
server = self.create_server(
networks=[{'uuid': network['id']}],
key_name=keypair['name'],
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 756ca4d..4efeffd 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -90,6 +90,8 @@
if not test.is_extension_enabled(ext, 'network'):
msg = "%s extension not enabled." % ext
raise cls.skipException(msg)
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
@classmethod
def setup_credentials(cls):
@@ -126,21 +128,21 @@
via checking the result of list_[networks,routers,subnets]
"""
- seen_nets = self.admin_manager.networks_client.list_networks()
+ seen_nets = self.os_admin.networks_client.list_networks()
seen_names = [n['name'] for n in seen_nets['networks']]
seen_ids = [n['id'] for n in seen_nets['networks']]
self.assertIn(self.network['name'], seen_names)
self.assertIn(self.network['id'], seen_ids)
if self.subnet:
- seen_subnets = self.admin_manager.subnets_client.list_subnets()
+ seen_subnets = self.os_admin.subnets_client.list_subnets()
seen_net_ids = [n['network_id'] for n in seen_subnets['subnets']]
seen_subnet_ids = [n['id'] for n in seen_subnets['subnets']]
self.assertIn(self.network['id'], seen_net_ids)
self.assertIn(self.subnet['id'], seen_subnet_ids)
if self.router:
- seen_routers = self.admin_manager.routers_client.list_routers()
+ seen_routers = self.os_admin.routers_client.list_routers()
seen_router_ids = [n['id'] for n in seen_routers['routers']]
seen_router_names = [n['name'] for n in seen_routers['routers']]
self.assertIn(self.router['name'],
@@ -210,7 +212,7 @@
self.servers, mtu=mtu)
def _disassociate_floating_ips(self):
- floating_ip, server = self.floating_ip_tuple
+ floating_ip, _ = self.floating_ip_tuple
self._disassociate_floating_ip(floating_ip)
self.floating_ip_tuple = Floating_IP_tuple(
floating_ip, None)
@@ -241,7 +243,7 @@
ip_address, private_key=private_key)
old_nic_list = self._get_server_nics(ssh_client)
# get a port from a list of one item
- port_list = self.admin_manager.ports_client.list_ports(
+ port_list = self.os_admin.ports_client.list_ports(
device_id=server['id'])['ports']
self.assertEqual(1, len(port_list))
old_port = port_list[0]
@@ -257,7 +259,7 @@
def check_ports():
self.new_port_list = [
port for port in
- self.admin_manager.ports_client.list_ports(
+ self.os_admin.ports_client.list_ports(
device_id=server['id'])['ports']
if port['id'] != old_port['id']
]
@@ -285,7 +287,7 @@
"guest after %s sec"
% CONF.network.build_timeout)
- num, new_nic = self.diff_list[0]
+ _, new_nic = self.diff_list[0]
ssh_client.exec_command("sudo ip addr add %s/%s dev %s" % (
new_port['fixed_ips'][0]['ip_address'],
CONF.network.project_network_mask_bits,
@@ -293,7 +295,7 @@
ssh_client.exec_command("sudo ip link set %s up" % new_nic)
def _get_server_nics(self, ssh_client):
- reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+):')
+ reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+)[@]?.*:')
ipatxt = ssh_client.exec_command("ip address")
return reg.findall(ipatxt)
@@ -309,7 +311,7 @@
# get all network ports in the new network
internal_ips = (
p['fixed_ips'][0]['ip_address'] for p in
- self.admin_manager.ports_client.list_ports(
+ self.os_admin.ports_client.list_ports(
tenant_id=server['tenant_id'],
network_id=network['id'])['ports']
if p['device_owner'].startswith('network')
@@ -330,7 +332,7 @@
# which is always IPv4, so we must only test connectivity to
# external IPv4 IPs if the external network is dualstack.
v4_subnets = [
- s for s in self.admin_manager.subnets_client.list_subnets(
+ s for s in self.os_admin.subnets_client.list_subnets(
network_id=CONF.network.public_network_id)['subnets']
if s['ip_version'] == 4
]
@@ -628,9 +630,9 @@
admin_state_up attribute of instance port to True
"""
self._setup_network_and_servers()
- floating_ip, server = self.floating_ip_tuple
+ _, server = self.floating_ip_tuple
server_id = server['id']
- port_id = self.admin_manager.ports_client.list_ports(
+ port_id = self.os_admin.ports_client.list_ports(
device_id=server_id)['ports'][0]['id']
server_pip = server['addresses'][self.network['name']][0]['addr']
@@ -685,7 +687,7 @@
'Server should have been created from a '
'pre-existing port.')
# Assert the port is bound to the server.
- port_list = self.admin_manager.ports_client.list_ports(
+ port_list = self.os_admin.ports_client.list_ports(
device_id=server['id'], network_id=self.network['id'])['ports']
self.assertEqual(1, len(port_list),
'There should only be one port created for '
@@ -704,7 +706,7 @@
# Boot another server with the same port to make sure nothing was
# left around that could cause issues.
server = self._create_server(self.network, port['id'])
- port_list = self.admin_manager.ports_client.list_ports(
+ port_list = self.os_admin.ports_client.list_ports(
device_id=server['id'], network_id=self.network['id'])['ports']
self.assertEqual(1, len(port_list),
'There should only be one port created for '
@@ -729,23 +731,23 @@
# TODO(yfried): refactor this test to be used for other agents (dhcp)
# as well
- list_hosts = (self.admin_manager.routers_client.
+ list_hosts = (self.os_admin.routers_client.
list_l3_agents_hosting_router)
- schedule_router = (self.admin_manager.network_agents_client.
+ schedule_router = (self.os_admin.network_agents_client.
create_router_on_l3_agent)
- unschedule_router = (self.admin_manager.network_agents_client.
+ unschedule_router = (self.os_admin.network_agents_client.
delete_router_from_l3_agent)
agent_list_alive = set(
a["id"] for a in
- self.admin_manager.network_agents_client.list_agents(
+ self.os_admin.network_agents_client.list_agents(
agent_type="L3 agent")['agents'] if a["alive"] is True
)
self._setup_network_and_servers()
# NOTE(kevinbenton): we have to use the admin credentials to check
# for the distributed flag because self.router only has a project view.
- admin = self.admin_manager.routers_client.show_router(
+ admin = self.os_admin.routers_client.show_router(
self.router['id'])
if admin['router'].get('distributed', False):
msg = "Rescheduling test does not apply to distributed routers."
@@ -823,7 +825,7 @@
self._create_new_network()
self._hotplug_server()
fip, server = self.floating_ip_tuple
- new_ports = self.admin_manager.ports_client.list_ports(
+ new_ports = self.os_admin.ports_client.list_ports(
device_id=server["id"], network_id=self.new_net["id"])['ports']
spoof_port = new_ports[0]
private_key = self._get_server_key(server)
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index daf4d13..6d9addd 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -51,6 +51,8 @@
if CONF.network.shared_physical_network:
msg = 'Deployment uses a shared physical network'
raise cls.skipException(msg)
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
@classmethod
def setup_credentials(cls):
@@ -144,7 +146,7 @@
"""
ports = [
p["mac_address"] for p in
- self.admin_manager.ports_client.list_ports(
+ self.os_admin.ports_client.list_ports(
device_id=sid, network_id=network_id)['ports']
]
@@ -169,7 +171,7 @@
# Turn on 2nd NIC for Cirros when dualnet
if dualnet:
- network, network_v6 = net_list
+ _, network_v6 = net_list
self.turn_nic6_on(sshv4_1, sid1, network_v6['id'])
self.turn_nic6_on(sshv4_2, sid2, network_v6['id'])
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 2116fe8..41c60f1 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -148,6 +148,8 @@
msg = ('Deployment uses a shared physical network, security '
'groups not supported')
raise cls.skipException(msg)
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
@classmethod
def setup_credentials(cls):
@@ -168,7 +170,7 @@
cls.floating_ips = {}
cls.tenants = {}
- cls.primary_tenant = cls.TenantProperties(cls.os)
+ cls.primary_tenant = cls.TenantProperties(cls.os_primary)
cls.alt_tenant = cls.TenantProperties(cls.os_alt)
for tenant in [cls.primary_tenant, cls.alt_tenant]:
cls.tenants[tenant.creds.tenant_id] = tenant
@@ -221,7 +223,7 @@
# Checks that we see the newly created network/subnet/router via
# checking the result of list_[networks,routers,subnets]
# Check that (router, subnet) couple exist in port_list
- seen_nets = self.admin_manager.networks_client.list_networks()
+ seen_nets = self.os_admin.networks_client.list_networks()
seen_names = [n['name'] for n in seen_nets['networks']]
seen_ids = [n['id'] for n in seen_nets['networks']]
@@ -230,13 +232,13 @@
seen_subnets = [
(n['id'], n['cidr'], n['network_id']) for n in
- self.admin_manager.subnets_client.list_subnets()['subnets']
+ self.os_admin.subnets_client.list_subnets()['subnets']
]
mysubnet = (tenant.subnet['id'], tenant.subnet['cidr'],
tenant.network['id'])
self.assertIn(mysubnet, seen_subnets)
- seen_routers = self.admin_manager.routers_client.list_routers()
+ seen_routers = self.os_admin.routers_client.list_routers()
seen_router_ids = [n['id'] for n in seen_routers['routers']]
seen_router_names = [n['name'] for n in seen_routers['routers']]
@@ -246,7 +248,7 @@
myport = (tenant.router['id'], tenant.subnet['id'])
router_ports = [
(i['device_id'], f['subnet_id'])
- for i in self.admin_manager.ports_client.list_ports(
+ for i in self.os_admin.ports_client.list_ports(
device_id=tenant.router['id'])['ports']
if net_info.is_router_interface_port(i)
for f in i['fixed_ips']
@@ -279,7 +281,7 @@
# Verify servers are on different compute nodes
if self.multi_node:
- adm_get_server = self.admin_manager.servers_client.show_server
+ adm_get_server = self.os_admin.servers_client.show_server
new_host = adm_get_server(server["id"])["server"][
"OS-EXT-SRV-ATTR:host"]
host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
@@ -447,7 +449,7 @@
mac_addr = mac_addr.strip().lower()
# Get the fixed_ips and mac_address fields of all ports. Select
# only those two columns to reduce the size of the response.
- port_list = self.admin_manager.ports_client.list_ports(
+ port_list = self.os_admin.ports_client.list_ports(
fields=['fixed_ips', 'mac_address'])['ports']
port_detail_list = [
(port['fixed_ips'][0]['subnet_id'],
@@ -541,7 +543,7 @@
dest=self._get_server_ip(server),
should_succeed=False)
server_id = server['id']
- port_id = self.admin_manager.ports_client.list_ports(
+ port_id = self.os_admin.ports_client.list_ports(
device_id=server_id)['ports'][0]['id']
# update port with new security group and check connectivity
@@ -605,7 +607,7 @@
access_point_ssh = self._connect_to_access_point(new_tenant)
server_id = server['id']
- port_id = self.admin_manager.ports_client.list_ports(
+ port_id = self.os_admin.ports_client.list_ports(
device_id=server_id)['ports'][0]['id']
# Flip the port's port security and check connectivity
@@ -647,7 +649,7 @@
sec_groups = []
server = self._create_server(name, tenant, sec_groups)
server_id = server['id']
- ports = self.admin_manager.ports_client.list_ports(
+ ports = self.os_admin.ports_client.list_ports(
device_id=server_id)['ports']
self.assertEqual(1, len(ports))
for port in ports:
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 2be9e06..77563b3 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -43,6 +43,12 @@
* Terminate the instance
"""
+ @classmethod
+ def skip_checks(cls):
+ super(TestServerBasicOps, cls).skip_checks()
+ if not CONF.network_feature_enabled.floating_ips:
+ raise cls.skipException("Floating ips are not available")
+
def setUp(self):
super(TestServerBasicOps, self).setUp()
self.run_ssh = CONF.validation.run_validation
diff --git a/tempest/scenario/test_server_multinode.py b/tempest/scenario/test_server_multinode.py
index d9bff09..552ab27 100644
--- a/tempest/scenario/test_server_multinode.py
+++ b/tempest/scenario/test_server_multinode.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-
from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
@@ -35,15 +34,6 @@
raise cls.skipException(
"Less than 2 compute nodes, skipping multinode tests.")
- @classmethod
- def setup_clients(cls):
- super(TestServerMultinode, cls).setup_clients()
- # Use admin client by default
- cls.manager = cls.admin_manager
- # this is needed so that we can use the availability_zone:host
- # scheduler hint, which is admin_only by default
- cls.servers_client = cls.admin_manager.servers_client
-
@decorators.idempotent_id('9cecbe35-b9d4-48da-a37e-7ce70aa43d30')
@decorators.attr(type='smoke')
@test.services('compute', 'network')
@@ -74,9 +64,13 @@
for host in hosts[:CONF.compute.min_compute_nodes]:
# by getting to active state here, this means this has
# landed on the host in question.
+ # in order to use the availability_zone:host scheduler hint,
+ # admin client is need here.
inst = self.create_server(
+ clients=self.os_admin,
availability_zone='%(zone)s:%(host_name)s' % host)
- server = self.servers_client.show_server(inst['id'])['server']
+ server = self.os_admin.servers_client.show_server(
+ inst['id'])['server']
# ensure server is located on the requested host
self.assertEqual(host['host_name'], server['OS-EXT-SRV-ATTR:host'])
servers.append(server)
diff --git a/tempest/test.py b/tempest/test.py
index e8108f4..f07c071 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -373,9 +373,9 @@
@classmethod
def resource_setup(cls):
"""Class level resource setup for test cases."""
- if hasattr(cls, "os"):
+ if hasattr(cls, "os_primary"):
cls.validation_resources = vresources.create_validation_resources(
- cls.os, cls.validation_resources)
+ cls.os_primary, cls.validation_resources)
else:
LOG.warning("Client manager not found, validation resources not"
" created")
@@ -388,8 +388,8 @@
resources, in case a failure during `resource_setup` should happen.
"""
if cls.validation_resources:
- if hasattr(cls, "os"):
- vresources.clear_validation_resources(cls.os,
+ if hasattr(cls, "os_primary"):
+ vresources.clear_validation_resources(cls.os_primary,
cls.validation_resources)
cls.validation_resources = {}
else:
diff --git a/tempest/tests/lib/services/base.py b/tempest/tests/lib/services/base.py
index 71b7f2d..90c9f63 100644
--- a/tempest/tests/lib/services/base.py
+++ b/tempest/tests/lib/services/base.py
@@ -31,12 +31,42 @@
def check_service_client_function(self, function, function2mock,
body, to_utf=False, status=200,
- headers=None, **kwargs):
+ headers=None, mock_args=None,
+ **kwargs):
+ """Mock a service client function for unit testing.
+
+ :param function: The service client function to call.
+ :param function2mock: The REST call to mock inside the service client
+ function.
+ :param body: Expected response body returned by the service client
+ function.
+ :param to_utf: Whether to use UTF-8 encoding for request.
+ :param status: Expected response status returned by the service client
+ function.
+ :param headers: Expected headers returned by the service client
+ function.
+ :param mock_args: List/dict/value of expected args/kwargs called by
+ function2mock. For example:
+ * If mock_args=['foo'] then ``assert_called_once_with('foo')``
+ is called.
+ * If mock_args={'foo': 'bar'} then
+ ``assert_called_once_with(foo='bar')`` is called.
+ * If mock_args='foo' then ``assert_called_once_with('foo')``
+ is called.
+ :param kwargs: kwargs that are passed to function.
+ """
mocked_response = self.create_response(body, to_utf, status, headers)
- self.useFixture(fixtures.MockPatch(
+ fixture = self.useFixture(fixtures.MockPatch(
function2mock, return_value=mocked_response))
if kwargs:
resp = function(**kwargs)
else:
resp = function()
self.assertEqual(body, resp)
+
+ if isinstance(mock_args, list):
+ fixture.mock.assert_called_once_with(*mock_args)
+ elif isinstance(mock_args, dict):
+ fixture.mock.assert_called_once_with(**mock_args)
+ elif mock_args is not None:
+ fixture.mock.assert_called_once_with(mock_args)
diff --git a/tempest/tests/lib/services/compute/test_server_groups_client.py b/tempest/tests/lib/services/compute/test_server_groups_client.py
index 1c535ca..9055a36 100644
--- a/tempest/tests/lib/services/compute/test_server_groups_client.py
+++ b/tempest/tests/lib/services/compute/test_server_groups_client.py
@@ -13,9 +13,10 @@
# under the License.
import fixtures
-from tempest.tests.lib import fake_auth_provider
+from tempest.lib.services.compute import base_compute_client
from tempest.lib.services.compute import server_groups_client
+from tempest.tests.lib import fake_auth_provider
from tempest.tests.lib import fake_http
from tempest.tests.lib.services import base
@@ -36,7 +37,7 @@
fake_auth, 'compute', 'regionOne')
def _test_create_server_group(self, bytes_body=False):
- expected = {"server_group": TestServerGroupsClient.server_group}
+ expected = {"server_group": self.server_group}
self.check_service_client_function(
self.client.create_server_group,
'tempest.lib.common.rest_client.RestClient.post', expected,
@@ -56,7 +57,7 @@
self.client.delete_server_group('fake-group')
def _test_list_server_groups(self, bytes_body=False):
- expected = {"server_groups": [TestServerGroupsClient.server_group]}
+ expected = {"server_groups": [self.server_group]}
self.check_service_client_function(
self.client.list_server_groups,
'tempest.lib.common.rest_client.RestClient.get',
@@ -69,7 +70,7 @@
self._test_list_server_groups(bytes_body=True)
def _test_show_server_group(self, bytes_body=False):
- expected = {"server_group": TestServerGroupsClient.server_group}
+ expected = {"server_group": self.server_group}
self.check_service_client_function(
self.client.show_server_group,
'tempest.lib.common.rest_client.RestClient.get',
@@ -81,3 +82,20 @@
def test_show_server_group_byte_body(self):
self._test_show_server_group(bytes_body=True)
+
+
+class TestServerGroupsClientMinV213(TestServerGroupsClient):
+
+ server_group = {
+ "id": "5bbcc3c4-1da2-4437-a48a-66f15b1b13f9",
+ "name": "test",
+ "policies": ["anti-affinity"],
+ "members": [],
+ "metadata": {},
+ "project_id": "0beb4bffb7a445eb8eb05fee3ee7660a",
+ "user_id": "86031628064a4f99bb66ec03c507dcd8"}
+
+ def setUp(self):
+ super(TestServerGroupsClientMinV213, self).setUp()
+ self.patchobject(base_compute_client, 'COMPUTE_MICROVERSION',
+ new='2.13')
diff --git a/tempest/tests/lib/services/identity/v3/test_services_client.py b/tempest/tests/lib/services/identity/v3/test_services_client.py
index f87fcce..b464644 100644
--- a/tempest/tests/lib/services/identity/v3/test_services_client.py
+++ b/tempest/tests/lib/services/identity/v3/test_services_client.py
@@ -101,12 +101,15 @@
bytes_body,
service_id="686766")
- def _test_list_services(self, bytes_body=False):
+ def _test_list_services(self, bytes_body=False, mock_args='services',
+ **params):
self.check_service_client_function(
self.client.list_services,
'tempest.lib.common.rest_client.RestClient.get',
self.FAKE_LIST_SERVICES,
- bytes_body)
+ bytes_body,
+ mock_args=[mock_args],
+ **params)
def _test_update_service(self, bytes_body=False):
self.check_service_client_function(
@@ -134,6 +137,10 @@
def test_list_services_with_bytes_body(self):
self._test_list_services(bytes_body=True)
+ def test_list_services_with_params(self):
+ self._test_list_services(
+ type='fake-type', mock_args='services?type=fake-type')
+
def test_update_service_with_str_body(self):
self._test_update_service()
diff --git a/tempest/tests/lib/services/network/test_subnetpools_client.py b/tempest/tests/lib/services/network/test_subnetpools_client.py
new file mode 100644
index 0000000..3abb438
--- /dev/null
+++ b/tempest/tests/lib/services/network/test_subnetpools_client.py
@@ -0,0 +1,163 @@
+# Copyright 2017 AT&T Corporation.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import copy
+
+from tempest.lib.services.network import subnetpools_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestSubnetsClient(base.BaseServiceTest):
+
+ FAKE_SUBNETPOOLS = {
+ "subnetpools": [
+ {
+ "min_prefixlen": "64",
+ "address_scope_id": None,
+ "default_prefixlen": "64",
+ "id": "03f761e6-eee0-43fc-a921-8acf64c14988",
+ "max_prefixlen": "64",
+ "name": "my-subnet-pool-ipv6",
+ "default_quota": None,
+ "is_default": False,
+ "project_id": "9fadcee8aa7c40cdb2114fff7d569c08",
+ "tenant_id": "9fadcee8aa7c40cdb2114fff7d569c08",
+ "prefixes": [
+ "2001:db8:0:2::/64",
+ "2001:db8::/63"
+ ],
+ "ip_version": 6,
+ "shared": False,
+ "description": "",
+ "revision_number": 2
+ },
+ {
+ "min_prefixlen": "24",
+ "address_scope_id": None,
+ "default_prefixlen": "25",
+ "id": "f49a1319-423a-4ee6-ba54-1d95a4f6cc68",
+ "max_prefixlen": "30",
+ "name": "my-subnet-pool-ipv4",
+ "default_quota": None,
+ "is_default": False,
+ "project_id": "9fadcee8aa7c40cdb2114fff7d569c08",
+ "tenant_id": "9fadcee8aa7c40cdb2114fff7d569c08",
+ "prefixes": [
+ "10.10.0.0/21",
+ "192.168.0.0/16"
+ ],
+ "ip_version": 4,
+ "shared": False,
+ "description": "",
+ "revision_number": 2
+ }
+ ]
+ }
+
+ FAKE_SUBNETPOOL_ID = "03f761e6-eee0-43fc-a921-8acf64c14988"
+
+ def setUp(self):
+ super(TestSubnetsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.subnetpools_client = subnetpools_client.SubnetpoolsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_list_subnetpools(self, bytes_body=False):
+ self.check_service_client_function(
+ self.subnetpools_client.list_subnetpools,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_SUBNETPOOLS,
+ bytes_body,
+ 200)
+
+ def _test_create_subnetpool(self, bytes_body=False):
+ self.check_service_client_function(
+ self.subnetpools_client.create_subnetpool,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ {'subnetpool': self.FAKE_SUBNETPOOLS['subnetpools'][1]},
+ bytes_body,
+ 201,
+ name="my-subnet-pool-ipv4",
+ prefixes=["192.168.0.0/16", "10.10.0.0/21"])
+
+ def _test_show_subnetpool(self, bytes_body=False):
+ self.check_service_client_function(
+ self.subnetpools_client.show_subnetpool,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ {'subnetpool': self.FAKE_SUBNETPOOLS['subnetpools'][0]},
+ bytes_body,
+ 200,
+ subnetpool_id=self.FAKE_SUBNETPOOL_ID)
+
+ def _test_update_subnetpool(self, bytes_body=False):
+ update_kwargs = {
+ "name": "my-new-subnetpool-name",
+ "prefixes": [
+ "2001:db8::/64",
+ "2001:db8:0:1::/64",
+ "2001:db8:0:2::/64"
+ ],
+ "min_prefixlen": 64,
+ "default_prefixlen": 64,
+ "max_prefixlen": 64
+ }
+
+ resp_body = {
+ 'subnetpool': copy.deepcopy(
+ self.FAKE_SUBNETPOOLS['subnetpools'][0])
+ }
+ resp_body['subnetpool'].update(update_kwargs)
+
+ self.check_service_client_function(
+ self.subnetpools_client.update_subnetpool,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ resp_body,
+ bytes_body,
+ 200,
+ subnetpool_id=self.FAKE_SUBNETPOOL_ID,
+ **update_kwargs)
+
+ def test_list_subnetpools_with_str_body(self):
+ self._test_list_subnetpools()
+
+ def test_list_subnetpools_with_bytes_body(self):
+ self._test_list_subnetpools(bytes_body=True)
+
+ def test_create_subnetpool_with_str_body(self):
+ self._test_create_subnetpool()
+
+ def test_create_subnetpool_with_bytes_body(self):
+ self._test_create_subnetpool(bytes_body=True)
+
+ def test_show_subnetpool_with_str_body(self):
+ self._test_show_subnetpool()
+
+ def test_show_subnetpool_with_bytes_body(self):
+ self._test_show_subnetpool(bytes_body=True)
+
+ def test_update_subnet_with_str_body(self):
+ self._test_update_subnetpool()
+
+ def test_update_subnet_with_bytes_body(self):
+ self._test_update_subnetpool(bytes_body=True)
+
+ def test_delete_subnetpool(self):
+ self.check_service_client_function(
+ self.subnetpools_client.delete_subnetpool,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ status=204,
+ subnetpool_id=self.FAKE_SUBNETPOOL_ID)
diff --git a/tempest/tests/lib/services/network/test_subnets_client.py b/tempest/tests/lib/services/network/test_subnets_client.py
new file mode 100644
index 0000000..0aadf54
--- /dev/null
+++ b/tempest/tests/lib/services/network/test_subnets_client.py
@@ -0,0 +1,250 @@
+# Copyright 2017 AT&T Corporation.
+# All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import copy
+
+from tempest.lib.services.network import subnets_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestSubnetsClient(base.BaseServiceTest):
+
+ FAKE_SUBNET = {
+ "subnet": {
+ "name": "",
+ "enable_dhcp": True,
+ "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+ "segment_id": None,
+ "project_id": "4fd44f30292945e481c7b8a0c8908869",
+ "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
+ "dns_nameservers": [],
+ "allocation_pools": [
+ {
+ "start": "192.168.199.2",
+ "end": "192.168.199.254"
+ }
+ ],
+ "host_routes": [],
+ "ip_version": 4,
+ "gateway_ip": "192.168.199.1",
+ "cidr": "192.168.199.0/24",
+ "id": "3b80198d-4f7b-4f77-9ef5-774d54e17126",
+ "created_at": "2016-10-10T14:35:47Z",
+ "description": "",
+ "ipv6_address_mode": None,
+ "ipv6_ra_mode": None,
+ "revision_number": 2,
+ "service_types": [],
+ "subnetpool_id": None,
+ "updated_at": "2016-10-10T14:35:47Z"
+ }
+ }
+
+ FAKE_UPDATED_SUBNET = {
+ "subnet": {
+ "name": "my_subnet",
+ "enable_dhcp": True,
+ "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+ "segment_id": None,
+ "project_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
+ "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
+ "dns_nameservers": [],
+ "allocation_pools": [
+ {
+ "start": "10.0.0.2",
+ "end": "10.0.0.254"
+ }
+ ],
+ "host_routes": [],
+ "ip_version": 4,
+ "gateway_ip": "10.0.0.1",
+ "cidr": "10.0.0.0/24",
+ "id": "08eae331-0402-425a-923c-34f7cfe39c1b",
+ "description": ""
+ }
+ }
+
+ FAKE_SUBNETS = {
+ "subnets": [
+ {
+ "name": "private-subnet",
+ "enable_dhcp": True,
+ "network_id": "db193ab3-96e3-4cb3-8fc5-05f4296d0324",
+ "segment_id": None,
+ "project_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
+ "tenant_id": "26a7980765d0414dbc1fc1f88cdb7e6e",
+ "dns_nameservers": [],
+ "allocation_pools": [
+ {
+ "start": "10.0.0.2",
+ "end": "10.0.0.254"
+ }
+ ],
+ "host_routes": [],
+ "ip_version": 4,
+ "gateway_ip": "10.0.0.1",
+ "cidr": "10.0.0.0/24",
+ "id": "08eae331-0402-425a-923c-34f7cfe39c1b",
+ "created_at": "2016-10-10T14:35:34Z",
+ "description": "",
+ "ipv6_address_mode": None,
+ "ipv6_ra_mode": None,
+ "revision_number": 2,
+ "service_types": [],
+ "subnetpool_id": None,
+ "updated_at": "2016-10-10T14:35:34Z"
+ },
+ {
+ "name": "my_subnet",
+ "enable_dhcp": True,
+ "network_id": "d32019d3-bc6e-4319-9c1d-6722fc136a22",
+ "segment_id": None,
+ "project_id": "4fd44f30292945e481c7b8a0c8908869",
+ "tenant_id": "4fd44f30292945e481c7b8a0c8908869",
+ "dns_nameservers": [],
+ "allocation_pools": [
+ {
+ "start": "192.0.0.2",
+ "end": "192.255.255.254"
+ }
+ ],
+ "host_routes": [],
+ "ip_version": 4,
+ "gateway_ip": "192.0.0.1",
+ "cidr": "192.0.0.0/8",
+ "id": "54d6f61d-db07-451c-9ab3-b9609b6b6f0b",
+ "created_at": "2016-10-10T14:35:47Z",
+ "description": "",
+ "ipv6_address_mode": None,
+ "ipv6_ra_mode": None,
+ "revision_number": 2,
+ "service_types": [],
+ "subnetpool_id": None,
+ "updated_at": "2016-10-10T14:35:47Z"
+ }
+ ]
+ }
+
+ FAKE_BULK_SUBNETS = copy.deepcopy(FAKE_SUBNETS)
+
+ FAKE_SUBNET_ID = "54d6f61d-db07-451c-9ab3-b9609b6b6f0b"
+
+ FAKE_NETWORK_ID = "d32019d3-bc6e-4319-9c1d-6722fc136a22"
+
+ def setUp(self):
+ super(TestSubnetsClient, self).setUp()
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.subnets_client = subnets_client.SubnetsClient(
+ fake_auth, 'compute', 'regionOne')
+
+ def _test_create_subnet(self, bytes_body=False):
+ self.check_service_client_function(
+ self.subnets_client.create_subnet,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_SUBNET,
+ bytes_body,
+ 201,
+ network_id=self.FAKE_NETWORK_ID,
+ ip_version=4,
+ cidr="192.168.199.0/24")
+
+ def _test_update_subnet(self, bytes_body=False):
+ self.check_service_client_function(
+ self.subnets_client.update_subnet,
+ 'tempest.lib.common.rest_client.RestClient.put',
+ self.FAKE_UPDATED_SUBNET,
+ bytes_body,
+ 200,
+ subnet_id=self.FAKE_SUBNET_ID,
+ name="fake_updated_subnet_name")
+
+ def _test_show_subnet(self, bytes_body=False):
+ self.check_service_client_function(
+ self.subnets_client.show_subnet,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_SUBNET,
+ bytes_body,
+ 200,
+ subnet_id=self.FAKE_SUBNET_ID)
+
+ def _test_list_subnets(self, bytes_body=False):
+ self.check_service_client_function(
+ self.subnets_client.list_subnets,
+ 'tempest.lib.common.rest_client.RestClient.get',
+ self.FAKE_SUBNETS,
+ bytes_body,
+ 200)
+
+ def _test_create_bulk_subnets(self, bytes_body=False):
+ kwargs = {
+ "subnets": [
+ {
+ "cidr": "192.168.199.0/24",
+ "ip_version": 4,
+ "network_id": "e6031bc2-901a-4c66-82da-f4c32ed89406"
+ },
+ {
+ "cidr": "10.56.4.0/22",
+ "ip_version": 4,
+ "network_id": "64239a54-dcc4-4b39-920b-b37c2144effa"
+ }
+ ]
+ }
+ self.check_service_client_function(
+ self.subnets_client.create_bulk_subnets,
+ 'tempest.lib.common.rest_client.RestClient.post',
+ self.FAKE_SUBNETS,
+ bytes_body,
+ 201,
+ **kwargs)
+
+ def test_create_subnet_with_str_body(self):
+ self._test_create_subnet()
+
+ def test_create_subnet_with_bytes_body(self):
+ self._test_create_subnet(bytes_body=True)
+
+ def test_update_subnet_with_str_body(self):
+ self._test_update_subnet()
+
+ def test_update_subnet_with_bytes_body(self):
+ self._test_update_subnet(bytes_body=True)
+
+ def test_show_subnet_with_str_body(self):
+ self._test_show_subnet()
+
+ def test_show_subnet_with_bytes_body(self):
+ self._test_show_subnet(bytes_body=True)
+
+ def test_list_subnets_with_str_body(self):
+ self._test_list_subnets()
+
+ def test_list_subnets_with_bytes_body(self):
+ self._test_list_subnets(bytes_body=True)
+
+ def test_delete_subnet(self):
+ self.check_service_client_function(
+ self.subnets_client.delete_subnet,
+ 'tempest.lib.common.rest_client.RestClient.delete',
+ {},
+ status=204,
+ subnet_id=self.FAKE_SUBNET_ID)
+
+ def test_create_bulk_subnets_with_str_body(self):
+ self._test_create_bulk_subnets()
+
+ def test_create_bulk_subnets_with_bytes_body(self):
+ self._test_create_bulk_subnets(bytes_body=True)
diff --git a/test-requirements.txt b/test-requirements.txt
index fbdad44..19b45ea 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,7 +5,7 @@
# needed for doc build
sphinx!=1.6.1,>=1.5.1 # BSD
oslosphinx>=4.7.0 # Apache-2.0
-reno>=1.8.0 # Apache-2.0
+reno!=2.3.1,>=1.8.0 # Apache-2.0
mock>=2.0 # BSD
coverage!=4.4,>=4.0 # Apache-2.0
oslotest>=1.10.0 # Apache-2.0
diff --git a/tools/check_logs.py b/tools/check_logs.py
index f82b387..fc21f75 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -25,7 +25,6 @@
import six.moves.urllib.request as urlreq
import yaml
-
# DEVSTACK_GATE_GRENADE is either unset if grenade is not running
# or a string describing what type of grenade run to perform.
is_grenade = os.environ.get('DEVSTACK_GATE_GRENADE') is not None
@@ -137,7 +136,7 @@
with open(WHITELIST_FILE) as stream:
loaded = yaml.safe_load(stream)
if loaded:
- for (name, l) in loaded.iteritems():
+ for (name, l) in six.iteritems(loaded):
for w in l:
assert 'module' in w, 'no module in %s' % name
assert 'message' in w, 'no message in %s' % name
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index 2ba8b16..1f2b88b 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -126,8 +126,8 @@
def print_stats(items, fname, verbose=False):
- errors = len(filter(lambda x: x.level == "ERROR", items))
- traces = len(filter(lambda x: x.level == "TRACE", items))
+ errors = len([x for x in items if x.level == "ERROR"])
+ traces = len([x for x in items if x.level == "TRACE"])
print("%d ERRORS found in %s" % (errors, fname))
print("%d TRACES found in %s" % (traces, fname))
diff --git a/tools/generate-tempest-plugins-list.py b/tools/generate-tempest-plugins-list.py
index acb29af..8d26c25 100644
--- a/tools/generate-tempest-plugins-list.py
+++ b/tools/generate-tempest-plugins-list.py
@@ -65,7 +65,7 @@
# json library won't choke.
projects = sorted(filter(is_in_openstack_namespace, json.loads(r.text[4:])))
-found_plugins = filter(has_tempest_plugin, projects)
+found_plugins = list(filter(has_tempest_plugin, projects))
# Every element of the found_plugins list begins with "openstack/".
# We drop those initial 10 octets when printing the list.