Merge "Add ipsec-site-connections to resource map of a network client"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 02609ae..3ade411 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -467,6 +467,16 @@
#endpoint_type = publicURL
+[data_processing-feature-enabled]
+
+#
+# From tempest.config
+#
+
+# List of enabled data processing plugins (list value)
+#plugins = vanilla,hdp
+
+
[database]
#
diff --git a/requirements.txt b/requirements.txt
index 2af8586..1ce2fc5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -11,7 +11,7 @@
netaddr>=0.7.12
python-ceilometerclient>=1.0.6
python-glanceclient>=0.15.0
-python-keystoneclient>=0.11.1
+python-keystoneclient>=1.0.0
python-novaclient>=2.18.0
python-neutronclient>=2.3.6,<3
python-cinderclient>=1.1.0
@@ -25,4 +25,4 @@
iso8601>=0.1.9
fixtures>=0.3.14
testscenarios>=0.4
-tempest-lib
+tempest-lib>=0.1.0
diff --git a/tempest/api/baremetal/admin/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
index 3392ab9..4aedaa4 100644
--- a/tempest/api/baremetal/admin/test_ports.py
+++ b/tempest/api/baremetal/admin/test_ports.py
@@ -87,6 +87,11 @@
self._assertExpected(self.port, port)
@test.attr(type='smoke')
+ def test_show_port_by_address(self):
+ _, port = self.client.show_port_by_address(self.port['address'])
+ self._assertExpected(self.port, port['ports'][0])
+
+ @test.attr(type='smoke')
def test_show_port_with_links(self):
_, port = self.client.show_port(self.port['uuid'])
self.assertIn('links', port.keys())
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 4f2715f..c245eb4 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -174,7 +174,7 @@
LOG.debug('Clearing server groups: %s', ','.join(cls.server_groups))
for server_group_id in cls.server_groups:
try:
- cls.client.delete_server_group(server_group_id)
+ cls.servers_client.delete_server_group(server_group_id)
except exceptions.NotFound:
# The server-group may have already been deleted which is OK.
pass
@@ -293,20 +293,20 @@
if 'name' in kwargs:
name = kwargs.pop('name')
- resp, image = cls.images_client.create_image(server_id, name)
- image_id = data_utils.parse_image_id(resp['location'])
+ image = cls.images_client.create_image(server_id, name)
+ image_id = data_utils.parse_image_id(image.response['location'])
cls.images.append(image_id)
if 'wait_until' in kwargs:
cls.images_client.wait_for_image_status(image_id,
kwargs['wait_until'])
- resp, image = cls.images_client.get_image(image_id)
+ image = cls.images_client.get_image(image_id)
if kwargs['wait_until'] == 'ACTIVE':
if kwargs.get('wait_for_server', True):
cls.servers_client.wait_for_server_status(server_id,
'ACTIVE')
- return resp, image
+ return image
@classmethod
def rebuild_server(cls, server_id, **kwargs):
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 38e55b1..c3b144d 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -49,61 +49,62 @@
def setUp(self):
super(ImagesMetadataTestJSON, self).setUp()
- meta = {'key1': 'value1', 'key2': 'value2'}
- resp, _ = self.client.set_image_metadata(self.image_id, meta)
- self.assertEqual(resp.status, 200)
+ meta = {'os_version': 'value1', 'os_distro': 'value2'}
+ self.client.set_image_metadata(self.image_id, meta)
@test.attr(type='gate')
def test_list_image_metadata(self):
# All metadata key/value pairs for an image should be returned
- resp, resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'key1': 'value1', 'key2': 'value2'}
+ resp_metadata = self.client.list_image_metadata(self.image_id)
+ expected = {'os_version': 'value1', 'os_distro': 'value2'}
self.assertEqual(expected, resp_metadata)
@test.attr(type='gate')
def test_set_image_metadata(self):
# The metadata for the image should match the new values
- req_metadata = {'meta2': 'value2', 'meta3': 'value3'}
- resp, body = self.client.set_image_metadata(self.image_id,
- req_metadata)
+ req_metadata = {'os_version': 'value2', 'architecture': 'value3'}
+ self.client.set_image_metadata(self.image_id,
+ req_metadata)
- resp, resp_metadata = self.client.list_image_metadata(self.image_id)
+ resp_metadata = self.client.list_image_metadata(self.image_id)
self.assertEqual(req_metadata, resp_metadata)
@test.attr(type='gate')
def test_update_image_metadata(self):
# The metadata for the image should match the updated values
- req_metadata = {'key1': 'alt1', 'key3': 'value3'}
- resp, metadata = self.client.update_image_metadata(self.image_id,
- req_metadata)
+ req_metadata = {'os_version': 'alt1', 'architecture': 'value3'}
+ self.client.update_image_metadata(self.image_id,
+ req_metadata)
- resp, resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
+ resp_metadata = self.client.list_image_metadata(self.image_id)
+ expected = {'os_version': 'alt1',
+ 'os_distro': 'value2',
+ 'architecture': 'value3'}
self.assertEqual(expected, resp_metadata)
@test.attr(type='gate')
def test_get_image_metadata_item(self):
# The value for a specific metadata key should be returned
- resp, meta = self.client.get_image_metadata_item(self.image_id,
- 'key2')
- self.assertEqual('value2', meta['key2'])
+ meta = self.client.get_image_metadata_item(self.image_id,
+ 'os_distro')
+ self.assertEqual('value2', meta['os_distro'])
@test.attr(type='gate')
def test_set_image_metadata_item(self):
# The value provided for the given meta item should be set for
# the image
- meta = {'key1': 'alt'}
- resp, body = self.client.set_image_metadata_item(self.image_id,
- 'key1', meta)
- resp, resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'key1': 'alt', 'key2': 'value2'}
+ meta = {'os_version': 'alt'}
+ self.client.set_image_metadata_item(self.image_id,
+ 'os_version', meta)
+ resp_metadata = self.client.list_image_metadata(self.image_id)
+ expected = {'os_version': 'alt', 'os_distro': 'value2'}
self.assertEqual(expected, resp_metadata)
@test.attr(type='gate')
def test_delete_image_metadata_item(self):
# The metadata value/key pair should be deleted from the image
- resp, body = self.client.delete_image_metadata_item(self.image_id,
- 'key1')
- resp, resp_metadata = self.client.list_image_metadata(self.image_id)
- expected = {'key2': 'value2'}
+ self.client.delete_image_metadata_item(self.image_id,
+ 'os_version')
+ resp_metadata = self.client.list_image_metadata(self.image_id)
+ expected = {'os_distro': 'value2'}
self.assertEqual(expected, resp_metadata)
diff --git a/tempest/api/compute/images/test_image_metadata_negative.py b/tempest/api/compute/images/test_image_metadata_negative.py
index 615b5d0..73412ff 100644
--- a/tempest/api/compute/images/test_image_metadata_negative.py
+++ b/tempest/api/compute/images/test_image_metadata_negative.py
@@ -36,7 +36,7 @@
@test.attr(type=['negative', 'gate'])
def test_update_nonexistent_image_metadata(self):
# Negative test:An update should not happen for a non-existent image
- meta = {'key1': 'alt1', 'key2': 'alt2'}
+ meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
self.assertRaises(exceptions.NotFound,
self.client.update_image_metadata,
data_utils.rand_uuid(), meta)
@@ -46,12 +46,12 @@
# Negative test: Get on non-existent image should not happen
self.assertRaises(exceptions.NotFound,
self.client.get_image_metadata_item,
- data_utils.rand_uuid(), 'key2')
+ data_utils.rand_uuid(), 'os_version')
@test.attr(type=['negative', 'gate'])
def test_set_nonexistent_image_metadata(self):
# Negative test: Metadata should not be set to a non-existent image
- meta = {'key1': 'alt1', 'key2': 'alt2'}
+ meta = {'os_distro': 'alt1', 'os_version': 'alt2'}
self.assertRaises(exceptions.NotFound, self.client.set_image_metadata,
data_utils.rand_uuid(), meta)
@@ -59,10 +59,10 @@
def test_set_nonexistent_image_metadata_item(self):
# Negative test: Metadata item should not be set to a
# nonexistent image
- meta = {'key1': 'alt'}
+ meta = {'os_distro': 'alt'}
self.assertRaises(exceptions.NotFound,
self.client.set_image_metadata_item,
- data_utils.rand_uuid(), 'key1',
+ data_utils.rand_uuid(), 'os_distro',
meta)
@test.attr(type=['negative', 'gate'])
@@ -71,4 +71,4 @@
# item from non-existent image
self.assertRaises(exceptions.NotFound,
self.client.delete_image_metadata_item,
- data_utils.rand_uuid(), 'key1')
+ data_utils.rand_uuid(), 'os_distro')
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index 51dae65..dc27a70 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -42,8 +42,7 @@
snapshot_name = data_utils.rand_name('test-snap-')
resp, server = self.create_test_server(wait_until='ACTIVE')
self.addCleanup(self.servers_client.delete_server, server['id'])
- resp, image = self.create_image_from_server(server['id'],
- name=snapshot_name,
- wait_until='SAVING')
- resp, body = self.client.delete_image(image['id'])
- self.assertEqual('204', resp['status'])
+ image = self.create_image_from_server(server['id'],
+ name=snapshot_name,
+ wait_until='SAVING')
+ self.client.delete_image(image['id'])
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 9570ca5..58fc20d 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -72,10 +72,10 @@
'SHUTOFF')
self.addCleanup(self.servers_client.delete_server, server['id'])
snapshot_name = data_utils.rand_name('test-snap-')
- resp, image = self.create_image_from_server(server['id'],
- name=snapshot_name,
- wait_until='ACTIVE',
- wait_for_server=False)
+ image = self.create_image_from_server(server['id'],
+ name=snapshot_name,
+ wait_until='ACTIVE',
+ wait_for_server=False)
self.addCleanup(self.client.delete_image, image['id'])
self.assertEqual(snapshot_name, image['name'])
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 91e0423..6156c5a 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -72,17 +72,16 @@
# Create a new image
name = data_utils.rand_name('image')
meta = {'image_type': 'test'}
- resp, body = self.client.create_image(self.server_id, name, meta)
- self.assertEqual(202, resp.status)
- image_id = data_utils.parse_image_id(resp['location'])
+ 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')
# Verify the image was created correctly
- resp, image = self.client.get_image(image_id)
+ image = self.client.get_image(image_id)
self.assertEqual(name, image['name'])
self.assertEqual('test', image['metadata']['image_type'])
- resp, original_image = self.client.get_image(self.image_ref)
+ original_image = self.client.get_image(self.image_ref)
# Verify minRAM is the same as the original image
self.assertEqual(image['minRam'], original_image['minRam'])
@@ -93,8 +92,7 @@
(str(original_image['minDisk']), str(flavor_disk_size)))
# Verify the image was deleted correctly
- resp, body = self.client.delete_image(image_id)
- self.assertEqual('204', resp['status'])
+ self.client.delete_image(image_id)
self.client.wait_for_resource_deletion(image_id)
@test.attr(type=['gate'])
@@ -106,7 +104,6 @@
# #1370954 in glance which will 500 if mysql is used as the
# backend and it attempts to store a 4 byte utf-8 character
utf8_name = data_utils.rand_name('\xe2\x82\xa1')
- resp, body = self.client.create_image(self.server_id, utf8_name)
- image_id = data_utils.parse_image_id(resp['location'])
+ body = self.client.create_image(self.server_id, utf8_name)
+ image_id = data_utils.parse_image_id(body.response['location'])
self.addCleanup(self.client.delete_image, image_id)
- self.assertEqual('202', resp['status'])
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index ae6e712..46cec9b 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -94,10 +94,9 @@
# Create first snapshot
snapshot_name = data_utils.rand_name('test-snap-')
- resp, body = self.client.create_image(self.server_id,
- snapshot_name)
- self.assertEqual(202, resp.status)
- image_id = data_utils.parse_image_id(resp['location'])
+ body = self.client.create_image(self.server_id,
+ snapshot_name)
+ image_id = data_utils.parse_image_id(body.response['location'])
self.image_ids.append(image_id)
self.addCleanup(self._reset_server)
@@ -119,15 +118,13 @@
# Return an error while trying to delete an image what is creating
snapshot_name = data_utils.rand_name('test-snap-')
- resp, body = self.client.create_image(self.server_id, snapshot_name)
- self.assertEqual(202, resp.status)
- image_id = data_utils.parse_image_id(resp['location'])
+ body = self.client.create_image(self.server_id, snapshot_name)
+ image_id = data_utils.parse_image_id(body.response['location'])
self.image_ids.append(image_id)
self.addCleanup(self._reset_server)
# Do not wait, attempt to delete the image, ensure it's successful
- resp, body = self.client.delete_image(image_id)
- self.assertEqual('204', resp['status'])
+ self.client.delete_image(image_id)
self.image_ids.remove(image_id)
self.assertRaises(exceptions.NotFound, self.client.get_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 d9a7201..742c2dd 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -54,7 +54,7 @@
image_file = StringIO.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.get_image(image_id)
return body
# Create non-snapshot images via glance
@@ -76,19 +76,19 @@
'ACTIVE')
# Create images to be used in the filter tests
- resp, cls.snapshot1 = cls.create_image_from_server(
+ cls.snapshot1 = cls.create_image_from_server(
cls.server1['id'], wait_until='ACTIVE')
cls.snapshot1_id = cls.snapshot1['id']
# Servers have a hidden property for when they are being imaged
# Performing back-to-back create image calls on a single
# server will sometimes cause failures
- resp, cls.snapshot3 = cls.create_image_from_server(
+ cls.snapshot3 = cls.create_image_from_server(
cls.server2['id'], wait_until='ACTIVE')
cls.snapshot3_id = cls.snapshot3['id']
# Wait for the server to be active after the image upload
- resp, cls.snapshot2 = cls.create_image_from_server(
+ cls.snapshot2 = cls.create_image_from_server(
cls.server1['id'], wait_until='ACTIVE')
cls.snapshot2_id = cls.snapshot2['id']
@@ -97,7 +97,7 @@
# The list of images should contain only images with the
# provided status
params = {'status': 'ACTIVE'}
- resp, images = self.client.list_images(params)
+ images = self.client.list_images(params)
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
@@ -108,7 +108,7 @@
# List of all images should contain the expected images filtered
# by name
params = {'name': self.image1['name']}
- resp, images = self.client.list_images(params)
+ images = self.client.list_images(params)
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
@@ -120,7 +120,7 @@
def test_list_images_filter_by_server_id(self):
# The images should contain images filtered by server id
params = {'server': self.server1['id']}
- resp, images = self.client.list_images(params)
+ images = self.client.list_images(params)
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot1_id]),
@@ -141,7 +141,7 @@
# Try all server link types
for link in server_links:
params = {'server': link['href']}
- resp, images = self.client.list_images(params)
+ images = self.client.list_images(params)
self.assertFalse(any([i for i in images
if i['id'] == self.snapshot1_id]))
@@ -156,7 +156,7 @@
def test_list_images_filter_by_type(self):
# The list of servers should be filtered by image type
params = {'type': 'snapshot'}
- resp, images = self.client.list_images(params)
+ images = self.client.list_images(params)
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot1_id]))
@@ -171,7 +171,7 @@
def test_list_images_limit_results(self):
# Verify only the expected number of results are returned
params = {'limit': '1'}
- resp, images = self.client.list_images(params)
+ images = self.client.list_images(params)
# when _interface='xml', one element for images_links in images
# ref: Question #224349
self.assertEqual(1, len([x for x in images if 'id' in x]))
@@ -183,7 +183,7 @@
# Becoming ACTIVE will modify the updated time
# Filter by the image's created time
params = {'changes-since': self.image3['created']}
- resp, images = self.client.list_images(params)
+ images = self.client.list_images(params)
found = any([i for i in images if i['id'] == self.image3_id])
self.assertTrue(found)
@@ -192,7 +192,7 @@
# Detailed list of all images should only contain images
# with the provided status
params = {'status': 'ACTIVE'}
- resp, images = self.client.list_images_with_detail(params)
+ images = self.client.list_images_with_detail(params)
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
@@ -203,7 +203,7 @@
# Detailed list of all images should contain the expected
# images filtered by name
params = {'name': self.image1['name']}
- resp, images = self.client.list_images_with_detail(params)
+ images = self.client.list_images_with_detail(params)
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
@@ -214,7 +214,7 @@
# Verify only the expected number of results (with full details)
# are returned
params = {'limit': '1'}
- resp, images = self.client.list_images_with_detail(params)
+ images = self.client.list_images_with_detail(params)
self.assertEqual(1, len(images))
@testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
@@ -227,7 +227,7 @@
# Try all server link types
for link in server_links:
params = {'server': link['href']}
- resp, images = self.client.list_images_with_detail(params)
+ images = self.client.list_images_with_detail(params)
self.assertFalse(any([i for i in images
if i['id'] == self.snapshot1_id]))
@@ -242,8 +242,8 @@
def test_list_images_with_detail_filter_by_type(self):
# The detailed list of servers should be filtered by image type
params = {'type': 'snapshot'}
- resp, images = self.client.list_images_with_detail(params)
- resp, image4 = self.client.get_image(self.image_ref)
+ images = self.client.list_images_with_detail(params)
+ self.client.get_image(self.image_ref)
self.assertTrue(any([i for i in images
if i['id'] == self.snapshot1_id]))
@@ -261,5 +261,5 @@
# Becoming ACTIVE will modify the updated time
# Filter by the image's created time
params = {'changes-since': self.image1['created']}
- resp, images = self.client.list_images_with_detail(params)
+ images = self.client.list_images_with_detail(params)
self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
diff --git a/tempest/api/compute/images/test_list_images.py b/tempest/api/compute/images/test_list_images.py
index 22d64e9..cd01147 100644
--- a/tempest/api/compute/images/test_list_images.py
+++ b/tempest/api/compute/images/test_list_images.py
@@ -33,19 +33,19 @@
@test.attr(type='smoke')
def test_get_image(self):
# Returns the correct details for a single image
- resp, image = self.client.get_image(self.image_ref)
+ image = self.client.get_image(self.image_ref)
self.assertEqual(self.image_ref, image['id'])
@test.attr(type='smoke')
def test_list_images(self):
# The list of all images should contain the image
- resp, images = self.client.list_images()
+ images = self.client.list_images()
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
@test.attr(type='smoke')
def test_list_images_with_detail(self):
# Detailed list of all images should contain the expected images
- resp, images = self.client.list_images_with_detail()
+ images = self.client.list_images_with_detail()
found = any([i for i in images if i['id'] == self.image_ref])
self.assertTrue(found)
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index a9c72fb..d537d83 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -14,12 +14,18 @@
# under the License.
from tempest.api.compute import base
+from tempest.common import tempest_fixtures as fixtures
from tempest import exceptions
from tempest import test
class AbsoluteLimitsNegativeTestJSON(base.BaseV2ComputeTest):
+ def setUp(self):
+ # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
+ self.useFixture(fixtures.LockFixture('compute_quotas'))
+ super(AbsoluteLimitsNegativeTestJSON, self).setUp()
+
@classmethod
def resource_setup(cls):
super(AbsoluteLimitsNegativeTestJSON, cls).resource_setup()
@@ -46,7 +52,4 @@
# A 403 Forbidden or 413 Overlimit (old behaviour) exception
# will be raised when out of quota
self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
- self.server_client.create_server,
- name='test', meta=meta_data,
- flavor_ref=self.flavor_ref,
- image_ref=self.image_ref)
+ self.create_test_server, meta=meta_data)
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 5ff39df..7964cf7 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -33,7 +33,7 @@
# Check to see if the alternate image ref actually exists...
images_client = cls.images_client
- resp, images = images_client.list_images()
+ images = images_client.list_images()
if cls.image_ref != cls.image_ref_alt and \
any([image for image in images
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 76c858b..17e3669 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -437,7 +437,7 @@
resp, server = self.client.get_server(self.server_id)
image_name = server['name'] + '-shelved'
params = {'name': image_name}
- resp, images = self.images_client.list_images(params)
+ images = self.images_client.list_images(params)
self.assertEqual(1, len(images))
self.assertEqual(image_name, images[0]['name'])
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index f44d158..b703cfe 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -431,7 +431,7 @@
resp, server = self.client.get_server(self.server_id)
image_name = server['name'] + '-shelved'
params = {'name': image_name}
- resp, images = self.images_client.list_images(params)
+ images = self.images_client.list_images(params)
self.assertEqual(1, len(images))
self.assertEqual(image_name, images[0]['name'])
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 3dd6e34..60cb812 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -65,7 +65,7 @@
image_file = StringIO.StringIO(('*' * 1024))
body = cls.glance_client.update_image(image_id, data=image_file)
cls.glance_client.wait_for_image_status(image_id, 'active')
- resp, cls.image = cls.images_client.get_image(image_id)
+ cls.image = cls.images_client.get_image(image_id)
cls.keypairname = data_utils.rand_name('keypair')
resp, keypair = \
diff --git a/tempest/api/data_processing/test_plugins.py b/tempest/api/data_processing/test_plugins.py
index 9fd7a17..4b4ec48 100644
--- a/tempest/api/data_processing/test_plugins.py
+++ b/tempest/api/data_processing/test_plugins.py
@@ -13,8 +13,11 @@
# under the License.
from tempest.api.data_processing import base as dp_base
+from tempest import config
from tempest import test
+CONF = config.CONF
+
class PluginsTest(dp_base.BaseDataProcessingTest):
def _list_all_plugin_names(self):
@@ -24,8 +27,8 @@
"""
_, plugins = self.client.list_plugins()
plugins_names = [plugin['name'] for plugin in plugins]
- self.assertIn('vanilla', plugins_names)
- self.assertIn('hdp', plugins_names)
+ for enabled_plugin in CONF.data_processing_feature_enabled.plugins:
+ self.assertIn(enabled_plugin, plugins_names)
return plugins_names
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 21f2578..d3dffbf 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -68,13 +68,13 @@
environment=None, files=None):
if parameters is None:
parameters = {}
- resp, body = cls.client.create_stack(
+ body = cls.client.create_stack(
stack_name,
template=template_data,
parameters=parameters,
environment=environment,
files=files)
- stack_id = resp['location'].split('/')[-1]
+ stack_id = body.response['location'].split('/')[-1]
stack_identifier = '%s/%s' % (stack_name, stack_id)
cls.stacks.append(stack_identifier)
return stack_identifier
@@ -164,7 +164,7 @@
def list_resources(self, stack_identifier):
"""Get a dict mapping of resource names to types."""
- _, resources = self.client.list_resources(stack_identifier)
+ resources = self.client.list_resources(stack_identifier)
self.assertIsInstance(resources, list)
for res in resources:
self.assert_fields_in_dict(res, 'logical_resource_id',
@@ -175,5 +175,5 @@
for r in resources)
def get_stack_output(self, stack_identifier, output_key):
- _, body = self.client.get_stack(stack_identifier)
+ body = self.client.get_stack(stack_identifier)
return self.stack_output(body, output_key)
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index 8352719..ea6d4be 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -65,14 +65,14 @@
cls.stack_id = cls.stack_identifier.split('/')[1]
try:
cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
- _, resources = cls.client.list_resources(cls.stack_identifier)
+ resources = cls.client.list_resources(cls.stack_identifier)
except exceptions.TimeoutException as e:
if CONF.compute_feature_enabled.console_output:
# attempt to log the server console to help with debugging
# the cause of the server not signalling the waitcondition
# to heat.
- _, body = cls.client.get_resource(cls.stack_identifier,
- 'Server')
+ body = cls.client.get_resource(cls.stack_identifier,
+ 'Server')
server_id = body['physical_resource_id']
LOG.debug('Console output for %s', server_id)
_, output = cls.servers_client.get_console_output(
diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py
index bf6c79c..db1ac9a 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -47,7 +47,7 @@
cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
def _list_stacks(self, expected_num=None, **filter_kwargs):
- _, stacks = self.client.list_stacks(params=filter_kwargs)
+ stacks = self.client.list_stacks(params=filter_kwargs)
self.assertIsInstance(stacks, list)
if expected_num is not None:
self.assertEqual(expected_num, len(stacks))
@@ -63,7 +63,7 @@
@test.attr(type='gate')
def test_stack_show(self):
"""Getting details about created stack should be possible."""
- _, stack = self.client.get_stack(self.stack_name)
+ stack = self.client.get_stack(self.stack_name)
self.assertIsInstance(stack, dict)
self.assert_fields_in_dict(stack, 'stack_name', 'id', 'links',
'parameters', 'outputs', 'disable_rollback',
@@ -82,10 +82,10 @@
@test.attr(type='gate')
def test_suspend_resume_stack(self):
"""Suspend and resume a stack."""
- _, suspend_stack = self.client.suspend_stack(self.stack_identifier)
+ self.client.suspend_stack(self.stack_identifier)
self.client.wait_for_stack_status(self.stack_identifier,
'SUSPEND_COMPLETE')
- _, resume_stack = self.client.resume_stack(self.stack_identifier)
+ self.client.resume_stack(self.stack_identifier)
self.client.wait_for_stack_status(self.stack_identifier,
'RESUME_COMPLETE')
@@ -99,8 +99,8 @@
@test.attr(type='gate')
def test_show_resource(self):
"""Getting details about created resource should be possible."""
- _, resource = self.client.get_resource(self.stack_identifier,
- self.resource_name)
+ resource = self.client.get_resource(self.stack_identifier,
+ self.resource_name)
self.assertIsInstance(resource, dict)
self.assert_fields_in_dict(resource, 'resource_name', 'description',
'links', 'logical_resource_id',
@@ -113,7 +113,7 @@
@test.attr(type='gate')
def test_resource_metadata(self):
"""Getting metadata for created resources should be possible."""
- _, metadata = self.client.show_resource_metadata(
+ metadata = self.client.show_resource_metadata(
self.stack_identifier,
self.resource_name)
self.assertIsInstance(metadata, dict)
@@ -122,7 +122,7 @@
@test.attr(type='gate')
def test_list_events(self):
"""Getting list of created events for the stack should be possible."""
- _, events = self.client.list_events(self.stack_identifier)
+ events = self.client.list_events(self.stack_identifier)
self.assertIsInstance(events, list)
for event in events:
@@ -137,13 +137,13 @@
@test.attr(type='gate')
def test_show_event(self):
"""Getting details about an event should be possible."""
- _, events = self.client.list_resource_events(self.stack_identifier,
- self.resource_name)
+ events = self.client.list_resource_events(self.stack_identifier,
+ self.resource_name)
self.assertNotEqual([], events)
events.sort(key=lambda event: event['event_time'])
event_id = events[0]['id']
- _, event = self.client.show_event(self.stack_identifier,
- self.resource_name, event_id)
+ event = self.client.show_event(self.stack_identifier,
+ self.resource_name, event_id)
self.assertIsInstance(event, dict)
self.assert_fields_in_dict(event, 'resource_name', 'event_time',
'links', 'logical_resource_id',
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
index 1da340c..772bab3 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -43,7 +43,7 @@
cls.stack_id = cls.stack_identifier.split('/')[1]
cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
- _, resources = cls.client.list_resources(cls.stack_identifier)
+ resources = cls.client.list_resources(cls.stack_identifier)
cls.test_resources = {}
for resource in resources:
cls.test_resources[resource['logical_resource_id']] = resource
@@ -70,7 +70,7 @@
@test.attr(type='gate')
def test_stack_keypairs_output(self):
- _, stack = self.client.get_stack(self.stack_name)
+ stack = self.client.get_stack(self.stack_name)
self.assertIsInstance(stack, dict)
output_map = {}
diff --git a/tempest/api/orchestration/stacks/test_stacks.py b/tempest/api/orchestration/stacks/test_stacks.py
index d7fbd65..5cdd8b4 100644
--- a/tempest/api/orchestration/stacks/test_stacks.py
+++ b/tempest/api/orchestration/stacks/test_stacks.py
@@ -28,7 +28,7 @@
@test.attr(type='smoke')
def test_stack_list_responds(self):
- _, stacks = self.client.list_stacks()
+ stacks = self.client.list_stacks()
self.assertIsInstance(stacks, list)
@test.attr(type='smoke')
@@ -44,20 +44,20 @@
self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
# check for stack in list
- _, stacks = self.client.list_stacks()
+ stacks = self.client.list_stacks()
list_ids = list([stack['id'] for stack in stacks])
self.assertIn(stack_id, list_ids)
# fetch the stack
- _, stack = self.client.get_stack(stack_identifier)
+ stack = self.client.get_stack(stack_identifier)
self.assertEqual('CREATE_COMPLETE', stack['stack_status'])
# fetch the stack by name
- _, stack = self.client.get_stack(stack_name)
+ stack = self.client.get_stack(stack_name)
self.assertEqual('CREATE_COMPLETE', stack['stack_status'])
# fetch the stack by id
- _, stack = self.client.get_stack(stack_id)
+ stack = self.client.get_stack(stack_id)
self.assertEqual('CREATE_COMPLETE', stack['stack_status'])
# delete the stack
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
index 307468e..0288fd4 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -42,7 +42,7 @@
cls.stack_id = cls.stack_identifier.split('/')[1]
cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
cls.test_resources = {}
- _, resources = cls.client.list_resources(cls.stack_identifier)
+ resources = cls.client.list_resources(cls.stack_identifier)
for resource in resources:
cls.test_resources[resource['logical_resource_id']] = resource
diff --git a/tempest/api/orchestration/stacks/test_templates.py b/tempest/api/orchestration/stacks/test_templates.py
index 262c576..6113cab 100644
--- a/tempest/api/orchestration/stacks/test_templates.py
+++ b/tempest/api/orchestration/stacks/test_templates.py
@@ -38,13 +38,13 @@
@test.attr(type='gate')
def test_show_template(self):
"""Getting template used to create the stack."""
- _, template = self.client.show_template(self.stack_identifier)
+ self.client.show_template(self.stack_identifier)
@test.attr(type='gate')
def test_validate_template(self):
"""Validating template passing it content."""
- _, parameters = self.client.validate_template(self.template,
- self.parameters)
+ self.client.validate_template(self.template,
+ self.parameters)
class TemplateAWSTestJSON(TemplateYAMLTestJSON):
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index 769c201..e840e3b 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -69,11 +69,11 @@
@classmethod
def create_image(cls, client):
- resp, body = client.create_image(
+ body = client.create_image(
data_utils.rand_name('image'), container_format='bare',
disk_format='raw', visibility='private')
cls.image_ids.append(body['id'])
- return resp, body
+ return body
@staticmethod
def cleanup_resources(method, list_of_ids):
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index 7267183..e64cd4a 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -48,7 +48,7 @@
"Glance api v1 is disabled")
@test.skip_because(bug='1351627')
def test_check_glance_v1_notifications(self):
- _, body = self.create_image(self.image_client)
+ body = self.create_image(self.image_client)
self.image_client.update_image(body['id'], data='data')
query = 'resource', 'eq', body['id']
@@ -64,7 +64,7 @@
"Glance api v2 is disabled")
@test.skip_because(bug='1351627')
def test_check_glance_v2_notifications(self):
- _, body = self.create_image(self.image_client_v2)
+ body = self.create_image(self.image_client_v2)
self.image_client_v2.store_image(body['id'], "file")
self.image_client_v2.get_image_file(body['id'])
diff --git a/tempest/cli/simple_read_only/compute/test_nova_manage.py b/tempest/cli/simple_read_only/compute/test_nova_manage.py
deleted file mode 100644
index 34ec671..0000000
--- a/tempest/cli/simple_read_only/compute/test_nova_manage.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2013 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.
-
-from tempest_lib import exceptions
-
-from tempest import cli
-from tempest import config
-from tempest.openstack.common import log as logging
-
-
-CONF = config.CONF
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyNovaManageTest(cli.ClientTestBase):
-
- """
- This is a first pass at a simple read only nova-manage test. This
- only exercises client commands that are read only.
-
- This should test commands:
- * with and without optional parameters
- * initially just check return codes, and later test command outputs
-
- """
-
- @classmethod
- def resource_setup(cls):
- if not CONF.service_available.nova:
- msg = ("%s skipped as Nova is not available" % cls.__name__)
- raise cls.skipException(msg)
- if not CONF.cli.has_manage:
- msg = ("%s skipped as *-manage commands not available"
- % cls.__name__)
- raise cls.skipException(msg)
- super(SimpleReadOnlyNovaManageTest, cls).resource_setup()
-
- def nova_manage(self, *args, **kwargs):
- return self.clients.nova_manage(*args, **kwargs)
-
- def test_admin_fake_action(self):
- self.assertRaises(exceptions.CommandFailed,
- self.nova_manage,
- 'this-does-nova-exist')
-
- # NOTE(jogo): Commands in order listed in 'nova-manage -h'
-
- # test flags
- def test_help_flag(self):
- self.nova_manage('', '-h')
-
- def test_version_flag(self):
- # Bug 1159957: nova-manage --version writes to stderr
- self.assertNotEqual("", self.nova_manage('', '--version',
- merge_stderr=True))
- self.assertEqual(self.nova_manage('version'),
- self.nova_manage('', '--version', merge_stderr=True))
-
- def test_debug_flag(self):
- self.assertNotEqual("", self.nova_manage('service list',
- '--debug'))
-
- def test_verbose_flag(self):
- self.assertNotEqual("", self.nova_manage('service list',
- '--verbose'))
-
- # test actions
- def test_version(self):
- self.assertNotEqual("", self.nova_manage('version'))
-
- def test_db_sync(self):
- # make sure command doesn't error out
- self.nova_manage('db sync')
-
- def test_db_version(self):
- self.assertNotEqual("", self.nova_manage('db version'))
-
- def test_cell_list(self):
- # make sure command doesn't error out
- self.nova_manage('cell list')
-
- def test_host_list(self):
- # make sure command doesn't error out
- self.nova_manage('host list')
diff --git a/tempest/clients.py b/tempest/clients.py
index de03f1d..e362ac0 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -13,6 +13,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import copy
+
from tempest import auth
from tempest.common import negative_rest_client
from tempest import config
@@ -133,6 +135,21 @@
Top level manager for OpenStack tempest clients
"""
+ default_params = {
+ 'disable_ssl_certificate_validation':
+ CONF.identity.disable_ssl_certificate_validation,
+ 'ca_certs': CONF.identity.ca_certificates_file,
+ 'trace_requests': CONF.debug.trace_requests
+ }
+
+ # NOTE: Tempest uses timeout values of compute API if project specific
+ # timeout values don't exist.
+ default_params_with_timeout_values = {
+ 'build_interval': CONF.compute.build_interval,
+ 'build_timeout': CONF.compute.build_timeout
+ }
+ default_params_with_timeout_values.update(default_params)
+
def __init__(self, credentials=None, interface='json', service=None):
# Set interface and client type first
self.interface = interface
@@ -144,11 +161,24 @@
self._set_volume_clients()
self.baremetal_client = BaremetalClientJSON(self.auth_provider)
- self.network_client = NetworkClientJSON(self.auth_provider)
+ self.network_client = NetworkClientJSON(
+ self.auth_provider,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type=CONF.network.endpoint_type,
+ build_interval=CONF.network.build_interval,
+ build_timeout=CONF.network.build_timeout,
+ **self.default_params)
self.database_flavors_client = DatabaseFlavorsClientJSON(
- self.auth_provider)
+ self.auth_provider,
+ CONF.database.catalog_type,
+ CONF.identity.region,
+ **self.default_params_with_timeout_values)
self.database_versions_client = DatabaseVersionsClientJSON(
- self.auth_provider)
+ self.auth_provider,
+ CONF.database.catalog_type,
+ CONF.identity.region,
+ **self.default_params_with_timeout_values)
self.messaging_client = MessagingClientJSON(self.auth_provider)
if CONF.service_available.ceilometer:
self.telemetry_client = TelemetryClientJSON(
@@ -170,43 +200,77 @@
self.container_client = ContainerClient(self.auth_provider)
self.object_client = ObjectClient(self.auth_provider)
self.orchestration_client = OrchestrationClient(
- self.auth_provider)
+ self.auth_provider,
+ CONF.orchestration.catalog_type,
+ CONF.orchestration.region or CONF.identity.region,
+ endpoint_type=CONF.orchestration.endpoint_type,
+ build_interval=CONF.orchestration.build_interval,
+ build_timeout=CONF.orchestration.build_timeout,
+ **self.default_params)
+
self.ec2api_client = botoclients.APIClientEC2(*ec2_client_args)
self.s3_client = botoclients.ObjectClientS3(*ec2_client_args)
self.data_processing_client = DataProcessingClient(
self.auth_provider)
def _set_compute_clients(self):
- self.agents_client = AgentsClientJSON(self.auth_provider)
- self.networks_client = NetworksClientJSON(self.auth_provider)
- self.migrations_client = MigrationsClientJSON(self.auth_provider)
+ params = {
+ 'service': CONF.compute.catalog_type,
+ 'region': CONF.compute.region or CONF.identity.region,
+ 'endpoint_type': CONF.compute.endpoint_type,
+ 'build_interval': CONF.compute.build_interval,
+ 'build_timeout': CONF.compute.build_timeout
+ }
+ params.update(self.default_params)
+
+ self.agents_client = AgentsClientJSON(self.auth_provider, **params)
+ self.networks_client = NetworksClientJSON(self.auth_provider, **params)
+ self.migrations_client = MigrationsClientJSON(self.auth_provider,
+ **params)
self.security_group_default_rules_client = (
- SecurityGroupDefaultRulesClientJSON(self.auth_provider))
- self.certificates_client = CertificatesClientJSON(self.auth_provider)
- self.servers_client = ServersClientJSON(self.auth_provider)
- self.limits_client = LimitsClientJSON(self.auth_provider)
- self.images_client = ImagesClientJSON(self.auth_provider)
- self.keypairs_client = KeyPairsClientJSON(self.auth_provider)
- self.quotas_client = QuotasClientJSON(self.auth_provider)
- self.quota_classes_client = QuotaClassesClientJSON(self.auth_provider)
- self.flavors_client = FlavorsClientJSON(self.auth_provider)
- self.extensions_client = ExtensionsClientJSON(self.auth_provider)
- self.volumes_extensions_client = VolumesExtensionsClientJSON(
- self.auth_provider)
- self.floating_ips_client = FloatingIPsClientJSON(self.auth_provider)
+ SecurityGroupDefaultRulesClientJSON(self.auth_provider, **params))
+ self.certificates_client = CertificatesClientJSON(self.auth_provider,
+ **params)
+ self.servers_client = ServersClientJSON(self.auth_provider, **params)
+ self.limits_client = LimitsClientJSON(self.auth_provider, **params)
+ self.images_client = ImagesClientJSON(self.auth_provider, **params)
+ self.keypairs_client = KeyPairsClientJSON(self.auth_provider, **params)
+ self.quotas_client = QuotasClientJSON(self.auth_provider, **params)
+ self.quota_classes_client = QuotaClassesClientJSON(self.auth_provider,
+ **params)
+ self.flavors_client = FlavorsClientJSON(self.auth_provider, **params)
+ self.extensions_client = ExtensionsClientJSON(self.auth_provider,
+ **params)
+ self.floating_ips_client = FloatingIPsClientJSON(self.auth_provider,
+ **params)
self.security_groups_client = SecurityGroupsClientJSON(
- self.auth_provider)
- self.interfaces_client = InterfacesClientJSON(self.auth_provider)
- self.fixed_ips_client = FixedIPsClientJSON(self.auth_provider)
+ self.auth_provider, **params)
+ self.interfaces_client = InterfacesClientJSON(self.auth_provider,
+ **params)
+ self.fixed_ips_client = FixedIPsClientJSON(self.auth_provider,
+ **params)
self.availability_zone_client = AvailabilityZoneClientJSON(
- self.auth_provider)
- self.aggregates_client = AggregatesClientJSON(self.auth_provider)
- self.services_client = ServicesClientJSON(self.auth_provider)
- self.tenant_usages_client = TenantUsagesClientJSON(self.auth_provider)
- self.hosts_client = HostsClientJSON(self.auth_provider)
- self.hypervisor_client = HypervisorClientJSON(self.auth_provider)
+ self.auth_provider, **params)
+ self.aggregates_client = AggregatesClientJSON(self.auth_provider,
+ **params)
+ self.services_client = ServicesClientJSON(self.auth_provider, **params)
+ self.tenant_usages_client = TenantUsagesClientJSON(self.auth_provider,
+ **params)
+ self.hosts_client = HostsClientJSON(self.auth_provider, **params)
+ self.hypervisor_client = HypervisorClientJSON(self.auth_provider,
+ **params)
self.instance_usages_audit_log_client = \
- InstanceUsagesAuditLogClientJSON(self.auth_provider)
+ InstanceUsagesAuditLogClientJSON(self.auth_provider, **params)
+
+ # NOTE: The following client needs special timeout values because
+ # the API is a proxy for the other component.
+ params_volume = copy.deepcopy(params)
+ params_volume.update({
+ 'build_interval': CONF.volume.build_interval,
+ 'build_timeout': CONF.volume.build_timeout
+ })
+ self.volumes_extensions_client = VolumesExtensionsClientJSON(
+ self.auth_provider, **params_volume)
def _set_identity_clients(self):
self.identity_client = IdentityClientJSON(self.auth_provider)
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index 2928777..a0bbb70 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -218,7 +218,7 @@
def list(self):
client = self.client
- _, stacks = client.list_stacks()
+ stacks = client.list_stacks()
LOG.debug("List count, %s Stacks" % len(stacks))
return stacks
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 6e1ca7a..e5ffb1b 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -144,21 +144,46 @@
servers = None
def __init__(self, user, pw, tenant):
+ default_params = {
+ 'disable_ssl_certificate_validation':
+ CONF.identity.disable_ssl_certificate_validation,
+ 'ca_certs': CONF.identity.ca_certificates_file,
+ 'trace_requests': CONF.debug.trace_requests
+ }
+ compute_params = {
+ 'service': CONF.compute.catalog_type,
+ 'region': CONF.compute.region or CONF.identity.region,
+ 'endpoint_type': CONF.compute.endpoint_type,
+ 'build_interval': CONF.compute.build_interval,
+ 'build_timeout': CONF.compute.build_timeout
+ }
+ compute_params.update(default_params)
+
_creds = tempest.auth.KeystoneV2Credentials(
username=user,
password=pw,
tenant_name=tenant)
_auth = tempest.auth.KeystoneV2AuthProvider(_creds)
self.identity = identity_client.IdentityClientJSON(_auth)
- self.servers = servers_client.ServersClientJSON(_auth)
+ self.servers = servers_client.ServersClientJSON(_auth,
+ **compute_params)
+ self.flavors = flavors_client.FlavorsClientJSON(_auth,
+ **compute_params)
+ self.secgroups = security_groups_client.SecurityGroupsClientJSON(
+ _auth, **compute_params)
self.objects = object_client.ObjectClient(_auth)
self.containers = container_client.ContainerClient(_auth)
self.images = image_client.ImageClientV2JSON(_auth)
- self.flavors = flavors_client.FlavorsClientJSON(_auth)
self.telemetry = telemetry_client.TelemetryClientJSON(_auth)
- self.secgroups = security_groups_client.SecurityGroupsClientJSON(_auth)
self.volumes = volumes_client.VolumesClientJSON(_auth)
- self.networks = network_client.NetworkClientJSON(_auth)
+ self.networks = network_client.NetworkClientJSON(
+ _auth,
+ CONF.network.catalog_type,
+ CONF.network.region or CONF.identity.region,
+ endpoint_type=CONF.network.endpoint_type,
+ build_interval=CONF.network.build_interval,
+ build_timeout=CONF.network.build_timeout,
+ **default_params)
def load_resources(fname):
diff --git a/tempest/common/glance_http.py b/tempest/common/glance_http.py
index 5f35c85..92ed8f1 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -67,7 +67,7 @@
_kwargs = {'timeout': float(kwargs.get('timeout', 600))}
if scheme == 'https':
- _kwargs['cacert'] = kwargs.get('cacert', None)
+ _kwargs['ca_certs'] = kwargs.get('ca_certs', None)
_kwargs['cert_file'] = kwargs.get('cert_file', None)
_kwargs['key_file'] = kwargs.get('key_file', None)
_kwargs['insecure'] = kwargs.get('insecure', False)
@@ -232,7 +232,7 @@
with native Python 3.3 code.
"""
def __init__(self, host, port=None, key_file=None, cert_file=None,
- cacert=None, timeout=None, insecure=False,
+ ca_certs=None, timeout=None, insecure=False,
ssl_compression=True):
httplib.HTTPSConnection.__init__(self, host, port,
key_file=key_file,
@@ -242,7 +242,7 @@
self.timeout = timeout
self.insecure = insecure
self.ssl_compression = ssl_compression
- self.cacert = cacert
+ self.ca_certs = ca_certs
self.setcontext()
@staticmethod
@@ -326,11 +326,11 @@
msg = 'Unable to load key from "%s" %s' % (self.key_file, e)
raise exc.SSLConfigurationError(msg)
- if self.cacert:
+ if self.ca_certs:
try:
- self.context.load_verify_locations(self.cacert)
+ self.context.load_verify_locations(self.ca_certs)
except Exception as e:
- msg = 'Unable to load CA from "%s"' % (self.cacert, e)
+ msg = 'Unable to load CA from "%s"' % (self.ca_certs, e)
raise exc.SSLConfigurationError(msg)
else:
self.context.set_default_verify_paths()
diff --git a/tempest/common/http.py b/tempest/common/http.py
deleted file mode 100644
index b3793bc..0000000
--- a/tempest/common/http.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# Copyright 2013 Citrix Systems, 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.
-
-import httplib2
-
-
-class ClosingHttp(httplib2.Http):
- def request(self, *args, **kwargs):
- original_headers = kwargs.get('headers', {})
- new_headers = dict(original_headers, connection='close')
- new_kwargs = dict(kwargs, headers=new_headers)
- return super(ClosingHttp, self).request(*args, **new_kwargs)
diff --git a/tempest/common/negative_rest_client.py b/tempest/common/negative_rest_client.py
index a9ae1c3..d9842e6 100644
--- a/tempest/common/negative_rest_client.py
+++ b/tempest/common/negative_rest_client.py
@@ -15,7 +15,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.common import rest_client
+from tempest_lib.common import rest_client
+
from tempest import config
CONF = config.CONF
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
deleted file mode 100644
index c5696b7..0000000
--- a/tempest/common/rest_client.py
+++ /dev/null
@@ -1,567 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# Copyright 2013 IBM Corp.
-# 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 collections
-import json
-import logging as real_logging
-import re
-import time
-
-import jsonschema
-import six
-
-from tempest.common import http
-from tempest.common.utils import misc as misc_utils
-from tempest import exceptions
-from tempest.openstack.common import log as logging
-
-# redrive rate limited calls at most twice
-MAX_RECURSION_DEPTH = 2
-
-# All the successful HTTP status codes from RFC 7231 & 4918
-HTTP_SUCCESS = (200, 201, 202, 203, 204, 205, 206, 207)
-
-
-class RestClient(object):
-
- TYPE = "json"
-
- LOG = logging.getLogger(__name__)
-
- def __init__(self, auth_provider, service, region,
- endpoint_type='publicURL',
- build_interval=1, build_timeout=60,
- disable_ssl_certificate_validation=False, ca_certs=None,
- trace_requests=''):
- self.auth_provider = auth_provider
- self.service = service
- self.region = region
- self.endpoint_type = endpoint_type
- self.build_interval = build_interval
- self.build_timeout = build_timeout
- self.trace_requests = trace_requests
-
- # The version of the API this client implements
- self.api_version = None
- self._skip_path = False
- self.general_header_lc = set(('cache-control', 'connection',
- 'date', 'pragma', 'trailer',
- 'transfer-encoding', 'via',
- 'warning'))
- self.response_header_lc = set(('accept-ranges', 'age', 'etag',
- 'location', 'proxy-authenticate',
- 'retry-after', 'server',
- 'vary', 'www-authenticate'))
- dscv = disable_ssl_certificate_validation
- self.http_obj = http.ClosingHttp(
- disable_ssl_certificate_validation=dscv, ca_certs=ca_certs)
-
- def _get_type(self):
- return self.TYPE
-
- def get_headers(self, accept_type=None, send_type=None):
- if accept_type is None:
- accept_type = self._get_type()
- if send_type is None:
- send_type = self._get_type()
- return {'Content-Type': 'application/%s' % send_type,
- 'Accept': 'application/%s' % accept_type}
-
- def __str__(self):
- STRING_LIMIT = 80
- str_format = ("service:%s, base_url:%s, "
- "filters: %s, build_interval:%s, build_timeout:%s"
- "\ntoken:%s..., \nheaders:%s...")
- return str_format % (self.service, self.base_url,
- self.filters, self.build_interval,
- self.build_timeout,
- str(self.token)[0:STRING_LIMIT],
- str(self.get_headers())[0:STRING_LIMIT])
-
- @property
- def user(self):
- return self.auth_provider.credentials.username
-
- @property
- def user_id(self):
- return self.auth_provider.credentials.user_id
-
- @property
- def tenant_name(self):
- return self.auth_provider.credentials.tenant_name
-
- @property
- def tenant_id(self):
- return self.auth_provider.credentials.tenant_id
-
- @property
- def password(self):
- return self.auth_provider.credentials.password
-
- @property
- def base_url(self):
- return self.auth_provider.base_url(filters=self.filters)
-
- @property
- def token(self):
- return self.auth_provider.get_token()
-
- @property
- def filters(self):
- _filters = dict(
- service=self.service,
- endpoint_type=self.endpoint_type,
- region=self.region
- )
- if self.api_version is not None:
- _filters['api_version'] = self.api_version
- if self._skip_path:
- _filters['skip_path'] = self._skip_path
- return _filters
-
- def skip_path(self):
- """
- When set, ignore the path part of the base URL from the catalog
- """
- self._skip_path = True
-
- def reset_path(self):
- """
- When reset, use the base URL from the catalog as-is
- """
- self._skip_path = False
-
- @classmethod
- def expected_success(cls, expected_code, read_code):
- assert_msg = ("This function only allowed to use for HTTP status"
- "codes which explicitly defined in the RFC 7231 & 4918."
- "{0} is not a defined Success Code!"
- ).format(expected_code)
- if isinstance(expected_code, list):
- for code in expected_code:
- assert code in HTTP_SUCCESS, assert_msg
- else:
- assert expected_code in HTTP_SUCCESS, assert_msg
-
- # NOTE(afazekas): the http status code above 400 is processed by
- # the _error_checker method
- if read_code < 400:
- pattern = """Unexpected http success status code {0},
- The expected status code is {1}"""
- if ((not isinstance(expected_code, list) and
- (read_code != expected_code)) or
- (isinstance(expected_code, list) and
- (read_code not in expected_code))):
- details = pattern.format(read_code, expected_code)
- raise exceptions.InvalidHttpSuccessCode(details)
-
- def post(self, url, body, headers=None, extra_headers=False):
- return self.request('POST', url, extra_headers, headers, body)
-
- def get(self, url, headers=None, extra_headers=False):
- return self.request('GET', url, extra_headers, headers)
-
- def delete(self, url, headers=None, body=None, extra_headers=False):
- return self.request('DELETE', url, extra_headers, headers, body)
-
- def patch(self, url, body, headers=None, extra_headers=False):
- return self.request('PATCH', url, extra_headers, headers, body)
-
- def put(self, url, body, headers=None, extra_headers=False):
- return self.request('PUT', url, extra_headers, headers, body)
-
- def head(self, url, headers=None, extra_headers=False):
- return self.request('HEAD', url, extra_headers, headers)
-
- def copy(self, url, headers=None, extra_headers=False):
- return self.request('COPY', url, extra_headers, headers)
-
- def get_versions(self):
- resp, body = self.get('')
- body = self._parse_resp(body)
- versions = map(lambda x: x['id'], body)
- return resp, versions
-
- def _get_request_id(self, resp):
- for i in ('x-openstack-request-id', 'x-compute-request-id'):
- if i in resp:
- return resp[i]
- return ""
-
- def _safe_body(self, body, maxlen=4096):
- # convert a structure into a string safely
- try:
- text = six.text_type(body)
- except UnicodeDecodeError:
- # if this isn't actually text, return marker that
- return "<BinaryData: removed>"
- if len(text) > maxlen:
- return text[:maxlen]
- else:
- return text
-
- def _log_request_start(self, method, req_url, req_headers=None,
- req_body=None):
- if req_headers is None:
- req_headers = {}
- caller_name = misc_utils.find_test_caller()
- if self.trace_requests and re.search(self.trace_requests, caller_name):
- self.LOG.debug('Starting Request (%s): %s %s' %
- (caller_name, method, req_url))
-
- def _log_request_full(self, method, req_url, resp,
- secs="", req_headers=None,
- req_body=None, resp_body=None,
- caller_name=None, extra=None):
- if 'X-Auth-Token' in req_headers:
- req_headers['X-Auth-Token'] = '<omitted>'
- log_fmt = """Request (%s): %s %s %s%s
- Request - Headers: %s
- Body: %s
- Response - Headers: %s
- Body: %s"""
-
- self.LOG.debug(
- log_fmt % (
- caller_name,
- resp['status'],
- method,
- req_url,
- secs,
- str(req_headers),
- self._safe_body(req_body),
- str(resp),
- self._safe_body(resp_body)),
- extra=extra)
-
- def _log_request(self, method, req_url, resp,
- secs="", req_headers=None,
- req_body=None, resp_body=None):
- if req_headers is None:
- req_headers = {}
- # if we have the request id, put it in the right part of the log
- extra = dict(request_id=self._get_request_id(resp))
- # NOTE(sdague): while we still have 6 callers to this function
- # we're going to just provide work around on who is actually
- # providing timings by gracefully adding no content if they don't.
- # Once we're down to 1 caller, clean this up.
- caller_name = misc_utils.find_test_caller()
- if secs:
- secs = " %.3fs" % secs
- if not self.LOG.isEnabledFor(real_logging.DEBUG):
- self.LOG.info(
- 'Request (%s): %s %s %s%s' % (
- caller_name,
- resp['status'],
- method,
- req_url,
- secs),
- extra=extra)
-
- # Also look everything at DEBUG if you want to filter this
- # out, don't run at debug.
- self._log_request_full(method, req_url, resp, secs, req_headers,
- req_body, resp_body, caller_name, extra)
-
- def _parse_resp(self, body):
- body = json.loads(body)
-
- # We assume, that if the first value of the deserialized body's
- # item set is a dict or a list, that we just return the first value
- # of deserialized body.
- # Essentially "cutting out" the first placeholder element in a body
- # that looks like this:
- #
- # {
- # "users": [
- # ...
- # ]
- # }
- try:
- # Ensure there are not more than one top-level keys
- if len(body.keys()) > 1:
- return body
- # Just return the "wrapped" element
- first_key, first_item = six.next(six.iteritems(body))
- if isinstance(first_item, (dict, list)):
- return first_item
- except (ValueError, IndexError):
- pass
- return body
-
- def response_checker(self, method, resp, resp_body):
- if (resp.status in set((204, 205, 304)) or resp.status < 200 or
- method.upper() == 'HEAD') and resp_body:
- raise exceptions.ResponseWithNonEmptyBody(status=resp.status)
- # NOTE(afazekas):
- # If the HTTP Status Code is 205
- # 'The response MUST NOT include an entity.'
- # A HTTP entity has an entity-body and an 'entity-header'.
- # In the HTTP response specification (Section 6) the 'entity-header'
- # 'generic-header' and 'response-header' are in OR relation.
- # All headers not in the above two group are considered as entity
- # header in every interpretation.
-
- if (resp.status == 205 and
- 0 != len(set(resp.keys()) - set(('status',)) -
- self.response_header_lc - self.general_header_lc)):
- raise exceptions.ResponseWithEntity()
- # NOTE(afazekas)
- # Now the swift sometimes (delete not empty container)
- # returns with non json error response, we can create new rest class
- # for swift.
- # Usually RFC2616 says error responses SHOULD contain an explanation.
- # The warning is normal for SHOULD/SHOULD NOT case
-
- # Likely it will cause an error
- if method != 'HEAD' and not resp_body and resp.status >= 400:
- self.LOG.warning("status >= 400 response with empty body")
-
- def _request(self, method, url, headers=None, body=None):
- """A simple HTTP request interface."""
- # Authenticate the request with the auth provider
- req_url, req_headers, req_body = self.auth_provider.auth_request(
- method, url, headers, body, self.filters)
-
- # Do the actual request, and time it
- start = time.time()
- self._log_request_start(method, req_url)
- resp, resp_body = self.raw_request(
- req_url, method, headers=req_headers, body=req_body)
- end = time.time()
- self._log_request(method, req_url, resp, secs=(end - start),
- req_headers=req_headers, req_body=req_body,
- resp_body=resp_body)
-
- # Verify HTTP response codes
- self.response_checker(method, resp, resp_body)
-
- return resp, resp_body
-
- def raw_request(self, url, method, headers=None, body=None):
- if headers is None:
- headers = self.get_headers()
- return self.http_obj.request(url, method,
- headers=headers, body=body)
-
- def request(self, method, url, extra_headers=False, headers=None,
- body=None):
- # if extra_headers is True
- # default headers would be added to headers
- retry = 0
-
- if headers is None:
- # NOTE(vponomaryov): if some client do not need headers,
- # it should explicitly pass empty dict
- headers = self.get_headers()
- elif extra_headers:
- try:
- headers = headers.copy()
- headers.update(self.get_headers())
- except (ValueError, TypeError):
- headers = self.get_headers()
-
- resp, resp_body = self._request(method, url,
- headers=headers, body=body)
-
- while (resp.status == 413 and
- 'retry-after' in resp and
- not self.is_absolute_limit(
- resp, self._parse_resp(resp_body)) and
- retry < MAX_RECURSION_DEPTH):
- retry += 1
- delay = int(resp['retry-after'])
- time.sleep(delay)
- resp, resp_body = self._request(method, url,
- headers=headers, body=body)
- self._error_checker(method, url, headers, body,
- resp, resp_body)
- return resp, resp_body
-
- def _error_checker(self, method, url,
- headers, body, resp, resp_body):
-
- # NOTE(mtreinish): Check for httplib response from glance_http. The
- # object can't be used here because importing httplib breaks httplib2.
- # If another object from a class not imported were passed here as
- # resp this could possibly fail
- if str(type(resp)) == "<type 'instance'>":
- ctype = resp.getheader('content-type')
- else:
- try:
- ctype = resp['content-type']
- # NOTE(mtreinish): Keystone delete user responses doesn't have a
- # content-type header. (They don't have a body) So just pretend it
- # is set.
- except KeyError:
- ctype = 'application/json'
-
- # It is not an error response
- if resp.status < 400:
- return
-
- JSON_ENC = ['application/json', 'application/json; charset=utf-8']
- # NOTE(mtreinish): This is for compatibility with Glance and swift
- # APIs. These are the return content types that Glance api v1
- # (and occasionally swift) are using.
- TXT_ENC = ['text/plain', 'text/html', 'text/html; charset=utf-8',
- 'text/plain; charset=utf-8']
-
- if ctype.lower() in JSON_ENC:
- parse_resp = True
- elif ctype.lower() in TXT_ENC:
- parse_resp = False
- else:
- raise exceptions.InvalidContentType(str(resp.status))
-
- if resp.status == 401 or resp.status == 403:
- raise exceptions.Unauthorized(resp_body)
-
- if resp.status == 404:
- raise exceptions.NotFound(resp_body)
-
- if resp.status == 400:
- if parse_resp:
- resp_body = self._parse_resp(resp_body)
- raise exceptions.BadRequest(resp_body)
-
- if resp.status == 409:
- if parse_resp:
- resp_body = self._parse_resp(resp_body)
- raise exceptions.Conflict(resp_body)
-
- if resp.status == 413:
- if parse_resp:
- resp_body = self._parse_resp(resp_body)
- if self.is_absolute_limit(resp, resp_body):
- raise exceptions.OverLimit(resp_body)
- else:
- raise exceptions.RateLimitExceeded(resp_body)
-
- if resp.status == 415:
- if parse_resp:
- resp_body = self._parse_resp(resp_body)
- raise exceptions.InvalidContentType(resp_body)
-
- if resp.status == 422:
- if parse_resp:
- resp_body = self._parse_resp(resp_body)
- raise exceptions.UnprocessableEntity(resp_body)
-
- if resp.status in (500, 501):
- message = resp_body
- if parse_resp:
- try:
- resp_body = self._parse_resp(resp_body)
- except ValueError:
- # If response body is a non-json string message.
- # Use resp_body as is and raise InvalidResponseBody
- # exception.
- raise exceptions.InvalidHTTPResponseBody(message)
- else:
- if isinstance(resp_body, dict):
- # I'm seeing both computeFault
- # and cloudServersFault come back.
- # Will file a bug to fix, but leave as is for now.
- if 'cloudServersFault' in resp_body:
- message = resp_body['cloudServersFault']['message']
- elif 'computeFault' in resp_body:
- message = resp_body['computeFault']['message']
- elif 'error' in resp_body:
- message = resp_body['error']['message']
- elif 'message' in resp_body:
- message = resp_body['message']
- else:
- message = resp_body
-
- if resp.status == 501:
- raise exceptions.NotImplemented(message)
- else:
- raise exceptions.ServerFault(message)
-
- if resp.status >= 400:
- raise exceptions.UnexpectedResponseCode(str(resp.status))
-
- def is_absolute_limit(self, resp, resp_body):
- if (not isinstance(resp_body, collections.Mapping) or
- 'retry-after' not in resp):
- return True
- over_limit = resp_body.get('overLimit', None)
- if not over_limit:
- return True
- return 'exceed' in over_limit.get('message', 'blabla')
-
- def wait_for_resource_deletion(self, id):
- """Waits for a resource to be deleted."""
- start_time = int(time.time())
- while True:
- if self.is_resource_deleted(id):
- return
- if int(time.time()) - start_time >= self.build_timeout:
- message = ('Failed to delete %(resource_type)s %(id)s within '
- 'the required time (%(timeout)s s).' %
- {'resource_type': self.resource_type, 'id': id,
- 'timeout': self.build_timeout})
- caller = misc_utils.find_test_caller()
- if caller:
- message = '(%s) %s' % (caller, message)
- raise exceptions.TimeoutException(message)
- time.sleep(self.build_interval)
-
- def is_resource_deleted(self, id):
- """
- Subclasses override with specific deletion detection.
- """
- message = ('"%s" does not implement is_resource_deleted'
- % self.__class__.__name__)
- raise NotImplementedError(message)
-
- @property
- def resource_type(self):
- """Returns the primary type of resource this client works with."""
- return 'resource'
-
- @classmethod
- def validate_response(cls, schema, resp, body):
- # Only check the response if the status code is a success code
- # TODO(cyeoh): Eventually we should be able to verify that a failure
- # code if it exists is something that we expect. This is explicitly
- # declared in the V3 API and so we should be able to export this in
- # the response schema. For now we'll ignore it.
- if resp.status in HTTP_SUCCESS:
- cls.expected_success(schema['status_code'], resp.status)
-
- # Check the body of a response
- body_schema = schema.get('response_body')
- if body_schema:
- try:
- jsonschema.validate(body, body_schema)
- except jsonschema.ValidationError as ex:
- msg = ("HTTP response body is invalid (%s)") % ex
- raise exceptions.InvalidHTTPResponseBody(msg)
- else:
- if body:
- msg = ("HTTP response body should not exist (%s)") % body
- raise exceptions.InvalidHTTPResponseBody(msg)
-
- # Check the header of a response
- header_schema = schema.get('response_header')
- if header_schema:
- try:
- jsonschema.validate(resp, header_schema)
- except jsonschema.ValidationError as ex:
- msg = ("HTTP response header is invalid (%s)") % ex
- raise exceptions.InvalidHTTPResponseHeader(msg)
diff --git a/tempest/common/service_client.py b/tempest/common/service_client.py
index c32a7d0..45a07f1 100644
--- a/tempest/common/service_client.py
+++ b/tempest/common/service_client.py
@@ -12,8 +12,11 @@
# License for the specific language governing permissions and limitations
# under the License.
-from tempest.common import rest_client
+from tempest_lib.common import rest_client
+from tempest_lib import exceptions as lib_exceptions
+
from tempest import config
+from tempest import exceptions
CONF = config.CONF
@@ -21,13 +24,21 @@
class ServiceClient(rest_client.RestClient):
def __init__(self, auth_provider, service, region,
- endpoint_type=None, build_interval=None, build_timeout=None):
+ endpoint_type=None, build_interval=None, build_timeout=None,
+ disable_ssl_certificate_validation=None, ca_certs=None,
+ trace_requests=None):
+
+ # TODO(oomichi): This params setting should be removed after all
+ # service clients pass these values, and we can make ServiceClient
+ # free from CONF values.
+ dscv = (disable_ssl_certificate_validation or
+ CONF.identity.disable_ssl_certificate_validation)
params = {
- 'disable_ssl_certificate_validation':
- CONF.identity.disable_ssl_certificate_validation,
- 'ca_certs': CONF.identity.ca_certificates_file,
- 'trace_requests': CONF.debug.trace_requests
+ 'disable_ssl_certificate_validation': dscv,
+ 'ca_certs': ca_certs or CONF.identity.ca_certificates_file,
+ 'trace_requests': trace_requests or CONF.debug.trace_requests
}
+
if endpoint_type is not None:
params.update({'endpoint_type': endpoint_type})
if build_interval is not None:
@@ -37,6 +48,42 @@
super(ServiceClient, self).__init__(auth_provider, service, region,
**params)
+ def request(self, method, url, extra_headers=False, headers=None,
+ body=None):
+ # TODO(oomichi): This translation is just for avoiding a single
+ # huge patch to migrate rest_client module to tempest-lib.
+ # Ideally(in the future), we need to remove this translation and
+ # replace each API tests with tempest-lib's exceptions.
+ try:
+ return super(ServiceClient, self).request(
+ method, url,
+ extra_headers=extra_headers,
+ headers=headers, body=body)
+ except lib_exceptions.Unauthorized as ex:
+ raise exceptions.Unauthorized(ex)
+ except lib_exceptions.NotFound as ex:
+ raise exceptions.NotFound(ex)
+ except lib_exceptions.BadRequest as ex:
+ raise exceptions.BadRequest(ex)
+ except lib_exceptions.Conflict as ex:
+ raise exceptions.Conflict(ex)
+ except lib_exceptions.OverLimit as ex:
+ raise exceptions.OverLimit(ex)
+ except lib_exceptions.RateLimitExceeded as ex:
+ raise exceptions.RateLimitExceeded(ex)
+ except lib_exceptions.InvalidContentType as ex:
+ raise exceptions.InvalidContentType(ex)
+ except lib_exceptions.UnprocessableEntity as ex:
+ raise exceptions.UnprocessableEntity(ex)
+ except lib_exceptions.InvalidHTTPResponseBody as ex:
+ raise exceptions.InvalidHTTPResponseBody(ex)
+ except lib_exceptions.NotImplemented as ex:
+ raise exceptions.NotImplemented(ex)
+ except lib_exceptions.ServerFault as ex:
+ raise exceptions.ServerFault(ex)
+ except lib_exceptions.UnexpectedResponseCode as ex:
+ raise exceptions.UnexpectedResponseCode(ex)
+
class ResponseBody(dict):
"""Class that wraps an http response and dict body into a single value.
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 3066667..c77c81e 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -101,12 +101,12 @@
The client should have a get_image(image_id) method to get the image.
The client should also have build_interval and build_timeout attributes.
"""
- resp, image = client.get_image(image_id)
+ image = client.get_image(image_id)
start = int(time.time())
while image['status'] != status:
time.sleep(client.build_interval)
- resp, image = client.get_image(image_id)
+ image = client.get_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 dd693e5..1b6ec62 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -743,6 +743,17 @@
]
+data_processing_feature_group = cfg.OptGroup(
+ name="data_processing-feature-enabled",
+ title="Enabled Data Processing features")
+
+DataProcessingFeaturesGroup = [
+ cfg.ListOpt('plugins',
+ default=["vanilla", "hdp"],
+ help="List of enabled data processing plugins")
+]
+
+
boto_group = cfg.OptGroup(name='boto',
title='EC2/S3 options')
BotoGroup = [
@@ -1050,6 +1061,7 @@
(telemetry_group, TelemetryGroup),
(dashboard_group, DashboardGroup),
(data_processing_group, DataProcessingGroup),
+ (data_processing_feature_group, DataProcessingFeaturesGroup),
(boto_group, BotoGroup),
(stress_group, StressGroup),
(scenario_group, ScenarioGroup),
@@ -1120,6 +1132,8 @@
self.telemetry = cfg.CONF.telemetry
self.dashboard = cfg.CONF.dashboard
self.data_processing = cfg.CONF.data_processing
+ self.data_processing_feature_enabled = cfg.CONF[
+ 'data_processing-feature-enabled']
self.boto = cfg.CONF.boto
self.stress = cfg.CONF.stress
self.scenario = cfg.CONF.scenario
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 9b2b4d4..86f488a 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -51,10 +51,6 @@
pass
-class RFCViolation(RestClientException):
- message = "RFC Violation"
-
-
class InvalidConfiguration(TempestException):
message = "Invalid Configuration"
@@ -63,18 +59,6 @@
message = "Invalid Credentials"
-class InvalidHttpSuccessCode(RestClientException):
- message = "The success code is different than the expected one"
-
-
-class NotFound(RestClientException):
- message = "Object not found"
-
-
-class Unauthorized(RestClientException):
- message = 'Unauthorized'
-
-
class InvalidServiceTag(TempestException):
message = "Invalid service tag"
@@ -123,15 +107,7 @@
"'%(resource_status_reason)s'")
-class BadRequest(RestClientException):
- message = "Bad request"
-
-
-class UnprocessableEntity(RestClientException):
- message = "Unprocessable entity"
-
-
-class AuthenticationFailure(RestClientException):
+class AuthenticationFailure(TempestException):
message = ("Authentication with user %(user)s and password "
"%(password)s failed auth using tenant %(tenant)s.")
@@ -140,22 +116,6 @@
message = "Endpoint not found"
-class RateLimitExceeded(RestClientException):
- message = "Rate limit exceeded"
-
-
-class OverLimit(RestClientException):
- message = "Quota exceeded"
-
-
-class ServerFault(RestClientException):
- message = "Got server fault"
-
-
-class NotImplemented(RestClientException):
- message = "Got NotImplemented error"
-
-
class ImageFault(TempestException):
message = "Got image fault"
@@ -164,10 +124,6 @@
message = "Got identity error"
-class Conflict(RestClientException):
- message = "An object with that identifier already exists"
-
-
class SSHTimeout(TempestException):
message = ("Connection to the %(host)s via SSH timed out.\n"
"User: %(user)s, Password: %(password)s")
@@ -187,6 +143,50 @@
message = "%(num)d cleanUp operation failed"
+class RFCViolation(RestClientException):
+ message = "RFC Violation"
+
+
+class InvalidHttpSuccessCode(RestClientException):
+ message = "The success code is different than the expected one"
+
+
+class NotFound(RestClientException):
+ message = "Object not found"
+
+
+class Unauthorized(RestClientException):
+ message = 'Unauthorized'
+
+
+class BadRequest(RestClientException):
+ message = "Bad request"
+
+
+class UnprocessableEntity(RestClientException):
+ message = "Unprocessable entity"
+
+
+class RateLimitExceeded(RestClientException):
+ message = "Rate limit exceeded"
+
+
+class OverLimit(RestClientException):
+ message = "Quota exceeded"
+
+
+class ServerFault(RestClientException):
+ message = "Got server fault"
+
+
+class NotImplemented(RestClientException):
+ message = "Got NotImplemented error"
+
+
+class Conflict(RestClientException):
+ message = "An object with that identifier already exists"
+
+
class ResponseWithNonEmptyBody(RFCViolation):
message = ("RFC Violation! Response with %(status)d HTTP Status Code "
"MUST NOT have a body")
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 1fdd26a..5b092c3 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -399,8 +399,8 @@
if name is None:
name = data_utils.rand_name('scenario-snapshot-')
LOG.debug("Creating a snapshot image for server: %s", server['name'])
- resp, image = _images_client.create_image(server['id'], name)
- image_id = resp['location'].split('images/')[1]
+ image = _images_client.create_image(server['id'], name)
+ image_id = image.response['location'].split('images/')[1]
_image_client.wait_for_image_status(image_id, 'active')
self.addCleanup_with_wait(
waiter_callable=_image_client.wait_for_resource_deletion,
@@ -789,7 +789,8 @@
tenant_id=tenant_id)
# Add rules to the security group
- rules = self._create_loginable_secgroup_rule(secgroup=secgroup)
+ rules = self._create_loginable_secgroup_rule(client=client,
+ secgroup=secgroup)
for rule in rules:
self.assertEqual(tenant_id, rule.tenant_id)
self.assertEqual(secgroup.id, rule.security_group_id)
diff --git a/tempest/scenario/orchestration/test_server_cfn_init.py b/tempest/scenario/orchestration/test_server_cfn_init.py
index f09f00c..18b759e 100644
--- a/tempest/scenario/orchestration/test_server_cfn_init.py
+++ b/tempest/scenario/orchestration/test_server_cfn_init.py
@@ -52,13 +52,13 @@
# create the stack
self.template = self._load_template(__file__, self.template_name)
- _, stack = self.client.create_stack(
+ stack = self.client.create_stack(
name=self.stack_name,
template=self.template,
parameters=self.parameters)
stack = stack['stack']
- _, self.stack = self.client.get_stack(stack['id'])
+ self.stack = self.client.get_stack(stack['id'])
self.stack_identifier = '%s/%s' % (self.stack_name, self.stack['id'])
self.addCleanup(self.delete_wrapper,
self.orchestration_client.delete_stack,
@@ -77,7 +77,7 @@
self.client.wait_for_resource_status(
sid, 'SmokeServer', 'CREATE_COMPLETE')
- _, server_resource = self.client.get_resource(sid, 'SmokeServer')
+ server_resource = self.client.get_resource(sid, 'SmokeServer')
server_id = server_resource['physical_resource_id']
_, server = self.servers_client.get_server(server_id)
server_ip =\
@@ -104,7 +104,7 @@
self.client.wait_for_stack_status(sid, 'CREATE_COMPLETE')
- _, stack = self.client.get_stack(sid)
+ stack = self.client.get_stack(sid)
# This is an assert of great significance, as it means the following
# has happened:
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 2cfec14..ebc6b15 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -436,6 +436,7 @@
act_serv=servers,
trgt_serv=dns_servers))
+ @test.skip_because(bug="1412325")
@testtools.skipUnless(CONF.scenario.dhcp_client,
"DHCP client is not available.")
@test.attr(type='smoke')
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index c584a6e..910fd79 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -66,7 +66,7 @@
def _create_snapshot_from_volume(self, vol_id):
snap_name = data_utils.rand_name('snapshot')
- _, snap = self.snapshots_client.create_snapshot(
+ snap = self.snapshots_client.create_snapshot(
volume_id=vol_id,
force=True,
display_name=snap_name)
diff --git a/tempest/scenario/utils.py b/tempest/scenario/utils.py
index e6624a3..7967949 100644
--- a/tempest/scenario/utils.py
+++ b/tempest/scenario/utils.py
@@ -46,7 +46,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.get_image(image_id)
for regex, user in self.ssh_users:
# First match wins
if re.match(regex, _image['name']) is not None:
@@ -59,14 +59,14 @@
string=str(image['name']))
def is_sshable_image(self, image_id):
- _, _image = self.images_client.get_image(image_id)
+ _image = self.images_client.get_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.get_image(image_id)
_, _flavor = self.flavors_client.get_flavor_details(flavor_id)
return self._is_flavor_enough(_flavor, _image)
@@ -120,7 +120,7 @@
if not CONF.service_available.glance:
return []
if not hasattr(self, '_scenario_images'):
- _, images = self.images_client.list_images()
+ images = self.images_client.list_images()
self._scenario_images = [
(self._normalize_name(i['name']), dict(image_ref=i['id']))
for i in images if re.search(self.image_pattern,
diff --git a/tempest/services/baremetal/v1/base_v1.py b/tempest/services/baremetal/v1/base_v1.py
index 9359808..9435dbf 100644
--- a/tempest/services/baremetal/v1/base_v1.py
+++ b/tempest/services/baremetal/v1/base_v1.py
@@ -114,6 +114,19 @@
"""
return self._show_request('ports', uuid)
+ @base.handle_errors
+ def show_port_by_address(self, address):
+ """
+ Gets a specific port by address.
+
+ :param address: MAC address of the port.
+ :return: Serialized port as a dictionary.
+
+ """
+ uri = '/ports/detail?address=%s' % address
+
+ return self._show_request('ports', uuid=None, uri=uri)
+
def show_driver(self, driver_name):
"""
Gets a specific driver.
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index 95d7880..e17495f 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -18,10 +18,9 @@
from tempest.api_schema.response.compute import agents as common_schema
from tempest.api_schema.response.compute.v2 import agents as schema
from tempest.common import service_client
-from tempest.services.compute.json import base
-class AgentsClientJSON(base.ComputeClient):
+class AgentsClientJSON(service_client.ServiceClient):
"""
Tests Agents API
"""
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 47dd401..94ea713 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -19,10 +19,9 @@
from tempest.api_schema.response.compute.v2 import aggregates as v2_schema
from tempest.common import service_client
from tempest import exceptions
-from tempest.services.compute.json import base
-class AggregatesClientJSON(base.ComputeClient):
+class AggregatesClientJSON(service_client.ServiceClient):
def list_aggregates(self):
"""Get aggregate list."""
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index b8bda68..e37c9d9 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -16,10 +16,10 @@
import json
from tempest.api_schema.response.compute.v2 import availability_zone as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class AvailabilityZoneClientJSON(base.ComputeClient):
+class AvailabilityZoneClientJSON(service_client.ServiceClient):
def get_availability_zone_list(self):
resp, body = self.get('os-availability-zone')
diff --git a/tempest/services/compute/json/base.py b/tempest/services/compute/json/base.py
deleted file mode 100644
index ae44ffb..0000000
--- a/tempest/services/compute/json/base.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2014 NEC Corporation. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from tempest.common import service_client
-from tempest import config
-
-CONF = config.CONF
-
-
-class ComputeClient(service_client.ServiceClient):
- """
- Base compute client class
- """
-
- def __init__(self, auth_provider,
- build_interval=None, build_timeout=None):
- if build_interval is None:
- build_interval = CONF.compute.build_interval
- if build_timeout is None:
- build_timeout = CONF.compute.build_timeout
-
- super(ComputeClient, self).__init__(
- auth_provider,
- CONF.compute.catalog_type,
- CONF.compute.region or CONF.identity.region,
- endpoint_type=CONF.compute.endpoint_type,
- build_interval=build_interval,
- build_timeout=build_timeout)
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index 123f0b9..b705c37 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -17,10 +17,10 @@
from tempest.api_schema.response.compute import certificates as schema
from tempest.api_schema.response.compute.v2 import certificates as v2schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class CertificatesClientJSON(base.ComputeClient):
+class CertificatesClientJSON(service_client.ServiceClient):
def get_certificate(self, id):
url = "os-certificates/%s" % (id)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index 69ad7c0..d3148b4 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -16,10 +16,10 @@
import json
from tempest.api_schema.response.compute.v2 import extensions as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class ExtensionsClientJSON(base.ComputeClient):
+class ExtensionsClientJSON(service_client.ServiceClient):
def list_extensions(self):
url = 'extensions'
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index 8fd24b6..5797c16 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -16,10 +16,10 @@
import json
from tempest.api_schema.response.compute.v2 import fixed_ips as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class FixedIPsClientJSON(base.ComputeClient):
+class FixedIPsClientJSON(service_client.ServiceClient):
def get_fixed_ip_details(self, fixed_ip):
url = "os-fixed-ips/%s" % (fixed_ip)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 6276d3c..b42ea40 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -21,10 +21,10 @@
from tempest.api_schema.response.compute import flavors_extra_specs \
as schema_extra_specs
from tempest.api_schema.response.compute.v2 import flavors as v2schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class FlavorsClientJSON(base.ComputeClient):
+class FlavorsClientJSON(service_client.ServiceClient):
def list_flavors(self, params=None):
url = 'flavors'
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 788b4d2..9c586e3 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -17,11 +17,11 @@
import urllib
from tempest.api_schema.response.compute.v2 import floating_ips as schema
+from tempest.common import service_client
from tempest import exceptions
-from tempest.services.compute.json import base
-class FloatingIPsClientJSON(base.ComputeClient):
+class FloatingIPsClientJSON(service_client.ServiceClient):
def list_floating_ips(self, params=None):
"""Returns a list of all floating IPs filtered by any parameters."""
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index f4e1f12..b06378b 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -18,10 +18,9 @@
from tempest.api_schema.response.compute import hosts as schema
from tempest.api_schema.response.compute.v2 import hosts as v2_schema
from tempest.common import service_client
-from tempest.services.compute.json import base
-class HostsClientJSON(base.ComputeClient):
+class HostsClientJSON(service_client.ServiceClient):
def list_hosts(self, params=None):
"""Lists all hosts."""
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 37be874..380b5ce 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -18,10 +18,9 @@
from tempest.api_schema.response.compute import hypervisors as common_schema
from tempest.api_schema.response.compute.v2 import hypervisors as v2schema
from tempest.common import service_client
-from tempest.services.compute.json import base
-class HypervisorClientJSON(base.ComputeClient):
+class HypervisorClientJSON(service_client.ServiceClient):
def get_hypervisor_list(self):
"""List hypervisors information."""
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index a4cfe57..a5755da 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -17,12 +17,12 @@
import urllib
from tempest.api_schema.response.compute.v2 import images as schema
+from tempest.common import service_client
from tempest.common import waiters
from tempest import exceptions
-from tempest.services.compute.json import base
-class ImagesClientJSON(base.ComputeClient):
+class ImagesClientJSON(service_client.ServiceClient):
def create_image(self, server_id, name, meta=None):
"""Creates an image of the original server."""
@@ -40,7 +40,7 @@
resp, body = self.post('servers/%s/action' % str(server_id),
post_body)
self.validate_response(schema.create_image, resp, body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def list_images(self, params=None):
"""Returns a list of all images filtered by any parameters."""
@@ -51,7 +51,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_images, resp, body)
- return resp, body['images']
+ return service_client.ResponseBodyList(resp, body['images'])
def list_images_with_detail(self, params=None):
"""Returns a detailed list of images filtered by any parameters."""
@@ -62,7 +62,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_images_details, resp, body)
- return resp, body['images']
+ return service_client.ResponseBodyList(resp, body['images'])
def get_image(self, image_id):
"""Returns the details of a single image."""
@@ -70,13 +70,13 @@
self.expected_success(200, resp.status)
body = json.loads(body)
self.validate_response(schema.get_image, resp, body)
- return resp, body['image']
+ return service_client.ResponseBody(resp, body['image'])
def delete_image(self, image_id):
"""Deletes the provided image."""
resp, body = self.delete("images/%s" % str(image_id))
self.validate_response(schema.delete, resp, body)
- return 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."""
@@ -87,7 +87,7 @@
resp, body = self.get("images/%s/metadata" % str(image_id))
body = json.loads(body)
self.validate_response(schema.image_metadata, resp, body)
- return resp, body['metadata']
+ return service_client.ResponseBody(resp, body['metadata'])
def set_image_metadata(self, image_id, meta):
"""Sets the metadata for an image."""
@@ -95,7 +95,7 @@
resp, body = self.put('images/%s/metadata' % str(image_id), post_body)
body = json.loads(body)
self.validate_response(schema.image_metadata, resp, body)
- return resp, body['metadata']
+ return service_client.ResponseBody(resp, body['metadata'])
def update_image_metadata(self, image_id, meta):
"""Updates the metadata for an image."""
@@ -103,14 +103,14 @@
resp, body = self.post('images/%s/metadata' % str(image_id), post_body)
body = json.loads(body)
self.validate_response(schema.image_metadata, resp, body)
- return resp, body['metadata']
+ return service_client.ResponseBody(resp, body['metadata'])
def get_image_metadata_item(self, image_id, key):
"""Returns the value for a specific image metadata key."""
resp, body = self.get("images/%s/metadata/%s" % (str(image_id), key))
body = json.loads(body)
self.validate_response(schema.image_meta_item, resp, body)
- return resp, body['meta']
+ return service_client.ResponseBody(resp, body['meta'])
def set_image_metadata_item(self, image_id, key, meta):
"""Sets the value for a specific image metadata key."""
@@ -119,14 +119,14 @@
post_body)
body = json.loads(body)
self.validate_response(schema.image_meta_item, resp, body)
- return resp, body['meta']
+ return service_client.ResponseBody(resp, body['meta'])
def delete_image_metadata_item(self, image_id, key):
"""Deletes a single image metadata key/value pair."""
resp, body = self.delete("images/%s/metadata/%s" %
(str(image_id), key))
self.validate_response(schema.delete, resp, body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def is_resource_deleted(self, id):
try:
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index f79c3de..80d7334 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -17,10 +17,10 @@
from tempest.api_schema.response.compute.v2 import instance_usage_audit_logs \
as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class InstanceUsagesAuditLogClientJSON(base.ComputeClient):
+class InstanceUsagesAuditLogClientJSON(service_client.ServiceClient):
def list_instance_usage_audit_logs(self):
url = 'os-instance_usage_audit_log'
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index f1e2660..595b23c 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -19,11 +19,11 @@
from tempest.api_schema.response.compute import interfaces as common_schema
from tempest.api_schema.response.compute import servers as servers_schema
from tempest.api_schema.response.compute.v2 import interfaces as schema
+from tempest.common import service_client
from tempest import exceptions
-from tempest.services.compute.json import base
-class InterfacesClientJSON(base.ComputeClient):
+class InterfacesClientJSON(service_client.ServiceClient):
def list_interfaces(self, server):
resp, body = self.get('servers/%s/os-interface' % server)
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index c4406f5..69dd9ae 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -17,10 +17,10 @@
from tempest.api_schema.response.compute import keypairs as common_schema
from tempest.api_schema.response.compute.v2 import keypairs as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class KeyPairsClientJSON(base.ComputeClient):
+class KeyPairsClientJSON(service_client.ServiceClient):
def list_keypairs(self):
resp, body = self.get("os-keypairs")
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 66a0649..3a725ae 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -16,10 +16,10 @@
import json
from tempest.api_schema.response.compute.v2 import limits as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class LimitsClientJSON(base.ComputeClient):
+class LimitsClientJSON(service_client.ServiceClient):
def get_absolute_limits(self):
resp, body = self.get("limits")
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index de183f1..b41abc8 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -16,10 +16,10 @@
import urllib
from tempest.api_schema.response.compute import migrations as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class MigrationsClientJSON(base.ComputeClient):
+class MigrationsClientJSON(service_client.ServiceClient):
def list_migrations(self, params=None):
"""Lists all migrations."""
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
index 5a2744d..361258a 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -15,10 +15,10 @@
import json
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class NetworksClientJSON(base.ComputeClient):
+class NetworksClientJSON(service_client.ServiceClient):
def list_networks(self):
resp, body = self.get("os-networks")
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 0fee57a..f9f02a5 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -18,10 +18,10 @@
from tempest.api_schema.response.compute.v2\
import quota_classes as classes_schema
from tempest.api_schema.response.compute.v2 import quotas as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class QuotasClientJSON(base.ComputeClient):
+class QuotasClientJSON(service_client.ServiceClient):
def get_quota_set(self, tenant_id, user_id=None):
"""List the quota set for a tenant."""
@@ -115,7 +115,7 @@
return resp, body
-class QuotaClassesClientJSON(base.ComputeClient):
+class QuotaClassesClientJSON(service_client.ServiceClient):
def get_quota_class_set(self, quota_class_id):
"""List the quota class set for a quota class."""
diff --git a/tempest/services/compute/json/security_group_default_rules_client.py b/tempest/services/compute/json/security_group_default_rules_client.py
index efaf329..5d0c16f 100644
--- a/tempest/services/compute/json/security_group_default_rules_client.py
+++ b/tempest/services/compute/json/security_group_default_rules_client.py
@@ -17,10 +17,10 @@
from tempest.api_schema.response.compute.v2 import \
security_group_default_rule as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class SecurityGroupDefaultRulesClientJSON(base.ComputeClient):
+class SecurityGroupDefaultRulesClientJSON(service_client.ServiceClient):
def create_security_default_group_rule(self, ip_protocol, from_port,
to_port, **kwargs):
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index a301a0f..1ac52af 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -17,11 +17,11 @@
import urllib
from tempest.api_schema.response.compute.v2 import security_groups as schema
+from tempest.common import service_client
from tempest import exceptions
-from tempest.services.compute.json import base
-class SecurityGroupsClientJSON(base.ComputeClient):
+class SecurityGroupsClientJSON(service_client.ServiceClient):
def list_security_groups(self, params=None):
"""List all security groups for a user."""
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 400f9a7..cbe1ca8 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -20,15 +20,15 @@
from tempest.api_schema.response.compute import servers as common_schema
from tempest.api_schema.response.compute.v2 import servers as schema
+from tempest.common import service_client
from tempest.common import waiters
from tempest import config
from tempest import exceptions
-from tempest.services.compute.json import base
CONF = config.CONF
-class ServersClientJSON(base.ComputeClient):
+class ServersClientJSON(service_client.ServiceClient):
def create_server(self, name, image_ref, flavor_ref, **kwargs):
"""
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index 52662fa..fc2274d 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -19,10 +19,9 @@
from tempest.api_schema.response.compute import services as schema
from tempest.common import service_client
-from tempest.services.compute.json import base
-class ServicesClientJSON(base.ComputeClient):
+class ServicesClientJSON(service_client.ServiceClient):
def list_services(self, params=None):
url = 'os-services'
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index eac23bb..5dc1d5d 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -17,10 +17,10 @@
import urllib
from tempest.api_schema.response.compute.v2 import tenant_usages as schema
-from tempest.services.compute.json import base
+from tempest.common import service_client
-class TenantUsagesClientJSON(base.ComputeClient):
+class TenantUsagesClientJSON(service_client.ServiceClient):
def list_tenant_usages(self, params=None):
url = 'os-simple-tenant-usage'
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index 69b9bea..61d0b23 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -18,20 +18,11 @@
import urllib
from tempest.api_schema.response.compute.v2 import volumes as schema
-from tempest import config
+from tempest.common import service_client
from tempest import exceptions
-from tempest.services.compute.json import base
-
-CONF = config.CONF
-class VolumesExtensionsClientJSON(base.ComputeClient):
-
- def __init__(self, auth_provider):
- super(VolumesExtensionsClientJSON, self).__init__(
- auth_provider,
- build_interval=CONF.volume.build_interval,
- build_timeout=CONF.volume.build_timeout)
+class VolumesExtensionsClientJSON(service_client.ServiceClient):
def list_volumes(self, params=None):
"""List all the volumes created."""
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
index 9a27443..dfb2eb3 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_client.py
@@ -16,19 +16,10 @@
import urllib
from tempest.common import service_client
-from tempest import config
-
-CONF = config.CONF
class DatabaseFlavorsClientJSON(service_client.ServiceClient):
- def __init__(self, auth_provider):
- super(DatabaseFlavorsClientJSON, self).__init__(
- auth_provider,
- CONF.database.catalog_type,
- CONF.identity.region)
-
def list_db_flavors(self, params=None):
url = 'flavors'
if params:
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index f5c5217..c3388bb 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -16,18 +16,23 @@
import urllib
from tempest.common import service_client
-from tempest import config
-
-CONF = config.CONF
class DatabaseVersionsClientJSON(service_client.ServiceClient):
- def __init__(self, auth_provider):
+ def __init__(self, auth_provider, service, region,
+ endpoint_type=None, build_interval=None, build_timeout=None,
+ disable_ssl_certificate_validation=None, ca_certs=None,
+ trace_requests=None):
+ dscv = disable_ssl_certificate_validation
super(DatabaseVersionsClientJSON, self).__init__(
- auth_provider,
- CONF.database.catalog_type,
- CONF.identity.region)
+ auth_provider, service, region,
+ endpoint_type=endpoint_type,
+ build_interval=build_interval,
+ build_timeout=build_timeout,
+ disable_ssl_certificate_validation=dscv,
+ ca_certs=ca_certs,
+ trace_requests=trace_requests)
self.skip_path()
def list_db_versions(self, params=None):
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index daf7101..e92708c 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -16,11 +16,8 @@
from tempest.common import service_client
from tempest.common.utils import misc
-from tempest import config
from tempest import exceptions
-CONF = config.CONF
-
class NetworkClientJSON(service_client.ServiceClient):
@@ -37,16 +34,8 @@
quotas
"""
- def __init__(self, auth_provider):
- super(NetworkClientJSON, self).__init__(
- auth_provider,
- CONF.network.catalog_type,
- CONF.network.region or CONF.identity.region,
- endpoint_type=CONF.network.endpoint_type,
- build_interval=CONF.network.build_interval,
- build_timeout=CONF.network.build_timeout)
- self.version = '2.0'
- self.uri_prefix = "v%s" % (self.version)
+ version = '2.0'
+ uri_prefix = "v2.0"
def get_uri(self, plural_name):
# get service prefix from resource name
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index d23d934..c813977 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -19,23 +19,11 @@
import urllib
from tempest.common import service_client
-from tempest import config
from tempest import exceptions
-CONF = config.CONF
-
class OrchestrationClient(service_client.ServiceClient):
- def __init__(self, auth_provider):
- super(OrchestrationClient, self).__init__(
- auth_provider,
- CONF.orchestration.catalog_type,
- CONF.orchestration.region or CONF.identity.region,
- endpoint_type=CONF.orchestration.endpoint_type,
- build_interval=CONF.orchestration.build_interval,
- build_timeout=CONF.orchestration.build_timeout)
-
def list_stacks(self, params=None):
"""Lists all stacks for a user."""
@@ -46,7 +34,7 @@
resp, body = self.get(uri)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['stacks']
+ return service_client.ResponseBodyList(resp, body['stacks'])
def create_stack(self, name, disable_rollback=True, parameters=None,
timeout_mins=60, template=None, template_url=None,
@@ -66,7 +54,7 @@
resp, body = self.post(uri, headers=headers, body=body)
self.expected_success(201, resp.status)
body = json.loads(body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def update_stack(self, stack_identifier, name, disable_rollback=True,
parameters=None, timeout_mins=60, template=None,
@@ -85,7 +73,7 @@
uri = "stacks/%s" % stack_identifier
resp, body = self.put(uri, headers=headers, body=body)
self.expected_success(202, resp.status)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def _prepare_update_create(self, name, disable_rollback=True,
parameters=None, timeout_mins=60,
@@ -121,7 +109,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['stack']
+ return service_client.ResponseBody(resp, body['stack'])
def suspend_stack(self, stack_identifier):
"""Suspend a stack."""
@@ -129,7 +117,7 @@
body = {'suspend': None}
resp, body = self.post(url, json.dumps(body))
self.expected_success(200, resp.status)
- return resp, body
+ return service_client.ResponseBody(resp)
def resume_stack(self, stack_identifier):
"""Resume a stack."""
@@ -137,7 +125,7 @@
body = {'resume': None}
resp, body = self.post(url, json.dumps(body))
self.expected_success(200, resp.status)
- return resp, body
+ return service_client.ResponseBody(resp)
def list_resources(self, stack_identifier):
"""Returns the details of a single resource."""
@@ -145,7 +133,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['resources']
+ return service_client.ResponseBodyList(resp, body['resources'])
def get_resource(self, stack_identifier, resource_name):
"""Returns the details of a single resource."""
@@ -153,13 +141,13 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['resource']
+ return service_client.ResponseBody(resp, body['resource'])
def delete_stack(self, stack_identifier):
"""Deletes the specified Stack."""
resp, _ = self.delete("stacks/%s" % str(stack_identifier))
self.expected_success(204, resp.status)
- return resp
+ return service_client.ResponseBody(resp)
def wait_for_resource_status(self, stack_identifier, resource_name,
status, failure_pattern='^.*_FAILED$'):
@@ -169,7 +157,7 @@
while True:
try:
- resp, body = self.get_resource(
+ body = self.get_resource(
stack_identifier, resource_name)
except exceptions.NotFound:
# ignore this, as the resource may not have
@@ -205,7 +193,7 @@
while True:
try:
- resp, body = self.get_stack(stack_identifier)
+ body = self.get_stack(stack_identifier)
except exceptions.NotFound:
if status == 'DELETE_COMPLETE':
return
@@ -234,7 +222,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['metadata']
+ return service_client.ResponseBody(resp, body['metadata'])
def list_events(self, stack_identifier):
"""Returns list of all events for a stack."""
@@ -242,7 +230,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['events']
+ return service_client.ResponseBodyList(resp, body['events'])
def list_resource_events(self, stack_identifier, resource_name):
"""Returns list of all events for a resource from stack."""
@@ -251,7 +239,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['events']
+ return service_client.ResponseBodyList(resp, body['events'])
def show_event(self, stack_identifier, resource_name, event_id):
"""Returns the details of a single stack's event."""
@@ -260,7 +248,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body['event']
+ return service_client.ResponseBody(resp, body['event'])
def show_template(self, stack_identifier):
"""Returns the template for the stack."""
@@ -268,7 +256,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def _validate_template(self, post_body):
"""Returns the validation request result."""
@@ -276,7 +264,7 @@
resp, body = self.post('validate', post_body)
self.expected_success(200, resp.status)
body = json.loads(body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def validate_template(self, template, parameters=None):
"""Returns the validation result for a template with parameters."""
@@ -303,21 +291,21 @@
resp, body = self.get('resource_types')
self.expected_success(200, resp.status)
body = json.loads(body)
- return body['resource_types']
+ return service_client.ResponseBodyList(resp, body['resource_types'])
def get_resource_type(self, resource_type_name):
"""Return the schema of a resource type."""
url = 'resource_types/%s' % resource_type_name
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return json.loads(body)
+ return service_client.ResponseBody(resp, json.loads(body))
def get_resource_type_template(self, resource_type_name):
"""Return the template of a resource type."""
url = 'resource_types/%s/template' % resource_type_name
resp, body = self.get(url)
self.expected_success(200, resp.status)
- return json.loads(body)
+ return service_client.ResponseBody(resp, json.loads(body))
def create_software_config(self, name=None, config=None, group=None,
inputs=None, outputs=None, options=None):
@@ -328,7 +316,7 @@
resp, body = self.post(url, headers=headers, body=body)
self.expected_success(200, resp.status)
body = json.loads(body)
- return body
+ return service_client.ResponseBody(resp, body)
def get_software_config(self, conf_id):
"""Returns a software configuration resource."""
@@ -336,13 +324,14 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return body
+ return service_client.ResponseBody(resp, body)
def delete_software_config(self, conf_id):
"""Deletes a specific software configuration."""
url = 'software_configs/%s' % str(conf_id)
resp, _ = self.delete(url)
self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)
def create_software_deploy(self, server_id=None, config_id=None,
action=None, status=None,
@@ -357,7 +346,7 @@
resp, body = self.post(url, headers=headers, body=body)
self.expected_success(200, resp.status)
body = json.loads(body)
- return body
+ return service_client.ResponseBody(resp, body)
def update_software_deploy(self, deploy_id=None, server_id=None,
config_id=None, action=None, status=None,
@@ -372,7 +361,7 @@
resp, body = self.put(url, headers=headers, body=body)
self.expected_success(200, resp.status)
body = json.loads(body)
- return body
+ return service_client.ResponseBody(resp, body)
def get_software_deploy_list(self):
"""Returns a list of all deployments."""
@@ -380,7 +369,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return body
+ return service_client.ResponseBody(resp, body)
def get_software_deploy(self, deploy_id):
"""Returns a specific software deployment."""
@@ -388,7 +377,7 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return body
+ return service_client.ResponseBody(resp, body)
def get_software_deploy_meta(self, server_id):
"""Return a config metadata for a specific server."""
@@ -396,13 +385,14 @@
resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
- return body
+ return service_client.ResponseBody(resp, body)
def delete_software_deploy(self, deploy_id):
"""Deletes a specific software deployment."""
url = 'software_deployments/%s' % str(deploy_id)
resp, _ = self.delete(url)
self.expected_success(204, resp.status)
+ return service_client.ResponseBody(resp)
def _prep_software_config_create(self, name=None, conf=None, group=None,
inputs=None, outputs=None, options=None):
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index 9a6c9de..c92a886 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -171,7 +171,7 @@
def test_get_connection_kwargs_set_timeout_for_http(self):
kwargs = self.client.get_connection_kwargs('http', timeout=10,
- cacert='foo')
+ ca_certs='foo')
self.assertEqual(10, kwargs['timeout'])
# nothing more than timeout is evaluated for http connections
self.assertEqual(1, len(kwargs.keys()))
@@ -179,7 +179,7 @@
def test_get_connection_kwargs_default_for_https(self):
kwargs = self.client.get_connection_kwargs('https')
self.assertEqual(600, kwargs['timeout'])
- self.assertEqual(None, kwargs['cacert'])
+ self.assertEqual(None, kwargs['ca_certs'])
self.assertEqual(None, kwargs['cert_file'])
self.assertEqual(None, kwargs['key_file'])
self.assertEqual(False, kwargs['insecure'])
@@ -188,13 +188,13 @@
def test_get_connection_kwargs_set_params_for_https(self):
kwargs = self.client.get_connection_kwargs('https', timeout=10,
- cacert='foo',
+ ca_certs='foo',
cert_file='/foo/bar.cert',
key_file='/foo/key.pem',
insecure=True,
ssl_compression=False)
self.assertEqual(10, kwargs['timeout'])
- self.assertEqual('foo', kwargs['cacert'])
+ self.assertEqual('foo', kwargs['ca_certs'])
self.assertEqual('/foo/bar.cert', kwargs['cert_file'])
self.assertEqual('/foo/key.pem', kwargs['key_file'])
self.assertEqual(True, kwargs['insecure'])
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
deleted file mode 100644
index 6a95a80..0000000
--- a/tempest/tests/test_rest_client.py
+++ /dev/null
@@ -1,470 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-# 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
-
-import httplib2
-from oslotest import mockpatch
-import six
-
-from tempest.common import rest_client
-from tempest import exceptions
-from tempest.tests import base
-from tempest.tests import fake_auth_provider
-from tempest.tests import fake_http
-
-
-class BaseRestClientTestClass(base.TestCase):
-
- url = 'fake_endpoint'
-
- def setUp(self):
- super(BaseRestClientTestClass, self).setUp()
- self.rest_client = rest_client.RestClient(
- fake_auth_provider.FakeAuthProvider(), None, None)
- self.stubs.Set(httplib2.Http, 'request', self.fake_http.request)
- self.useFixture(mockpatch.PatchObject(self.rest_client,
- '_log_request'))
-
-
-class TestRestClientHTTPMethods(BaseRestClientTestClass):
- def setUp(self):
- self.fake_http = fake_http.fake_httplib2()
- super(TestRestClientHTTPMethods, self).setUp()
- self.useFixture(mockpatch.PatchObject(self.rest_client,
- '_error_checker'))
-
- def test_post(self):
- __, return_dict = self.rest_client.post(self.url, {}, {})
- self.assertEqual('POST', return_dict['method'])
-
- def test_get(self):
- __, return_dict = self.rest_client.get(self.url)
- self.assertEqual('GET', return_dict['method'])
-
- def test_delete(self):
- __, return_dict = self.rest_client.delete(self.url)
- self.assertEqual('DELETE', return_dict['method'])
-
- def test_patch(self):
- __, return_dict = self.rest_client.patch(self.url, {}, {})
- self.assertEqual('PATCH', return_dict['method'])
-
- def test_put(self):
- __, return_dict = self.rest_client.put(self.url, {}, {})
- self.assertEqual('PUT', return_dict['method'])
-
- def test_head(self):
- self.useFixture(mockpatch.PatchObject(self.rest_client,
- 'response_checker'))
- __, return_dict = self.rest_client.head(self.url)
- self.assertEqual('HEAD', return_dict['method'])
-
- def test_copy(self):
- __, return_dict = self.rest_client.copy(self.url)
- self.assertEqual('COPY', return_dict['method'])
-
-
-class TestRestClientNotFoundHandling(BaseRestClientTestClass):
- def setUp(self):
- self.fake_http = fake_http.fake_httplib2(404)
- super(TestRestClientNotFoundHandling, self).setUp()
-
- def test_post(self):
- self.assertRaises(exceptions.NotFound, self.rest_client.post,
- self.url, {}, {})
-
-
-class TestRestClientHeadersJSON(TestRestClientHTTPMethods):
- TYPE = "json"
-
- def _verify_headers(self, resp):
- self.assertEqual(self.rest_client._get_type(), self.TYPE)
- resp = dict((k.lower(), v) for k, v in six.iteritems(resp))
- self.assertEqual(self.header_value, resp['accept'])
- self.assertEqual(self.header_value, resp['content-type'])
-
- def setUp(self):
- super(TestRestClientHeadersJSON, self).setUp()
- self.rest_client.TYPE = self.TYPE
- self.header_value = 'application/%s' % self.rest_client._get_type()
-
- def test_post(self):
- resp, __ = self.rest_client.post(self.url, {})
- self._verify_headers(resp)
-
- def test_get(self):
- resp, __ = self.rest_client.get(self.url)
- self._verify_headers(resp)
-
- def test_delete(self):
- resp, __ = self.rest_client.delete(self.url)
- self._verify_headers(resp)
-
- def test_patch(self):
- resp, __ = self.rest_client.patch(self.url, {})
- self._verify_headers(resp)
-
- def test_put(self):
- resp, __ = self.rest_client.put(self.url, {})
- self._verify_headers(resp)
-
- def test_head(self):
- self.useFixture(mockpatch.PatchObject(self.rest_client,
- 'response_checker'))
- resp, __ = self.rest_client.head(self.url)
- self._verify_headers(resp)
-
- def test_copy(self):
- resp, __ = self.rest_client.copy(self.url)
- self._verify_headers(resp)
-
-
-class TestRestClientUpdateHeaders(BaseRestClientTestClass):
- def setUp(self):
- self.fake_http = fake_http.fake_httplib2()
- super(TestRestClientUpdateHeaders, self).setUp()
- self.useFixture(mockpatch.PatchObject(self.rest_client,
- '_error_checker'))
- self.headers = {'X-Configuration-Session': 'session_id'}
-
- def test_post_update_headers(self):
- __, return_dict = self.rest_client.post(self.url, {},
- extra_headers=True,
- headers=self.headers)
-
- self.assertDictContainsSubset(
- {'X-Configuration-Session': 'session_id',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'},
- return_dict['headers']
- )
-
- def test_get_update_headers(self):
- __, return_dict = self.rest_client.get(self.url,
- extra_headers=True,
- headers=self.headers)
-
- self.assertDictContainsSubset(
- {'X-Configuration-Session': 'session_id',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'},
- return_dict['headers']
- )
-
- def test_delete_update_headers(self):
- __, return_dict = self.rest_client.delete(self.url,
- extra_headers=True,
- headers=self.headers)
-
- self.assertDictContainsSubset(
- {'X-Configuration-Session': 'session_id',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'},
- return_dict['headers']
- )
-
- def test_patch_update_headers(self):
- __, return_dict = self.rest_client.patch(self.url, {},
- extra_headers=True,
- headers=self.headers)
-
- self.assertDictContainsSubset(
- {'X-Configuration-Session': 'session_id',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'},
- return_dict['headers']
- )
-
- def test_put_update_headers(self):
- __, return_dict = self.rest_client.put(self.url, {},
- extra_headers=True,
- headers=self.headers)
-
- self.assertDictContainsSubset(
- {'X-Configuration-Session': 'session_id',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'},
- return_dict['headers']
- )
-
- def test_head_update_headers(self):
- self.useFixture(mockpatch.PatchObject(self.rest_client,
- 'response_checker'))
-
- __, return_dict = self.rest_client.head(self.url,
- extra_headers=True,
- headers=self.headers)
-
- self.assertDictContainsSubset(
- {'X-Configuration-Session': 'session_id',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'},
- return_dict['headers']
- )
-
- def test_copy_update_headers(self):
- __, return_dict = self.rest_client.copy(self.url,
- extra_headers=True,
- headers=self.headers)
-
- self.assertDictContainsSubset(
- {'X-Configuration-Session': 'session_id',
- 'Content-Type': 'application/json',
- 'Accept': 'application/json'},
- return_dict['headers']
- )
-
-
-class TestRestClientParseRespJSON(BaseRestClientTestClass):
- TYPE = "json"
-
- keys = ["fake_key1", "fake_key2"]
- values = ["fake_value1", "fake_value2"]
- item_expected = dict((key, value) for (key, value) in zip(keys, values))
- list_expected = {"body_list": [
- {keys[0]: values[0]},
- {keys[1]: values[1]},
- ]}
- dict_expected = {"body_dict": {
- keys[0]: values[0],
- keys[1]: values[1],
- }}
-
- def setUp(self):
- self.fake_http = fake_http.fake_httplib2()
- super(TestRestClientParseRespJSON, self).setUp()
- self.rest_client.TYPE = self.TYPE
-
- def test_parse_resp_body_item(self):
- body = self.rest_client._parse_resp(json.dumps(self.item_expected))
- self.assertEqual(self.item_expected, body)
-
- def test_parse_resp_body_list(self):
- body = self.rest_client._parse_resp(json.dumps(self.list_expected))
- self.assertEqual(self.list_expected["body_list"], body)
-
- def test_parse_resp_body_dict(self):
- body = self.rest_client._parse_resp(json.dumps(self.dict_expected))
- self.assertEqual(self.dict_expected["body_dict"], body)
-
- def test_parse_resp_two_top_keys(self):
- dict_two_keys = self.dict_expected.copy()
- dict_two_keys.update({"second_key": ""})
- body = self.rest_client._parse_resp(json.dumps(dict_two_keys))
- self.assertEqual(dict_two_keys, body)
-
- def test_parse_resp_one_top_key_without_list_or_dict(self):
- data = {"one_top_key": "not_list_or_dict_value"}
- body = self.rest_client._parse_resp(json.dumps(data))
- self.assertEqual(data, body)
-
-
-class TestRestClientErrorCheckerJSON(base.TestCase):
- c_type = "application/json"
-
- def set_data(self, r_code, enc=None, r_body=None):
- if enc is None:
- enc = self.c_type
- resp_dict = {'status': r_code, 'content-type': enc}
- resp = httplib2.Response(resp_dict)
- data = {
- "method": "fake_method",
- "url": "fake_url",
- "headers": "fake_headers",
- "body": "fake_body",
- "resp": resp,
- "resp_body": '{"resp_body": "fake_resp_body"}',
- }
- if r_body is not None:
- data.update({"resp_body": r_body})
- return data
-
- def setUp(self):
- super(TestRestClientErrorCheckerJSON, self).setUp()
- self.rest_client = rest_client.RestClient(
- fake_auth_provider.FakeAuthProvider(), None, None)
-
- def test_response_less_than_400(self):
- self.rest_client._error_checker(**self.set_data("399"))
-
- def test_response_400(self):
- self.assertRaises(exceptions.BadRequest,
- self.rest_client._error_checker,
- **self.set_data("400"))
-
- def test_response_401(self):
- self.assertRaises(exceptions.Unauthorized,
- self.rest_client._error_checker,
- **self.set_data("401"))
-
- def test_response_403(self):
- self.assertRaises(exceptions.Unauthorized,
- self.rest_client._error_checker,
- **self.set_data("403"))
-
- def test_response_404(self):
- self.assertRaises(exceptions.NotFound,
- self.rest_client._error_checker,
- **self.set_data("404"))
-
- def test_response_409(self):
- self.assertRaises(exceptions.Conflict,
- self.rest_client._error_checker,
- **self.set_data("409"))
-
- def test_response_413(self):
- self.assertRaises(exceptions.OverLimit,
- self.rest_client._error_checker,
- **self.set_data("413"))
-
- def test_response_415(self):
- self.assertRaises(exceptions.InvalidContentType,
- self.rest_client._error_checker,
- **self.set_data("415"))
-
- def test_response_422(self):
- self.assertRaises(exceptions.UnprocessableEntity,
- self.rest_client._error_checker,
- **self.set_data("422"))
-
- def test_response_500_with_text(self):
- # _parse_resp is expected to return 'str'
- self.assertRaises(exceptions.ServerFault,
- self.rest_client._error_checker,
- **self.set_data("500"))
-
- def test_response_501_with_text(self):
- self.assertRaises(exceptions.NotImplemented,
- self.rest_client._error_checker,
- **self.set_data("501"))
-
- def test_response_500_with_dict(self):
- r_body = '{"resp_body": {"err": "fake_resp_body"}}'
- self.assertRaises(exceptions.ServerFault,
- self.rest_client._error_checker,
- **self.set_data("500", r_body=r_body))
-
- def test_response_501_with_dict(self):
- r_body = '{"resp_body": {"err": "fake_resp_body"}}'
- self.assertRaises(exceptions.NotImplemented,
- self.rest_client._error_checker,
- **self.set_data("501", r_body=r_body))
-
- def test_response_bigger_than_400(self):
- # Any response code, that bigger than 400, and not in
- # (401, 403, 404, 409, 413, 422, 500, 501)
- self.assertRaises(exceptions.UnexpectedResponseCode,
- self.rest_client._error_checker,
- **self.set_data("402"))
-
-
-class TestRestClientErrorCheckerTEXT(TestRestClientErrorCheckerJSON):
- c_type = "text/plain"
-
- def test_fake_content_type(self):
- # This test is required only in one exemplar
- # Any response code, that bigger than 400, and not in
- # (401, 403, 404, 409, 413, 422, 500, 501)
- self.assertRaises(exceptions.InvalidContentType,
- self.rest_client._error_checker,
- **self.set_data("405", enc="fake_enc"))
-
-
-class TestRestClientUtils(BaseRestClientTestClass):
-
- def _is_resource_deleted(self, resource_id):
- if not isinstance(self.retry_pass, int):
- return False
- if self.retry_count >= self.retry_pass:
- return True
- self.retry_count = self.retry_count + 1
- return False
-
- def setUp(self):
- self.fake_http = fake_http.fake_httplib2()
- super(TestRestClientUtils, self).setUp()
- self.retry_count = 0
- self.retry_pass = None
- self.original_deleted_method = self.rest_client.is_resource_deleted
- self.rest_client.is_resource_deleted = self._is_resource_deleted
-
- def test_wait_for_resource_deletion(self):
- self.retry_pass = 2
- # Ensure timeout long enough for loop execution to hit retry count
- self.rest_client.build_timeout = 500
- sleep_mock = self.patch('time.sleep')
- self.rest_client.wait_for_resource_deletion('1234')
- self.assertEqual(len(sleep_mock.mock_calls), 2)
-
- def test_wait_for_resource_deletion_not_deleted(self):
- self.patch('time.sleep')
- # Set timeout to be very quick to force exception faster
- self.rest_client.build_timeout = 1
- self.assertRaises(exceptions.TimeoutException,
- self.rest_client.wait_for_resource_deletion,
- '1234')
-
- def test_wait_for_deletion_with_unimplemented_deleted_method(self):
- self.rest_client.is_resource_deleted = self.original_deleted_method
- self.assertRaises(NotImplementedError,
- self.rest_client.wait_for_resource_deletion,
- '1234')
-
-
-class TestExpectedSuccess(BaseRestClientTestClass):
-
- def setUp(self):
- self.fake_http = fake_http.fake_httplib2()
- super(TestExpectedSuccess, self).setUp()
-
- def test_expected_succes_int_match(self):
- expected_code = 202
- read_code = 202
- resp = self.rest_client.expected_success(expected_code, read_code)
- # Assert None resp on success
- self.assertFalse(resp)
-
- def test_expected_succes_int_no_match(self):
- expected_code = 204
- read_code = 202
- self.assertRaises(exceptions.InvalidHttpSuccessCode,
- self.rest_client.expected_success,
- expected_code, read_code)
-
- def test_expected_succes_list_match(self):
- expected_code = [202, 204]
- read_code = 202
- resp = self.rest_client.expected_success(expected_code, read_code)
- # Assert None resp on success
- self.assertFalse(resp)
-
- def test_expected_succes_list_no_match(self):
- expected_code = [202, 204]
- read_code = 200
- self.assertRaises(exceptions.InvalidHttpSuccessCode,
- self.rest_client.expected_success,
- expected_code, read_code)
-
- def test_non_success_expected_int(self):
- expected_code = 404
- read_code = 202
- self.assertRaises(AssertionError, self.rest_client.expected_success,
- expected_code, read_code)
-
- def test_non_success_expected_list(self):
- expected_code = [404, 202]
- read_code = 202
- self.assertRaises(AssertionError, self.rest_client.expected_success,
- expected_code, read_code)
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index f6779c6..58a8060 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -110,7 +110,7 @@
return_value={'router': {'id': id, 'name': name}}))
return router_fix
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_primary_creds(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
iso_creds = isolated_creds.IsolatedCreds('test class',
@@ -126,7 +126,7 @@
self.assertEqual(primary_creds.tenant_id, '1234')
self.assertEqual(primary_creds.user_id, '1234')
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_admin_creds(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
iso_creds = isolated_creds.IsolatedCreds('test class',
@@ -151,7 +151,7 @@
self.assertEqual(admin_creds.tenant_id, '1234')
self.assertEqual(admin_creds.user_id, '1234')
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_all_cred_cleanup(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
iso_creds = isolated_creds.IsolatedCreds('test class',
@@ -195,7 +195,7 @@
self.assertIn('12345', args)
self.assertIn('123456', args)
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_alt_creds(self, MockRestClient):
cfg.CONF.set_default('neutron', False, 'service_available')
iso_creds = isolated_creds.IsolatedCreds('test class',
@@ -211,7 +211,7 @@
self.assertEqual(alt_creds.tenant_id, '1234')
self.assertEqual(alt_creds.user_id, '1234')
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_creation(self, MockRestClient):
iso_creds = isolated_creds.IsolatedCreds('test class',
password='fake_password')
@@ -237,7 +237,7 @@
self.assertEqual(router['id'], '1234')
self.assertEqual(router['name'], 'fake_router')
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_cleanup(self, MockRestClient):
def side_effect(**args):
return {"security_groups": [{"tenant_id": args['tenant_id'],
@@ -360,7 +360,7 @@
self.assertIn('12345', args)
self.assertIn('123456', args)
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_alt_creation(self, MockRestClient):
iso_creds = isolated_creds.IsolatedCreds('test class',
password='fake_password')
@@ -386,7 +386,7 @@
self.assertEqual(router['id'], '1234')
self.assertEqual(router['name'], 'fake_alt_router')
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_network_admin_creation(self, MockRestClient):
iso_creds = isolated_creds.IsolatedCreds('test class',
password='fake_password')
@@ -412,7 +412,7 @@
self.assertEqual(router['id'], '1234')
self.assertEqual(router['name'], 'fake_admin_router')
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_no_network_resources(self, MockRestClient):
net_dict = {
'network': False,
@@ -448,7 +448,7 @@
self.assertIsNone(subnet)
self.assertIsNone(router)
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_router_without_network(self, MockRestClient):
net_dict = {
'network': False,
@@ -466,7 +466,7 @@
self.assertRaises(exceptions.InvalidConfiguration,
iso_creds.get_primary_creds)
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_subnet_without_network(self, MockRestClient):
net_dict = {
'network': False,
@@ -484,7 +484,7 @@
self.assertRaises(exceptions.InvalidConfiguration,
iso_creds.get_primary_creds)
- @mock.patch('tempest.common.rest_client.RestClient')
+ @mock.patch('tempest_lib.common.rest_client.RestClient')
def test_dhcp_without_subnet(self, MockRestClient):
net_dict = {
'network': False,
diff --git a/tempest/tests/test_waiters.py b/tempest/tests/test_waiters.py
index 1f9825e..cdf5362 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 = (None, {'status': 'active'})
+ self.client.get_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 = (None, {'status': 'saving'})
+ self.client.get_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 = (None, {'status': 'ERROR'})
+ self.client.get_image.return_value = ({'status': 'ERROR'})
self.assertRaises(exceptions.AddImageException,
waiters.wait_for_image_status,
self.client, 'fake_image_id', 'active')