Merge "More Javelin Unit tests"
diff --git a/.testr.conf b/.testr.conf
index 4f6e0b3..95a4fb4 100644
--- a/.testr.conf
+++ b/.testr.conf
@@ -3,7 +3,7 @@
OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \
OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \
OS_TEST_LOCK_PATH=${OS_TEST_LOCK_PATH:-${TMPDIR:-'/tmp'}} \
- ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./tempest/test_discover} $LISTOPT $IDOPTION
+ ${PYTHON:-python} -m subunit.run discover -t ${OS_TOP_LEVEL:-./} ${OS_TEST_PATH:-./tempest/test_discover} $LISTOPT $IDOPTION
test_id_option=--load-list $IDFILE
test_list_option=--list
group_regex=([^\.]*\.)*
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index b434fdc..eab7487 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -310,6 +310,12 @@
will additionally be used as a fallback for server creation. However, unlike
accounts.yaml this should never be triggered.
+However, there is an option *create_isolated_networks* to disable tenant
+isolation's automatic provisioning of network resources. If this option is
+used you will have to either rely on there only being a single/default network
+available for the server creation, or use *fixed_network_name* to inform
+Tempest which network to use.
+
Configuring Available Services
------------------------------
OpenStack is really a constellation of several different projects which
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 5b15c5e..b3aca42 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -40,13 +40,15 @@
#log_dir = <None>
# Use syslog for logging. Existing syslog format is DEPRECATED during
-# I, and will change in J to honor RFC5424. (boolean value)
+# I, and changed in J to honor RFC5424. (boolean value)
#use_syslog = false
# (Optional) Enables or disables syslog rfc5424 format for logging. If
# enabled, prefixes the MSG part of the syslog message with APP-NAME
# (RFC5424). The format without the APP-NAME is deprecated in K, and
-# will be removed in L, along with this option. (boolean value)
+# will be removed in M, along with this option. (boolean value)
+# This option is deprecated for removal.
+# Its value may be silently ignored in the future.
#use_syslog_rfc_format = true
# Syslog facility to receive log lines. (string value)
@@ -67,7 +69,7 @@
# Prefix each line of exception output with this format. (string
# value)
-#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s
+#logging_exception_prefix = %(asctime)s.%(msecs)03d %(process)d ERROR %(name)s %(instance)s
# List of logger=LEVEL pairs. (list value)
#default_log_levels = amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,requests.packages.urllib3.util.retry=WARN,urllib3.util.retry=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN
@@ -86,6 +88,9 @@
# (string value)
#instance_uuid_format = "[instance: %(uuid)s] "
+# Enables or disables fatal status of deprecations. (boolean value)
+#fatal_deprecations = false
+
[auth]
@@ -117,6 +122,14 @@
# the domain from theadmin user is used instead. (string value)
#tenant_isolation_domain_name = <None>
+# If allow_tenant_isolation is set to True and Neutron is enabled
+# Tempest will try to create a useable network, subnet, and router
+# when needed for each tenant it creates. However in some neutron
+# configurations, like with VLAN provider networks, this doesn't work.
+# So if set to False the isolated networks will not be created
+# (boolean value)
+#create_isolated_networks = true
+
[baremetal]
@@ -571,6 +584,9 @@
# applies to user and project (string value)
#admin_domain_name = <None>
+# ID of the default domain (string value)
+#default_domain_id = default
+
[identity-feature-enabled]
@@ -935,6 +951,10 @@
# Image container format (string value)
#img_container_format = bare
+# Glance image properties. Use for custom images which require them
+# (dict value)
+#img_properties = <None>
+
# AMI image file name (string value)
#ami_img_file = cirros-0.3.1-x86_64-blank.img
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index c4581e5..9aacfa5 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -303,7 +303,7 @@
if 'wait_until' in kwargs:
cls.images_client.wait_for_image_status(image_id,
kwargs['wait_until'])
- image = cls.images_client.get_image(image_id)
+ image = cls.images_client.show_image(image_id)
if kwargs['wait_until'] == 'ACTIVE':
if kwargs.get('wait_for_server', True):
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index a92048f..3771a43 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -84,11 +84,11 @@
self.client.wait_for_image_status(image_id, 'ACTIVE')
# Verify the image was created correctly
- image = self.client.get_image(image_id)
+ image = self.client.show_image(image_id)
self.assertEqual(name, image['name'])
self.assertEqual('test', image['metadata']['image_type'])
- original_image = self.client.get_image(self.image_ref)
+ original_image = self.client.show_image(self.image_ref)
# Verify minRAM is the same as the original image
self.assertEqual(image['minRam'], original_image['minRam'])
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index aa12044..8a39d90 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -140,4 +140,4 @@
self.client.delete_image(image_id)
self.image_ids.remove(image_id)
- self.assertRaises(lib_exc.NotFound, self.client.get_image, image_id)
+ self.assertRaises(lib_exc.NotFound, 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 abe7be5..e2d4bd9 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -62,7 +62,7 @@
image_file = six.StringIO(('*' * 1024))
cls.glance_client.update_image(image_id, data=image_file)
cls.client.wait_for_image_status(image_id, 'ACTIVE')
- body = cls.client.get_image(image_id)
+ body = cls.client.show_image(image_id)
return body
# Create non-snapshot images via glance
@@ -249,7 +249,7 @@
# The detailed list of servers should be filtered by image type
params = {'type': 'snapshot'}
images = self.client.list_images_with_detail(params)
- self.client.get_image(self.image_ref)
+ self.client.show_image(self.image_ref)
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot1_id]))
diff --git a/tempest/api/compute/images/test_list_image_filters_negative.py b/tempest/api/compute/images/test_list_image_filters_negative.py
index 334516b..4110619 100644
--- a/tempest/api/compute/images/test_list_image_filters_negative.py
+++ b/tempest/api/compute/images/test_list_image_filters_negative.py
@@ -41,5 +41,5 @@
def test_get_nonexistent_image(self):
# Check raises a NotFound
nonexistent_image = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound, self.client.get_image,
+ self.assertRaises(lib_exc.NotFound, self.client.show_image,
nonexistent_image)
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index 95f49c9..5b80c72 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -37,7 +37,7 @@
@test.idempotent_id('490d0898-e12a-463f-aef0-c50156b9f789')
def test_get_image(self):
# Returns the correct details for a single image
- image = self.client.get_image(self.image_ref)
+ image = self.client.show_image(self.image_ref)
self.assertEqual(self.image_ref, image['id'])
@test.idempotent_id('fd51b7f4-d4a3-4331-9885-866658112a6f')
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 5374af0..d7607ab 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -56,13 +56,13 @@
# Do some sanity checks here. If one of the images does
# not exist, fail early since the tests won't work...
try:
- cls.images_client.get_image(cls.image_ref)
+ cls.images_client.show_image(cls.image_ref)
except lib_exc.NotFound:
raise RuntimeError("Image %s (image_ref) was not found!" %
cls.image_ref)
try:
- cls.images_client.get_image(cls.image_ref_alt)
+ cls.images_client.show_image(cls.image_ref_alt)
except lib_exc.NotFound:
raise RuntimeError("Image %s (image_ref_alt) was not found!" %
cls.image_ref_alt)
@@ -275,8 +275,14 @@
msg = 'fixed_network_name needs to be configured to run this test'
raise self.skipException(msg)
self.s1 = self.client.get_server(self.s1['id'])
- ip = self.s1['addresses'][self.fixed_network_name][0]['addr']
- params = {'ip': ip}
+ for addr_spec in self.s1['addresses'][self.fixed_network_name]:
+ ip = addr_spec['addr']
+ if addr_spec['version'] == 4:
+ params = {'ip': ip}
+ break
+ else:
+ msg = "Skipped until bug 1450859 is resolved"
+ raise self.skipException(msg)
body = self.client.list_servers(params)
servers = body['servers']
@@ -295,8 +301,12 @@
msg = 'fixed_network_name needs to be configured to run this test'
raise self.skipException(msg)
self.s1 = self.client.get_server(self.s1['id'])
- ip = self.s1['addresses'][self.fixed_network_name][0]['addr'][0:-3]
- params = {'ip': ip}
+ addr_spec = self.s1['addresses'][self.fixed_network_name][0]
+ ip = addr_spec['addr'][0:-3]
+ if addr_spec['version'] == 4:
+ params = {'ip': ip}
+ else:
+ params = {'ip6': ip}
body = self.client.list_servers(params)
servers = body['servers']
diff --git a/tempest/api/compute/servers/test_multiple_create.py b/tempest/api/compute/servers/test_multiple_create.py
index eed3be8..11b457b 100644
--- a/tempest/api/compute/servers/test_multiple_create.py
+++ b/tempest/api/compute/servers/test_multiple_create.py
@@ -30,7 +30,9 @@
This is the right way to create_multiple servers and manage to get the
created servers into the servers list to be cleaned up after all.
"""
- kwargs['name'] = kwargs.get('name', self._generate_name())
+ kwargs['name'] = name if name else self._generate_name()
+ if wait_until:
+ kwargs['wait_until'] = wait_until
body = self.create_test_server(**kwargs)
return body
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index c4cabaa..c2ed0ce 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -47,8 +47,6 @@
self.__class__.server_id = self.rebuild_server(self.server_id)
def tearDown(self):
- server = self.client.get_server(self.server_id)
- self.assertEqual(self.image_ref, server['image']['id'])
self.server_check_teardown()
super(ServerActionsTestJSON, self).tearDown()
@@ -110,6 +108,14 @@
# The server should be signaled to reboot gracefully
self._test_reboot_server('SOFT')
+ def _rebuild_server_and_check(self, image_ref):
+ rebuilt_server = self.client.rebuild(self.server_id, image_ref)
+ self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+ msg = ('Server was not rebuilt to the original image. '
+ 'The original image: {0}. The current image: {1}'
+ .format(image_ref, rebuilt_server['image']['id']))
+ self.assertEqual(image_ref, rebuilt_server['image']['id'], msg)
+
@test.idempotent_id('aaa6cdf3-55a7-461a-add9-1c8596b9a07c')
def test_rebuild_server(self):
# The server should be rebuilt using the provided image and data
@@ -129,8 +135,7 @@
# If the server was rebuilt on a different image, restore it to the
# original image once the test ends
if self.image_ref_alt != self.image_ref:
- self.addCleanup(self.client.rebuild,
- (self.server_id, self.image_ref))
+ self.addCleanup(self._rebuild_server_and_check, self.image_ref)
# Verify the properties in the initial response are correct
self.assertEqual(self.server_id, rebuilt_server['id'])
@@ -157,11 +162,15 @@
# image and remain in SHUTOFF state
server = self.client.get_server(self.server_id)
old_image = server['image']['id']
- new_image = self.image_ref_alt \
- if old_image == self.image_ref else self.image_ref
+ new_image = (self.image_ref_alt
+ if old_image == self.image_ref else self.image_ref)
self.client.stop(self.server_id)
self.client.wait_for_server_status(self.server_id, 'SHUTOFF')
rebuilt_server = self.client.rebuild(self.server_id, new_image)
+ # If the server was rebuilt on a different image, restore it to the
+ # original image once the test ends
+ if self.image_ref_alt != self.image_ref:
+ self.addCleanup(self._rebuild_server_and_check, old_image)
# Verify the properties in the initial response are correct
self.assertEqual(self.server_id, rebuilt_server['id'])
@@ -175,10 +184,6 @@
rebuilt_image_id = server['image']['id']
self.assertEqual(new_image, rebuilt_image_id)
- # Restore to the original image (The tearDown will test it again)
- if self.image_ref_alt != self.image_ref:
- self.client.rebuild(self.server_id, old_image)
- self.client.wait_for_server_status(self.server_id, 'SHUTOFF')
self.client.start(self.server_id)
def _test_resize_server_confirm(self, stop=False):
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 9f007bf..63b78a0 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -73,7 +73,7 @@
image_file = six.StringIO(('*' * 1024))
body = cls.glance_client.update_image(image_id, data=image_file)
cls.glance_client.wait_for_image_status(image_id, 'active')
- cls.image = cls.images_client.get_image(image_id)
+ cls.image = cls.images_client.show_image(image_id)
cls.keypairname = data_utils.rand_name('keypair')
cls.keypairs_client.create_keypair(cls.keypairname)
@@ -233,7 +233,7 @@
def test_get_image_for_alt_account_fails(self):
# A GET request for an image on another user's account should fail
self.assertRaises(lib_exc.NotFound,
- self.alt_images_client.get_image, self.image['id'])
+ self.alt_images_client.show_image, self.image['id'])
@test.idempotent_id('9facb962-f043-4a9d-b9ee-166a32dea098')
def test_delete_image_for_alt_account_fails(self):
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 79943bb..b775e91 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -13,10 +13,13 @@
# License for the specific language governing permissions and limitations
# under the License.
+from tempest.api.identity import base
+from tempest import config
+from tempest import test
+
from tempest_lib.common.utils import data_utils
-from tempest.api.identity import base
-from tempest import test
+CONF = config.CONF
class DomainsTestJSON(base.BaseIdentityV3AdminTest):
@@ -105,3 +108,18 @@
expected_data = {'name': d_name, 'enabled': True}
self.assertIsNone(domain['description'])
self.assertDictContainsSubset(expected_data, domain)
+
+
+class DefaultDomainTestJSON(base.BaseIdentityV3AdminTest):
+
+ @classmethod
+ def resource_setup(cls):
+ cls.domain_id = CONF.identity.default_domain_id
+ super(DefaultDomainTestJSON, cls).resource_setup()
+
+ @test.attr(type='smoke')
+ @test.idempotent_id('17a5de24-e6a0-4e4a-a9ee-d85b6e5612b5')
+ def test_default_domain_exists(self):
+ domain = self.client.get_domain(self.domain_id)
+
+ self.assertTrue(domain['enabled'])
diff --git a/tempest/api/identity/admin/v3/test_domains_negative.py b/tempest/api/identity/admin/v3/test_domains_negative.py
new file mode 100644
index 0000000..e2f3ef5
--- /dev/null
+++ b/tempest/api/identity/admin/v3/test_domains_negative.py
@@ -0,0 +1,38 @@
+# Copyright 2015 Red Hat Inc.
+# All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+from tempest.api.identity import base
+from tempest import test
+
+from tempest_lib.common.utils import data_utils
+from tempest_lib import exceptions as lib_exc
+
+
+class DomainsNegativeTestJSON(base.BaseIdentityV3AdminTest):
+ _interface = 'json'
+
+ @test.attr(type=['negative', 'gate'])
+ @test.idempotent_id('1f3fbff5-4e44-400d-9ca1-d953f05f609b')
+ def test_delete_active_domain(self):
+ d_name = data_utils.rand_name('domain')
+ d_desc = data_utils.rand_name('domain-desc')
+ domain = self.client.create_domain(d_name, description=d_desc)
+ domain_id = domain['id']
+
+ self.addCleanup(self.delete_domain, domain_id)
+
+ # domain need to be disabled before deleting
+ self.assertRaises(lib_exc.Forbidden, self.client.delete_domain,
+ domain_id)
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 878ff6d..913e807 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -172,6 +172,12 @@
if len(role) > 0:
return role[0]
+ def delete_domain(self, domain_id):
+ # NOTE(mpavlase) It is necessary to disable the domain before deleting
+ # otherwise it raises Forbidden exception
+ self.client.update_domain(domain_id, enabled=False)
+ self.client.delete_domain(domain_id)
+
class DataGenerator(object):
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index acf8272..00959d9 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -146,7 +146,7 @@
cls.alt_tenant_id = cls.alt_img_client.tenant_id
def _list_image_ids_as_alt(self):
- image_list = self.alt_img_client.image_list()
+ image_list = self.alt_img_client.list_images()
image_ids = map(lambda x: x['id'], image_list)
return image_ids
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index d57cb93..4969858 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -23,12 +23,12 @@
def test_add_image_member(self):
image = self._create_image()
self.client.add_member(self.alt_tenant_id, image)
- body = self.client.get_image_membership(image)
+ body = self.client.list_image_members(image)
members = body['members']
members = map(lambda x: x['member_id'], members)
self.assertIn(self.alt_tenant_id, members)
# get image as alt user
- self.alt_img_cli.get_image(image)
+ self.alt_img_cli.show_image(image)
@test.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
def test_get_shared_images(self):
@@ -47,6 +47,6 @@
image_id = self._create_image()
self.client.add_member(self.alt_tenant_id, image_id)
self.client.delete_member(self.alt_tenant_id, image_id)
- body = self.client.get_image_membership(image_id)
+ body = self.client.list_image_members(image_id)
members = body['members']
self.assertEqual(0, len(members), str(members))
diff --git a/tempest/api/image/v1/test_image_members_negative.py b/tempest/api/image/v1/test_image_members_negative.py
index b96cf71..df0e88a 100644
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ b/tempest/api/image/v1/test_image_members_negative.py
@@ -52,5 +52,5 @@
# Image is hidden from another tenants.
image_id = self._create_image()
self.assertRaises(lib_exc.NotFound,
- self.alt_img_cli.get_image,
+ self.alt_img_cli.show_image,
image_id)
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index ea95059..6c25c93 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -77,7 +77,7 @@
self.assertEqual('New Http Image', body.get('name'))
self.assertFalse(body.get('is_public'))
self.client.wait_for_image_status(image_id, 'active')
- self.client.get_image(image_id)
+ self.client.show_image(image_id)
@test.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
def test_register_image_with_min_ram(self):
@@ -168,14 +168,14 @@
@test.idempotent_id('246178ab-3b33-4212-9a4b-a7fe8261794d')
def test_index_no_params(self):
# Simple test to see all fixture images returned
- images_list = self.client.image_list()
+ images_list = self.client.list_images()
image_list = map(lambda x: x['id'], images_list)
for image_id in self.created_images:
self.assertIn(image_id, image_list)
@test.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
def test_index_disk_format(self):
- images_list = self.client.image_list(disk_format='ami')
+ images_list = self.client.list_images(disk_format='ami')
for image in images_list:
self.assertEqual(image['disk_format'], 'ami')
result_set = set(map(lambda x: x['id'], images_list))
@@ -184,7 +184,7 @@
@test.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
def test_index_container_format(self):
- images_list = self.client.image_list(container_format='bare')
+ images_list = self.client.list_images(container_format='bare')
for image in images_list:
self.assertEqual(image['container_format'], 'bare')
result_set = set(map(lambda x: x['id'], images_list))
@@ -193,7 +193,7 @@
@test.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
def test_index_max_size(self):
- images_list = self.client.image_list(size_max=42)
+ images_list = self.client.list_images(size_max=42)
for image in images_list:
self.assertTrue(image['size'] <= 42)
result_set = set(map(lambda x: x['id'], images_list))
@@ -202,7 +202,7 @@
@test.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
def test_index_min_size(self):
- images_list = self.client.image_list(size_min=142)
+ images_list = self.client.list_images(size_min=142)
for image in images_list:
self.assertTrue(image['size'] >= 142)
result_set = set(map(lambda x: x['id'], images_list))
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 32f80a2..8cccddd 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -59,7 +59,7 @@
self.client.store_image(image_id, image_file)
# Now try to get image details
- body = self.client.get_image(image_id)
+ body = self.client.show_image(image_id)
self.assertEqual(image_id, body['id'])
self.assertEqual(image_name, body['name'])
self.assertEqual(uuid, body['ramdisk_id'])
@@ -88,7 +88,7 @@
self.client.wait_for_resource_deletion(image_id)
# Verifying deletion
- images = self.client.image_list()
+ images = self.client.list_images()
images_id = [item['id'] for item in images]
self.assertNotIn(image_id, images_id)
@@ -118,7 +118,7 @@
# Verifying updating
- body = self.client.get_image(image_id)
+ body = self.client.show_image(image_id)
self.assertEqual(image_id, body['id'])
self.assertEqual(new_image_name, body['name'])
@@ -164,7 +164,7 @@
"""
Perform list action with given params and validates result.
"""
- images_list = self.client.image_list(params=params)
+ images_list = self.client.list_images(params=params)
# Validating params of fetched images
for image in images_list:
for key in params:
@@ -174,7 +174,7 @@
@test.idempotent_id('1e341d7a-90a9-494c-b143-2cdf2aeb6aee')
def test_index_no_params(self):
# Simple test to see all fixture images returned
- images_list = self.client.image_list()
+ images_list = self.client.list_images()
image_list = map(lambda x: x['id'], images_list)
for image in self.created_images:
@@ -203,7 +203,7 @@
# Test to get all images by size
image_id = self.created_images[1]
# Get image metadata
- image = self.client.get_image(image_id)
+ image = self.client.show_image(image_id)
params = {"size": image['size']}
self._list_by_param_value_and_assert(params)
@@ -213,11 +213,11 @@
# Test to get all images with size between 2000 to 3000
image_id = self.created_images[1]
# Get image metadata
- image = self.client.get_image(image_id)
+ image = self.client.show_image(image_id)
size = image['size']
params = {"size_min": size - 500, "size_max": size + 500}
- images_list = self.client.image_list(params=params)
+ images_list = self.client.list_images(params=params)
image_size_list = map(lambda x: x['size'], images_list)
for image_size in image_size_list:
@@ -235,7 +235,7 @@
def test_list_images_param_limit(self):
# Test to get images by limit
params = {"limit": 2}
- images_list = self.client.image_list(params=params)
+ images_list = self.client.list_images(params=params)
self.assertEqual(len(images_list), params['limit'],
"Failed to get images by limit")
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index 26d4197..07c2073 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -29,7 +29,7 @@
self.alt_tenant_id,
'accepted')
self.assertIn(image_id, self._list_image_ids_as_alt())
- body = self.os_img_client.get_image_membership(image_id)
+ body = self.os_img_client.list_image_members(image_id)
members = body['members']
member = members[0]
self.assertEqual(len(members), 1, str(members))
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index 60a10a2..c5c5e8b 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -25,7 +25,7 @@
class ImagesNegativeTest(base.BaseV2ImageTest):
"""
- here we have -ve tests for get_image and delete_image api
+ here we have -ve tests for show_image and delete_image api
Tests
** get non-existent image
@@ -41,7 +41,7 @@
def test_get_non_existent_image(self):
# get the non-existent image
non_existent_id = str(uuid.uuid4())
- self.assertRaises(lib_exc.NotFound, self.client.get_image,
+ self.assertRaises(lib_exc.NotFound, self.client.show_image,
non_existent_id)
@test.attr(type=['negative'])
@@ -49,7 +49,7 @@
def test_get_image_null_id(self):
# get image with image_id = NULL
image_id = ""
- self.assertRaises(lib_exc.NotFound, self.client.get_image, image_id)
+ self.assertRaises(lib_exc.NotFound, self.client.show_image, image_id)
@test.attr(type=['negative'])
@test.idempotent_id('e57fc127-7ba0-4693-92d7-1d8a05ebcba9')
@@ -64,7 +64,7 @@
self.client.wait_for_resource_deletion(image_id)
# get the deleted image
- self.assertRaises(lib_exc.NotFound, self.client.get_image, image_id)
+ self.assertRaises(lib_exc.NotFound, self.client.show_image, image_id)
# delete the deleted image
self.assertRaises(lib_exc.NotFound, self.client.delete_image,
diff --git a/tempest/api/image/v2/test_images_tags.py b/tempest/api/image/v2/test_images_tags.py
index 24688dc..e38136e 100644
--- a/tempest/api/image/v2/test_images_tags.py
+++ b/tempest/api/image/v2/test_images_tags.py
@@ -31,10 +31,10 @@
# Creating image tag and verify it.
self.client.add_image_tag(image_id, tag)
- body = self.client.get_image(image_id)
+ body = self.client.show_image(image_id)
self.assertIn(tag, body['tags'])
# Deleting image tag and verify it.
self.client.delete_image_tag(image_id, tag)
- body = self.client.get_image(image_id)
+ body = self.client.show_image(image_id)
self.assertNotIn(tag, body['tags'])
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 1cd1386..f864f95 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -123,10 +123,6 @@
for floating_ip in cls.floating_ips:
cls._try_delete_resource(cls.client.delete_floatingip,
floating_ip['id'])
- # Clean up routers
- for router in cls.routers:
- cls._try_delete_resource(cls.delete_router,
- router)
# Clean up health monitors
for health_monitor in cls.health_monitors:
@@ -158,6 +154,10 @@
for port in cls.ports:
cls._try_delete_resource(cls.client.delete_port,
port['id'])
+ # Clean up routers
+ for router in cls.routers:
+ cls._try_delete_resource(cls.delete_router,
+ router)
# Clean up subnets
for subnet in cls.subnets:
cls._try_delete_resource(cls.client.delete_subnet,
diff --git a/tempest/api/network/test_fwaas_extensions.py b/tempest/api/network/test_fwaas_extensions.py
index 0622e87..651b4ab 100644
--- a/tempest/api/network/test_fwaas_extensions.py
+++ b/tempest/api/network/test_fwaas_extensions.py
@@ -99,8 +99,13 @@
if not test.call_until_true(_wait, CONF.network.build_timeout,
CONF.network.build_interval):
- m = ("Timed out waiting for firewall %s to reach %s state(s)" %
- (fw_id, target_states))
+ status = self.client.show_firewall(fw_id)['firewall']['status']
+ m = ("Timed out waiting for firewall %s to reach %s state(s) "
+ "after %ss, currently in %s state." %
+ (fw_id,
+ target_states,
+ CONF.network.build_interval,
+ status))
raise exceptions.TimeoutException(m)
@test.idempotent_id('1b84cf01-9c09-4ce7-bc72-b15e39076468')
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 5e3e374..7a96f34 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -393,7 +393,9 @@
" in filtered list (%s)." % nonexternal)
self.assertIn(CONF.network.public_network_id, networks)
- subnets_iter = (network['subnets'] for network in body['networks'])
+ subnets_iter = (network['subnets']
+ for network in body['networks']
+ if not network['shared'])
# subnets_iter is a list (iterator) of lists. This flattens it to a
# list of UUIDs
public_subnets_iter = itertools.chain(*subnets_iter)
diff --git a/tempest/api/volume/test_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index b8e87f0..641317a 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+from testtools import matchers
+
from tempest.api.volume import base
from tempest import test
@@ -50,12 +52,14 @@
metadata)
# Get the metadata of the snapshot
body = self.client.show_snapshot_metadata(self.snapshot_id)
- self.assertEqual(metadata, body)
+ self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
+
# Delete one item metadata of the snapshot
self.client.delete_snapshot_metadata_item(
self.snapshot_id, "key1")
body = self.client.show_snapshot_metadata(self.snapshot_id)
- self.assertEqual(expected, body)
+ self.assertThat(body.items(), matchers.ContainsAll(expected.items()))
+ self.assertNotIn("key1", body)
@test.idempotent_id('bd2363bc-de92-48a4-bc98-28943c6e4be1')
def test_update_snapshot_metadata(self):
@@ -70,7 +74,8 @@
metadata)
# Get the metadata of the snapshot
body = self.client.show_snapshot_metadata(self.snapshot_id)
- self.assertEqual(metadata, body)
+ self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
+
# Update metadata item
body = self.client.update_snapshot_metadata(
self.snapshot_id, update)
@@ -93,13 +98,13 @@
metadata)
# Get the metadata of the snapshot
body = self.client.show_snapshot_metadata(self.snapshot_id)
- self.assertEqual(metadata, body)
+ self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
# Update metadata item
body = self.client.update_snapshot_metadata_item(
self.snapshot_id, "key3", update_item)
# Get the metadata of the snapshot
body = self.client.show_snapshot_metadata(self.snapshot_id)
- self.assertEqual(expect, body)
+ self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
class SnapshotV1MetadataTestJSON(SnapshotV2MetadataTestJSON):
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index e89ff9a..8529cfc 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -75,7 +75,7 @@
self.volume_id, update)
# Get the metadata of the volume
body = self.volumes_client.show_volume_metadata(self.volume_id)
- self.assertThat(body.items(), matchers.ContainsAll(update.items()))
+ self.assertEqual(update, body)
@test.idempotent_id('862261c5-8df4-475a-8c21-946e50e36a20')
def test_update_volume_metadata_item(self):
diff --git a/tempest/api_schema/response/compute/baremetal_nodes.py b/tempest/api_schema/response/compute/v2_1/baremetal_nodes.py
similarity index 100%
rename from tempest/api_schema/response/compute/baremetal_nodes.py
rename to tempest/api_schema/response/compute/v2_1/baremetal_nodes.py
diff --git a/tempest/api_schema/response/compute/v2_1/flavors.py b/tempest/api_schema/response/compute/v2_1/flavors.py
index 725d17a..26760ac 100644
--- a/tempest/api_schema/response/compute/v2_1/flavors.py
+++ b/tempest/api_schema/response/compute/v2_1/flavors.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api_schema.response.compute import parameter_types
+from tempest.api_schema.response.compute.v2_1 import parameter_types
list_flavors = {
'status_code': [200],
diff --git a/tempest/api_schema/response/compute/flavors_access.py b/tempest/api_schema/response/compute/v2_1/flavors_access.py
similarity index 100%
rename from tempest/api_schema/response/compute/flavors_access.py
rename to tempest/api_schema/response/compute/v2_1/flavors_access.py
diff --git a/tempest/api_schema/response/compute/flavors_extra_specs.py b/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
similarity index 94%
rename from tempest/api_schema/response/compute/flavors_extra_specs.py
rename to tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
index 4003d36..faa25d0 100644
--- a/tempest/api_schema/response/compute/flavors_extra_specs.py
+++ b/tempest/api_schema/response/compute/v2_1/flavors_extra_specs.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-flavor_extra_specs = {
+set_get_flavor_extra_specs = {
'status_code': [200],
'response_body': {
'type': 'object',
@@ -28,7 +28,7 @@
}
}
-flavor_extra_specs_key = {
+set_get_flavor_extra_specs_key = {
'status_code': [200],
'response_body': {
'type': 'object',
diff --git a/tempest/api_schema/response/compute/v2_1/floating_ips.py b/tempest/api_schema/response/compute/v2_1/floating_ips.py
index 7369bec..ad1c531 100644
--- a/tempest/api_schema/response/compute/v2_1/floating_ips.py
+++ b/tempest/api_schema/response/compute/v2_1/floating_ips.py
@@ -48,7 +48,7 @@
}
}
-floating_ip = {
+create_get_floating_ip = {
'status_code': [200],
'response_body': {
'type': 'object',
@@ -59,7 +59,7 @@
}
}
-floating_ip_pools = {
+list_floating_ip_pools = {
'status_code': [200],
'response_body': {
'type': 'object',
diff --git a/tempest/api_schema/response/compute/v2_1/images.py b/tempest/api_schema/response/compute/v2_1/images.py
index 3c0b80e..e6f8db6 100644
--- a/tempest/api_schema/response/compute/v2_1/images.py
+++ b/tempest/api_schema/response/compute/v2_1/images.py
@@ -14,7 +14,7 @@
import copy
-from tempest.api_schema.response.compute import parameter_types
+from tempest.api_schema.response.compute.v2_1 import parameter_types
image_links = copy.deepcopy(parameter_types.links)
image_links['items']['properties'].update({'type': {'type': 'string'}})
diff --git a/tempest/api_schema/response/compute/v2_1/interfaces.py b/tempest/api_schema/response/compute/v2_1/interfaces.py
index 4de3309..033f816 100644
--- a/tempest/api_schema/response/compute/v2_1/interfaces.py
+++ b/tempest/api_schema/response/compute/v2_1/interfaces.py
@@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.api_schema.response.compute import parameter_types
+from tempest.api_schema.response.compute.v2_1 import parameter_types
interface_common_info = {
'type': 'object',
diff --git a/tempest/api_schema/response/compute/migrations.py b/tempest/api_schema/response/compute/v2_1/migrations.py
similarity index 100%
rename from tempest/api_schema/response/compute/migrations.py
rename to tempest/api_schema/response/compute/v2_1/migrations.py
diff --git a/tempest/api_schema/response/compute/parameter_types.py b/tempest/api_schema/response/compute/v2_1/parameter_types.py
similarity index 100%
rename from tempest/api_schema/response/compute/parameter_types.py
rename to tempest/api_schema/response/compute/v2_1/parameter_types.py
diff --git a/tempest/api_schema/response/compute/v2_1/servers.py b/tempest/api_schema/response/compute/v2_1/servers.py
index 726f9b1..875f607 100644
--- a/tempest/api_schema/response/compute/v2_1/servers.py
+++ b/tempest/api_schema/response/compute/v2_1/servers.py
@@ -14,7 +14,7 @@
import copy
-from tempest.api_schema.response.compute import parameter_types
+from tempest.api_schema.response.compute.v2_1 import parameter_types
create_server = {
'status_code': [202],
diff --git a/tempest/api_schema/response/compute/services.py b/tempest/api_schema/response/compute/v2_1/services.py
similarity index 100%
rename from tempest/api_schema/response/compute/services.py
rename to tempest/api_schema/response/compute/v2_1/services.py
diff --git a/tempest/api_schema/response/compute/v2_1/tenant_usages.py b/tempest/api_schema/response/compute/v2_1/tenant_usages.py
index 0b824a1..d51ef12 100644
--- a/tempest/api_schema/response/compute/v2_1/tenant_usages.py
+++ b/tempest/api_schema/response/compute/v2_1/tenant_usages.py
@@ -66,7 +66,7 @@
'total_hours', 'total_local_gb_usage',
'total_memory_mb_usage', 'total_vcpus_usage']
-list_tenant = {
+list_tenant_usage = {
'status_code': [200],
'response_body': {
'type': 'object',
@@ -80,7 +80,7 @@
}
}
-get_tenant = {
+get_tenant_usage = {
'status_code': [200],
'response_body': {
'type': 'object',
diff --git a/tempest/api_schema/response/compute/version.py b/tempest/api_schema/response/compute/v2_1/version.py
similarity index 100%
rename from tempest/api_schema/response/compute/version.py
rename to tempest/api_schema/response/compute/v2_1/version.py
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 4e2af76..d3426c6 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -617,7 +617,7 @@
def _get_image_by_name(client, name):
- body = client.images.image_list()
+ body = client.images.list_images()
for image in body:
if name == image['name']:
return image
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index fee1467..5ded3ee 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -311,7 +311,8 @@
LOG.info("Acquired isolated creds:\n credentials: %s"
% credentials)
if (CONF.service_available.neutron and
- not CONF.baremetal.driver_enabled):
+ not CONF.baremetal.driver_enabled and
+ CONF.auth.create_isolated_networks):
network, subnet, router = self._create_network_resources(
credentials.tenant_id)
credentials.set_resources(network=network, subnet=subnet,
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index bedff1f..4b3995b 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -46,6 +46,9 @@
channel_timeout=ssh_channel_timeout)
def exec_command(self, cmd):
+ # Shell options below add more clearness on failures,
+ # path is extended for some non-cirros guest oses (centos7)
+ cmd = "set -eu -o pipefail; PATH=$PATH:/sbin; " + cmd
return self.ssh_client.exec_command(cmd)
def validate_authentication(self):
@@ -95,26 +98,26 @@
return self.exec_command(cmd)
def get_mac_address(self):
- cmd = "/bin/ip addr | awk '/ether/ {print $2}'"
+ cmd = "ip addr | awk '/ether/ {print $2}'"
return self.exec_command(cmd)
def get_nic_name(self, address):
- cmd = "/bin/ip -o addr | awk '/%s/ {print $2}'" % address
+ cmd = "ip -o addr | awk '/%s/ {print $2}'" % address
return self.exec_command(cmd)
def get_ip_list(self):
- cmd = "/bin/ip address"
+ cmd = "ip address"
return self.exec_command(cmd)
def assign_static_ip(self, nic, addr):
- cmd = "sudo /bin/ip addr add {ip}/{mask} dev {nic}".format(
+ cmd = "sudo ip addr add {ip}/{mask} dev {nic}".format(
ip=addr, mask=CONF.network.tenant_network_mask_bits,
nic=nic
)
return self.exec_command(cmd)
def turn_nic_on(self, nic):
- cmd = "sudo /bin/ip link set {nic} up".format(nic=nic)
+ cmd = "sudo ip link set {nic} up".format(nic=nic)
return self.exec_command(cmd)
def get_pids(self, pr_name):
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 64ff7f2..249bac9 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -99,15 +99,15 @@
def wait_for_image_status(client, image_id, status):
"""Waits for an image to reach a given status.
- The client should have a get_image(image_id) method to get the image.
+ The client should have a show_image(image_id) method to get the image.
The client should also have build_interval and build_timeout attributes.
"""
- image = client.get_image(image_id)
+ image = client.show_image(image_id)
start = int(time.time())
while image['status'] != status:
time.sleep(client.build_interval)
- image = client.get_image(image_id)
+ image = client.show_image(image_id)
status_curr = image['status']
if status_curr == 'ERROR':
raise exceptions.AddImageException(image_id=image_id)
diff --git a/tempest/config.py b/tempest/config.py
index bdbf942..603ccd2 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -69,7 +69,15 @@
help="Only applicable when identity.auth_version is v3."
"Domain within which isolated credentials are provisioned."
"The default \"None\" means that the domain from the"
- "admin user is used instead.")
+ "admin user is used instead."),
+ cfg.BoolOpt('create_isolated_networks',
+ default=True,
+ help="If allow_tenant_isolation is set to True and Neutron is "
+ "enabled Tempest will try to create a useable network, "
+ "subnet, and router when needed for each tenant it "
+ "creates. However in some neutron configurations, like "
+ "with VLAN provider networks, this doesn't work. So if "
+ "set to False the isolated networks will not be created"),
]
identity_group = cfg.OptGroup(name='identity',
@@ -142,6 +150,9 @@
cfg.StrOpt('admin_domain_name',
help="Admin domain name for authentication (Keystone V3)."
"The same domain applies to user and project"),
+ cfg.StrOpt('default_domain_id',
+ default='default',
+ help="ID of the default domain"),
]
identity_feature_group = cfg.OptGroup(name='identity-feature-enabled',
@@ -947,6 +958,8 @@
cfg.StrOpt('img_container_format',
default='bare',
help='Image container format'),
+ cfg.DictOpt('img_properties', help='Glance image properties. '
+ 'Use for custom images which require them'),
cfg.StrOpt('ami_img_file',
default='cirros-0.3.1-x86_64-blank.img',
help='AMI image file name'),
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index cfd5169..5f8d605 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -323,7 +323,8 @@
return linux_client
- def _image_create(self, name, fmt, path, properties=None):
+ def _image_create(self, name, fmt, path,
+ disk_format=None, properties=None):
if properties is None:
properties = {}
name = data_utils.rand_name('%s-' % name)
@@ -332,10 +333,10 @@
params = {
'name': name,
'container_format': fmt,
- 'disk_format': fmt,
+ 'disk_format': disk_format or fmt,
'is_public': 'False',
}
- params.update(properties)
+ params['properties'] = properties
image = self.image_client.create_image(**params)
self.addCleanup(self.image_client.delete_image, image['id'])
self.assertEqual("queued", image['status'])
@@ -349,23 +350,22 @@
ami_img_path = CONF.scenario.img_dir + "/" + CONF.scenario.ami_img_file
img_container_format = CONF.scenario.img_container_format
img_disk_format = CONF.scenario.img_disk_format
+ img_properties = CONF.scenario.img_properties
LOG.debug("paths: img: %s, container_fomat: %s, disk_format: %s, "
- "ami: %s, ari: %s, aki: %s" %
+ "properties: %s, ami: %s, ari: %s, aki: %s" %
(img_path, img_container_format, img_disk_format,
- ami_img_path, ari_img_path, aki_img_path))
+ img_properties, ami_img_path, ari_img_path, aki_img_path))
try:
self.image = self._image_create('scenario-img',
img_container_format,
img_path,
- properties={'disk_format':
- img_disk_format})
+ disk_format=img_disk_format,
+ properties=img_properties)
except IOError:
LOG.debug("A qcow2 image was not found. Try to get a uec image.")
kernel = self._image_create('scenario-aki', 'aki', aki_img_path)
ramdisk = self._image_create('scenario-ari', 'ari', ari_img_path)
- properties = {
- 'properties': {'kernel_id': kernel, 'ramdisk_id': ramdisk}
- }
+ properties = {'kernel_id': kernel, 'ramdisk_id': ramdisk}
self.image = self._image_create('scenario-ami', 'ami',
path=ami_img_path,
properties=properties)
@@ -413,9 +413,9 @@
return snapshot_image
def nova_volume_attach(self):
- # TODO(andreaf) Device should be here CONF.compute.volume_device_name
volume = self.servers_client.attach_volume(
- self.server['id'], self.volume['id'], '/dev/vdb')
+ self.server['id'], self.volume['id'], '/dev/%s'
+ % CONF.compute.volume_device_name)
self.assertEqual(self.volume['id'], volume['id'])
self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
# Refresh the volume after the attachment
@@ -991,7 +991,7 @@
router_id = CONF.network.public_router_id
network_id = CONF.network.public_network_id
if router_id:
- resp, body = client.show_router(router_id)
+ body = client.show_router(router_id)
return net_resources.AttributeDict(**body['router'])
elif network_id:
router = self._create_router(client, tenant_id)
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index 0789c21..56d4c7d 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -17,6 +17,7 @@
from tempest_lib.common.utils import data_utils
from tempest_lib import exceptions as lib_exc
+from tempest.common import fixed_network
from tempest import config
from tempest.scenario import manager
from tempest import test
@@ -87,13 +88,18 @@
'secgroup-%s' % name, 'secgroup-desc-%s' % name)
self.addCleanupClass(self.security_groups_client.delete_security_group,
secgroup['id'])
-
+ create_kwargs = {
+ 'min_count': CONF.scenario.large_ops_number,
+ 'security_groups': [{'name': secgroup['name']}]
+ }
+ network = self.get_tenant_network()
+ create_kwargs = fixed_network.set_networks_kwarg(network,
+ create_kwargs)
self.servers_client.create_server(
name,
self.image,
flavor_id,
- min_count=CONF.scenario.large_ops_number,
- security_groups=[{'name': secgroup['name']}])
+ **create_kwargs)
# needed because of bug 1199788
params = {'name': name}
server_list = self.servers_client.list_servers(params)
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index 53b471a..51c4c59 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -103,9 +103,9 @@
return self.create_volume(snapshot_id=snapshot_id)
def _attach_volume(self, server, volume):
- # TODO(andreaf) we should use device from config instead if vdb
attached_volume = self.servers_client.attach_volume(
- server['id'], volume['id'], device='/dev/vdb')
+ server['id'], volume['id'], device='/dev/%s'
+ % CONF.compute.volume_device_name)
self.assertEqual(volume['id'], attached_volume['id'])
self._wait_for_volume_status(attached_volume, 'in-use')
@@ -119,7 +119,7 @@
def _func():
part = ssh.get_partitions()
LOG.debug("Partitions:%s" % part)
- return 'vdb' in part
+ return CONF.compute.volume_device_name in part
if not tempest.test.call_until_true(_func,
CONF.compute.build_timeout,
@@ -128,15 +128,18 @@
def _create_timestamp(self, server_or_ip):
ssh_client = self._ssh_to_server(server_or_ip)
- ssh_client.exec_command('sudo /usr/sbin/mkfs.ext4 /dev/vdb')
- ssh_client.exec_command('sudo mount /dev/vdb /mnt')
+ ssh_client.exec_command('sudo /usr/sbin/mkfs.ext4 /dev/%s'
+ % CONF.compute.volume_device_name)
+ ssh_client.exec_command('sudo mount /dev/%s /mnt'
+ % CONF.compute.volume_device_name)
ssh_client.exec_command('sudo sh -c "date > /mnt/timestamp;sync"')
self.timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
ssh_client.exec_command('sudo umount /mnt')
def _check_timestamp(self, server_or_ip):
ssh_client = self._ssh_to_server(server_or_ip)
- ssh_client.exec_command('sudo mount /dev/vdb /mnt')
+ ssh_client.exec_command('sudo mount /dev/%s /mnt'
+ % CONF.compute.volume_device_name)
got_timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
self.assertEqual(self.timestamp, got_timestamp)
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 177697b..1731c48 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -41,8 +41,6 @@
super(TestVolumeBootPattern, cls).skip_checks()
if not CONF.volume_feature_enabled.snapshot:
raise cls.skipException("Cinder volume snapshots are disabled")
- if CONF.volume.storage_protocol == 'ceph':
- raise cls.skipException('Skip until bug 1439371 is fixed.')
def _create_volume_from_image(self):
img_uuid = CONF.compute.image_ref
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index b4f2466..f8d9dd4 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -44,7 +44,7 @@
self.flavors_client = os.flavors_client
def ssh_user(self, image_id):
- _image = self.images_client.get_image(image_id)
+ _image = self.images_client.show_image(image_id)
for regex, user in self.ssh_users:
# First match wins
if re.match(regex, _image['name']) is not None:
@@ -57,14 +57,14 @@
string=str(image['name']))
def is_sshable_image(self, image_id):
- _image = self.images_client.get_image(image_id)
+ _image = self.images_client.show_image(image_id)
return self._is_sshable_image(_image)
def _is_flavor_enough(self, flavor, image):
return image['minDisk'] <= flavor['disk']
def is_flavor_enough(self, flavor_id, image_id):
- _image = self.images_client.get_image(image_id)
+ _image = self.images_client.show_image(image_id)
_flavor = self.flavors_client.get_flavor_details(flavor_id)
return self._is_flavor_enough(_flavor, _image)
diff --git a/tempest/services/compute/json/baremetal_nodes_client.py b/tempest/services/compute/json/baremetal_nodes_client.py
index fa2d7f4..d8f13c4 100644
--- a/tempest/services/compute/json/baremetal_nodes_client.py
+++ b/tempest/services/compute/json/baremetal_nodes_client.py
@@ -16,7 +16,8 @@
from six.moves.urllib import parse as urllib
-from tempest.api_schema.response.compute import baremetal_nodes as schema
+from tempest.api_schema.response.compute.v2_1 import baremetal_nodes \
+ as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 80cbe4d..7938d8e 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -17,10 +17,11 @@
from six.moves.urllib import parse as urllib
-from tempest.api_schema.response.compute import flavors_access as schema_access
-from tempest.api_schema.response.compute import flavors_extra_specs \
- as schema_extra_specs
from tempest.api_schema.response.compute.v2_1 import flavors as schema
+from tempest.api_schema.response.compute.v2_1 import flavors_access \
+ as schema_access
+from tempest.api_schema.response.compute.v2_1 import flavors_extra_specs \
+ as schema_extra_specs
from tempest.common import service_client
@@ -103,7 +104,7 @@
resp, body = self.post('flavors/%s/os-extra_specs' % flavor_id,
post_body)
body = json.loads(body)
- self.validate_response(schema_extra_specs.flavor_extra_specs,
+ self.validate_response(schema_extra_specs.set_get_flavor_extra_specs,
resp, body)
return service_client.ResponseBody(resp, body['extra_specs'])
@@ -111,7 +112,7 @@
"""Gets extra Specs details of the mentioned flavor."""
resp, body = self.get('flavors/%s/os-extra_specs' % flavor_id)
body = json.loads(body)
- self.validate_response(schema_extra_specs.flavor_extra_specs,
+ self.validate_response(schema_extra_specs.set_get_flavor_extra_specs,
resp, body)
return service_client.ResponseBody(resp, body['extra_specs'])
@@ -120,8 +121,9 @@
resp, body = self.get('flavors/%s/os-extra_specs/%s' % (str(flavor_id),
key))
body = json.loads(body)
- self.validate_response(schema_extra_specs.flavor_extra_specs_key,
- resp, body)
+ self.validate_response(
+ schema_extra_specs.set_get_flavor_extra_specs_key,
+ resp, body)
return service_client.ResponseBody(resp, body)
def update_flavor_extra_spec(self, flavor_id, key, **kwargs):
@@ -129,8 +131,9 @@
resp, body = self.put('flavors/%s/os-extra_specs/%s' %
(flavor_id, key), json.dumps(kwargs))
body = json.loads(body)
- self.validate_response(schema_extra_specs.flavor_extra_specs_key,
- resp, body)
+ self.validate_response(
+ schema_extra_specs.set_get_flavor_extra_specs_key,
+ resp, body)
return service_client.ResponseBody(resp, body)
def unset_flavor_extra_spec(self, flavor_id, key):
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 9568a5e..f30bfdb 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -40,7 +40,7 @@
url = "os-floating-ips/%s" % str(floating_ip_id)
resp, body = self.get(url)
body = json.loads(body)
- self.validate_response(schema.floating_ip, resp, body)
+ self.validate_response(schema.create_get_floating_ip, resp, body)
return service_client.ResponseBody(resp, body['floating_ip'])
def create_floating_ip(self, pool_name=None):
@@ -50,7 +50,7 @@
post_body = json.dumps(post_body)
resp, body = self.post(url, post_body)
body = json.loads(body)
- self.validate_response(schema.floating_ip, resp, body)
+ self.validate_response(schema.create_get_floating_ip, resp, body)
return service_client.ResponseBody(resp, body['floating_ip'])
def delete_floating_ip(self, floating_ip_id):
@@ -108,7 +108,7 @@
resp, body = self.get(url)
body = json.loads(body)
- self.validate_response(schema.floating_ip_pools, resp, 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):
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 5462efc..30aa962 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -65,7 +65,7 @@
self.validate_response(schema.list_images_details, resp, body)
return service_client.ResponseBodyList(resp, body['images'])
- def get_image(self, image_id):
+ def show_image(self, image_id):
"""Returns the details of a single image."""
resp, body = self.get("images/%s" % str(image_id))
self.expected_success(200, resp.status)
@@ -131,7 +131,7 @@
def is_resource_deleted(self, id):
try:
- self.get_image(id)
+ self.show_image(id)
except lib_exc.NotFound:
return True
return False
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index 009992c..f708a07 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -16,7 +16,7 @@
from six.moves.urllib import parse as urllib
-from tempest.api_schema.response.compute import migrations as schema
+from tempest.api_schema.response.compute.v2_1 import migrations as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index e2d959b..156ad8d 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -18,7 +18,7 @@
from six.moves.urllib import parse as urllib
-from tempest.api_schema.response.compute import services as schema
+from tempest.api_schema.response.compute.v2_1 import services as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index b7e2b2a..52f46e2 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -30,7 +30,7 @@
resp, body = self.get(url)
body = json.loads(body)
- self.validate_response(schema.list_tenant, resp, body)
+ self.validate_response(schema.list_tenant_usage, resp, body)
return service_client.ResponseBodyList(resp, body['tenant_usages'][0])
def get_tenant_usage(self, tenant_id, params=None):
@@ -40,5 +40,5 @@
resp, body = self.get(url)
body = json.loads(body)
- self.validate_response(schema.get_tenant, resp, body)
+ self.validate_response(schema.get_tenant_usage, resp, body)
return service_client.ResponseBodyList(resp, body['tenant_usage'])
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 5e442fa..7c58f01 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -201,7 +201,7 @@
self.expected_success(200, resp.status)
return service_client.ResponseBody(resp, body)
- def image_list(self, **kwargs):
+ def list_images(self, **kwargs):
url = 'v1/images'
if len(kwargs) > 0:
@@ -240,7 +240,7 @@
body = self._image_meta_from_headers(resp)
return service_client.ResponseBody(resp, body)
- def get_image(self, image_id):
+ def show_image(self, image_id):
url = 'v1/images/%s' % image_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
@@ -258,7 +258,7 @@
"""Returns the primary type of resource this client works with."""
return 'image_meta'
- def get_image_membership(self, image_id):
+ def list_image_members(self, image_id):
url = 'v1/images/%s/members' % image_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index aff8e85..a4cb48c 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -102,7 +102,7 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp)
- def image_list(self, params=None):
+ def list_images(self, params=None):
url = 'v2/images'
if params:
@@ -114,7 +114,7 @@
self._validate_schema(body, type='images')
return service_client.ResponseBodyList(resp, body['images'])
- def get_image(self, image_id):
+ def show_image(self, image_id):
url = 'v2/images/%s' % image_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
@@ -123,7 +123,7 @@
def is_resource_deleted(self, id):
try:
- self.get_image(id)
+ self.show_image(id)
except lib_exc.NotFound:
return True
return False
@@ -159,7 +159,7 @@
self.expected_success(204, resp.status)
return service_client.ResponseBody(resp)
- def get_image_membership(self, image_id):
+ def list_image_members(self, image_id):
url = 'v2/images/%s/members' % image_id
resp, body = self.get(url)
self.expected_success(200, resp.status)
diff --git a/tempest/test.py b/tempest/test.py
index 675071b..0d709f6c 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -324,7 +324,7 @@
if 'admin' in cls.credentials and not credentials.is_admin_available():
msg = "Missing Identity Admin API credentials in configuration."
raise cls.skipException(msg)
- if 'alt' is cls.credentials and not credentials.is_alt_available():
+ if 'alt' in cls.credentials and not credentials.is_alt_available():
msg = "Missing a 2nd set of API credentials in configuration."
raise cls.skipException(msg)
if hasattr(cls, 'identity_version'):
diff --git a/tempest/tests/common/utils/linux/test_remote_client.py b/tempest/tests/common/utils/linux/test_remote_client.py
index d6377e6..3506856 100644
--- a/tempest/tests/common/utils/linux/test_remote_client.py
+++ b/tempest/tests/common/utils/linux/test_remote_client.py
@@ -73,6 +73,7 @@
# the information using gnu/linux tools.
def _assert_exec_called_with(self, cmd):
+ cmd = "set -eu -o pipefail; PATH=$PATH:/sbin; " + cmd
self.ssh_mock.mock.exec_command.assert_called_with(cmd)
def test_get_number_of_vcpus(self):
@@ -119,7 +120,7 @@
self.assertEqual(self.conn.get_mac_address(), macs)
self._assert_exec_called_with(
- "/bin/ip addr | awk '/ether/ {print $2}'")
+ "ip addr | awk '/ether/ {print $2}'")
def test_get_ip_list(self):
ips = """1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue
@@ -136,7 +137,7 @@
valid_lft forever preferred_lft forever"""
self.ssh_mock.mock.exec_command.return_value = ips
self.assertEqual(self.conn.get_ip_list(), ips)
- self._assert_exec_called_with('/bin/ip address')
+ self._assert_exec_called_with('ip address')
def test_assign_static_ip(self):
self.ssh_mock.mock.exec_command.return_value = ''
@@ -144,9 +145,10 @@
nic = 'eth0'
self.assertEqual(self.conn.assign_static_ip(nic, ip), '')
self._assert_exec_called_with(
- "sudo /bin/ip addr add %s/%s dev %s" % (ip, '28', nic))
+ "sudo ip addr add %s/%s dev %s" % (ip, '28', nic))
def test_turn_nic_on(self):
nic = 'eth0'
self.conn.turn_nic_on(nic)
- self._assert_exec_called_with('sudo /bin/ip link set %s up' % nic)
+ self._assert_exec_called_with(
+ 'sudo ip link set %s up' % nic)
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index 47e6abd..72a63c3 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -268,6 +268,36 @@
self.assertEqual(alt_creds.user_id, '1234')
@mock.patch('tempest_lib.common.rest_client.RestClient')
+ def test_no_network_creation_with_config_set(self, MockRestClient):
+ cfg.CONF.set_default('create_isolated_networks', False, group='auth')
+ iso_creds = isolated_creds.IsolatedCreds(name='test class',
+ password='fake_password')
+ self._mock_assign_user_role()
+ self._mock_list_role()
+ self._mock_user_create('1234', 'fake_prim_user')
+ self._mock_tenant_create('1234', 'fake_prim_tenant')
+ net = mock.patch.object(iso_creds.network_admin_client,
+ 'delete_network')
+ net_mock = net.start()
+ subnet = mock.patch.object(iso_creds.network_admin_client,
+ 'delete_subnet')
+ subnet_mock = subnet.start()
+ router = mock.patch.object(iso_creds.network_admin_client,
+ 'delete_router')
+ router_mock = router.start()
+
+ primary_creds = iso_creds.get_primary_creds()
+ self.assertEqual(net_mock.mock_calls, [])
+ self.assertEqual(subnet_mock.mock_calls, [])
+ self.assertEqual(router_mock.mock_calls, [])
+ network = primary_creds.network
+ subnet = primary_creds.subnet
+ router = primary_creds.router
+ self.assertIsNone(network)
+ self.assertIsNone(subnet)
+ self.assertIsNone(router)
+
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_creation(self, MockRestClient):
iso_creds = isolated_creds.IsolatedCreds(name='test class',
password='fake_password')
diff --git a/tempest/tests/test_waiters.py b/tempest/tests/test_waiters.py
index cdf5362..329d610 100644
--- a/tempest/tests/test_waiters.py
+++ b/tempest/tests/test_waiters.py
@@ -29,7 +29,7 @@
self.client.build_interval = 1
def test_wait_for_image_status(self):
- self.client.get_image.return_value = ({'status': 'active'})
+ self.client.show_image.return_value = ({'status': 'active'})
start_time = int(time.time())
waiters.wait_for_image_status(self.client, 'fake_image_id', 'active')
end_time = int(time.time())
@@ -37,13 +37,13 @@
self.assertTrue((end_time - start_time) < 10)
def test_wait_for_image_status_timeout(self):
- self.client.get_image.return_value = ({'status': 'saving'})
+ self.client.show_image.return_value = ({'status': 'saving'})
self.assertRaises(exceptions.TimeoutException,
waiters.wait_for_image_status,
self.client, 'fake_image_id', 'active')
def test_wait_for_image_status_error_on_image_create(self):
- self.client.get_image.return_value = ({'status': 'ERROR'})
+ self.client.show_image.return_value = ({'status': 'ERROR'})
self.assertRaises(exceptions.AddImageException,
waiters.wait_for_image_status,
self.client, 'fake_image_id', 'active')
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 19a77dc..b7f0e81 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -283,7 +283,17 @@
CONF.compute.ssh_user,
pkey=self.keypair.material)
text = data_utils.rand_name("Pattern text for console output")
- resp = ssh.write_to_console(text)
+ try:
+ resp = ssh.write_to_console(text)
+ except Exception:
+ if not CONF.compute_feature_enabled.console_output:
+ LOG.debug('Console output not supported, cannot log')
+ else:
+ console_output = instance.get_console_output().output
+ LOG.debug('Console output for %s\nbody=\n%s',
+ instance.id, console_output)
+ raise
+
self.assertFalse(resp)
def _output():
diff --git a/tox.ini b/tox.ini
index 2d2ed38..4bb5df6 100644
--- a/tox.ini
+++ b/tox.ini
@@ -59,16 +59,6 @@
find . -type f -name "*.pyc" -delete
bash tools/pretty_tox_serial.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty)) {posargs}'
-[testenv:heat-slow]
-sitepackages = {[tempestenv]sitepackages}
-setenv = {[tempestenv]setenv}
- OS_TEST_TIMEOUT=1200
-deps = {[tempestenv]deps}
-# The regex below is used to select heat api/scenario tests tagged as slow.
-commands =
- find . -type f -name "*.pyc" -delete
- bash tools/pretty_tox.sh '(?=.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)\.orchestration) {posargs}'
-
[testenv:large-ops]
sitepackages = {[tempestenv]sitepackages}
setenv = {[tempestenv]setenv}