Files
tempest/tempest/api/image/base.py
T
Ghanshyam MannandMartin Kopec 3562cd0017 Remove Glance v1 APIs tests
Glance v1 APIs were removed in Rocky and tempest master
does not support the Rocky release. If glance v1 APIs
needs to be tested for older release then older Tempest
can be used.

This removes the Glance v1 APIs tests, config option,
and its service clients.

Change-Id: I6741e2204de251ee8f16b0249a73bee5912c1135
2023-08-14 11:35:59 +02:00

225 lines
8.4 KiB
Python

# 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 time
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions
import tempest.test
CONF = config.CONF
BAD_REQUEST_RETRIES = 3
class BaseImageTest(tempest.test.BaseTestCase):
"""Base test class for Image API tests."""
credentials = ['primary']
@classmethod
def skip_checks(cls):
super(BaseImageTest, cls).skip_checks()
if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
@classmethod
def setup_credentials(cls):
cls.set_network_resources()
super(BaseImageTest, cls).setup_credentials()
@classmethod
def resource_setup(cls):
super(BaseImageTest, cls).resource_setup()
cls.created_images = []
@classmethod
def create_image(cls, data=None, **kwargs):
"""Wrapper that returns a test image."""
if 'name' not in kwargs:
name = data_utils.rand_name(cls.__name__ + "-image")
kwargs['name'] = name
image = cls.client.create_image(**kwargs)
cls.created_images.append(image['id'])
cls.addClassResourceCleanup(cls.client.wait_for_resource_deletion,
image['id'])
cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
cls.client.delete_image, image['id'])
return image
class BaseV2ImageTest(BaseImageTest):
@classmethod
def skip_checks(cls):
super(BaseV2ImageTest, cls).skip_checks()
if not CONF.image_feature_enabled.api_v2:
msg = "Glance API v2 not supported"
raise cls.skipException(msg)
@classmethod
def setup_clients(cls):
super(BaseV2ImageTest, cls).setup_clients()
cls.client = cls.os_primary.image_client_v2
cls.schemas_client = cls.os_primary.schemas_client
cls.versions_client = cls.os_primary.image_versions_client
def create_namespace(self, namespace_name=None, visibility='public',
description='Tempest', protected=False,
**kwargs):
if not namespace_name:
namespace_name = data_utils.rand_name('test-ns')
kwargs.setdefault('display_name', namespace_name)
namespace = self.namespaces_client.create_namespace(
namespace=namespace_name, visibility=visibility,
description=description, protected=protected, **kwargs)
self.addCleanup(self.namespaces_client.delete_namespace,
namespace_name)
return namespace
@classmethod
def get_available_stores(cls):
stores = []
try:
stores = cls.client.info_stores()['stores']
except exceptions.NotFound:
pass
return stores
def _update_image_with_retries(self, image, patch):
# NOTE(danms): If glance was unable to fetch the remote image via
# HTTP, it will return BadRequest. Because this can be transient in
# CI, we try this a few times before we agree that it has failed
# for a reason worthy of failing the test.
for i in range(BAD_REQUEST_RETRIES):
try:
self.client.update_image(image, patch)
break
except exceptions.BadRequest:
if i + 1 == BAD_REQUEST_RETRIES:
raise
else:
time.sleep(1)
def check_set_location(self):
image = self.client.create_image(container_format='bare',
disk_format='raw')
# Locations should be empty when there is no data
self.assertEqual('queued', image['status'])
self.assertEqual([], image['locations'])
# Add a new location
new_loc = {'metadata': {'foo': 'bar'},
'url': CONF.image.http_image}
self._update_image_with_retries(image['id'], [
dict(add='/locations/-', value=new_loc)])
# The image should now be active, with one location that looks
# like we expect
image = self.client.show_image(image['id'])
self.assertEqual(1, len(image['locations']),
'Image should have one location but has %i' % (
len(image['locations'])))
self.assertEqual(new_loc['url'], image['locations'][0]['url'])
self.assertEqual('bar', image['locations'][0]['metadata'].get('foo'))
if 'direct_url' in image:
self.assertEqual(image['direct_url'], image['locations'][0]['url'])
# If we added the location directly, the image goes straight
# to active and no hashing is done
self.assertEqual('active', image['status'])
self.assertIsNone(None, image['os_hash_algo'])
self.assertIsNone(None, image['os_hash_value'])
return image
def check_set_multiple_locations(self):
image = self.check_set_location()
new_loc = {'metadata': {'speed': '88mph'},
'url': '%s#new' % CONF.image.http_image}
self._update_image_with_retries(image['id'],
[dict(add='/locations/-',
value=new_loc)])
# The image should now have two locations and the last one
# (locations are ordered) should have the new URL.
image = self.client.show_image(image['id'])
self.assertEqual(2, len(image['locations']),
'Image should have two locations but has %i' % (
len(image['locations'])))
self.assertEqual(new_loc['url'], image['locations'][1]['url'])
# The image should still be active and still have no hashes
self.assertEqual('active', image['status'])
self.assertIsNone(None, image['os_hash_algo'])
self.assertIsNone(None, image['os_hash_value'])
# The direct_url should still match the first location
if 'direct_url' in image:
self.assertEqual(image['direct_url'], image['locations'][0]['url'])
return image
class BaseV2MemberImageTest(BaseV2ImageTest):
credentials = ['primary', 'alt']
@classmethod
def setup_clients(cls):
super(BaseV2MemberImageTest, cls).setup_clients()
cls.image_member_client = cls.os_primary.image_member_client_v2
cls.alt_image_member_client = cls.os_alt.image_member_client_v2
cls.alt_img_client = cls.os_alt.image_client_v2
@classmethod
def resource_setup(cls):
super(BaseV2MemberImageTest, cls).resource_setup()
cls.alt_tenant_id = cls.alt_image_member_client.tenant_id
def _list_image_ids_as_alt(self):
image_list = self.alt_img_client.list_images()['images']
image_ids = map(lambda x: x['id'], image_list)
return image_ids
def _create_image(self):
name = data_utils.rand_name(self.__class__.__name__ + '-image')
image = self.client.create_image(name=name,
container_format='bare',
disk_format='raw')
self.addCleanup(self.client.delete_image, image['id'])
return image['id']
class BaseV2ImageAdminTest(BaseV2ImageTest):
credentials = ['admin', 'primary']
@classmethod
def setup_clients(cls):
super(BaseV2ImageAdminTest, cls).setup_clients()
cls.admin_client = cls.os_admin.image_client_v2
cls.namespaces_client = cls.os_admin.namespaces_client
cls.resource_types_client = cls.os_admin.resource_types_client
cls.namespace_properties_client =\
cls.os_admin.namespace_properties_client
cls.namespace_objects_client = cls.os_admin.namespace_objects_client
cls.namespace_tags_client = cls.os_admin.namespace_tags_client