Merge "Make the names of image_member methods consistent"
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index d3b1f5e..a03439a 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -78,7 +78,7 @@
return server_id
def _volume_clean_up(self, server_id, volume_id):
- body = self.volumes_client.get_volume(volume_id)
+ body = self.volumes_client.show_volume(volume_id)
if body['status'] == 'in-use':
self.servers_client.detach_volume(server_id, volume_id)
self.volumes_client.wait_for_volume_status(volume_id, 'available')
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index c2ed0ce..10b08a1 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -42,6 +42,10 @@
# Check if the server is in a clean state after test
try:
self.client.wait_for_server_status(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')
+ self.__class__.server_id = server['id']
except Exception:
# Rebuild server if something happened to it during a test
self.__class__.server_id = self.rebuild_server(self.server_id)
@@ -287,8 +291,9 @@
'backup_type': "daily",
'instance_uuid': self.server_id,
}
- image_list = self.os.image_client.image_list_detail(
- properties,
+ image_list = self.os.image_client.list_images(
+ detail=True,
+ properties=properties,
status='active',
sort_key='created_at',
sort_dir='asc')
@@ -310,8 +315,9 @@
self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
self.os.image_client.wait_for_resource_deletion(image1_id)
oldest_backup_exist = False
- image_list = self.os.image_client.image_list_detail(
- properties,
+ image_list = self.os.image_client.list_images(
+ detail=True,
+ properties=properties,
status='active',
sort_key='created_at',
sort_dir='asc')
diff --git a/tempest/api/identity/admin/v2/test_users.py b/tempest/api/identity/admin/v2/test_users.py
index bcac853..8eac80c 100644
--- a/tempest/api/identity/admin/v2/test_users.py
+++ b/tempest/api/identity/admin/v2/test_users.py
@@ -50,7 +50,7 @@
self.alt_email, enabled=False)
self.data.users.append(user)
self.assertEqual(name, user['name'])
- self.assertEqual('false', str(user['enabled']).lower())
+ self.assertEqual(False, user['enabled'])
self.assertEqual(self.alt_email, user['email'])
@test.idempotent_id('39d05857-e8a5-4ed4-ba83-0b52d3ab97ee')
@@ -71,13 +71,13 @@
enabled=False)
self.assertEqual(u_name2, update_user['name'])
self.assertEqual(u_email2, update_user['email'])
- self.assertEqual('false', str(update_user['enabled']).lower())
+ self.assertEqual(False, update_user['enabled'])
# GET by id after updating
updated_user = self.client.get_user(user['id'])
# Assert response body of GET after updating
self.assertEqual(u_name2, updated_user['name'])
self.assertEqual(u_email2, updated_user['email'])
- self.assertEqual('false', str(updated_user['enabled']).lower())
+ self.assertEqual(False, update_user['enabled'])
@test.idempotent_id('29ed26f4-a74e-4425-9a85-fdb49fa269d2')
def test_delete_user(self):
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index b775e91..b1a9d3b 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -79,12 +79,12 @@
self.assertIsNotNone(updated_domain['id'])
self.assertEqual(new_name, updated_domain['name'])
self.assertEqual(new_desc, updated_domain['description'])
- self.assertEqual('true', str(updated_domain['enabled']).lower())
+ self.assertEqual(True, updated_domain['enabled'])
fetched_domain = self.client.get_domain(domain['id'])
self.assertEqual(new_name, fetched_domain['name'])
self.assertEqual(new_desc, fetched_domain['description'])
- self.assertEqual('true', str(fetched_domain['enabled']).lower())
+ self.assertEqual(True, fetched_domain['enabled'])
@test.idempotent_id('036df86e-bb5d-42c0-a7c2-66b9db3a6046')
def test_create_domain_with_disabled_status(self):
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 1672d47..9ca10a4 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -126,4 +126,4 @@
self.assertEqual(interface2, endpoint['interface'])
self.assertEqual(url2, endpoint['url'])
self.assertEqual(region2, endpoint['region'])
- self.assertEqual('false', str(endpoint['enabled']).lower())
+ self.assertEqual(False, endpoint['enabled'])
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 7fe369e..c2456c4 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -53,7 +53,7 @@
self.assertEqual(project['id'],
update_user['project_id'])
self.assertEqual(u_email2, update_user['email'])
- self.assertEqual('false', str(update_user['enabled']).lower())
+ self.assertEqual(False, update_user['enabled'])
# GET by id after updation
new_user_get = self.client.get_user(user['id'])
# Assert response body of GET after updation
@@ -62,7 +62,7 @@
self.assertEqual(project['id'],
new_user_get['project_id'])
self.assertEqual(u_email2, new_user_get['email'])
- self.assertEqual('false', str(new_user_get['enabled']).lower())
+ self.assertEqual(False, new_user_get['enabled'])
@test.idempotent_id('2d223a0e-e457-4a70-9fb1-febe027a0ff9')
def test_update_user_password(self):
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index 4969858..eb6969b 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -36,7 +36,7 @@
self.client.add_member(self.alt_tenant_id, image)
share_image = self._create_image()
self.client.add_member(self.alt_tenant_id, share_image)
- body = self.client.get_shared_images(self.alt_tenant_id)
+ body = self.client.list_shared_images(self.alt_tenant_id)
images = body['shared_images']
images = map(lambda x: x['image_id'], images)
self.assertIn(share_image, images)
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 6c25c93..3f71fcb 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -211,9 +211,10 @@
@test.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
def test_index_status_active_detail(self):
- images_list = self.client.image_list_detail(status='active',
- sort_key='size',
- sort_dir='desc')
+ images_list = self.client.list_images(detail=True,
+ status='active',
+ sort_key='size',
+ sort_dir='desc')
top_size = images_list[0]['size'] # We have non-zero sized images
for image in images_list:
size = image['size']
@@ -223,7 +224,8 @@
@test.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
def test_index_name(self):
- images_list = self.client.image_list_detail(
+ images_list = self.client.list_images(
+ detail=True,
name='New Remote Image dup')
result_set = set(map(lambda x: x['id'], images_list))
for image in images_list:
diff --git a/tempest/api/object_storage/test_object_slo.py b/tempest/api/object_storage/test_object_slo.py
index 7df0dde..6fc7821 100644
--- a/tempest/api/object_storage/test_object_slo.py
+++ b/tempest/api/object_storage/test_object_slo.py
@@ -110,6 +110,7 @@
self.assertHeaders(resp, 'Object', method)
@test.idempotent_id('2c3f24a6-36e8-4711-9aa2-800ee1fc7b5b')
+ @test.requires_ext(extension='slo', service='object')
def test_upload_manifest(self):
# create static large object from multipart manifest
manifest = self._create_manifest()
@@ -124,6 +125,7 @@
self._assertHeadersSLO(resp, 'PUT')
@test.idempotent_id('e69ad766-e1aa-44a2-bdd2-bf62c09c1456')
+ @test.requires_ext(extension='slo', service='object')
def test_list_large_object_metadata(self):
# list static large object metadata using multipart manifest
object_name = self._create_large_object()
@@ -135,6 +137,7 @@
self._assertHeadersSLO(resp, 'HEAD')
@test.idempotent_id('49bc49bc-dd1b-4c0f-904e-d9f10b830ee8')
+ @test.requires_ext(extension='slo', service='object')
def test_retrieve_large_object(self):
# list static large object using multipart manifest
object_name = self._create_large_object()
@@ -149,6 +152,7 @@
self.assertEqual(body, sum_data)
@test.idempotent_id('87b6dfa1-abe9-404d-8bf0-6c3751e6aa77')
+ @test.requires_ext(extension='slo', service='object')
def test_delete_large_object(self):
# delete static large object using multipart manifest
object_name = self._create_large_object()
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 6e67c4b..fba839a 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations
# under the License.
import functools
-import netaddr
from oslo_log import log as logging
import six
@@ -28,12 +27,13 @@
class TestGettingAddress(manager.NetworkScenarioTest):
- """Create network with 2 subnets: IPv4 and IPv6 in a given address mode
+ """Create network with subnets: one IPv4 and
+ one or few IPv6 in a given address mode
Boot 2 VMs on this network
Allocate and assign 2 FIP4
- Check that vNIC of server matches port data from OpenStack DB
- Ping4 tenant IPv4 of one VM from another one
- Will do the same with ping6 when available in VM
+ Check that vNICs of all VMs gets all addresses actually assigned
+ Ping4 to one VM from another one
+ If ping6 available in VM, do ping6 to all v6 addresses
"""
@classmethod
@@ -65,41 +65,41 @@
'key_name': self.keypair['name'],
'security_groups': [{'name': self.sec_grp['name']}]}
- def prepare_network(self, address6_mode):
+ def prepare_network(self, address6_mode, n_subnets6=1):
"""Creates network with
- one IPv6 subnet in the given mode and
+ given number of IPv6 subnets in the given mode and
one IPv4 subnet
- Creates router with ports on both subnets
+ Creates router with ports on all subnets
"""
self.network = self._create_network(tenant_id=self.tenant_id)
sub4 = self._create_subnet(network=self.network,
namestart='sub4',
ip_version=4,)
- # since https://bugs.launchpad.net/neutron/+bug/1394112 we need
- # to specify gateway_ip manually
- net_range = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
- gateway_ip = (netaddr.IPAddress(net_range) + 1).format()
- sub6 = self._create_subnet(network=self.network,
- namestart='sub6',
- ip_version=6,
- gateway_ip=gateway_ip,
- ipv6_ra_mode=address6_mode,
- ipv6_address_mode=address6_mode)
router = self._get_router(tenant_id=self.tenant_id)
sub4.add_to_router(router_id=router['id'])
- sub6.add_to_router(router_id=router['id'])
self.addCleanup(sub4.delete)
- self.addCleanup(sub6.delete)
+
+ for _ in range(n_subnets6):
+ sub6 = self._create_subnet(network=self.network,
+ namestart='sub6',
+ ip_version=6,
+ ipv6_ra_mode=address6_mode,
+ ipv6_address_mode=address6_mode)
+
+ sub6.add_to_router(router_id=router['id'])
+ self.addCleanup(sub6.delete)
@staticmethod
def define_server_ips(srv):
+ ips = {'4': None, '6': []}
for net_name, nics in six.iteritems(srv['addresses']):
for nic in nics:
if nic['version'] == 6:
- srv['accessIPv6'] = nic['addr']
+ ips['6'].append(nic['addr'])
else:
- srv['accessIPv4'] = nic['addr']
+ ips['4'] = nic['addr']
+ return ips
def prepare_server(self):
username = CONF.compute.image_ssh_user
@@ -109,53 +109,56 @@
srv = self.create_server(create_kwargs=create_kwargs)
fip = self.create_floating_ip(thing=srv)
- self.define_server_ips(srv=srv)
+ ips = self.define_server_ips(srv=srv)
ssh = self.get_remote_client(
server_or_ip=fip.floating_ip_address,
username=username)
- return ssh, srv
+ return ssh, ips
- def _prepare_and_test(self, address6_mode):
- self.prepare_network(address6_mode=address6_mode)
+ def _prepare_and_test(self, address6_mode, n_subnets6=1):
+ self.prepare_network(address6_mode=address6_mode,
+ n_subnets6=n_subnets6)
- ssh1, srv1 = self.prepare_server()
- ssh2, srv2 = self.prepare_server()
+ sshv4_1, ips_from_api_1 = self.prepare_server()
+ sshv4_2, ips_from_api_2 = self.prepare_server()
def guest_has_address(ssh, addr):
return addr in ssh.get_ip_list()
- srv1_v6_addr_assigned = functools.partial(
- guest_has_address, ssh1, srv1['accessIPv6'])
- srv2_v6_addr_assigned = functools.partial(
- guest_has_address, ssh2, srv2['accessIPv6'])
+ # get addresses assigned to vNIC as reported by 'ip address' utility
+ ips_from_ip_1 = sshv4_1.get_ip_list()
+ ips_from_ip_2 = sshv4_2.get_ip_list()
+ self.assertIn(ips_from_api_1['4'], ips_from_ip_1)
+ self.assertIn(ips_from_api_2['4'], ips_from_ip_2)
+ for i in range(n_subnets6):
+ # v6 should be configured since the image supports it
+ # It can take time for ipv6 automatic address to get assigned
+ srv1_v6_addr_assigned = functools.partial(
+ guest_has_address, sshv4_1, ips_from_api_1['6'][i])
- result = ssh1.get_ip_list()
- self.assertIn(srv1['accessIPv4'], result)
- # v6 should be configured since the image supports it
- # It can take time for ipv6 automatic address to get assigned
- self.assertTrue(
- test.call_until_true(srv1_v6_addr_assigned,
- CONF.compute.ping_timeout, 1))
- result = ssh2.get_ip_list()
- self.assertIn(srv2['accessIPv4'], result)
- # v6 should be configured since the image supports it
- # It can take time for ipv6 automatic address to get assigned
- self.assertTrue(
- test.call_until_true(srv2_v6_addr_assigned,
- CONF.compute.ping_timeout, 1))
- result = ssh1.ping_host(srv2['accessIPv4'])
+ srv2_v6_addr_assigned = functools.partial(
+ guest_has_address, sshv4_2, ips_from_api_2['6'][i])
+
+ self.assertTrue(test.call_until_true(srv1_v6_addr_assigned,
+ CONF.compute.ping_timeout, 1))
+
+ self.assertTrue(test.call_until_true(srv2_v6_addr_assigned,
+ CONF.compute.ping_timeout, 1))
+
+ result = sshv4_1.ping_host(ips_from_api_2['4'])
self.assertIn('0% packet loss', result)
- result = ssh2.ping_host(srv1['accessIPv4'])
+ result = sshv4_2.ping_host(ips_from_api_1['4'])
self.assertIn('0% packet loss', result)
# Some VM (like cirros) may not have ping6 utility
- result = ssh1.exec_command('whereis ping6')
+ result = sshv4_1.exec_command('whereis ping6')
is_ping6 = False if result == 'ping6:\n' else True
if is_ping6:
- result = ssh1.ping_host(srv2['accessIPv6'])
- self.assertIn('0% packet loss', result)
- result = ssh2.ping_host(srv1['accessIPv6'])
- self.assertIn('0% packet loss', result)
+ for i in range(n_subnets6):
+ result = sshv4_1.ping_host(ips_from_api_2['6'][i])
+ self.assertIn('0% packet loss', result)
+ result = sshv4_2.ping_host(ips_from_api_1['6'][i])
+ self.assertIn('0% packet loss', result)
else:
LOG.warning('Ping6 is not available, skipping')
@@ -168,3 +171,13 @@
@test.services('compute', 'network')
def test_dhcp6_stateless_from_os(self):
self._prepare_and_test(address6_mode='dhcpv6-stateless')
+
+ @test.idempotent_id('7ab23f41-833b-4a16-a7c9-5b42fe6d4123')
+ @test.services('compute', 'network')
+ def test_multi_prefix_dhcpv6_stateless(self):
+ self._prepare_and_test(address6_mode='dhcpv6-stateless', n_subnets6=2)
+
+ @test.idempotent_id('dec222b1-180c-4098-b8c5-cc1b8342d611')
+ @test.services('compute', 'network')
+ def test_multi_prefix_slaac(self):
+ self._prepare_and_test(address6_mode='slaac', n_subnets6=2)
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 7c58f01..add26a9 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -201,20 +201,12 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def list_images(self, **kwargs):
+ def list_images(self, detail=False, properties=dict(),
+ changes_since=None, **kwargs):
url = 'v1/images'
- if len(kwargs) > 0:
- url += '?%s' % urllib.urlencode(kwargs)
-
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return service_client.ResponseBodyList(resp, body['images'])
-
- def image_list_detail(self, properties=dict(), changes_since=None,
- **kwargs):
- url = 'v1/images/detail'
+ if detail:
+ url += '/detail'
params = {}
for key, value in properties.items():
@@ -265,8 +257,9 @@
body = json.loads(body)
return service_client.ResponseBody(resp, body)
- def get_shared_images(self, member_id):
- url = 'v1/shared-images/%s' % member_id
+ def list_shared_images(self, tenant_id):
+ """List shared images with the specified tenant"""
+ url = 'v1/shared-images/%s' % tenant_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)