Merge "Fix non-admin compute quota issue"
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/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/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_servers.py b/tempest/api/compute/admin/test_servers.py
index 0062c1e..51a03f5 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -52,7 +52,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 +61,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 +77,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 +91,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)
@@ -118,10 +118,10 @@
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'],
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 04b909a..ea8e112 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -20,6 +20,7 @@
from tempest.common import compute
from tempest.common.utils import data_utils
+from tempest.common import waiters
from tempest import config
from tempest import exceptions
import tempest.test
@@ -56,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
@@ -182,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
@@ -230,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
@@ -280,8 +283,8 @@
cls.images.append(image_id)
if 'wait_until' in kwargs:
- cls.images_client.wait_for_image_status(image_id,
- kwargs['wait_until'])
+ waiters.wait_for_image_status(cls.images_client,
+ image_id, kwargs['wait_until'])
image = cls.images_client.show_image(image_id)
if kwargs['wait_until'] == 'ACTIVE':
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_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index b307b59..ab82d91 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.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
@@ -52,7 +53,7 @@
cls.images.append(cls.image_id)
image_file = six.StringIO(('*' * 1024))
cls.glance_client.update_image(cls.image_id, data=image_file)
- cls.client.wait_for_image_status(cls.image_id, 'ACTIVE')
+ waiters.wait_for_image_status(cls.client, cls.image_id, 'ACTIVE')
def setUp(self):
super(ImagesMetadataTestJSON, self).setUp()
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 38fed25..1741e86 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.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
@@ -81,7 +82,7 @@
meta = {'image_type': 'test'}
body = self.client.create_image(self.server_id, name, meta)
image_id = data_utils.parse_image_id(body.response['location'])
- self.client.wait_for_image_status(image_id, 'ACTIVE')
+ waiters.wait_for_image_status(self.client, image_id, 'ACTIVE')
# Verify the image was created correctly
image = self.client.show_image(image_id)
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index cc59084..b0bbc91 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -21,6 +21,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
@@ -61,7 +62,7 @@
time.sleep(1)
image_file = six.StringIO(('*' * 1024))
cls.glance_client.update_image(image_id, data=image_file)
- cls.client.wait_for_image_status(image_id, 'ACTIVE')
+ waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE')
body = cls.client.show_image(image_id)
return body
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index c3c50d6..396327b 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -46,6 +46,28 @@
super(AttachInterfacesTestJSON, cls).setup_clients()
cls.client = cls.os.interfaces_client
+ def wait_for_interface_status(self, server, port_id, status):
+ """Waits for a interface to reach a given status."""
+ body = self.client.show_interface(server, port_id)
+ interface_status = body['port_state']
+ start = int(time.time())
+
+ while(interface_status != status):
+ time.sleep(self.build_interval)
+ body = self.client.show_interface(server, port_id)
+ interface_status = body['port_state']
+
+ timed_out = int(time.time()) - start >= self.build_timeout
+
+ if interface_status != status and timed_out:
+ message = ('Interface %s failed to reach %s status '
+ '(current %s) within the required time (%s s).' %
+ (port_id, status, interface_status,
+ self.build_timeout))
+ raise exceptions.TimeoutException(message)
+
+ return body
+
def _check_interface(self, iface, port_id=None, network_id=None,
fixed_ip=None, mac_addr=None):
self.assertIn('port_state', iface)
@@ -61,14 +83,14 @@
def _create_server_get_interfaces(self):
server = self.create_test_server(wait_until='ACTIVE')
ifs = self.client.list_interfaces(server['id'])
- body = self.client.wait_for_interface_status(
+ body = self.wait_for_interface_status(
server['id'], ifs[0]['port_id'], 'ACTIVE')
ifs[0]['port_state'] = body['port_state']
return server, ifs
def _test_create_interface(self, server):
iface = self.client.create_interface(server['id'])
- iface = self.client.wait_for_interface_status(
+ iface = self.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface)
return iface
@@ -77,7 +99,7 @@
network_id = ifs[0]['net_id']
iface = self.client.create_interface(server['id'],
network_id=network_id)
- iface = self.client.wait_for_interface_status(
+ iface = self.wait_for_interface_status(
server['id'], iface['port_id'], 'ACTIVE')
self._check_interface(iface, network_id=network_id)
return iface
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..990ad47 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
@@ -117,15 +118,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_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 326334c..6d546d8 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -92,7 +92,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 +103,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 +114,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 +125,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))
@@ -139,7 +139,7 @@
self.client.stop(self.s1['id'])
self.client.wait_for_server_status(self.s1['id'],
'SHUTOFF')
- body = self.client.list_servers(params)
+ body = self.client.list_servers(**params)
self.client.start(self.s1['id'])
self.client.wait_for_server_status(self.s1['id'],
'ACTIVE')
@@ -153,21 +153,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 +177,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 +188,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 +199,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 +210,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 +224,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 +235,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 +248,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 +259,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 +282,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 +304,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 +315,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_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_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 9cc9e9b..4300dd4 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
@@ -61,14 +62,14 @@
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)
@@ -143,8 +144,8 @@
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,
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/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/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..95a8356 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -559,27 +559,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):
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index ffb35fb..1a18be5 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -102,7 +102,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_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/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index 15b019f..da1aa94 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -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 cd7ecbc..ec60872 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -28,11 +28,6 @@
self.validate_response(schema.list_extensions, resp, body)
return service_client.ResponseBodyList(resp, body['extensions'])
- def is_enabled(self, extension):
- extensions = self.list_extensions()
- exts = extensions['extensions']
- return any([e for e in exts if e['name'] == extension])
-
def show_extension(self, extension_alias):
resp, body = self.get('extensions/%s' % extension_alias)
body = json.loads(body)
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index 53a5476..b921107 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -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/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..1a32861 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -99,44 +99,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/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 865c5bc..61a4dc1 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -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 9ce2eef..172bbe2 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -20,7 +20,6 @@
from tempest.api_schema.response.compute.v2_1 import images as schema
from tempest.common import service_client
-from tempest.common import waiters
class ImagesClient(service_client.ServiceClient):
@@ -73,10 +72,6 @@
self.validate_response(schema.delete, resp, body)
return service_client.ResponseBody(resp, body)
- def wait_for_image_status(self, image_id, status):
- """Waits for an image to reach a given status."""
- waiters.wait_for_image_status(self, image_id, status)
-
def list_image_metadata(self, image_id):
"""Lists all metadata items for an image."""
resp, body = self.get("images/%s/metadata" % image_id)
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 9d6c9d4..e5ab965 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -14,24 +14,22 @@
# under the License.
import json
-import time
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
from tempest.common import service_client
-from tempest import exceptions
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:
@@ -42,46 +40,25 @@
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)
- def wait_for_interface_status(self, server, port_id, status):
- """Waits for a interface to reach a given status."""
- body = self.show_interface(server, port_id)
- interface_status = body['port_state']
- start = int(time.time())
-
- while(interface_status != status):
- time.sleep(self.build_interval)
- body = self.show_interface(server, port_id)
- interface_status = body['port_state']
-
- timed_out = int(time.time()) - start >= self.build_timeout
-
- if interface_status != status and timed_out:
- message = ('Interface %s failed to reach %s status '
- '(current %s) within the required time (%s s).' %
- (port_id, status, interface_status,
- self.build_timeout))
- raise exceptions.TimeoutException(message)
-
- return body
-
def add_fixed_ip(self, server_id, network_id):
"""Add a fixed IP to input server instance."""
post_body = json.dumps({
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index ba8b1e2..cf03a24 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -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/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..1a3864c 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -149,28 +149,21 @@
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)
- 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)
+ self.validate_response(_schema, resp, body)
return service_client.ResponseBody(resp, body)
def wait_for_server_status(self, server_id, status, extra_timeout=0,
@@ -532,41 +525,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/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 08bb4bc..121f160 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -14,14 +14,12 @@
# under the License.
import json
-import time
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 +79,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/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 13449ea..b3663fc 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -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)
- result = {plural_name: self.deserialize_list(body)}
- self.expected_success(200, resp.status)
- return service_client.ResponseBody(resp, result)
-
- 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]
@@ -268,7 +292,7 @@
body = self.serialize_list(post_data, "networks", "network")
uri = self.get_uri("networks")
resp, body = self.post(uri, body)
- body = {'networks': self.deserialize_list(body)}
+ body = self.deserialize_list(body)
self.expected_success(201, resp.status)
return service_client.ResponseBody(resp, body)
@@ -277,7 +301,7 @@
body = self.serialize_list(post_data, 'subnets', 'subnet')
uri = self.get_uri('subnets')
resp, body = self.post(uri, body)
- body = {'subnets': self.deserialize_list(body)}
+ body = self.deserialize_list(body)
self.expected_success(201, resp.status)
return service_client.ResponseBody(resp, body)
@@ -286,7 +310,7 @@
body = self.serialize_list(post_data, 'ports', 'port')
uri = self.get_uri('ports')
resp, body = self.post(uri, body)
- body = {'ports': self.deserialize_list(body)}
+ body = self.deserialize_list(body)
self.expected_success(201, resp.status)
return service_client.ResponseBody(resp, body)
@@ -351,14 +375,7 @@
return json.loads(body)
def deserialize_list(self, body):
- res = json.loads(body)
- # expecting response in form
- # {'resources': [ res1, res2] } => when pagination disabled
- # {'resources': [..], 'resources_links': {}} => if pagination enabled
- for k in res.keys():
- if k.endswith("_links"):
- continue
- return res[k]
+ return json.loads(body)
def serialize(self, data):
return json.dumps(data)
@@ -385,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
@@ -442,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.
@@ -514,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/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 1f8548e..b8e3464 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -14,13 +14,13 @@
# under the License.
import json
-import time
+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 +40,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 +200,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/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_discover/test_discover.py b/tempest/test_discover/test_discover.py
index a871d10..86aa855 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()
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/test_glance_http.py b/tempest/tests/test_glance_http.py
index 7850ee4..71aa395 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -137,7 +137,8 @@
resp, body = self.client.raw_request('PUT', '/images', body=req_body)
self.assertEqual(200, resp.status)
self.assertEqual('fake_response_body', body.read())
- httplib.HTTPConnection.send.assert_call_count(req_body.tell())
+ call_count = httplib.HTTPConnection.send.call_count
+ self.assertEqual(call_count - 1, req_body.tell())
def test_get_connection_class_for_https(self):
conn_class = self.client.get_connection_class('https')
diff --git a/test-requirements.txt b/test-requirements.txt
index 2b3607d..7115168 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
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 && "$@"