Merge "network_client should support multi routes"
diff --git a/openstack-common.conf b/openstack-common.conf
index 1920295..16ba6a7 100644
--- a/openstack-common.conf
+++ b/openstack-common.conf
@@ -3,6 +3,8 @@
# The list of modules to copy from openstack-common
module=install_venv_common
module=versionutils
+module=with_venv
+module=install_venv
# The base module to hold the copy of openstack.common
base=tempest
diff --git a/requirements.txt b/requirements.txt
index 66e5b16..d0419f7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,7 +1,7 @@
# The order of packages is significant, because pip processes them in the order
# of appearance. Changing the order has an impact on the overall integration
# process, which may cause wedges in the gate later.
-pbr<2.0,>=0.11
+pbr<2.0,>=1.3
cliff>=1.13.0 # Apache-2.0
anyjson>=0.3.3
httplib2>=0.7.5
@@ -11,13 +11,13 @@
paramiko>=1.13.0
netaddr>=0.7.12
testrepository>=0.0.18
-pyOpenSSL>=0.11
+pyOpenSSL>=0.14
oslo.concurrency>=2.1.0 # Apache-2.0
oslo.config>=1.11.0 # Apache-2.0
oslo.i18n>=1.5.0 # Apache-2.0
-oslo.log>=1.2.0 # Apache-2.0
+oslo.log>=1.6.0 # Apache-2.0
oslo.serialization>=1.4.0 # Apache-2.0
-oslo.utils>=1.6.0 # Apache-2.0
+oslo.utils>=1.9.0 # Apache-2.0
six>=1.9.0
iso8601>=0.1.9
fixtures>=1.3.1
diff --git a/run_tempest.sh b/run_tempest.sh
index 5a9b742..0f32045 100755
--- a/run_tempest.sh
+++ b/run_tempest.sh
@@ -20,7 +20,7 @@
}
testrargs=""
-venv=.venv
+venv=${VENV:-.venv}
with_venv=tools/with_venv.sh
serial=0
always_venv=0
diff --git a/run_tests.sh b/run_tests.sh
index 971f89b..9a158e4 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -19,7 +19,7 @@
testrargs=""
just_pep8=0
-venv=.venv
+venv=${VENV:-.venv}
with_venv=tools/with_venv.sh
serial=0
always_venv=0
diff --git a/setup.py b/setup.py
index 056c16c..d8080d0 100644
--- a/setup.py
+++ b/setup.py
@@ -25,5 +25,5 @@
pass
setuptools.setup(
- setup_requires=['pbr'],
+ setup_requires=['pbr>=1.3'],
pbr=True)
diff --git a/tempest/api/compute/admin/test_floating_ips_bulk.py b/tempest/api/compute/admin/test_floating_ips_bulk.py
index 5c45dd8..4ac1915 100644
--- a/tempest/api/compute/admin/test_floating_ips_bulk.py
+++ b/tempest/api/compute/admin/test_floating_ips_bulk.py
@@ -34,7 +34,7 @@
@classmethod
def setup_clients(cls):
super(FloatingIPsBulkAdminTestJSON, cls).setup_clients()
- cls.client = cls.os_adm.floating_ips_client
+ cls.client = cls.os_adm.floating_ips_bulk_client
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 548cd4f..6ffa4e9 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -17,6 +17,7 @@
import testtools
from tempest.api.compute import base
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -103,10 +104,11 @@
if state == 'PAUSED':
self.admin_servers_client.pause_server(server_id)
- self.admin_servers_client.wait_for_server_status(server_id, state)
+ waiters.wait_for_server_status(self.admin_servers_client,
+ server_id, state)
self._migrate_server_to(server_id, target_host)
- self.servers_client.wait_for_server_status(server_id, state)
+ waiters.wait_for_server_status(self.servers_client, server_id, state)
self.assertEqual(target_host, self._get_host_for_server(server_id))
@test.idempotent_id('1dce86b8-eb04-4c03-a9d8-9c1dc3ee0c7b')
@@ -156,5 +158,6 @@
self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
self._migrate_server_to(server_id, target_host)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ server_id, 'ACTIVE')
self.assertEqual(target_host, self._get_host_for_server(server_id))
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index 5434d93..5af7406 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -15,6 +15,7 @@
import testtools
from tempest.api.compute import base
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -42,9 +43,11 @@
server_id = server['id']
self.servers_client.resize(server_id, self.flavor_ref_alt)
- self.servers_client.wait_for_server_status(server_id, 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.servers_client,
+ server_id, 'VERIFY_RESIZE')
self.servers_client.confirm_resize(server_id)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ server_id, 'ACTIVE')
body = self.client.list_migrations()
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index 0062c1e..1982eda 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -17,6 +17,7 @@
from tempest.api.compute import base
from tempest.common import fixed_network
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import test
@@ -52,7 +53,7 @@
@test.idempotent_id('51717b38-bdc1-458b-b636-1cf82d99f62f')
def test_list_servers_by_admin(self):
# Listing servers by admin user returns empty list by default
- body = self.client.list_servers_with_detail()
+ body = self.client.list_servers(detail=True)
servers = body['servers']
self.assertEqual([], servers)
@@ -61,7 +62,7 @@
# Filter the list of servers by server error status
params = {'status': 'error'}
self.client.reset_state(self.s1_id, state='error')
- body = self.non_admin_client.list_servers(params)
+ body = self.non_admin_client.list_servers(**params)
# Reset server's state to 'active'
self.client.reset_state(self.s1_id, state='active')
# Verify server's state
@@ -77,7 +78,7 @@
# Listing servers by admin user with all tenants parameter
# Here should be listed all servers
params = {'all_tenants': ''}
- body = self.client.list_servers_with_detail(params)
+ body = self.client.list_servers(detail=True, **params)
servers = body['servers']
servers_name = map(lambda x: x['name'], servers)
@@ -91,14 +92,14 @@
# List the primary tenant but get nothing due to odd specified behavior
tenant_id = self.non_admin_client.tenant_id
params = {'tenant_id': tenant_id}
- body = self.client.list_servers_with_detail(params)
+ body = self.client.list_servers(detail=True, **params)
servers = body['servers']
self.assertEqual([], servers)
# List the admin tenant which has no servers
admin_tenant_id = self.client.tenant_id
params = {'all_tenants': '', 'tenant_id': admin_tenant_id}
- body = self.client.list_servers_with_detail(params)
+ body = self.client.list_servers(detail=True, **params)
servers = body['servers']
self.assertEqual([], servers)
@@ -113,15 +114,16 @@
test_server = self.client.create_server(name, image_id, flavor,
**network_kwargs)
self.addCleanup(self.client.delete_server, test_server['id'])
- self.client.wait_for_server_status(test_server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client,
+ test_server['id'], 'ACTIVE')
server = self.client.show_server(test_server['id'])
self.assertEqual(server['status'], 'ACTIVE')
hostname = server[self._host_key]
params = {'host': hostname}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
nonexistent_params = {'host': 'nonexistent_host'}
- nonexistent_body = self.client.list_servers(nonexistent_params)
+ nonexistent_body = self.client.list_servers(**nonexistent_params)
nonexistent_servers = nonexistent_body['servers']
self.assertIn(test_server['id'], map(lambda x: x['id'], servers))
self.assertNotIn(test_server['id'],
@@ -163,7 +165,7 @@
self.client.reset_state(self.s1_id, state='error')
rebuilt_server = self.non_admin_client.rebuild(
self.s1_id, self.image_ref_alt)
- self.addCleanup(self.non_admin_client.wait_for_server_status,
+ self.addCleanup(waiters.wait_for_server_status, self.non_admin_client,
self.s1_id, 'ACTIVE')
self.addCleanup(self.non_admin_client.rebuild, self.s1_id,
self.image_ref)
@@ -173,9 +175,9 @@
rebuilt_image_id = rebuilt_server['image']['id']
self.assertEqual(self.image_ref_alt, rebuilt_image_id)
self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
- self.non_admin_client.wait_for_server_status(rebuilt_server['id'],
- 'ACTIVE',
- raise_on_error=False)
+ waiters.wait_for_server_status(self.non_admin_client,
+ rebuilt_server['id'], 'ACTIVE',
+ raise_on_error=False)
# Verify the server properties after rebuilding
server = self.non_admin_client.show_server(rebuilt_server['id'])
rebuilt_image_id = server['image']['id']
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 6d3c4a3..b93aaca 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -20,6 +20,7 @@
from tempest.api.compute import base
from tempest.common import tempest_fixtures as fixtures
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -151,7 +152,8 @@
server_id = server['id']
# suspend the server.
self.client.suspend_server(server_id)
- self.client.wait_for_server_status(server_id, 'SUSPENDED')
+ waiters.wait_for_server_status(self.client,
+ server_id, 'SUSPENDED')
# migrate an suspended server should fail
self.assertRaises(lib_exc.Conflict,
self.client.migrate_server,
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 2b36180..37c1e0a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -57,9 +57,11 @@
def setup_clients(cls):
super(BaseComputeTest, cls).setup_clients()
cls.servers_client = cls.os.servers_client
+ cls.server_groups_client = cls.os.server_groups_client
cls.flavors_client = cls.os.flavors_client
cls.images_client = cls.os.images_client
cls.extensions_client = cls.os.extensions_client
+ cls.floating_ip_pools_client = cls.os.floating_ip_pools_client
cls.floating_ips_client = cls.os.floating_ips_client
cls.keypairs_client = cls.os.keypairs_client
cls.security_groups_client = cls.os.security_groups_client
@@ -142,8 +144,8 @@
"""
if getattr(cls, 'server_id', None) is not None:
try:
- cls.servers_client.wait_for_server_status(cls.server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(cls.servers_client,
+ cls.server_id, 'ACTIVE')
except Exception as exc:
LOG.exception(exc)
cls.servers_client.delete_server(cls.server_id)
@@ -183,7 +185,7 @@
LOG.debug('Clearing server groups: %s', ','.join(cls.server_groups))
for server_group_id in cls.server_groups:
try:
- cls.servers_client.delete_server_group(server_group_id)
+ cls.server_groups_client.delete_server_group(server_group_id)
except lib_exc.NotFound:
# The server-group may have already been deleted which is OK.
pass
@@ -231,7 +233,7 @@
name = data_utils.rand_name(cls.__name__ + "-Server-Group")
if policy is None:
policy = ['affinity']
- body = cls.servers_client.create_server_group(name, policy)
+ body = cls.server_groups_client.create_server_group(name, policy)
cls.server_groups.append(body['id'])
return body
@@ -287,8 +289,8 @@
if kwargs['wait_until'] == 'ACTIVE':
if kwargs.get('wait_for_server', True):
- cls.servers_client.wait_for_server_status(server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(cls.servers_client,
+ server_id, 'ACTIVE')
return image
@classmethod
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 2cc1b59..8bb4fac 100644
--- a/tempest/api/compute/floating_ips/test_floating_ips_actions.py
+++ b/tempest/api/compute/floating_ips/test_floating_ips_actions.py
@@ -17,6 +17,7 @@
from tempest.api.compute.floating_ips import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import test
@@ -113,7 +114,8 @@
# Create server so as to use for Multiple association
new_name = data_utils.rand_name('floating_server')
body = self.create_test_server(name=new_name)
- self.servers_client.wait_for_server_status(body['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ body['id'], 'ACTIVE')
self.new_server_id = body['id']
self.addCleanup(self.servers_client.delete_server, self.new_server_id)
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 ad52b8c..d26a5e5 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -23,6 +23,7 @@
def setup_clients(cls):
super(FloatingIPDetailsTestJSON, cls).setup_clients()
cls.client = cls.floating_ips_client
+ cls.pools_client = cls.floating_ip_pools_client
@classmethod
def resource_setup(cls):
@@ -76,6 +77,6 @@
@test.services('network')
def test_list_floating_ip_pools(self):
# Positive test:Should return the list of floating IP Pools
- floating_ip_pools = self.client.list_floating_ip_pools()
+ floating_ip_pools = self.pools_client.list_floating_ip_pools()
self.assertNotEqual(0, len(floating_ip_pools),
"Expected floating IP Pools. Got zero.")
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 07eca9e..9721fa5 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -16,6 +16,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -74,8 +75,8 @@
def test_create_image_from_stopped_server(self):
server = self.create_test_server(wait_until='ACTIVE')
self.servers_client.stop(server['id'])
- self.servers_client.wait_for_server_status(server['id'],
- 'SHUTOFF')
+ waiters.wait_for_server_status(self.servers_client,
+ server['id'], 'SHUTOFF')
self.addCleanup(self.servers_client.delete_server, server['id'])
snapshot_name = data_utils.rand_name('test-snap')
image = self.create_image_from_server(server['id'],
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 1741e86..40a781c 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -38,8 +38,8 @@
super(ImagesOneServerTestJSON, self).setUp()
# Check if the server is in a clean state after test
try:
- self.servers_client.wait_for_server_status(self.server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ self.server_id, 'ACTIVE')
except Exception:
LOG.exception('server %s timed out to become ACTIVE. rebuilding'
% self.server_id)
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 1cd1ab7..2f78e9d 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -19,6 +19,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -43,8 +44,8 @@
super(ImagesOneServerNegativeTestJSON, self).setUp()
# Check if the server is in a clean state after test
try:
- self.servers_client.wait_for_server_status(self.server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, self.server_id,
+ 'ACTIVE')
except Exception:
LOG.exception('server %s timed out to become ACTIVE. rebuilding'
% self.server_id)
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index b0bbc91..2c0ce59 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -81,8 +81,8 @@
cls.server1 = cls.create_test_server()
cls.server2 = cls.create_test_server(wait_until='ACTIVE')
# NOTE(sdague) this is faster than doing the sync wait_util on both
- cls.servers_client.wait_for_server_status(cls.server1['id'],
- 'ACTIVE')
+ waiters.wait_for_server_status(cls.servers_client,
+ cls.server1['id'], 'ACTIVE')
# Create images to be used in the filter tests
cls.snapshot1 = cls.create_image_from_server(
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 491e52e..bd252b0 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -17,6 +17,7 @@
from tempest.api.compute.security_groups import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import test
@@ -97,7 +98,8 @@
server_name = data_utils.rand_name('server')
server = self.create_test_server(name=server_name)
server_id = server['id']
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, server_id,
+ 'ACTIVE')
self.servers_client.add_security_group(server_id, sg['name'])
# Check that we are not able to delete the security
@@ -108,7 +110,8 @@
# Reboot and add the other security group
self.servers_client.reboot(server_id, 'HARD')
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, server_id,
+ 'ACTIVE')
self.servers_client.add_security_group(server_id, sg2['name'])
# Check that we are not able to delete the other security
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index 8b0e1a4..94b6cf0 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -91,7 +91,7 @@
@test.idempotent_id('585e934c-448e-43c4-acbf-d06a9b899997')
def test_list_servers_with_detail(self):
# The created server should be in the detailed list of all servers
- body = self.client.list_servers_with_detail()
+ body = self.client.list_servers(detail=True)
servers = body['servers']
found = any([i for i in servers if i['id'] == self.server['id']])
self.assertTrue(found)
@@ -121,17 +121,18 @@
# Create a server with the scheduler hint "group".
name = data_utils.rand_name('server_group')
policies = ['affinity']
- body = self.client.create_server_group(name=name,
- policies=policies)
+ body = self.server_groups_client.create_server_group(
+ name=name, policies=policies)
group_id = body['id']
- self.addCleanup(self.client.delete_server_group, group_id)
+ self.addCleanup(self.server_groups_client.delete_server_group,
+ group_id)
hints = {'group': group_id}
server = self.create_test_server(sched_hints=hints,
wait_until='ACTIVE')
# Check a server is in the group
- server_group = self.client.get_server_group(group_id)
+ server_group = self.server_groups_client.get_server_group(group_id)
self.assertIn(server['id'], server_group['members'])
@test.idempotent_id('0578d144-ed74-43f8-8e57-ab10dbf9b3c2')
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index b36b721..b2acd34 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -16,6 +16,7 @@
import testtools
from tempest.api.compute import base
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -51,7 +52,7 @@
# Delete a server while it's VM state is Shutoff
server = self.create_test_server(wait_until='ACTIVE')
self.client.stop(server['id'])
- self.client.wait_for_server_status(server['id'], 'SHUTOFF')
+ waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
self.client.delete_server(server['id'])
self.client.wait_for_server_termination(server['id'])
@@ -62,7 +63,7 @@
# Delete a server while it's VM state is Pause
server = self.create_test_server(wait_until='ACTIVE')
self.client.pause_server(server['id'])
- self.client.wait_for_server_status(server['id'], 'PAUSED')
+ waiters.wait_for_server_status(self.client, server['id'], 'PAUSED')
self.client.delete_server(server['id'])
self.client.wait_for_server_termination(server['id'])
@@ -73,7 +74,7 @@
# Delete a server while it's VM state is Suspended
server = self.create_test_server(wait_until='ACTIVE')
self.client.suspend_server(server['id'])
- self.client.wait_for_server_status(server['id'], 'SUSPENDED')
+ waiters.wait_for_server_status(self.client, server['id'], 'SUSPENDED')
self.client.delete_server(server['id'])
self.client.wait_for_server_termination(server['id'])
@@ -87,12 +88,12 @@
offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
- self.client.wait_for_server_status(server['id'],
- 'SHELVED_OFFLOADED',
- extra_timeout=offload_time)
+ waiters.wait_for_server_status(self.client, server['id'],
+ 'SHELVED_OFFLOADED',
+ extra_timeout=offload_time)
else:
- self.client.wait_for_server_status(server['id'],
- 'SHELVED')
+ waiters.wait_for_server_status(self.client, server['id'],
+ 'SHELVED')
self.client.delete_server(server['id'])
self.client.wait_for_server_termination(server['id'])
@@ -103,7 +104,8 @@
# Delete a server while it's VM state is VERIFY_RESIZE
server = self.create_test_server(wait_until='ACTIVE')
self.client.resize(server['id'], self.flavor_ref_alt)
- self.client.wait_for_server_status(server['id'], 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.client, server['id'],
+ 'VERIFY_RESIZE')
self.client.delete_server(server['id'])
self.client.wait_for_server_termination(server['id'])
@@ -117,15 +119,18 @@
volume = volumes_client.create_volume()
self.addCleanup(volumes_client.delete_volume, volume['id'])
- volumes_client.wait_for_volume_status(volume['id'], 'available')
+ waiters.wait_for_volume_status(volumes_client,
+ volume['id'], 'available')
self.client.attach_volume(server['id'],
volume['id'],
device=device)
- volumes_client.wait_for_volume_status(volume['id'], 'in-use')
+ waiters.wait_for_volume_status(volumes_client,
+ volume['id'], 'in-use')
self.client.delete_server(server['id'])
self.client.wait_for_server_termination(server['id'])
- volumes_client.wait_for_volume_status(volume['id'], 'available')
+ waiters.wait_for_volume_status(volumes_client,
+ volume['id'], 'available')
class DeleteServersAdminTestJSON(base.BaseV2ComputeAdminTest):
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 00aa510..3e8a0d2 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -16,6 +16,7 @@
import testtools
from tempest.api.compute import base
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -47,7 +48,7 @@
if disk_config != server['OS-DCF:diskConfig']:
server = self.client.update_server(self.server_id,
disk_config=disk_config)
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
server = self.client.show_server(server['id'])
self.assertEqual(disk_config, server['OS-DCF:diskConfig'])
@@ -61,7 +62,7 @@
disk_config='MANUAL')
# Wait for the server to become active
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the specified attributes are set correctly
server = self.client.show_server(server['id'])
@@ -77,7 +78,7 @@
disk_config='AUTO')
# Wait for the server to become active
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the specified attributes are set correctly
server = self.client.show_server(server['id'])
@@ -101,9 +102,10 @@
# Resize with auto option
flavor_id = self._get_alternative_flavor()
self.client.resize(self.server_id, flavor_id, disk_config='AUTO')
- self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'VERIFY_RESIZE')
self.client.confirm_resize(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
server = self.client.show_server(self.server_id)
self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
@@ -118,9 +120,10 @@
# Resize with manual option
flavor_id = self._get_alternative_flavor()
self.client.resize(self.server_id, flavor_id, disk_config='MANUAL')
- self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'VERIFY_RESIZE')
self.client.confirm_resize(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
server = self.client.show_server(self.server_id)
self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
@@ -133,7 +136,7 @@
# Update the disk_config attribute to manual
server = self.client.update_server(self.server_id,
disk_config='MANUAL')
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the disk_config attribute is set correctly
server = self.client.show_server(server['id'])
diff --git a/tempest/api/compute/servers/test_instance_actions.py b/tempest/api/compute/servers/test_instance_actions.py
index 6233c58..dc126a5 100644
--- a/tempest/api/compute/servers/test_instance_actions.py
+++ b/tempest/api/compute/servers/test_instance_actions.py
@@ -14,6 +14,7 @@
# under the License.
from tempest.api.compute import base
+from tempest.common import waiters
from tempest import test
@@ -35,7 +36,7 @@
def test_list_instance_actions(self):
# List actions of the provided server
self.client.reboot(self.server_id, 'HARD')
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
body = self.client.list_instance_actions(self.server_id)
self.assertTrue(len(body) == 2, str(body))
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 326334c..a75cb3e 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -19,6 +19,7 @@
from tempest.api import utils
from tempest.common import fixed_network
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -92,7 +93,7 @@
def test_list_servers_filter_by_image(self):
# Filter the list of servers by image
params = {'image': self.image_ref}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -103,7 +104,7 @@
def test_list_servers_filter_by_flavor(self):
# Filter the list of servers by flavor
params = {'flavor': self.flavor_ref_alt}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -114,7 +115,7 @@
def test_list_servers_filter_by_server_name(self):
# Filter the list of servers by server name
params = {'name': self.s1_name}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -125,7 +126,7 @@
def test_list_servers_filter_by_server_status(self):
# Filter the list of servers by server status
params = {'status': 'active'}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -137,12 +138,12 @@
# Filter the list of servers by server shutoff status
params = {'status': 'shutoff'}
self.client.stop(self.s1['id'])
- self.client.wait_for_server_status(self.s1['id'],
- 'SHUTOFF')
- body = self.client.list_servers(params)
+ waiters.wait_for_server_status(self.client, self.s1['id'],
+ 'SHUTOFF')
+ body = self.client.list_servers(**params)
self.client.start(self.s1['id'])
- self.client.wait_for_server_status(self.s1['id'],
- 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.s1['id'],
+ 'ACTIVE')
servers = body['servers']
self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -153,21 +154,21 @@
def test_list_servers_filter_by_limit(self):
# Verify only the expected number of servers are returned
params = {'limit': 1}
- servers = self.client.list_servers(params)
+ servers = self.client.list_servers(**params)
self.assertEqual(1, len([x for x in servers['servers'] if 'id' in x]))
@test.idempotent_id('b1495414-2d93-414c-8019-849afe8d319e')
def test_list_servers_filter_by_zero_limit(self):
# Verify only the expected number of servers are returned
params = {'limit': 0}
- servers = self.client.list_servers(params)
+ servers = self.client.list_servers(**params)
self.assertEqual(0, len(servers['servers']))
@test.idempotent_id('37791bbd-90c0-4de0-831e-5f38cba9c6b3')
def test_list_servers_filter_by_exceed_limit(self):
# Verify only the expected number of servers are returned
params = {'limit': 100000}
- servers = self.client.list_servers(params)
+ servers = self.client.list_servers(**params)
all_servers = self.client.list_servers()
self.assertEqual(len([x for x in all_servers['servers'] if 'id' in x]),
len([x for x in servers['servers'] if 'id' in x]))
@@ -177,7 +178,7 @@
def test_list_servers_detailed_filter_by_image(self):
# Filter the detailed list of servers by image
params = {'image': self.image_ref}
- body = self.client.list_servers_with_detail(params)
+ body = self.client.list_servers(detail=True, **params)
servers = body['servers']
self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -188,7 +189,7 @@
def test_list_servers_detailed_filter_by_flavor(self):
# Filter the detailed list of servers by flavor
params = {'flavor': self.flavor_ref_alt}
- body = self.client.list_servers_with_detail(params)
+ body = self.client.list_servers(detail=True, **params)
servers = body['servers']
self.assertNotIn(self.s1['id'], map(lambda x: x['id'], servers))
@@ -199,7 +200,7 @@
def test_list_servers_detailed_filter_by_server_name(self):
# Filter the detailed list of servers by server name
params = {'name': self.s1_name}
- body = self.client.list_servers_with_detail(params)
+ body = self.client.list_servers(detail=True, **params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -210,7 +211,7 @@
def test_list_servers_detailed_filter_by_server_status(self):
# Filter the detailed list of servers by server status
params = {'status': 'active'}
- body = self.client.list_servers_with_detail(params)
+ body = self.client.list_servers(detail=True, **params)
servers = body['servers']
test_ids = [s['id'] for s in (self.s1, self.s2, self.s3)]
@@ -224,7 +225,7 @@
def test_list_servers_filtered_by_name_wildcard(self):
# List all servers that contains '-instance' in name
params = {'name': '-instance'}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -235,7 +236,7 @@
part_name = self.s1_name[6:-1]
params = {'name': part_name}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -248,7 +249,7 @@
regexes = ['^.*\-instance\-[0-9]+$', '^.*\-instance\-.*$']
for regex in regexes:
params = {'name': regex}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -259,7 +260,7 @@
part_name = self.s1_name[-10:]
params = {'name': part_name}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -282,7 +283,7 @@
else:
msg = "Skipped until bug 1450859 is resolved"
raise self.skipException(msg)
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -304,7 +305,7 @@
params = {'ip': ip}
else:
params = {'ip6': ip}
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
servers = body['servers']
self.assertIn(self.s1_name, map(lambda x: x['name'], servers))
@@ -315,5 +316,5 @@
def test_list_servers_detailed_limit_results(self):
# Verify only the expected number of detailed results are returned
params = {'limit': 1}
- servers = self.client.list_servers_with_detail(params)
+ servers = self.client.list_servers(detail=True, **params)
self.assertEqual(1, len(servers['servers']))
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index fd4d902..def6cf5 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -68,7 +68,7 @@
def test_list_servers_by_non_existing_image(self):
# Listing servers for a non existing image returns empty list
non_existing_image = '1234abcd-zzz0-aaa9-ppp3-0987654abcde'
- body = self.client.list_servers(dict(image=non_existing_image))
+ body = self.client.list_servers(image=non_existing_image)
servers = body['servers']
self.assertEqual([], servers)
@@ -77,7 +77,7 @@
def test_list_servers_by_non_existing_flavor(self):
# Listing servers by non existing flavor returns empty list
non_existing_flavor = 1234
- body = self.client.list_servers(dict(flavor=non_existing_flavor))
+ body = self.client.list_servers(flavor=non_existing_flavor)
servers = body['servers']
self.assertEqual([], servers)
@@ -86,7 +86,7 @@
def test_list_servers_by_non_existing_server_name(self):
# Listing servers for a non existent server name returns empty list
non_existing_name = 'junk_server_1234'
- body = self.client.list_servers(dict(name=non_existing_name))
+ body = self.client.list_servers(name=non_existing_name)
servers = body['servers']
self.assertEqual([], servers)
@@ -95,21 +95,21 @@
def test_list_servers_status_non_existing(self):
# Return an empty list when invalid status is specified
non_existing_status = 'BALONEY'
- body = self.client.list_servers(dict(status=non_existing_status))
+ body = self.client.list_servers(status=non_existing_status)
servers = body['servers']
self.assertEqual([], servers)
@test.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})
+ body = self.client.list_servers(limit=1)
self.assertEqual(1, len([x for x in body['servers'] if 'id' in x]))
@test.attr(type=['negative'])
@test.idempotent_id('d47c17fb-eebd-4287-8e95-f20a7e627b18')
def test_list_servers_by_limits_greater_than_actual_count(self):
# List servers by specifying a greater value for limit
- body = self.client.list_servers({'limit': 100})
+ body = self.client.list_servers(limit=100)
self.assertEqual(len(self.existing_fixtures), len(body['servers']))
@test.attr(type=['negative'])
@@ -117,28 +117,29 @@
def test_list_servers_by_limits_pass_string(self):
# Return an error if a string value is passed for limit
self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
- {'limit': 'testing'})
+ limit='testing')
@test.attr(type=['negative'])
@test.idempotent_id('62610dd9-4713-4ee0-8beb-fd2c1aa7f950')
def test_list_servers_by_limits_pass_negative_value(self):
# Return an error if a negative value for limit is passed
self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
- {'limit': -1})
+ limit=-1)
@test.attr(type=['negative'])
@test.idempotent_id('87d12517-e20a-4c9c-97b6-dd1628d6d6c9')
def test_list_servers_by_changes_since_invalid_date(self):
# Return an error when invalid date format is passed
+ params = {'changes-since': '2011/01/01'}
self.assertRaises(lib_exc.BadRequest, self.client.list_servers,
- {'changes-since': '2011/01/01'})
+ **params)
@test.attr(type=['negative'])
@test.idempotent_id('74745ad8-b346-45b5-b9b8-509d7447fc1f')
def test_list_servers_by_changes_since_future_date(self):
# Return an empty list when a date in the future is passed
changes_since = {'changes-since': '2051-01-01T12:34:00Z'}
- body = self.client.list_servers(changes_since)
+ body = self.client.list_servers(**changes_since)
self.assertEqual(0, len(body['servers']))
@test.attr(type=['negative'])
@@ -146,7 +147,7 @@
def test_list_servers_detail_server_is_deleted(self):
# Server details are not listed for a deleted server
deleted_ids = [s['id'] for s in self.deleted_fixtures]
- body = self.client.list_servers_with_detail()
+ body = self.client.list_servers(detail=True)
servers = body['servers']
actual = [srv for srv in servers
if srv['id'] in deleted_ids]
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 3aff595..b95250a 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -24,6 +24,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
from tempest.common.utils.linux import remote_client
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -41,7 +42,8 @@
super(ServerActionsTestJSON, self).setUp()
# Check if the server is in a clean state after test
try:
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client,
+ self.server_id, 'ACTIVE')
except lib_exc.NotFound:
# The server was deleted by previous test, create a new one
server = self.create_test_server(wait_until='ACTIVE')
@@ -72,7 +74,7 @@
# The server's password should be set to the provided password
new_password = 'Newpass1234'
self.client.change_password(self.server_id, new_password)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
if self.run_ssh:
# Verify that the user can authenticate with the new password
@@ -90,7 +92,7 @@
boot_time = linux_client.get_boot_time()
self.client.reboot(self.server_id, reboot_type)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
if self.run_ssh:
# Log in and verify the boot time has changed
@@ -114,7 +116,7 @@
def _rebuild_server_and_check(self, image_ref):
rebuilt_server = self.client.rebuild(self.server_id, image_ref)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
msg = ('Server was not rebuilt to the original image. '
'The original image: {0}. The current image: {1}'
.format(image_ref, rebuilt_server['image']['id']))
@@ -148,7 +150,8 @@
self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
# Verify the server properties after the rebuild completes
- self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client,
+ rebuilt_server['id'], 'ACTIVE')
server = self.client.show_server(rebuilt_server['id'])
rebuilt_image_id = server['image']['id']
self.assertTrue(self.image_ref_alt.endswith(rebuilt_image_id))
@@ -169,7 +172,7 @@
new_image = (self.image_ref_alt
if old_image == self.image_ref else self.image_ref)
self.client.stop(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'SHUTOFF')
+ waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
rebuilt_server = self.client.rebuild(self.server_id, new_image)
# If the server was rebuilt on a different image, restore it to the
# original image once the test ends
@@ -183,7 +186,8 @@
self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
# Verify the server properties after the rebuild completes
- self.client.wait_for_server_status(rebuilt_server['id'], 'SHUTOFF')
+ waiters.wait_for_server_status(self.client,
+ rebuilt_server['id'], 'SHUTOFF')
server = self.client.show_server(rebuilt_server['id'])
rebuilt_image_id = server['image']['id']
self.assertEqual(new_image, rebuilt_image_id)
@@ -195,16 +199,18 @@
# the provided flavor
if stop:
- self.servers_client.stop(self.server_id)
- self.servers_client.wait_for_server_status(self.server_id,
- 'SHUTOFF')
+ self.client.stop(self.server_id)
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'SHUTOFF')
self.client.resize(self.server_id, self.flavor_ref_alt)
- self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'VERIFY_RESIZE')
self.client.confirm_resize(self.server_id)
expected_status = 'SHUTOFF' if stop else 'ACTIVE'
- self.client.wait_for_server_status(self.server_id, expected_status)
+ waiters.wait_for_server_status(self.client, self.server_id,
+ expected_status)
server = self.client.show_server(self.server_id)
self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
@@ -237,10 +243,11 @@
# values after a resize is reverted
self.client.resize(self.server_id, self.flavor_ref_alt)
- self.client.wait_for_server_status(self.server_id, 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'VERIFY_RESIZE')
self.client.revert_resize(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
server = self.client.show_server(self.server_id)
self.assertEqual(self.flavor_ref, server['flavor']['id'])
@@ -253,10 +260,10 @@
# Positive test:create backup successfully and rotate backups correctly
# create the first and the second backup
backup1 = data_utils.rand_name('backup-1')
- resp = self.servers_client.create_backup(self.server_id,
- 'daily',
- 2,
- backup1).response
+ resp = self.client.create_backup(self.server_id,
+ 'daily',
+ 2,
+ backup1).response
oldest_backup_exist = True
# the oldest one should be deleted automatically in this test
@@ -276,11 +283,11 @@
self.os.image_client.wait_for_image_status(image1_id, 'active')
backup2 = data_utils.rand_name('backup-2')
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
- resp = self.servers_client.create_backup(self.server_id,
- 'daily',
- 2,
- backup2).response
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+ resp = self.client.create_backup(self.server_id,
+ 'daily',
+ 2,
+ backup2).response
image2_id = data_utils.parse_image_id(resp['location'])
self.addCleanup(self.os.image_client.delete_image, image2_id)
self.os.image_client.wait_for_image_status(image2_id, 'active')
@@ -304,15 +311,15 @@
# create the third one, due to the rotation is 2,
# the first one will be deleted
backup3 = data_utils.rand_name('backup-3')
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
- resp = self.servers_client.create_backup(self.server_id,
- 'daily',
- 2,
- backup3).response
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
+ resp = self.client.create_backup(self.server_id,
+ 'daily',
+ 2,
+ backup3).response
image3_id = data_utils.parse_image_id(resp['location'])
self.addCleanup(self.os.image_client.delete_image, image3_id)
# the first back up should be deleted
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
self.os.image_client.wait_for_resource_deletion(image1_id)
oldest_backup_exist = False
image_list = self.os.image_client.list_images(
@@ -330,7 +337,7 @@
(image_list[0]['name'], image_list[1]['name']))
def _get_output(self):
- output = self.servers_client.get_console_output(
+ output = self.client.get_console_output(
self.server_id, 10).data
self.assertTrue(output, "Console output was empty.")
lines = len(output.split('\n'))
@@ -348,9 +355,8 @@
# log file is truncated and we cannot get any console log through
# "console-log" API.
# The detail is https://bugs.launchpad.net/nova/+bug/1251920
- self.servers_client.reboot(self.server_id, 'HARD')
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
-
+ self.client.reboot(self.server_id, 'HARD')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
self.wait_for(self._get_output)
@test.idempotent_id('89104062-69d8-4b19-a71b-f47b7af093d7')
@@ -360,8 +366,8 @@
server = self.create_test_server(wait_until='ACTIVE')
def _check_full_length_console_log():
- output = self.servers_client.get_console_output(server['id'],
- None).data
+ output = self.client.get_console_output(server['id'],
+ None).data
self.assertTrue(output, "Console output was empty.")
lines = len(output.split('\n'))
@@ -385,9 +391,8 @@
server = self.create_test_server(wait_until='ACTIVE')
temp_server_id = server['id']
- self.servers_client.stop(temp_server_id)
- self.servers_client.wait_for_server_status(temp_server_id, 'SHUTOFF')
-
+ self.client.stop(temp_server_id)
+ waiters.wait_for_server_status(self.client, temp_server_id, 'SHUTOFF')
self.wait_for(self._get_output)
@test.idempotent_id('bd61a9fd-062f-4670-972b-2d6c3e3b9e73')
@@ -395,18 +400,19 @@
'Pause is not available.')
def test_pause_unpause_server(self):
self.client.pause_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'PAUSED')
+ waiters.wait_for_server_status(self.client, self.server_id, 'PAUSED')
self.client.unpause_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
@test.idempotent_id('0d8ee21e-b749-462d-83da-b85b41c86c7f')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
'Suspend is not available.')
def test_suspend_resume_server(self):
self.client.suspend_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'SUSPENDED')
self.client.resume_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
@test.idempotent_id('77eba8e0-036e-4635-944b-f7a8f3b78dc9')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
@@ -416,16 +422,16 @@
offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED_OFFLOADED',
- extra_timeout=offload_time)
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'SHELVED_OFFLOADED',
+ extra_timeout=offload_time)
else:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'SHELVED')
self.client.shelve_offload_server(self.server_id)
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED_OFFLOADED')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'SHELVED_OFFLOADED')
server = self.client.show_server(self.server_id)
image_name = server['name'] + '-shelved'
@@ -435,29 +441,29 @@
self.assertEqual(image_name, images[0]['name'])
self.client.unshelve_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
@test.idempotent_id('af8eafd4-38a7-4a4b-bdbc-75145a580560')
def test_stop_start_server(self):
- self.servers_client.stop(self.server_id)
- self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
- self.servers_client.start(self.server_id)
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+ self.client.stop(self.server_id)
+ waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
+ self.client.start(self.server_id)
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
@test.idempotent_id('80a8094c-211e-440a-ab88-9e59d556c7ee')
def test_lock_unlock_server(self):
# Lock the server,try server stop(exceptions throw),unlock it and retry
- self.servers_client.lock_server(self.server_id)
- server = self.servers_client.show_server(self.server_id)
+ self.client.lock_server(self.server_id)
+ server = self.client.show_server(self.server_id)
self.assertEqual(server['status'], 'ACTIVE')
# Locked server is not allowed to be stopped by non-admin user
self.assertRaises(lib_exc.Conflict,
- self.servers_client.stop, self.server_id)
- self.servers_client.unlock_server(self.server_id)
- self.servers_client.stop(self.server_id)
- self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
- self.servers_client.start(self.server_id)
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+ self.client.stop, self.server_id)
+ self.client.unlock_server(self.server_id)
+ self.client.stop(self.server_id)
+ waiters.wait_for_server_status(self.client, self.server_id, 'SHUTOFF')
+ self.client.start(self.server_id)
+ waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
def _validate_url(self, url):
valid_scheme = ['http', 'https']
@@ -473,8 +479,8 @@
# Get the VNC console of type 'novnc' and 'xvpvnc'
console_types = ['novnc', 'xvpvnc']
for console_type in console_types:
- body = self.servers_client.get_vnc_console(self.server_id,
- console_type)
+ body = self.client.get_vnc_console(self.server_id,
+ console_type)
self.assertEqual(console_type, body['type'])
self.assertNotEqual('', body['url'])
self._validate_url(body['url'])
diff --git a/tempest/api/compute/servers/test_server_group.py b/tempest/api/compute/servers/test_server_group.py
index f6dd5e3..0e7c1eb 100644
--- a/tempest/api/compute/servers/test_server_group.py
+++ b/tempest/api/compute/servers/test_server_group.py
@@ -37,7 +37,7 @@
@classmethod
def setup_clients(cls):
super(ServerGroupTestJSON, cls).setup_clients()
- cls.client = cls.servers_client
+ cls.client = cls.server_groups_client
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index 20bc77f..98a2f9d 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -56,7 +57,8 @@
server = cls.create_test_server(wait_until='BUILD')
cls.server_id = server['id']
cls.password = server['adminPass']
- cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(cls.servers_client, cls.server_id,
+ 'ACTIVE')
def setUp(self):
super(ServerRescueTestJSON, self).setUp()
@@ -74,22 +76,26 @@
def _unrescue(self, server_id):
self.servers_client.unrescue_server(server_id)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, server_id,
+ 'ACTIVE')
@test.idempotent_id('fd032140-714c-42e4-a8fd-adcd8df06be6')
def test_rescue_unrescue_instance(self):
self.servers_client.rescue_server(
self.server_id, adminPass=self.password)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+ waiters.wait_for_server_status(self.servers_client, self.server_id,
+ 'RESCUE')
self.servers_client.unrescue_server(self.server_id)
- self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, self.server_id,
+ 'ACTIVE')
@test.idempotent_id('4842e0cf-e87d-4d9d-b61f-f4791da3cacc')
def test_rescued_vm_associate_dissociate_floating_ip(self):
# Rescue the server
self.servers_client.rescue_server(
self.server_id, adminPass=self.password)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+ waiters.wait_for_server_status(self.servers_client, self.server_id,
+ 'RESCUE')
self.addCleanup(self._unrescue, self.server_id)
# Association of floating IP to a rescued vm
@@ -106,7 +112,8 @@
# Rescue the server
self.servers_client.rescue_server(
self.server_id, adminPass=self.password)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+ waiters.wait_for_server_status(self.servers_client, self.server_id,
+ 'RESCUE')
self.addCleanup(self._unrescue, self.server_id)
# Add Security group
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 9cc9e9b..2fe63ed 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -18,6 +18,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -53,30 +54,34 @@
cls.servers_client.rescue_server(
cls.rescue_id, adminPass=rescue_password)
- cls.servers_client.wait_for_server_status(cls.rescue_id, 'RESCUE')
- cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(cls.servers_client,
+ cls.rescue_id, 'RESCUE')
+ waiters.wait_for_server_status(cls.servers_client,
+ cls.server_id, 'ACTIVE')
def _create_volume(self):
volume = self.volumes_extensions_client.create_volume(
CONF.volume.volume_size, display_name=data_utils.rand_name(
self.__class__.__name__ + '_volume'))
self.addCleanup(self.delete_volume, volume['id'])
- self.volumes_extensions_client.wait_for_volume_status(
- volume['id'], 'available')
+ waiters.wait_for_volume_status(self.volumes_extensions_client,
+ volume['id'], 'available')
return volume
def _detach(self, server_id, volume_id):
self.servers_client.detach_volume(server_id, volume_id)
- self.volumes_extensions_client.wait_for_volume_status(volume_id,
- 'available')
+ waiters.wait_for_volume_status(self.volumes_extensions_client,
+ volume_id, 'available')
def _unrescue(self, server_id):
self.servers_client.unrescue_server(server_id)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ server_id, 'ACTIVE')
def _unpause(self, server_id):
self.servers_client.unpause_server(server_id)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ server_id, 'ACTIVE')
@test.idempotent_id('cc3a883f-43c0-4fb6-a9bb-5579d64984ed')
@testtools.skipUnless(CONF.compute_feature_enabled.pause,
@@ -86,7 +91,8 @@
# Rescue a paused server
self.servers_client.pause_server(self.server_id)
self.addCleanup(self._unpause, self.server_id)
- self.servers_client.wait_for_server_status(self.server_id, 'PAUSED')
+ waiters.wait_for_server_status(self.servers_client,
+ self.server_id, 'PAUSED')
self.assertRaises(lib_exc.Conflict,
self.servers_client.rescue_server,
self.server_id)
@@ -123,7 +129,8 @@
# Rescue the server
self.servers_client.rescue_server(self.server_id,
adminPass=self.password)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+ waiters.wait_for_server_status(self.servers_client,
+ self.server_id, 'RESCUE')
self.addCleanup(self._unrescue, self.server_id)
# Attach the volume to the server
@@ -143,13 +150,14 @@
self.servers_client.attach_volume(self.server_id,
volume['id'],
device='/dev/%s' % self.device)
- self.volumes_extensions_client.wait_for_volume_status(
- volume['id'], 'in-use')
+ waiters.wait_for_volume_status(self.volumes_extensions_client,
+ volume['id'], 'in-use')
# Rescue the server
self.servers_client.rescue_server(self.server_id,
adminPass=self.password)
- self.servers_client.wait_for_server_status(self.server_id, 'RESCUE')
+ waiters.wait_for_server_status(self.servers_client,
+ self.server_id, 'RESCUE')
# addCleanup is a LIFO queue
self.addCleanup(self._detach, self.server_id, volume['id'])
self.addCleanup(self._unrescue, self.server_id)
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index a7ebc09..2c1e69c 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import test
@@ -66,7 +67,7 @@
self.addCleanup(self.keypairs_client.delete_keypair, key_name)
self.keypairs_client.list_keypairs()
server = self.create_test_server(key_name=key_name)
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
server = self.client.show_server(server['id'])
self.assertEqual(key_name, server['key_name'])
@@ -76,7 +77,7 @@
# Update the server with a new name
self.client.update_server(server_id,
name=new_name)
- self.client.wait_for_server_status(server_id, status)
+ waiters.wait_for_server_status(self.client, server_id, status)
# Verify the name of the server has changed
server = self.client.show_server(server_id)
@@ -95,7 +96,7 @@
# The server name should be changed to the the provided value
server = self.create_test_server(wait_until='ACTIVE')
self.client.stop(server['id'])
- self.client.wait_for_server_status(server['id'], 'SHUTOFF')
+ waiters.wait_for_server_status(self.client, server['id'], 'SHUTOFF')
updated_server = self._update_server_name(server['id'], 'SHUTOFF')
self.assertNotIn('progress', updated_server)
@@ -108,7 +109,7 @@
self.client.update_server(server['id'],
accessIPv4='1.1.1.1',
accessIPv6='::babe:202:202')
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
# Verify the access addresses have been updated
server = self.client.show_server(server['id'])
@@ -119,6 +120,6 @@
def test_create_server_with_ipv6_addr_only(self):
# Create a server without an IPv4 address(only IPv6 address).
server = self.create_test_server(accessIPv6='2001:2001::3')
- self.client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.client, server['id'], 'ACTIVE')
server = self.client.show_server(server['id'])
self.assertEqual('2001:2001::3', server['accessIPv6'])
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index d13d9d6..fe05456 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -20,6 +20,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -33,7 +34,8 @@
def setUp(self):
super(ServersNegativeTestJSON, self).setUp()
try:
- self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'ACTIVE')
except Exception:
self.__class__.server_id = self.rebuild_server(self.server_id)
@@ -157,7 +159,7 @@
def test_pause_paused_server(self):
# Pause a paused server.
self.client.pause_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'PAUSED')
+ waiters.wait_for_server_status(self.client, self.server_id, 'PAUSED')
self.assertRaises(lib_exc.Conflict,
self.client.pause_server,
self.server_id)
@@ -384,7 +386,8 @@
def test_suspend_server_invalid_state(self):
# suspend a suspended server.
self.client.suspend_server(self.server_id)
- self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
+ waiters.wait_for_server_status(self.client, self.server_id,
+ 'SUSPENDED')
self.assertRaises(lib_exc.Conflict,
self.client.suspend_server,
self.server_id)
@@ -465,12 +468,14 @@
offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED_OFFLOADED',
- extra_timeout=offload_time)
+ waiters.wait_for_server_status(self.client,
+ self.server_id,
+ 'SHELVED_OFFLOADED',
+ extra_timeout=offload_time)
else:
- self.client.wait_for_server_status(self.server_id,
- 'SHELVED')
+ waiters.wait_for_server_status(self.client,
+ self.server_id,
+ 'SHELVED')
server = self.client.show_server(self.server_id)
image_name = server['name'] + '-shelved'
diff --git a/tempest/api/compute/test_live_block_migration_negative.py b/tempest/api/compute/test_live_block_migration_negative.py
index 47251b2..fabe55d 100644
--- a/tempest/api/compute/test_live_block_migration_negative.py
+++ b/tempest/api/compute/test_live_block_migration_negative.py
@@ -17,6 +17,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -55,4 +56,5 @@
self.assertRaises(lib_exc.BadRequest, self._migrate_server_to,
server_id, target_host)
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, server_id,
+ 'ACTIVE')
diff --git a/tempest/api/compute/test_quotas.py b/tempest/api/compute/test_quotas.py
index e302798..9f37143 100644
--- a/tempest/api/compute/test_quotas.py
+++ b/tempest/api/compute/test_quotas.py
@@ -20,6 +20,13 @@
class QuotasTestJSON(base.BaseV2ComputeTest):
+ @classmethod
+ def skip_checks(cls):
+ super(QuotasTestJSON, cls).skip_checks()
+ if not test.is_extension_enabled('os-quota-sets', 'compute'):
+ msg = "quotas extension not enabled."
+ raise cls.skipException(msg)
+
def setUp(self):
# NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
self.useFixture(fixtures.LockFixture('compute_quotas'))
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 580fb84..0496063 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -17,6 +17,7 @@
from tempest.api.compute import base
from tempest.common.utils.linux import remote_client
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -93,11 +94,12 @@
self._create_and_attach()
self.servers_client.stop(self.server['id'])
- self.servers_client.wait_for_server_status(self.server['id'],
- 'SHUTOFF')
+ waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ 'SHUTOFF')
self.servers_client.start(self.server['id'])
- self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ 'ACTIVE')
linux_client = remote_client.RemoteClient(self.server,
self.image_ssh_user,
@@ -108,11 +110,12 @@
self._detach(self.server['id'], self.volume['id'])
self.attachment = None
self.servers_client.stop(self.server['id'])
- self.servers_client.wait_for_server_status(self.server['id'],
- 'SHUTOFF')
+ waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ 'SHUTOFF')
self.servers_client.start(self.server['id'])
- self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ 'ACTIVE')
linux_client = remote_client.RemoteClient(self.server,
self.image_ssh_user,
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 1a64b22..44339a3 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -17,6 +17,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -56,7 +57,7 @@
self.assertTrue(volume['id'] is not None,
"Field volume id is empty or not found.")
# Wait for Volume status to become ACTIVE
- self.client.wait_for_volume_status(volume['id'], 'available')
+ waiters.wait_for_volume_status(self.client, volume['id'], 'available')
# GET Volume
fetched_volume = self.client.show_volume(volume['id'])
# Verification of details of fetched Volume
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 7ba62b0..22b3d13 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -15,6 +15,7 @@
from tempest.api.compute import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -55,7 +56,8 @@
try:
volume = cls.client.create_volume(display_name=v_name,
metadata=metadata)
- cls.client.wait_for_volume_status(volume['id'], 'available')
+ waiters.wait_for_volume_status(cls.client,
+ volume['id'], 'available')
volume = cls.client.show_volume(volume['id'])
cls.volume_list.append(volume)
cls.volume_id_list.append(volume['id'])
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index d497005..d89803d 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -89,3 +89,19 @@
def test_get_image_members_schema(self):
body = self.os_img_client.show_schema("members")
self.assertEqual("members", body['name'])
+
+ @test.idempotent_id('cb961424-3f68-4d21-8e36-30ad66fb6bfb')
+ def test_get_private_image(self):
+ image_id = self._create_image()
+ member = self.os_img_client.add_image_member(image_id,
+ self.alt_tenant_id)
+ self.assertEqual(member['member_id'], self.alt_tenant_id)
+ self.assertEqual(member['image_id'], image_id)
+ self.assertEqual(member['status'], 'pending')
+ self.assertNotIn(image_id, self._list_image_ids_as_alt())
+ self.alt_img_client.update_image_member(image_id,
+ self.alt_tenant_id,
+ {'status': 'accepted'})
+ self.assertIn(image_id, self._list_image_ids_as_alt())
+ self.os_img_client.remove_image_member(image_id, self.alt_tenant_id)
+ self.assertNotIn(image_id, self._list_image_ids_as_alt())
diff --git a/tempest/api/object_storage/test_object_slo.py b/tempest/api/object_storage/test_object_slo.py
index 9aa1b82..5811cb8 100644
--- a/tempest/api/object_storage/test_object_slo.py
+++ b/tempest/api/object_storage/test_object_slo.py
@@ -13,8 +13,8 @@
# under the License.
import hashlib
-import json
+from oslo_serialization import jsonutils as json
from tempest_lib import exceptions as lib_exc
from tempest.api.object_storage import base
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 0ebcf3a..067c0c1 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -15,6 +15,7 @@
from tempest.api.volume import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
import testtools
@@ -37,7 +38,8 @@
# Create a test shared instance
srv_name = data_utils.rand_name(cls.__name__ + '-Instance')
cls.server = cls.create_server(srv_name)
- cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(cls.servers_client, cls.server['id'],
+ 'ACTIVE')
# Create a test shared volume for attach/detach tests
cls.volume = cls.create_volume()
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index da8f52a..5203444 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -19,6 +19,7 @@
from tempest.api.volume import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import test
@@ -180,8 +181,11 @@
def test_attach_volumes_with_nonexistent_volume_id(self):
srv_name = data_utils.rand_name('Instance')
server = self.create_server(srv_name)
+ self.addCleanup(self.servers_client.wait_for_server_termination,
+ server['id'])
self.addCleanup(self.servers_client.delete_server, server['id'])
- self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'ACTIVE')
self.assertRaises(lib_exc.NotFound,
self.client.attach_volume,
str(uuid.uuid4()),
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 340f019..1df1896 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -14,6 +14,7 @@
from tempest.api.volume import base
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import test
@@ -70,7 +71,8 @@
server_name = data_utils.rand_name('instance')
server = self.create_server(server_name)
self.addCleanup(self.servers_client.delete_server, server['id'])
- self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'ACTIVE')
mountpoint = '/dev/%s' % CONF.compute.volume_device_name
self.servers_client.attach_volume(
server['id'], self.volume_origin['id'], mountpoint)
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 4c774da..d1eb694 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -14,6 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from six.moves.urllib import parse
+
from tempest.api.volume import base
from tempest import test
@@ -87,3 +89,101 @@
_list_details_with_multiple_params()
_list_details_with_multiple_params(sort_dir='desc')
+
+ def _test_pagination(self, resource, ids=None, limit=1, **kwargs):
+ """Check list pagination functionality for a resource.
+
+ This method requests the list of resources and follows pagination
+ links.
+
+ If an iterable is supplied in ids it will check that all ids are
+ retrieved and that only those are listed, that we will get a next
+ link for an empty page if the number of items is divisible by used
+ limit (this is expected behavior).
+
+ We can specify number of items per request using limit argument.
+ """
+
+ # Get list method for the type of resource from the client
+ client = getattr(self, resource + '_client')
+ method = getattr(client, 'list_' + resource)
+
+ # Include limit in params for list request
+ params = kwargs.pop('params', {})
+ params['limit'] = limit
+
+ # Store remaining items we are expecting from list
+ if ids is not None:
+ remaining = list(ids)
+ else:
+ remaining = None
+
+ # Mark that we are not comming from a next link
+ next = None
+
+ while True:
+ # Get a list page
+ response = method(return_body=True, params=params, **kwargs)
+
+ # If we have to check ids
+ if remaining is not None:
+ # Confirm we receive expected number of elements
+ num_expected = min(len(remaining), limit)
+ self.assertEqual(num_expected, len(response[resource]),
+ 'Requested %(#expect)d but got %(#received)d '
+ % {'#expect': num_expected,
+ '#received': len(response[resource])})
+
+ # For each received element
+ for element in response[resource]:
+ element_id = element['id']
+ # Check it's one of expected ids
+ self.assertIn(element_id,
+ ids,
+ 'Id %(id)s is not in expected ids %(ids)s' %
+ {'id': element_id, 'ids': ids})
+ # If not in remaining, we have received it twice
+ self.assertIn(element_id,
+ remaining,
+ 'Id %s was received twice' % element_id)
+ # We no longer expect it
+ remaining.remove(element_id)
+
+ # If we come from a next link check that absolute url is the same
+ # as the one used for this request
+ if next:
+ self.assertEqual(next, response.response['content-location'])
+
+ # Get next from response
+ next = None
+ for link in response.get(resource + '_links', ()):
+ if link['rel'] == 'next':
+ next = link['href']
+ break
+
+ # Check if we have next and we shouldn't or the other way around
+ if remaining is not None:
+ if remaining or (num_expected and len(ids) % limit == 0):
+ self.assertIsNotNone(next, 'Missing link to next page')
+ else:
+ self.assertIsNone(next, 'Unexpected link to next page')
+
+ # If we can follow to the next page, get params from url to make
+ # request in the form of a relative URL
+ if next:
+ params = parse.urlparse(next).query
+
+ # If cannot follow make sure it's because we have finished
+ else:
+ self.assertListEqual([], remaining or [],
+ 'No more pages reported, but still '
+ 'missing ids %s' % remaining)
+ break
+
+ @test.idempotent_id('e9138a2c-f67b-4796-8efa-635c196d01de')
+ def test_volume_list_details_pagination(self):
+ self._test_pagination('volumes', ids=self.volume_id_list, detail=True)
+
+ @test.idempotent_id('af55e775-8e4b-4feb-8719-215c43b0238c')
+ def test_volume_list_pagination(self):
+ self._test_pagination('volumes', ids=self.volume_id_list, detail=False)
diff --git a/tempest/clients.py b/tempest/clients.py
index ab6bd43..6a2c601 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -41,6 +41,10 @@
ExtensionsClient
from tempest.services.compute.json.fixed_ips_client import FixedIPsClient
from tempest.services.compute.json.flavors_client import FlavorsClient
+from tempest.services.compute.json.floating_ip_pools_client import \
+ FloatingIpPoolsClient
+from tempest.services.compute.json.floating_ips_bulk_client import \
+ FloatingIpsBulkClient
from tempest.services.compute.json.floating_ips_client import \
FloatingIPsClient
from tempest.services.compute.json.hosts_client import HostsClient
@@ -63,6 +67,8 @@
SecurityGroupDefaultRulesClient
from tempest.services.compute.json.security_groups_client import \
SecurityGroupsClient
+from tempest.services.compute.json.server_groups_client import \
+ ServerGroupsClient
from tempest.services.compute.json.servers_client import ServersClient
from tempest.services.compute.json.services_client import ServicesClient
from tempest.services.compute.json.tenant_networks_client import \
@@ -263,6 +269,8 @@
enable_instance_password=CONF.compute_feature_enabled
.enable_instance_password,
**params)
+ self.server_groups_client = ServerGroupsClient(
+ self.auth_provider, **params)
self.limits_client = LimitsClient(self.auth_provider, **params)
self.images_client = ImagesClient(self.auth_provider, **params)
self.keypairs_client = KeyPairsClient(self.auth_provider, **params)
@@ -272,6 +280,10 @@
self.flavors_client = FlavorsClient(self.auth_provider, **params)
self.extensions_client = ExtensionsClient(self.auth_provider,
**params)
+ self.floating_ip_pools_client = FloatingIpPoolsClient(
+ self.auth_provider, **params)
+ self.floating_ips_bulk_client = FloatingIpsBulkClient(
+ self.auth_provider, **params)
self.floating_ips_client = FloatingIPsClient(self.auth_provider,
**params)
self.security_groups_client = SecurityGroupsClient(
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index ed6716e..7898035 100755
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -51,10 +51,10 @@
Please run with **--help** to see full list of options.
"""
import argparse
-import json
import sys
from oslo_log import log as logging
+from oslo_serialization import jsonutils as json
from tempest import clients
from tempest.cmd import cleanup_service
diff --git a/tempest/cmd/run_stress.py b/tempest/cmd/run_stress.py
index 06b338d..0448589 100755
--- a/tempest/cmd/run_stress.py
+++ b/tempest/cmd/run_stress.py
@@ -16,7 +16,6 @@
import argparse
import inspect
-import json
import sys
try:
from unittest import loader
@@ -25,6 +24,7 @@
from unittest2 import loader
from oslo_log import log as logging
+from oslo_serialization import jsonutils as json
from testtools import testsuite
from tempest.stress import driver
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 2269d41..9e7d894 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -15,11 +15,11 @@
# under the License.
import argparse
-import json
import os
import sys
import httplib2
+from oslo_serialization import jsonutils as json
from six import moves
from six.moves.urllib import parse as urlparse
diff --git a/tempest/common/compute.py b/tempest/common/compute.py
index 5de4b0e..06e3493 100644
--- a/tempest/common/compute.py
+++ b/tempest/common/compute.py
@@ -18,6 +18,7 @@
from tempest_lib.common.utils import data_utils
from tempest.common import fixed_network
+from tempest.common import waiters
from tempest import config
CONF = config.CONF
@@ -98,8 +99,8 @@
if 'wait_until' in kwargs:
for server in servers:
try:
- clients.servers_client.wait_for_server_status(
- server['id'], kwargs['wait_until'])
+ waiters.wait_for_server_status(
+ clients.servers_client, server['id'], kwargs['wait_until'])
# Multiple validatable servers are not supported for now. Their
# creation will fail with the condition above (l.58).
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 5cd844c..4be3da1 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -17,7 +17,6 @@
import copy
import hashlib
-import json
import posixpath
import re
import socket
@@ -25,6 +24,7 @@
import OpenSSL
from oslo_log import log as logging
+from oslo_serialization import jsonutils as json
import six
from six import moves
from six.moves import http_client as httplib
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 2102638..ff4eda9 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -51,11 +51,21 @@
def create_project(self, name, description):
pass
- def assign_user_role(self, user, project, role_name):
+ def _check_role_exists(self, role_name):
try:
roles = self._list_roles()
role = next(r for r in roles if r['name'] == role_name)
except StopIteration:
+ return None
+ return role
+
+ def create_user_role(self, role_name):
+ if not self._check_role_exists(role_name):
+ self.identity_client.create_role(role_name)
+
+ def assign_user_role(self, user, project, role_name):
+ role = self._check_role_exists(role_name)
+ if not role:
msg = 'No "%s" role found' % role_name
raise lib_exc.NotFound(msg)
try:
@@ -196,16 +206,27 @@
email = data_utils.rand_name(root) + suffix + "@example.com"
user = self.creds_client.create_user(
username, user_password, project, email)
+ role_assigned = False
if admin:
self.creds_client.assign_user_role(user, project,
CONF.identity.admin_role)
+ role_assigned = True
# Add roles specified in config file
for conf_role in CONF.auth.tempest_roles:
self.creds_client.assign_user_role(user, project, conf_role)
+ role_assigned = True
# Add roles requested by caller
if roles:
for role in roles:
self.creds_client.assign_user_role(user, project, role)
+ role_assigned = True
+ # NOTE(mtreinish) For a user to have access to a project with v3 auth
+ # it must beassigned a role on the project. So we need to ensure that
+ # our newly created user has a role on the newly created project.
+ if self.identity_version == 'v3' and not role_assigned:
+ self.creds_client.create_user_role('Member')
+ self.creds_client.assign_user_role(user, project, 'Member')
+
creds = self.creds_client.get_credentials(user, project, user_password)
return cred_provider.TestResources(creds)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index bdbd6bc..85a03cf 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -132,6 +132,27 @@
raise exceptions.TimeoutException(message)
+def wait_for_volume_status(client, volume_id, status):
+ """Waits for a Volume to reach a given status."""
+ body = client.show_volume(volume_id)
+ volume_status = body['status']
+ start = int(time.time())
+
+ while volume_status != status:
+ time.sleep(client.build_interval)
+ body = client.show_volume(volume_id)
+ volume_status = body['status']
+ if volume_status == 'error':
+ raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
+
+ if int(time.time()) - start >= client.build_timeout:
+ message = ('Volume %s failed to reach %s status (current %s) '
+ 'within the required time (%s s).' %
+ (volume_id, status, volume_status,
+ client.build_timeout))
+ raise exceptions.TimeoutException(message)
+
+
def wait_for_bm_node_status(client, node_id, attr, status):
"""Waits for a baremetal node attribute to reach given status.
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 8f0b4dc..03e572f 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -25,6 +25,7 @@
from tempest.common import fixed_network
from tempest.common.utils import data_utils
from tempest.common.utils.linux import remote_client
+from tempest.common import waiters
from tempest import config
from tempest import exceptions
from tempest.services.network import resources as net_resources
@@ -177,8 +178,9 @@
cleanup_callable=self.delete_wrapper,
cleanup_args=[self.servers_client.delete_server, server['id']])
if wait_on_boot:
- self.servers_client.wait_for_server_status(server_id=server['id'],
- status='ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ server_id=server['id'],
+ status='ACTIVE')
# The instance retrieved on creation is missing network
# details, necessitating retrieval after it becomes active to
# ensure correct details.
@@ -443,7 +445,8 @@
preserve_ephemeral=preserve_ephemeral,
**rebuild_kwargs)
if wait:
- self.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ server_id, 'ACTIVE')
def ping_ip_address(self, ip_address, should_succeed=True,
ping_timeout=None):
@@ -559,27 +562,27 @@
def _list_networks(self, *args, **kwargs):
"""List networks using admin creds """
- return self._admin_lister('networks')(*args, **kwargs)
+ networks_list = self.admin_manager.network_client.list_networks(
+ *args, **kwargs)
+ return networks_list['networks']
def _list_subnets(self, *args, **kwargs):
"""List subnets using admin creds """
- return self._admin_lister('subnets')(*args, **kwargs)
+ subnets_list = self.admin_manager.network_client.list_subnets(
+ *args, **kwargs)
+ return subnets_list['subnets']
def _list_routers(self, *args, **kwargs):
"""List routers using admin creds """
- return self._admin_lister('routers')(*args, **kwargs)
+ routers_list = self.admin_manager.network_client.list_routers(
+ *args, **kwargs)
+ return routers_list['routers']
def _list_ports(self, *args, **kwargs):
"""List ports using admin creds """
- return self._admin_lister('ports')(*args, **kwargs)
-
- def _admin_lister(self, resource_type):
- def temp(*args, **kwargs):
- temp_method = self.admin_manager.network_client.__getattr__(
- 'list_%s' % resource_type)
- resource_list = temp_method(*args, **kwargs)
- return resource_list[resource_type]
- return temp
+ ports_list = self.admin_manager.network_client.list_ports(
+ *args, **kwargs)
+ return ports_list['ports']
def _create_subnet(self, network, client=None, namestart='subnet-smoke',
**kwargs):
@@ -1226,8 +1229,8 @@
BaremetalProvisionStates.ACTIVE,
timeout=CONF.baremetal.active_timeout)
- self.servers_client.wait_for_server_status(self.instance['id'],
- 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ self.instance['id'], 'ACTIVE')
self.node = self.get_node(instance_id=self.instance['id'])
self.instance = self.servers_client.show_server(self.instance['id'])
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index 9fdba39..346f56b 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -15,6 +15,7 @@
from oslo_log import log as logging
+from tempest.common import waiters
from tempest import config
from tempest.scenario import manager
from tempest import test
@@ -52,11 +53,13 @@
self.assertEqual(self.node['uuid'], node['uuid'])
self.node = node
- self.servers_client.wait_for_server_status(
+ waiters.wait_for_server_status(
+ self.servers_client,
server_id=self.instance['id'],
status='REBUILD',
ready_wait=False)
- self.servers_client.wait_for_server_status(
+ waiters.wait_for_server_status(
+ self.servers_client,
server_id=self.instance['id'],
status='ACTIVE')
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index ffb35fb..fa70d3f 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -18,6 +18,7 @@
from tempest.common import fixed_network
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest.scenario import manager
from tempest import test
@@ -76,7 +77,8 @@
for server in self.servers:
# Make sure nova list keeps working throughout the build process
self.servers_client.list_servers()
- self.servers_client.wait_for_server_status(server['id'], status)
+ waiters.wait_for_server_status(self.servers_client,
+ server['id'], status)
def nova_boot(self):
name = data_utils.rand_name('scenario-server')
@@ -102,7 +104,7 @@
**create_kwargs)
# needed because of bug 1199788
params = {'name': name}
- server_list = self.servers_client.list_servers(params)
+ server_list = self.servers_client.list_servers(**params)
self.servers = server_list['servers']
for server in self.servers:
# after deleting all servers - wait for all servers to clear
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 6057cd3..83bca88 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -16,6 +16,7 @@
from oslo_log import log as logging
from tempest.common import custom_matchers
+from tempest.common import waiters
from tempest import config
from tempest import exceptions
from tempest.scenario import manager
@@ -43,7 +44,8 @@
server_id = self.server['id']
# Raise on error defaults to True, which is consistent with the
# original function from scenario tests here
- self.servers_client.wait_for_server_status(server_id, status)
+ waiters.wait_for_server_status(self.servers_client,
+ server_id, status)
def nova_keypair_add(self):
self.keypair = self.create_keypair()
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index c864379..3d233d8 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -17,6 +17,7 @@
import testtools
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest.scenario import manager
from tempest import test
@@ -90,7 +91,8 @@
servers=[self.server])
def _wait_server_status_and_check_network_connectivity(self):
- self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client,
+ self.server['id'], 'ACTIVE')
self._check_network_connectivity()
@test.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
@@ -99,8 +101,8 @@
def test_server_connectivity_stop_start(self):
self._setup_network_and_servers()
self.servers_client.stop(self.server['id'])
- self.servers_client.wait_for_server_status(self.server['id'],
- 'SHUTOFF')
+ waiters.wait_for_server_status(self.servers_client,
+ self.server['id'], 'SHUTOFF')
self._check_network_connectivity(should_connect=False)
self.servers_client.start(self.server['id'])
self._wait_server_status_and_check_network_connectivity()
@@ -128,7 +130,8 @@
def test_server_connectivity_pause_unpause(self):
self._setup_network_and_servers()
self.servers_client.pause_server(self.server['id'])
- self.servers_client.wait_for_server_status(self.server['id'], 'PAUSED')
+ waiters.wait_for_server_status(self.servers_client,
+ self.server['id'], 'PAUSED')
self._check_network_connectivity(should_connect=False)
self.servers_client.unpause_server(self.server['id'])
self._wait_server_status_and_check_network_connectivity()
@@ -140,8 +143,8 @@
def test_server_connectivity_suspend_resume(self):
self._setup_network_and_servers()
self.servers_client.suspend_server(self.server['id'])
- self.servers_client.wait_for_server_status(self.server['id'],
- 'SUSPENDED')
+ waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ 'SUSPENDED')
self._check_network_connectivity(should_connect=False)
self.servers_client.resume_server(self.server['id'])
self._wait_server_status_and_check_network_connectivity()
@@ -157,7 +160,7 @@
raise self.skipException(msg)
self._setup_network_and_servers()
self.servers_client.resize(self.server['id'], flavor_ref=resize_flavor)
- self.servers_client.wait_for_server_status(self.server['id'],
- 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.servers_client, self.server['id'],
+ 'VERIFY_RESIZE')
self.servers_client.confirm_resize(self.server['id'])
self._wait_server_status_and_check_network_connectivity()
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 6461886..ff58eea 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -243,7 +243,7 @@
self.assertEqual(1, len(port_list))
old_port = port_list[0]
interface = self.interface_client.create_interface(
- server=server['id'],
+ server_id=server['id'],
network_id=self.new_net.id)
self.addCleanup(self.network_client.wait_for_resource_deletion,
'port',
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 04d5c8b..e405cf5 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -16,6 +16,7 @@
from oslo_log import log as logging
import testtools
+from tempest.common import waiters
from tempest import config
from tempest.scenario import manager
from tempest import test
@@ -58,14 +59,14 @@
LOG.debug("Resizing instance %s from flavor %s to flavor %s",
instance['id'], instance['flavor']['id'], resize_flavor)
self.servers_client.resize(instance_id, resize_flavor)
- self.servers_client.wait_for_server_status(instance_id,
- 'VERIFY_RESIZE')
+ waiters.wait_for_server_status(self.servers_client, instance_id,
+ 'VERIFY_RESIZE')
LOG.debug("Confirming resize of instance %s", instance_id)
self.servers_client.confirm_resize(instance_id)
- self.servers_client.wait_for_server_status(instance_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, instance_id,
+ 'ACTIVE')
@test.idempotent_id('949da7d5-72c8-4808-8802-e3d70df98e2c')
@testtools.skipUnless(CONF.compute_feature_enabled.suspend,
@@ -78,23 +79,23 @@
LOG.debug("Suspending instance %s. Current status: %s",
instance_id, instance['status'])
self.servers_client.suspend_server(instance_id)
- self.servers_client.wait_for_server_status(instance_id,
- 'SUSPENDED')
+ waiters.wait_for_server_status(self.servers_client, instance_id,
+ 'SUSPENDED')
fetched_instance = self.servers_client.show_server(instance_id)
LOG.debug("Resuming instance %s. Current status: %s",
instance_id, fetched_instance['status'])
self.servers_client.resume_server(instance_id)
- self.servers_client.wait_for_server_status(instance_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, instance_id,
+ 'ACTIVE')
fetched_instance = self.servers_client.show_server(instance_id)
LOG.debug("Suspending instance %s. Current status: %s",
instance_id, fetched_instance['status'])
self.servers_client.suspend_server(instance_id)
- self.servers_client.wait_for_server_status(instance_id,
- 'SUSPENDED')
+ waiters.wait_for_server_status(self.servers_client, instance_id,
+ 'SUSPENDED')
fetched_instance = self.servers_client.show_server(instance_id)
LOG.debug("Resuming instance %s. Current status: %s",
instance_id, fetched_instance['status'])
self.servers_client.resume_server(instance_id)
- self.servers_client.wait_for_server_status(instance_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, instance_id,
+ 'ACTIVE')
diff --git a/tempest/scenario/test_shelve_instance.py b/tempest/scenario/test_shelve_instance.py
index e674101..02ee7b9 100644
--- a/tempest/scenario/test_shelve_instance.py
+++ b/tempest/scenario/test_shelve_instance.py
@@ -16,6 +16,7 @@
from oslo_log import log
import testtools
+from tempest.common import waiters
from tempest import config
from tempest.scenario import manager
from tempest import test
@@ -50,15 +51,18 @@
self.servers_client.shelve_server(server['id'])
offload_time = CONF.compute.shelved_offload_time
if offload_time >= 0:
- self.servers_client.wait_for_server_status(
- server['id'], 'SHELVED_OFFLOADED', extra_timeout=offload_time)
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'SHELVED_OFFLOADED',
+ extra_timeout=offload_time)
else:
- self.servers_client.wait_for_server_status(server['id'], 'SHELVED')
+ waiters.wait_for_server_status(self.servers_client,
+ server['id'], 'SHELVED')
self.servers_client.shelve_offload_server(server['id'])
- self.servers_client.wait_for_server_status(server['id'],
- 'SHELVED_OFFLOADED')
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'SHELVED_OFFLOADED')
self.servers_client.unshelve_server(server['id'])
- self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
+ waiters.wait_for_server_status(self.servers_client, server['id'],
+ 'ACTIVE')
@test.idempotent_id('1164e700-0af0-4a4c-8792-35909a88743c')
@testtools.skipUnless(CONF.compute_feature_enabled.shelve,
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 102e9a3..45b7b74 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -13,6 +13,7 @@
from oslo_log import log
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest.scenario import manager
from tempest import test
@@ -85,7 +86,8 @@
for i in instances:
self.servers_client.stop(i['id'])
for i in instances:
- self.servers_client.wait_for_server_status(i['id'], 'SHUTOFF')
+ waiters.wait_for_server_status(self.servers_client,
+ i['id'], 'SHUTOFF')
def _detach_volumes(self, volumes):
# NOTE(gfidente): two loops so we do not wait for the status twice
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index cd9d925..b1246d2 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -13,11 +13,11 @@
# under the License.
-import json
import re
import string
import unicodedata
+from oslo_serialization import jsonutils as json
from tempest_lib.common.utils import misc
import testscenarios
import testtools
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index 1461198..2ac3fb2 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -11,8 +11,8 @@
# under the License.
import functools
-import json
+from oslo_serialization import jsonutils as json
import six
from six.moves.urllib import parse as urllib
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index e0e3ec3..525946e 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -12,8 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import agents as schema
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index e275895..28d4ff5 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import aggregates as schema
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index 9686854..c74fd10 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import availability_zone \
as schema
diff --git a/tempest/services/compute/json/baremetal_nodes_client.py b/tempest/services/compute/json/baremetal_nodes_client.py
index 42caa7b..20be790 100644
--- a/tempest/services/compute/json/baremetal_nodes_client.py
+++ b/tempest/services/compute/json/baremetal_nodes_client.py
@@ -12,8 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import baremetal_nodes \
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index 15b019f..c25b273 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import certificates as schema
from tempest.common import service_client
@@ -21,8 +21,8 @@
class CertificatesClient(service_client.ServiceClient):
- def show_certificate(self, id):
- url = "os-certificates/%s" % (id)
+ def show_certificate(self, certificate_id):
+ url = "os-certificates/%s" % certificate_id
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.get_certificate, resp, body)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index ec60872..da342a8 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import extensions as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index 53a5476..69de79f 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import fixed_ips as schema
from tempest.common import service_client
@@ -22,15 +22,15 @@
class FixedIPsClient(service_client.ServiceClient):
def show_fixed_ip(self, fixed_ip):
- url = "os-fixed-ips/%s" % (fixed_ip)
+ url = "os-fixed-ips/%s" % fixed_ip
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.get_fixed_ip, resp, body)
return service_client.ResponseBody(resp, body['fixed_ip'])
- def reserve_fixed_ip(self, ip, body):
+ def reserve_fixed_ip(self, fixed_ip, body):
"""This reserves and unreserves fixed ips."""
- url = "os-fixed-ips/%s/action" % (ip)
+ url = "os-fixed-ips/%s/action" % fixed_ip
resp, body = self.post(url, json.dumps(body))
self.validate_response(schema.reserve_fixed_ip, resp, body)
return service_client.ResponseBody(resp)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 2f7de3f..b928f9f 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import flavors as schema
diff --git a/tempest/services/compute/json/floating_ip_pools_client.py b/tempest/services/compute/json/floating_ip_pools_client.py
new file mode 100644
index 0000000..1cc411b
--- /dev/null
+++ b/tempest/services/compute/json/floating_ip_pools_client.py
@@ -0,0 +1,35 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+
+from six.moves.urllib import parse as urllib
+
+from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
+from tempest.common import service_client
+
+
+class FloatingIpPoolsClient(service_client.ServiceClient):
+
+ def list_floating_ip_pools(self, params=None):
+ """Returns a list of all floating IP Pools."""
+ url = 'os-floating-ip-pools'
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.validate_response(schema.list_floating_ip_pools, resp, body)
+ return service_client.ResponseBodyList(resp, body['floating_ip_pools'])
diff --git a/tempest/services/compute/json/floating_ips_bulk_client.py b/tempest/services/compute/json/floating_ips_bulk_client.py
new file mode 100644
index 0000000..c8e7350
--- /dev/null
+++ b/tempest/services/compute/json/floating_ips_bulk_client.py
@@ -0,0 +1,52 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+
+from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
+from tempest.common import service_client
+
+
+class FloatingIpsBulkClient(service_client.ServiceClient):
+
+ def create_floating_ips_bulk(self, ip_range, pool, interface):
+ """Allocate floating IPs in bulk."""
+ post_body = {
+ 'ip_range': ip_range,
+ 'pool': pool,
+ 'interface': interface
+ }
+ post_body = json.dumps({'floating_ips_bulk_create': post_body})
+ resp, body = self.post('os-floating-ips-bulk', post_body)
+ body = json.loads(body)
+ self.validate_response(schema.create_floating_ips_bulk, resp, body)
+ return service_client.ResponseBody(resp,
+ body['floating_ips_bulk_create'])
+
+ def list_floating_ips_bulk(self):
+ """Returns a list of all floating IPs bulk."""
+ resp, body = self.get('os-floating-ips-bulk')
+ body = json.loads(body)
+ self.validate_response(schema.list_floating_ips_bulk, resp, body)
+ return service_client.ResponseBodyList(resp, body['floating_ip_info'])
+
+ def delete_floating_ips_bulk(self, ip_range):
+ """Deletes the provided floating IPs bulk."""
+ post_body = json.dumps({'ip_range': ip_range})
+ resp, body = self.put('os-floating-ips-bulk/delete', post_body)
+ body = json.loads(body)
+ self.validate_response(schema.delete_floating_ips_bulk, resp, body)
+ data = body['floating_ips_bulk_delete']
+ return service_client.ResponseBodyData(resp, data)
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 420037b..8923d64 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
@@ -99,44 +98,3 @@
def resource_type(self):
"""Returns the primary type of resource this client works with."""
return 'floating_ip'
-
- def list_floating_ip_pools(self, params=None):
- """Returns a list of all floating IP Pools."""
- url = 'os-floating-ip-pools'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_floating_ip_pools, resp, body)
- return service_client.ResponseBodyList(resp, body['floating_ip_pools'])
-
- def create_floating_ips_bulk(self, ip_range, pool, interface):
- """Allocate floating IPs in bulk."""
- post_body = {
- 'ip_range': ip_range,
- 'pool': pool,
- 'interface': interface
- }
- post_body = json.dumps({'floating_ips_bulk_create': post_body})
- resp, body = self.post('os-floating-ips-bulk', post_body)
- body = json.loads(body)
- self.validate_response(schema.create_floating_ips_bulk, resp, body)
- return service_client.ResponseBody(resp,
- body['floating_ips_bulk_create'])
-
- def list_floating_ips_bulk(self):
- """Returns a list of all floating IPs bulk."""
- resp, body = self.get('os-floating-ips-bulk')
- body = json.loads(body)
- self.validate_response(schema.list_floating_ips_bulk, resp, body)
- return service_client.ResponseBodyList(resp, body['floating_ip_info'])
-
- def delete_floating_ips_bulk(self, ip_range):
- """Deletes the provided floating IPs bulk."""
- post_body = json.dumps({'ip_range': ip_range})
- resp, body = self.put('os-floating-ips-bulk/delete', post_body)
- body = json.loads(body)
- self.validate_response(schema.delete_floating_ips_bulk, resp, body)
- data = body['floating_ips_bulk_delete']
- return service_client.ResponseBodyData(resp, data)
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index 0510104..d597a06 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -12,8 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import hosts as schema
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 865c5bc..e894a5c 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import hypervisors as schema
from tempest.common import service_client
@@ -34,16 +34,16 @@
self.validate_response(_schema, resp, body)
return service_client.ResponseBodyList(resp, body['hypervisors'])
- def show_hypervisor(self, hyper_id):
+ def show_hypervisor(self, hypervisor_id):
"""Display the details of the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s' % hyper_id)
+ resp, body = self.get('os-hypervisors/%s' % hypervisor_id)
body = json.loads(body)
self.validate_response(schema.get_hypervisor, resp, body)
return service_client.ResponseBody(resp, body['hypervisor'])
- def list_servers_on_hypervisor(self, hyper_name):
+ def list_servers_on_hypervisor(self, hypervisor_name):
"""List instances belonging to the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/servers' % hyper_name)
+ resp, body = self.get('os-hypervisors/%s/servers' % hypervisor_name)
body = json.loads(body)
self.validate_response(schema.get_hypervisors_servers, resp, body)
return service_client.ResponseBodyList(resp, body['hypervisors'])
@@ -55,16 +55,16 @@
self.validate_response(schema.get_hypervisor_statistics, resp, body)
return service_client.ResponseBody(resp, body['hypervisor_statistics'])
- def show_hypervisor_uptime(self, hyper_id):
+ def show_hypervisor_uptime(self, hypervisor_id):
"""Display the uptime of the specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/uptime' % hyper_id)
+ resp, body = self.get('os-hypervisors/%s/uptime' % hypervisor_id)
body = json.loads(body)
self.validate_response(schema.get_hypervisor_uptime, resp, body)
return service_client.ResponseBody(resp, body['hypervisor'])
- def search_hypervisor(self, hyper_name):
+ def search_hypervisor(self, hypervisor_name):
"""Search specified hypervisor."""
- resp, body = self.get('os-hypervisors/%s/search' % hyper_name)
+ resp, body = self.get('os-hypervisors/%s/search' % hypervisor_name)
body = json.loads(body)
self.validate_response(schema.list_search_hypervisors, resp, body)
return service_client.ResponseBodyList(resp, body['hypervisors'])
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 172bbe2..b0ce2dc 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index c0841bf..f06a675 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import \
instance_usage_audit_logs as schema
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 0e0ff47..e8b2b64 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import interfaces as schema
from tempest.api_schema.response.compute.v2_1 import servers as servers_schema
@@ -22,14 +22,14 @@
class InterfacesClient(service_client.ServiceClient):
- def list_interfaces(self, server):
- resp, body = self.get('servers/%s/os-interface' % server)
+ def list_interfaces(self, server_id):
+ resp, body = self.get('servers/%s/os-interface' % server_id)
body = json.loads(body)
self.validate_response(schema.list_interfaces, resp, body)
return service_client.ResponseBodyList(resp,
body['interfaceAttachments'])
- def create_interface(self, server, port_id=None, network_id=None,
+ def create_interface(self, server_id, port_id=None, network_id=None,
fixed_ip=None):
post_body = dict(interfaceAttachment=dict())
if port_id:
@@ -40,20 +40,21 @@
fip = dict(ip_address=fixed_ip)
post_body['interfaceAttachment']['fixed_ips'] = [fip]
post_body = json.dumps(post_body)
- resp, body = self.post('servers/%s/os-interface' % server,
+ resp, body = self.post('servers/%s/os-interface' % server_id,
body=post_body)
body = json.loads(body)
self.validate_response(schema.get_create_interfaces, resp, body)
return service_client.ResponseBody(resp, body['interfaceAttachment'])
- def show_interface(self, server, port_id):
- resp, body = self.get('servers/%s/os-interface/%s' % (server, port_id))
+ def show_interface(self, server_id, port_id):
+ resp, body = self.get('servers/%s/os-interface/%s' % (server_id,
+ port_id))
body = json.loads(body)
self.validate_response(schema.get_create_interfaces, resp, body)
return service_client.ResponseBody(resp, body['interfaceAttachment'])
- def delete_interface(self, server, port_id):
- resp, body = self.delete('servers/%s/os-interface/%s' % (server,
+ def delete_interface(self, server_id, port_id):
+ resp, body = self.delete('servers/%s/os-interface/%s' % (server_id,
port_id))
self.validate_response(schema.delete_interface, resp, body)
return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index ba8b1e2..6f819ae 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import keypairs as schema
from tempest.common import service_client
@@ -32,8 +32,8 @@
self.validate_response(schema.list_keypairs, resp, body)
return service_client.ResponseBodyList(resp, body['keypairs'])
- def show_keypair(self, key_name):
- resp, body = self.get("os-keypairs/%s" % key_name)
+ def show_keypair(self, keypair_name):
+ resp, body = self.get("os-keypairs/%s" % keypair_name)
body = json.loads(body)
self.validate_response(schema.get_keypair, resp, body)
return service_client.ResponseBody(resp, body['keypair'])
@@ -48,7 +48,7 @@
self.validate_response(schema.create_keypair, resp, body)
return service_client.ResponseBody(resp, body['keypair'])
- def delete_keypair(self, key_name):
- resp, body = self.delete("os-keypairs/%s" % key_name)
+ def delete_keypair(self, keypair_name):
+ resp, body = self.delete("os-keypairs/%s" % keypair_name)
self.validate_response(schema.delete_keypair, resp, body)
return service_client.ResponseBody(resp, body)
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index bfa340c..4287619 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import limits as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index cd04e45..2a2bcd2 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -12,8 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import migrations as schema
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
index cf9f534..6373f01 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/compute/json/quota_classes_client.py b/tempest/services/compute/json/quota_classes_client.py
index a741be4..30d3501 100644
--- a/tempest/services/compute/json/quota_classes_client.py
+++ b/tempest/services/compute/json/quota_classes_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1\
import quota_classes as classes_schema
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index b038508..4ea47ed 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import quotas as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/security_group_default_rules_client.py b/tempest/services/compute/json/security_group_default_rules_client.py
index 304e759..fcc715a 100644
--- a/tempest/services/compute/json/security_group_default_rules_client.py
+++ b/tempest/services/compute/json/security_group_default_rules_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import \
security_group_default_rule as schema
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index ca4f9bc..bee8d41 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
diff --git a/tempest/services/compute/json/server_groups_client.py b/tempest/services/compute/json/server_groups_client.py
new file mode 100644
index 0000000..9fec930
--- /dev/null
+++ b/tempest/services/compute/json/server_groups_client.py
@@ -0,0 +1,61 @@
+# Copyright 2012 OpenStack Foundation
+# Copyright 2013 Hewlett-Packard Development Company, L.P.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import json
+
+from tempest.api_schema.response.compute.v2_1 import servers as schema
+from tempest.common import service_client
+
+
+class ServerGroupsClient(service_client.ServiceClient):
+
+ def create_server_group(self, name, policies):
+ """
+ Create the server group
+ name : Name of the server-group
+ policies : List of the policies - affinity/anti-affinity)
+ """
+ post_body = {
+ 'name': name,
+ 'policies': policies,
+ }
+
+ post_body = json.dumps({'server_group': post_body})
+ resp, body = self.post('os-server-groups', post_body)
+
+ body = json.loads(body)
+ self.validate_response(schema.create_get_server_group, resp, body)
+ return service_client.ResponseBody(resp, body['server_group'])
+
+ def delete_server_group(self, server_group_id):
+ """Delete the given server-group."""
+ resp, body = self.delete("os-server-groups/%s" % server_group_id)
+ self.validate_response(schema.delete_server_group, resp, body)
+ return service_client.ResponseBody(resp, body)
+
+ def list_server_groups(self):
+ """List the server-groups."""
+ resp, body = self.get("os-server-groups")
+ body = json.loads(body)
+ self.validate_response(schema.list_server_groups, resp, body)
+ return service_client.ResponseBodyList(resp, body['server_groups'])
+
+ def get_server_group(self, server_group_id):
+ """Get the details of given server_group."""
+ resp, body = self.get("os-server-groups/%s" % server_group_id)
+ body = json.loads(body)
+ self.validate_response(schema.create_get_server_group, resp, body)
+ return service_client.ResponseBody(resp, body['server_group'])
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 2ecb2d4..1159a58 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -14,15 +14,14 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import time
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import servers as schema
from tempest.common import service_client
-from tempest.common import waiters
from tempest import exceptions
@@ -149,38 +148,23 @@
self.validate_response(schema.delete_server, resp, body)
return service_client.ResponseBody(resp, body)
- def list_servers(self, params=None):
+ def list_servers(self, detail=False, **params):
"""Lists all servers for a user."""
url = 'servers'
+ _schema = schema.list_servers
+
+ if detail:
+ url += '/detail'
+ _schema = schema.list_servers_detail
if params:
url += '?%s' % urllib.urlencode(params)
resp, body = self.get(url)
body = json.loads(body)
- self.validate_response(schema.list_servers, resp, body)
+ self.validate_response(_schema, resp, body)
return service_client.ResponseBody(resp, body)
- def list_servers_with_detail(self, params=None):
- """Lists all servers in detail for a user."""
-
- url = 'servers/detail'
- if params:
- url += '?%s' % urllib.urlencode(params)
-
- resp, body = self.get(url)
- body = json.loads(body)
- self.validate_response(schema.list_servers_detail, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def wait_for_server_status(self, server_id, status, extra_timeout=0,
- raise_on_error=True, ready_wait=True):
- """Waits for a server to reach a given status."""
- return waiters.wait_for_server_status(self, server_id, status,
- extra_timeout=extra_timeout,
- raise_on_error=raise_on_error,
- ready_wait=ready_wait)
-
def wait_for_server_termination(self, server_id, ignore_error=False):
"""Waits for server to reach termination."""
start_time = int(time.time())
@@ -532,41 +516,3 @@
return self.action(server_id, "os-getVNCConsole",
"console", schema.get_vnc_console,
type=console_type)
-
- def create_server_group(self, name, policies):
- """
- Create the server group
- name : Name of the server-group
- policies : List of the policies - affinity/anti-affinity)
- """
- post_body = {
- 'name': name,
- 'policies': policies,
- }
-
- post_body = json.dumps({'server_group': post_body})
- resp, body = self.post('os-server-groups', post_body)
-
- body = json.loads(body)
- self.validate_response(schema.create_get_server_group, resp, body)
- return service_client.ResponseBody(resp, body['server_group'])
-
- def delete_server_group(self, server_group_id):
- """Delete the given server-group."""
- resp, body = self.delete("os-server-groups/%s" % server_group_id)
- self.validate_response(schema.delete_server_group, resp, body)
- return service_client.ResponseBody(resp, body)
-
- def list_server_groups(self):
- """List the server-groups."""
- resp, body = self.get("os-server-groups")
- body = json.loads(body)
- self.validate_response(schema.list_server_groups, resp, body)
- return service_client.ResponseBodyList(resp, body['server_groups'])
-
- def get_server_group(self, server_group_id):
- """Get the details of given server_group."""
- resp, body = self.get("os-server-groups/%s" % server_group_id)
- body = json.loads(body)
- self.validate_response(schema.create_get_server_group, resp, body)
- return service_client.ResponseBody(resp, body['server_group'])
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index 01f96af..e1b48bb 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -14,8 +14,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import services as schema
diff --git a/tempest/services/compute/json/tenant_networks_client.py b/tempest/services/compute/json/tenant_networks_client.py
index b15ebe3..d31c5f5 100644
--- a/tempest/services/compute/json/tenant_networks_client.py
+++ b/tempest/services/compute/json/tenant_networks_client.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.api_schema.response.compute.v2_1 import tenant_networks as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index fac412e..cd9f3b6 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.compute.v2_1 import tenant_usages as schema
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 08bb4bc..ac55049 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -13,15 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-import time
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute.v2_1 import volumes as schema
from tempest.common import service_client
-from tempest import exceptions
class VolumesExtensionsClient(service_client.ServiceClient):
@@ -81,26 +78,6 @@
self.validate_response(schema.delete_volume, resp, body)
return service_client.ResponseBody(resp, body)
- def wait_for_volume_status(self, volume_id, status):
- """Waits for a Volume to reach a given status."""
- body = self.show_volume(volume_id)
- volume_status = body['status']
- start = int(time.time())
-
- while volume_status != status:
- time.sleep(self.build_interval)
- body = self.show_volume(volume_id)
- volume_status = body['status']
- if volume_status == 'error':
- raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
-
- if int(time.time()) - start >= self.build_timeout:
- message = ('Volume %s failed to reach %s status (current %s) '
- 'within the required time (%s s).' %
- (volume_id, status, volume_status,
- self.build_timeout))
- raise exceptions.TimeoutException(message)
-
def is_resource_deleted(self, id):
try:
self.show_volume(id)
diff --git a/tempest/services/data_processing/v1_1/data_processing_client.py b/tempest/services/data_processing/v1_1/data_processing_client.py
index 04cf9a3..bbc0f2a 100644
--- a/tempest/services/data_processing/v1_1/data_processing_client.py
+++ b/tempest/services/data_processing/v1_1/data_processing_client.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/identity/v2/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
index fd4160f..1076fca 100644
--- a/tempest/services/identity/v2/json/identity_client.py
+++ b/tempest/services/identity/v2/json/identity_client.py
@@ -10,7 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest_lib import exceptions as lib_exc
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/services/identity/v3/json/credentials_client.py
index 281f3cd..e27f960 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/services/identity/v3/json/credentials_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index 44acb47..f93fb74 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index d8afd2c..87d4b79 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/policy_client.py b/tempest/services/identity/v3/json/policy_client.py
index 424fb1d..f820598 100644
--- a/tempest/services/identity/v3/json/policy_client.py
+++ b/tempest/services/identity/v3/json/policy_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/region_client.py b/tempest/services/identity/v3/json/region_client.py
index 9d7d496..43226be 100644
--- a/tempest/services/identity/v3/json/region_client.py
+++ b/tempest/services/identity/v3/json/region_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/identity/v3/json/service_client.py b/tempest/services/identity/v3/json/service_client.py
index c678918..52ff479 100644
--- a/tempest/services/identity/v3/json/service_client.py
+++ b/tempest/services/identity/v3/json/service_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index eae5c64..a07612a 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -15,11 +15,11 @@
import copy
import errno
-import json
import os
import time
from oslo_log import log as logging
+from oslo_serialization import jsonutils as json
import six
from six.moves.urllib import parse as urllib
from tempest_lib.common.utils import misc as misc_utils
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 95972ae..67f7708 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -13,9 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
import jsonschema
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
index b99e0a7..2f233a9 100644
--- a/tempest/services/messaging/json/messaging_client.py
+++ b/tempest/services/messaging/json/messaging_client.py
@@ -13,9 +13,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import json
import uuid
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.api_schema.response.messaging.v1 import queues as queues_schema
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 25eaf7e..65f3aa7 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -10,9 +10,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import time
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib.common.utils import misc
from tempest_lib import exceptions as lib_exc
@@ -73,17 +73,14 @@
}
return resource_plural_map.get(resource_name, resource_name + 's')
- def _lister(self, plural_name):
- def _list(**filters):
- uri = self.get_uri(plural_name)
- if filters:
- uri += '?' + urllib.urlencode(filters, doseq=1)
- resp, body = self.get(uri)
- body = self.deserialize_list(body)
- self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, body)
-
- return _list
+ def _list_resources(self, uri, **filters):
+ req_uri = self.uri_prefix + uri
+ if filters:
+ req_uri += '?' + urllib.urlencode(filters, doseq=1)
+ resp, body = self.get(req_uri)
+ body = self.deserialize_list(body)
+ self.expected_success(200, resp.status)
+ return service_client.ResponseBody(resp, body)
def _delete_resource(self, uri):
req_uri = self.uri_prefix + uri
@@ -119,15 +116,6 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def __getattr__(self, name):
- method_prefixes = ["list_"]
- method_functors = [self._lister]
- for index, prefix in enumerate(method_prefixes):
- prefix_len = len(prefix)
- if name[:prefix_len] == prefix:
- return method_functors[index](name[prefix_len:])
- raise AttributeError(name)
-
def create_network(self, **kwargs):
uri = '/networks'
post_data = {'network': kwargs}
@@ -146,6 +134,10 @@
uri = '/networks/%s' % network_id
return self._delete_resource(uri)
+ def list_networks(self, **filters):
+ uri = '/networks'
+ return self._list_resources(uri, **filters)
+
def create_subnet(self, **kwargs):
uri = '/subnets'
post_data = {'subnet': kwargs}
@@ -164,6 +156,10 @@
uri = '/subnets/%s' % subnet_id
return self._delete_resource(uri)
+ def list_subnets(self, **filters):
+ uri = '/subnets'
+ return self._list_resources(uri, **filters)
+
def create_port(self, **kwargs):
uri = '/ports'
post_data = {'port': kwargs}
@@ -182,6 +178,10 @@
uri = '/ports/%s' % port_id
return self._delete_resource(uri)
+ def list_ports(self, **filters):
+ uri = '/ports'
+ return self._list_resources(uri, **filters)
+
def create_floatingip(self, **kwargs):
uri = '/floatingips'
post_data = {'floatingip': kwargs}
@@ -200,6 +200,10 @@
uri = '/floatingips/%s' % floatingip_id
return self._delete_resource(uri)
+ def list_floatingips(self, **filters):
+ uri = '/floatingips'
+ return self._list_resources(uri, **filters)
+
def create_metering_label(self, **kwargs):
uri = '/metering/metering-labels'
post_data = {'metering_label': kwargs}
@@ -213,6 +217,10 @@
uri = '/metering/metering-labels/%s' % metering_label_id
return self._delete_resource(uri)
+ def list_metering_labels(self, **filters):
+ uri = '/metering/metering-labels'
+ return self._list_resources(uri, **filters)
+
def create_metering_label_rule(self, **kwargs):
uri = '/metering/metering-label-rules'
post_data = {'metering_label_rule': kwargs}
@@ -226,6 +234,10 @@
uri = '/metering/metering-label-rules/%s' % metering_label_rule_id
return self._delete_resource(uri)
+ def list_metering_label_rules(self, **filters):
+ uri = '/metering/metering-label-rules'
+ return self._list_resources(uri, **filters)
+
def create_security_group(self, **kwargs):
uri = '/security-groups'
post_data = {'security_group': kwargs}
@@ -244,6 +256,10 @@
uri = '/security-groups/%s' % security_group_id
return self._delete_resource(uri)
+ def list_security_groups(self, **filters):
+ uri = '/security-groups'
+ return self._list_resources(uri, **filters)
+
def create_security_group_rule(self, **kwargs):
uri = '/security-group-rules'
post_data = {'security_group_rule': kwargs}
@@ -257,10 +273,18 @@
uri = '/security-group-rules/%s' % security_group_rule_id
return self._delete_resource(uri)
+ def list_security_group_rules(self, **filters):
+ uri = '/security-group-rules'
+ return self._list_resources(uri, **filters)
+
def show_extension(self, ext_alias, **fields):
uri = '/extensions/%s' % ext_alias
return self._show_resource(uri, **fields)
+ def list_extensions(self, **filters):
+ uri = '/extensions'
+ return self._list_resources(uri, **filters)
+
# Common methods that are hard to automate
def create_bulk_network(self, names):
network_list = [{'name': name} for name in names]
@@ -378,6 +402,10 @@
uri = '/quotas/%s' % tenant_id
return self._show_resource(uri, **fields)
+ def list_quotas(self, **filters):
+ uri = '/quotas'
+ return self._list_resources(uri, **filters)
+
def create_router(self, name, admin_state_up=True, **kwargs):
post_body = {'router': kwargs}
post_body['router']['name'] = name
@@ -435,6 +463,10 @@
uri = '/routers/%s' % router_id
return self._delete_resource(uri)
+ def list_routers(self, **filters):
+ uri = '/routers'
+ return self._list_resources(uri, **filters)
+
def update_router_with_snat_gw_info(self, router_id, **kwargs):
"""Update a router passing also the enable_snat attribute.
@@ -507,6 +539,10 @@
uri = '/agents/%s' % agent_id
return self._show_resource(uri, **fields)
+ def list_agents(self, **filters):
+ uri = '/agents'
+ return self._list_resources(uri, **filters)
+
def list_routers_on_l3_agent(self, agent_id):
uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
resp, body = self.get(uri)
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index dece763..d89aa5d 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -13,9 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
from xml.etree import ElementTree as etree
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/object_storage/container_client.py b/tempest/services/object_storage/container_client.py
index 8e225b0..b31fe1b 100644
--- a/tempest/services/object_storage/container_client.py
+++ b/tempest/services/object_storage/container_client.py
@@ -13,9 +13,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
from xml.etree import ElementTree as etree
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index 4d443d3..84a9ed9 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -13,10 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import re
import time
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
diff --git a/tempest/services/volume/json/admin/volume_hosts_client.py b/tempest/services/volume/json/admin/volume_hosts_client.py
index 260679e..6801453 100644
--- a/tempest/services/volume/json/admin/volume_hosts_client.py
+++ b/tempest/services/volume/json/admin/volume_hosts_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/volume/json/admin/volume_services_client.py b/tempest/services/volume/json/admin/volume_services_client.py
index 2b2a696..c8607c1 100644
--- a/tempest/services/volume/json/admin/volume_services_client.py
+++ b/tempest/services/volume/json/admin/volume_services_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest.common import service_client
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index 9a75f6c..84c7bc5 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -13,8 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
diff --git a/tempest/services/volume/json/availability_zone_client.py b/tempest/services/volume/json/availability_zone_client.py
index e60d5c1..13d5d55 100644
--- a/tempest/services/volume/json/availability_zone_client.py
+++ b/tempest/services/volume/json/availability_zone_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/volume/json/backups_client.py b/tempest/services/volume/json/backups_client.py
index bf9af6e..0f83b8d 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/json/backups_client.py
@@ -13,9 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import time
+from oslo_serialization import jsonutils as json
+
from tempest.common import service_client
from tempest import exceptions
diff --git a/tempest/services/volume/json/extensions_client.py b/tempest/services/volume/json/extensions_client.py
index 3bf468a..1098e1e 100644
--- a/tempest/services/volume/json/extensions_client.py
+++ b/tempest/services/volume/json/extensions_client.py
@@ -13,7 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
+from oslo_serialization import jsonutils as json
from tempest.common import service_client
diff --git a/tempest/services/volume/json/qos_client.py b/tempest/services/volume/json/qos_client.py
index 37ab9cd..e3d6a29 100644
--- a/tempest/services/volume/json/qos_client.py
+++ b/tempest/services/volume/json/qos_client.py
@@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import time
+from oslo_serialization import jsonutils as json
from tempest_lib import exceptions as lib_exc
from tempest.common import service_client
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index 7f7cceb..fa1f9dd 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -10,10 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import time
from oslo_log import log as logging
+from oslo_serialization import jsonutils as json
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 1f8548e..26f186e 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -13,14 +13,13 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-import time
-
+from oslo_serialization import jsonutils as json
+import six
from six.moves.urllib import parse as urllib
from tempest_lib import exceptions as lib_exc
from tempest.common import service_client
-from tempest import exceptions
+from tempest.common import waiters
class BaseVolumesClient(service_client.ServiceClient):
@@ -40,18 +39,57 @@
"""Return the element 'attachment' from input volumes."""
return volume['attachments'][0]
- def list_volumes(self, detail=False, params=None):
- """List all the volumes created."""
+ def _ext_get(self, url, key=None, status=200):
+ """Extended get method.
+
+ Retrieves requested url, checks that status is expected status and
+ return a ResponseBody, ResponseBodyList or ResponseBodyData depending
+ on received data's key entry.
+
+ If key is not specified or is None we will return the whole body in a
+ ResponseBody class.
+ """
+
+ resp, body = self.get(url)
+ body = json.loads(body)
+ self.expected_success(status, resp.status)
+
+ if not key:
+ return service_client.ResponseBody(resp, body)
+ elif isinstance(body[key], dict):
+ return service_client.ResponseBody(resp, body[key])
+ elif isinstance(body[key], list):
+ return service_client.ResponseBodyList(resp, body[key])
+
+ return service_client.ResponseBodyData(resp, body[key])
+
+ def _prepare_params(self, params):
+ """Prepares params for use in get or _ext_get methods.
+
+ If params is a string it will be left as it is, but if it's not it will
+ be urlencoded.
+ """
+ if isinstance(params, six.string_types):
+ return params
+ return urllib.urlencode(params)
+
+ def list_volumes(self, detail=False, params=None, return_body=False):
+ """List all the volumes created.
+
+ Params can be a string (must be urlencoded) or a dictionary.
+ If return_body is True then we will return the whole response body in
+ a ResponseBody class, it it's False or has not been specified we will
+ return only the list of volumes in a ResponseBodyList (inherits from
+ list).
+ """
url = 'volumes'
if detail:
url += '/detail'
if params:
- url += '?%s' % urllib.urlencode(params)
+ url += '?%s' % self._prepare_params(params)
- resp, body = self.get(url)
- body = json.loads(body)
- self.expected_success(200, resp.status)
- return service_client.ResponseBodyList(resp, body['volumes'])
+ key = None if return_body else 'volumes'
+ return self._ext_get(url, key)
def show_volume(self, volume_id):
"""Returns the details of a single volume."""
@@ -161,25 +199,7 @@
def wait_for_volume_status(self, volume_id, status):
"""Waits for a Volume to reach a given status."""
- body = self.show_volume(volume_id)
- volume_status = body['status']
- start = int(time.time())
-
- while volume_status != status:
- time.sleep(self.build_interval)
- body = self.show_volume(volume_id)
- volume_status = body['status']
- if volume_status == 'error':
- raise exceptions.VolumeBuildErrorException(volume_id=volume_id)
-
- if int(time.time()) - start >= self.build_timeout:
- message = ('Volume %s failed to reach %s status (current: %s) '
- 'within the required time '
- '(%s s).' % (volume_id,
- status,
- volume_status,
- self.build_timeout))
- raise exceptions.TimeoutException(message)
+ waiters.wait_for_volume_status(self, volume_id, status)
def is_resource_deleted(self, id):
try:
diff --git a/tempest/stress/actions/server_create_destroy.py b/tempest/stress/actions/server_create_destroy.py
index d0e4eea..9f41526 100644
--- a/tempest/stress/actions/server_create_destroy.py
+++ b/tempest/stress/actions/server_create_destroy.py
@@ -13,6 +13,7 @@
# limitations under the License.
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
import tempest.stress.stressaction as stressaction
@@ -31,8 +32,8 @@
server = self.manager.servers_client.create_server(
name, self.image, self.flavor)
server_id = server['id']
- self.manager.servers_client.wait_for_server_status(server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.manager.servers_client, server_id,
+ 'ACTIVE')
self.logger.info("created %s" % server_id)
self.logger.info("deleting %s" % name)
self.manager.servers_client.delete_server(server_id)
diff --git a/tempest/stress/actions/ssh_floating.py b/tempest/stress/actions/ssh_floating.py
index 9e540fa..4a27466 100644
--- a/tempest/stress/actions/ssh_floating.py
+++ b/tempest/stress/actions/ssh_floating.py
@@ -14,6 +14,7 @@
import subprocess
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
import tempest.stress.stressaction as stressaction
import tempest.test
@@ -79,8 +80,8 @@
**vm_args)
self.server_id = server['id']
if self.wait_after_vm_create:
- self.manager.servers_client.wait_for_server_status(self.server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.manager.servers_client,
+ self.server_id, 'ACTIVE')
def _destroy_vm(self):
self.logger.info("deleting %s" % self.server_id)
@@ -172,8 +173,8 @@
self._create_vm()
if self.reboot:
self.manager.servers_client.reboot(self.server_id, 'HARD')
- self.manager.servers_client.wait_for_server_status(self.server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.manager.servers_client,
+ self.server_id, 'ACTIVE')
self.run_core()
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index a5e393f..d6965c7 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -12,6 +12,7 @@
# limitations under the License.
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
import tempest.stress.stressaction as stressaction
@@ -40,7 +41,8 @@
server = self.manager.servers_client.create_server(
vm_name, self.image, self.flavor)
server_id = server['id']
- self.manager.servers_client.wait_for_server_status(server_id, 'ACTIVE')
+ waiters.wait_for_server_status(self.manager.servers_client, server_id,
+ 'ACTIVE')
self.logger.info("created vm %s" % server_id)
# Step 3: attach volume to vm
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index 1cd96ed..3ba2a91 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -14,6 +14,7 @@
from tempest.common.utils import data_utils
from tempest.common.utils.linux import remote_client
+from tempest.common import waiters
from tempest import config
import tempest.stress.stressaction as stressaction
import tempest.test
@@ -41,8 +42,8 @@
self.flavor,
**vm_args)
self.server_id = server['id']
- self.manager.servers_client.wait_for_server_status(self.server_id,
- 'ACTIVE')
+ waiters.wait_for_server_status(self.manager.servers_client,
+ self.server_id, 'ACTIVE')
def _destroy_vm(self):
self.logger.info("deleting server: %s" % self.server_id)
diff --git a/tempest/stress/cleanup.py b/tempest/stress/cleanup.py
index 29c4401..d9b430e 100644
--- a/tempest/stress/cleanup.py
+++ b/tempest/stress/cleanup.py
@@ -24,7 +24,7 @@
def cleanup():
admin_manager = clients.AdminManager()
- body = admin_manager.servers_client.list_servers({"all_tenants": True})
+ body = admin_manager.servers_client.list_servers(all_tenants=True)
LOG.info("Cleanup::remove %s servers" % len(body['servers']))
for s in body['servers']:
try:
diff --git a/tempest/test.py b/tempest/test.py
index 80e61c7..0e60041 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -15,7 +15,6 @@
import atexit
import functools
-import json
import os
import re
import sys
@@ -25,6 +24,7 @@
import fixtures
from oslo_log import log as logging
+from oslo_serialization import jsonutils as json
from oslo_utils import importutils
import six
import testscenarios
diff --git a/tempest/test_discover/plugins.py b/tempest/test_discover/plugins.py
index 197bd0c..2701f02 100644
--- a/tempest/test_discover/plugins.py
+++ b/tempest/test_discover/plugins.py
@@ -13,12 +13,16 @@
# under the License.
import abc
+import logging
import six
import stevedore
from tempest_lib.common.utils import misc
+LOG = logging.getLogger(__name__)
+
+
@six.add_metaclass(abc.ABCMeta)
class TempestPlugin(object):
"""A TempestPlugin class provides the basic hooks for an external
@@ -46,8 +50,14 @@
"""
def __init__(self):
self.ext_plugins = stevedore.ExtensionManager(
- 'tempest.test.plugins', invoke_on_load=True,
- propagate_map_exceptions=True)
+ 'tempest.test_plugins', invoke_on_load=True,
+ propagate_map_exceptions=True,
+ on_load_failure_callback=self.failure_hook)
+
+ @staticmethod
+ def failure_hook(_, ep, err):
+ LOG.error('Could not load %r: %s', ep.name, err)
+ raise err
def get_plugin_load_tests_tuple(self):
load_tests_dict = {}
diff --git a/tempest/test_discover/test_discover.py b/tempest/test_discover/test_discover.py
index a871d10..dac7d91 100644
--- a/tempest/test_discover/test_discover.py
+++ b/tempest/test_discover/test_discover.py
@@ -30,12 +30,14 @@
base_path = os.path.split(os.path.dirname(os.path.abspath(__file__)))[0]
base_path = os.path.split(base_path)[0]
# Load local tempest tests
- for test_dir in ['./tempest/api', './tempest/scenario',
- './tempest/thirdparty']:
+ for test_dir in ['tempest/api', 'tempest/scenario',
+ 'tempest/thirdparty']:
+ full_test_dir = os.path.join(base_path, test_dir)
if not pattern:
- suite.addTests(loader.discover(test_dir, top_level_dir=base_path))
+ suite.addTests(loader.discover(full_test_dir,
+ top_level_dir=base_path))
else:
- suite.addTests(loader.discover(test_dir, pattern=pattern,
+ suite.addTests(loader.discover(full_test_dir, pattern=pattern,
top_level_dir=base_path))
plugin_load_tests = ext_plugins.get_plugin_load_tests_tuple()
@@ -46,8 +48,8 @@
for plugin in plugin_load_tests:
test_dir, top_path = plugin_load_tests[plugin]
if not pattern:
- suite.addTests(loader.discover(test_dir, top_level=top_path))
+ suite.addTests(loader.discover(test_dir, top_level_dir=top_path))
else:
suite.addTests(loader.discover(test_dir, pattern=pattern,
- top_level=top_path))
+ top_level_dir=top_path))
return suite
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 7286d76..6bc96f2 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -12,9 +12,9 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import mock
+from oslo_serialization import jsonutils as json
from oslotest import mockpatch
from tempest.cmd import verify_tempest_config
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index 3de7aba..695d4a4 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -24,6 +24,8 @@
from tempest.services.compute.json import extensions_client
from tempest.services.compute.json import fixed_ips_client
from tempest.services.compute.json import flavors_client
+from tempest.services.compute.json import floating_ip_pools_client
+from tempest.services.compute.json import floating_ips_bulk_client
from tempest.services.compute.json import floating_ips_client
from tempest.services.compute.json import hosts_client
from tempest.services.compute.json import hypervisor_client
@@ -39,6 +41,7 @@
from tempest.services.compute.json import security_group_default_rules_client \
as nova_secgrop_default_client
from tempest.services.compute.json import security_groups_client
+from tempest.services.compute.json import server_groups_client
from tempest.services.compute.json import servers_client
from tempest.services.compute.json import services_client
from tempest.services.compute.json import tenant_usages_client
@@ -112,6 +115,8 @@
extensions_client.ExtensionsClient,
fixed_ips_client.FixedIPsClient,
flavors_client.FlavorsClient,
+ floating_ip_pools_client.FloatingIpPoolsClient,
+ floating_ips_bulk_client.FloatingIpsBulkClient,
floating_ips_client.FloatingIPsClient,
hosts_client.HostsClient,
hypervisor_client.HypervisorClient,
@@ -126,6 +131,7 @@
quota_classes_client.QuotaClassesClient,
nova_secgrop_default_client.SecurityGroupDefaultRulesClient,
security_groups_client.SecurityGroupsClient,
+ server_groups_client.ServerGroupsClient,
servers_client.ServersClient,
services_client.ServicesClient,
tenant_usages_client.TenantUsagesClient,
diff --git a/tempest/tests/fake_identity.py b/tempest/tests/fake_identity.py
index ad78f85..d0de927 100644
--- a/tempest/tests/fake_identity.py
+++ b/tempest/tests/fake_identity.py
@@ -13,9 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
-
import httplib2
+from oslo_serialization import jsonutils as json
FAKE_AUTH_URL = 'http://fake_uri.com/auth'
diff --git a/tempest/tests/services/__init__.py b/tempest/tests/services/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/services/__init__.py
diff --git a/tempest/tests/services/compute/__init__.py b/tempest/tests/services/compute/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/tests/services/compute/__init__.py
diff --git a/tempest/tests/services/compute/test_agents_client.py b/tempest/tests/services/compute/test_agents_client.py
new file mode 100644
index 0000000..e8ea525
--- /dev/null
+++ b/tempest/tests/services/compute/test_agents_client.py
@@ -0,0 +1,50 @@
+# Copyright 2015 NEC Corporation. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import httplib2
+
+from oslotest import mockpatch
+
+from tempest.services.compute.json import agents_client
+from tempest.tests import base
+from tempest.tests import fake_auth_provider
+from tempest.tests import fake_config
+
+
+class TestAgentsClient(base.TestCase):
+
+ def setUp(self):
+ super(TestAgentsClient, self).setUp()
+ self.useFixture(fake_config.ConfigFixture())
+ fake_auth = fake_auth_provider.FakeAuthProvider()
+ self.client = agents_client.AgentsClient(fake_auth,
+ 'compute', 'regionOne')
+
+ def _test_list_agents(self, bytes_body=False):
+ if bytes_body:
+ body = bytes(b'{"agents": []}')
+ else:
+ body = '{"agents": []}'
+ expected = []
+ response = (httplib2.Response({'status': 200}), body)
+ self.useFixture(mockpatch.Patch(
+ 'tempest.common.service_client.ServiceClient.get',
+ return_value=response))
+ self.assertEqual(expected, self.client.list_agents())
+
+ def test_list_agents_with_str_body(self):
+ self._test_list_agents()
+
+ def test_list_agents_with_bytes_body(self):
+ self._test_list_agents(bytes_body=True)
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index 71aa395..105caec 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -13,10 +13,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-import json
import socket
import mock
+from oslo_serialization import jsonutils as json
from oslotest import mockpatch
import six
from six.moves import http_client as httplib
diff --git a/test-requirements.txt b/test-requirements.txt
index 2b3607d..8fcf071 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -7,6 +7,7 @@
python-subunit>=0.0.18
oslosphinx>=2.5.0 # Apache-2.0
mox>=0.5.3
-mock>=1.0
+mock>=1.1;python_version!='2.6'
+mock==1.0.1;python_version=='2.6'
coverage>=3.6
-oslotest>=1.5.1 # Apache-2.0
+oslotest>=1.7.0 # Apache-2.0
diff --git a/tools/install_venv.py b/tools/install_venv.py
index 96b8279..d6d9c8e 100644
--- a/tools/install_venv.py
+++ b/tools/install_venv.py
@@ -48,11 +48,11 @@
def main(argv):
root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
- if os.environ.get('tools_path'):
- root = os.environ['tools_path']
+ if os.environ.get('TOOLS_PATH'):
+ root = os.environ['TOOLS_PATH']
venv = os.path.join(root, '.venv')
- if os.environ.get('venv'):
- venv = os.environ['venv']
+ if os.environ.get('VENV'):
+ venv = os.environ['VENV']
pip_requires = os.path.join(root, 'requirements.txt')
test_requires = os.path.join(root, 'test-requirements.txt')
diff --git a/tools/install_venv_common.py b/tools/install_venv_common.py
index 743b59d..e279159 100644
--- a/tools/install_venv_common.py
+++ b/tools/install_venv_common.py
@@ -101,6 +101,7 @@
print('done.')
else:
print("venv already exists...")
+ pass
def pip_install(self, *args):
self.run_command(['tools/with_venv.sh',
@@ -124,7 +125,7 @@
parser.add_option('-n', '--no-site-packages',
action='store_true',
help="Do not inherit packages from global Python "
- "install")
+ "install.")
return parser.parse_args(argv[1:])[0]
diff --git a/tools/with_venv.sh b/tools/with_venv.sh
index 550c477..165c883 100755
--- a/tools/with_venv.sh
+++ b/tools/with_venv.sh
@@ -1,4 +1,6 @@
#!/bin/bash
-TOOLS=`dirname $0`
-VENV=$TOOLS/../.venv
-source $VENV/bin/activate && "$@"
+TOOLS_PATH=${TOOLS_PATH:-$(dirname $0)/../}
+VENV_PATH=${VENV_PATH:-${TOOLS_PATH}}
+VENV_DIR=${VENV_DIR:-/.venv}
+VENV=${VENV:-${VENV_PATH}/${VENV_DIR}}
+source ${VENV}/bin/activate && "$@"