Merge "Remove Glance v1 APIs tests"
diff --git a/releasenotes/notes/remove-glance-v1-api-tests-5a39d3ea4b6bd71e.yaml b/releasenotes/notes/remove-glance-v1-api-tests-5a39d3ea4b6bd71e.yaml
new file mode 100644
index 0000000..dc36ac0
--- /dev/null
+++ b/releasenotes/notes/remove-glance-v1-api-tests-5a39d3ea4b6bd71e.yaml
@@ -0,0 +1,8 @@
+---
+prelude: >
+ Glance v1 APIs were removed in Rocky release and last
+ supported release for v1 was Queens. Tempest master does
+ not support the Rocky or Queens release so we removed
+ the Glance v1 tests, config option, and its service clients.
+ If you would like to test the v1 APIs then you can use the old
+ Tempest version.
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 4fdc012..d02532d 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -113,14 +113,11 @@
cls.attachments_client = cls.os_primary.attachments_client_latest
cls.snapshots_client = cls.os_primary.snapshots_client_latest
if CONF.service_available.glance:
- if CONF.image_feature_enabled.api_v1:
- cls.images_client = cls.os_primary.image_client
- elif CONF.image_feature_enabled.api_v2:
+ if CONF.image_feature_enabled.api_v2:
cls.images_client = cls.os_primary.image_client_v2
else:
raise lib_exc.InvalidConfiguration(
- 'Either api_v1 or api_v2 must be True in '
- '[image-feature-enabled].')
+ 'api_v2 must be True in [image-feature-enabled].')
@classmethod
def resource_setup(cls):
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
index 5d6a7d7..22b71fc 100644
--- a/tempest/api/compute/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -17,7 +17,6 @@
import random
from tempest.api.compute import base
-from tempest.common import image as common_image
from tempest.common import utils
from tempest import config
from tempest.lib.common.utils import data_utils
@@ -48,23 +47,15 @@
'name': data_utils.rand_name('image'),
'container_format': CONF.image.container_formats[0],
'disk_format': CONF.image.disk_formats[0],
- 'min_ram': min_img_ram
+ 'min_ram': min_img_ram,
+ 'visibility': 'private'
}
- if CONF.image_feature_enabled.api_v1:
- params.update({'is_public': False})
- params = {'headers': common_image.image_meta_to_headers(**params)}
- else:
- params.update({'visibility': 'private'})
-
image = self.images_client.create_image(**params)
image = image['image'] if 'image' in image else image
self.addCleanup(self.images_client.delete_image, image['id'])
- if CONF.image_feature_enabled.api_v1:
- self.images_client.update_image(image['id'], data=image_file)
- else:
- self.images_client.store_image_file(image['id'], data=image_file)
+ self.images_client.store_image_file(image['id'], data=image_file)
self.assertEqual(min_img_ram, image['min_ram'])
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index ece983d..f630bc8 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -16,7 +16,6 @@
import io
from tempest.api.compute import base
-from tempest.common import image as common_image
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
@@ -42,17 +41,11 @@
@classmethod
def setup_clients(cls):
super(ImagesMetadataTestJSON, cls).setup_clients()
- # Check if glance v1 is available to determine which client to use. We
- # prefer glance v1 for the compute API tests since the compute image
- # API proxy was written for glance v1.
- if CONF.image_feature_enabled.api_v1:
- cls.glance_client = cls.os_primary.image_client
- elif CONF.image_feature_enabled.api_v2:
+ if CONF.image_feature_enabled.api_v2:
cls.glance_client = cls.os_primary.image_client_v2
else:
raise exceptions.InvalidConfiguration(
- 'Either api_v1 or api_v2 must be True in '
- '[image-feature-enabled].')
+ 'api_v2 must be True in [image-feature-enabled].')
cls.client = cls.compute_images_client
@classmethod
@@ -63,13 +56,9 @@
params = {
'name': data_utils.rand_name('image'),
'container_format': 'bare',
- 'disk_format': 'raw'
+ 'disk_format': 'raw',
+ 'visibility': 'private'
}
- if CONF.image_feature_enabled.api_v1:
- params.update({'is_public': False})
- params = {'headers': common_image.image_meta_to_headers(**params)}
- else:
- params.update({'visibility': 'private'})
body = cls.glance_client.create_image(**params)
body = body['image'] if 'image' in body else body
@@ -78,10 +67,7 @@
cls.glance_client.delete_image,
cls.image_id)
image_file = io.BytesIO((b'*' * 1024))
- if CONF.image_feature_enabled.api_v1:
- cls.glance_client.update_image(cls.image_id, data=image_file)
- else:
- cls.glance_client.store_image_file(cls.image_id, data=image_file)
+ cls.glance_client.store_image_file(cls.image_id, data=image_file)
waiters.wait_for_image_status(cls.client, cls.image_id, 'ACTIVE')
def setUp(self):
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 15b8a00..c6eff9b 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -19,7 +19,6 @@
import testtools
from tempest.api.compute import base
-from tempest.common import image as common_image
from tempest.common import waiters
from tempest import config
from tempest.lib.common.utils import data_utils
@@ -46,17 +45,11 @@
def setup_clients(cls):
super(ListImageFiltersTestJSON, cls).setup_clients()
cls.client = cls.compute_images_client
- # Check if glance v1 is available to determine which client to use. We
- # prefer glance v1 for the compute API tests since the compute image
- # API proxy was written for glance v1.
- if CONF.image_feature_enabled.api_v1:
- cls.glance_client = cls.os_primary.image_client
- elif CONF.image_feature_enabled.api_v2:
+ if CONF.image_feature_enabled.api_v2:
cls.glance_client = cls.os_primary.image_client_v2
else:
raise exceptions.InvalidConfiguration(
- 'Either api_v1 or api_v2 must be True in '
- '[image-feature-enabled].')
+ 'api_v2 must be True in [image-feature-enabled].')
@classmethod
def resource_setup(cls):
@@ -66,14 +59,9 @@
params = {
'name': data_utils.rand_name(cls.__name__ + '-image'),
'container_format': 'bare',
- 'disk_format': 'raw'
+ 'disk_format': 'raw',
+ 'visibility': 'private'
}
- if CONF.image_feature_enabled.api_v1:
- params.update({'is_public': False})
- params = {'headers':
- common_image.image_meta_to_headers(**params)}
- else:
- params.update({'visibility': 'private'})
body = cls.glance_client.create_image(**params)
body = body['image'] if 'image' in body else body
@@ -86,10 +74,7 @@
# between created_at and updated_at.
time.sleep(1)
image_file = io.BytesIO((b'*' * 1024))
- if CONF.image_feature_enabled.api_v1:
- cls.glance_client.update_image(image_id, data=image_file)
- else:
- cls.glance_client.store_image_file(image_id, data=image_file)
+ cls.glance_client.store_image_file(image_id, data=image_file)
waiters.wait_for_image_status(cls.client, image_id, 'ACTIVE')
body = cls.client.show_image(image_id)['image']
return body
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f853473..a181839 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -569,17 +569,11 @@
# create the first and the second backup
- # Check if glance v1 is available to determine which client to use. We
- # prefer glance v1 for the compute API tests since the compute image
- # API proxy was written for glance v1.
- if CONF.image_feature_enabled.api_v1:
- glance_client = self.os_primary.image_client
- elif CONF.image_feature_enabled.api_v2:
+ if CONF.image_feature_enabled.api_v2:
glance_client = self.os_primary.image_client_v2
else:
raise lib_exc.InvalidConfiguration(
- 'Either api_v1 or api_v2 must be True in '
- '[image-feature-enabled].')
+ 'api_v2 must be True in [image-feature-enabled].')
backup1 = data_utils.rand_name('backup-1')
resp = self.client.create_backup(self.server_id,
@@ -635,16 +629,9 @@
'sort_key': 'created_at',
'sort_dir': 'asc'
}
- if CONF.image_feature_enabled.api_v1:
- for key, value in properties.items():
- params['property-%s' % key] = value
- image_list = glance_client.list_images(
- detail=True,
- **params)['images']
- else:
- # Additional properties are flattened in glance v2.
- params.update(properties)
- image_list = glance_client.list_images(params)['images']
+ # Additional properties are flattened in glance v2.
+ params.update(properties)
+ image_list = glance_client.list_images(params)['images']
self.assertEqual(2, len(image_list))
self.assertEqual((backup1, backup2),
@@ -668,11 +655,7 @@
waiters.wait_for_server_status(self.client, self.server_id, 'ACTIVE')
glance_client.wait_for_resource_deletion(image1_id)
oldest_backup_exist = False
- if CONF.image_feature_enabled.api_v1:
- image_list = glance_client.list_images(
- detail=True, **params)['images']
- else:
- image_list = glance_client.list_images(params)['images']
+ image_list = glance_client.list_images(params)['images']
self.assertEqual(2, len(image_list),
'Unexpected number of images for '
'v2:test_create_backup; was the oldest backup not '
@@ -733,23 +716,16 @@
"""Test shelving and unshelving server"""
if CONF.image_feature_enabled.api_v2:
glance_client = self.os_primary.image_client_v2
- elif CONF.image_feature_enabled.api_v1:
- glance_client = self.os_primary.image_client
else:
raise lib_exc.InvalidConfiguration(
- 'Either api_v1 or api_v2 must be True in '
- '[image-feature-enabled].')
+ 'api_v2 must be True in [image-feature-enabled].')
compute.shelve_server(self.client, self.server_id,
force_shelve_offload=True)
server = self.client.show_server(self.server_id)['server']
image_name = server['name'] + '-shelved'
params = {'name': image_name}
- if CONF.image_feature_enabled.api_v2:
- images = glance_client.list_images(params)['images']
- elif CONF.image_feature_enabled.api_v1:
- images = glance_client.list_images(
- detail=True, **params)['images']
+ images = glance_client.list_images(params)['images']
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 4f85048..bd383d3 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -508,10 +508,7 @@
server = self.client.show_server(self.server_id)['server']
image_name = server['name'] + '-shelved'
- if CONF.image_feature_enabled.api_v1:
- kwargs = {'name': image_name}
- else:
- kwargs = {'params': {'name': image_name}}
+ kwargs = {'params': {'name': image_name}}
images = self.images_client.list_images(**kwargs)['images']
self.assertEqual(1, len(images))
self.assertEqual(image_name, images[0]['name'])
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 11a1e6c..7bae712 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -12,10 +12,8 @@
# License for the specific language governing permissions and limitations
# under the License.
-import io
import time
-from tempest.common import image as common_image
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
@@ -56,17 +54,7 @@
name = data_utils.rand_name(cls.__name__ + "-image")
kwargs['name'] = name
- params = cls._get_create_params(**kwargs)
- if data:
- # NOTE: On glance v1 API, the data should be passed on
- # a header. Then here handles the data separately.
- params['data'] = data
-
- image = cls.client.create_image(**params)
- # Image objects returned by the v1 client have the image
- # data inside a dict that is keyed against 'image'.
- if 'image' in image:
- image = image['image']
+ image = cls.client.create_image(**kwargs)
cls.created_images.append(image['id'])
cls.addClassResourceCleanup(cls.client.wait_for_resource_deletion,
image['id'])
@@ -74,54 +62,6 @@
cls.client.delete_image, image['id'])
return image
- @classmethod
- def _get_create_params(cls, **kwargs):
- return kwargs
-
-
-class BaseV1ImageTest(BaseImageTest):
-
- @classmethod
- def skip_checks(cls):
- super(BaseV1ImageTest, cls).skip_checks()
- if not CONF.image_feature_enabled.api_v1:
- msg = "Glance API v1 not supported"
- raise cls.skipException(msg)
-
- @classmethod
- def setup_clients(cls):
- super(BaseV1ImageTest, cls).setup_clients()
- cls.client = cls.os_primary.image_client
-
- @classmethod
- def _get_create_params(cls, **kwargs):
- return {'headers': common_image.image_meta_to_headers(**kwargs)}
-
-
-class BaseV1ImageMembersTest(BaseV1ImageTest):
-
- credentials = ['primary', 'alt']
-
- @classmethod
- def setup_clients(cls):
- super(BaseV1ImageMembersTest, cls).setup_clients()
- cls.image_member_client = cls.os_primary.image_member_client
- cls.alt_image_member_client = cls.os_alt.image_member_client
- cls.alt_img_cli = cls.os_alt.image_client
-
- @classmethod
- def resource_setup(cls):
- super(BaseV1ImageMembersTest, cls).resource_setup()
- cls.alt_tenant_id = cls.alt_image_member_client.tenant_id
-
- def _create_image(self):
- image_file = io.BytesIO(data_utils.random_bytes())
- image = self.create_image(container_format='bare',
- disk_format='raw',
- is_public=False,
- data=image_file)
- return image['id']
-
class BaseV2ImageTest(BaseImageTest):
diff --git a/tempest/api/image/v1/__init__.py b/tempest/api/image/v1/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/api/image/v1/__init__.py
+++ /dev/null
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
deleted file mode 100644
index 5e2c8af..0000000
--- a/tempest/api/image/v1/test_image_members.py
+++ /dev/null
@@ -1,63 +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.
-
-
-from tempest.api.image import base
-from tempest.lib import decorators
-from tempest.lib import exceptions as lib_exc
-
-
-class ImageMembersTest(base.BaseV1ImageMembersTest):
- """Test image members"""
-
- @decorators.idempotent_id('1d6ef640-3a20-4c84-8710-d95828fdb6ad')
- def test_add_image_member(self):
- """Test adding member for image"""
- image = self._create_image()
- self.image_member_client.create_image_member(image, self.alt_tenant_id)
- body = self.image_member_client.list_image_members(image)
- members = body['members']
- members = [member['member_id'] for member in members]
- self.assertIn(self.alt_tenant_id, members)
- # get image as alt user
- self.alt_img_cli.show_image(image)
-
- @decorators.idempotent_id('6a5328a5-80e8-4b82-bd32-6c061f128da9')
- def test_get_shared_images(self):
- """Test getting shared images"""
- image = self._create_image()
- self.image_member_client.create_image_member(image, self.alt_tenant_id)
- share_image = self._create_image()
- self.image_member_client.create_image_member(share_image,
- self.alt_tenant_id)
- body = self.image_member_client.list_shared_images(
- self.alt_tenant_id)
- images = body['shared_images']
- images = [img['image_id'] for img in images]
- self.assertIn(share_image, images)
- self.assertIn(image, images)
-
- @decorators.idempotent_id('a76a3191-8948-4b44-a9d6-4053e5f2b138')
- def test_remove_member(self):
- """Test removing member from image"""
- image_id = self._create_image()
- self.image_member_client.create_image_member(image_id,
- self.alt_tenant_id)
- self.image_member_client.delete_image_member(image_id,
- self.alt_tenant_id)
- body = self.image_member_client.list_image_members(image_id)
- members = body['members']
- self.assertEmpty(members)
- self.assertRaises(
- lib_exc.NotFound, self.alt_img_cli.show_image, image_id)
diff --git a/tempest/api/image/v1/test_image_members_negative.py b/tempest/api/image/v1/test_image_members_negative.py
deleted file mode 100644
index 4e3c27c..0000000
--- a/tempest/api/image/v1/test_image_members_negative.py
+++ /dev/null
@@ -1,62 +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.
-
-from tempest.api.image import base
-from tempest.lib.common.utils import data_utils
-from tempest.lib import decorators
-from tempest.lib import exceptions as lib_exc
-
-
-class ImageMembersNegativeTest(base.BaseV1ImageMembersTest):
- """Negative tests of image members"""
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('147a9536-18e3-45da-91ea-b037a028f364')
- def test_add_member_with_non_existing_image(self):
- """Add member with non existing image"""
- non_exist_image = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound,
- self.image_member_client.create_image_member,
- non_exist_image, self.alt_tenant_id)
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('e1559f05-b667-4f1b-a7af-518b52dc0c0f')
- def test_delete_member_with_non_existing_image(self):
- """Delete member with non existing image"""
- non_exist_image = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound,
- self.image_member_client.delete_image_member,
- non_exist_image, self.alt_tenant_id)
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('f5720333-dd69-4194-bb76-d2f048addd56')
- def test_delete_member_with_non_existing_tenant(self):
- """Delete member from image with non existing tenant"""
- image_id = self._create_image()
- non_exist_tenant = data_utils.rand_uuid_hex()
- self.assertRaises(lib_exc.NotFound,
- self.image_member_client.delete_image_member,
- image_id, non_exist_tenant)
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('f25f89e4-0b6c-453b-a853-1f80b9d7ef26')
- def test_get_image_without_membership(self):
- """Get image without membership
-
- Image is hidden from another tenants.
- """
- image_id = self._create_image()
- self.assertRaises(lib_exc.NotFound,
- self.alt_img_cli.show_image,
- image_id)
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
deleted file mode 100644
index 6fd6c4e..0000000
--- a/tempest/api/image/v1/test_images.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# Copyright 2012 OpenStack Foundation
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import io
-
-from tempest.api.image import base
-from tempest.common import image as common_image
-from tempest.common import waiters
-from tempest import config
-from tempest.lib.common.utils import data_utils
-from tempest.lib import decorators
-from tempest.lib import exceptions
-
-CONF = config.CONF
-
-
-def get_container_and_disk_format():
- a_formats = ['ami', 'ari', 'aki']
-
- container_format = CONF.image.container_formats[0]
-
- # In v1, If container_format is one of ['ami', 'ari', 'aki'], then
- # disk_format must be same with container_format.
- # If they are of different item sequence in tempest.conf, such as:
- # container_formats = ami,ari,aki,bare
- # disk_formats = ari,ami,aki,vhd
- # we can select one in disk_format list that is same with container_format.
- if container_format in a_formats:
- if container_format in CONF.image.disk_formats:
- disk_format = container_format
- else:
- msg = ("The container format and the disk format don't match. "
- "Container format: %(container)s, Disk format: %(disk)s." %
- {'container': container_format, 'disk':
- CONF.image.disk_formats})
- raise exceptions.InvalidConfiguration(msg)
- else:
- disk_format = CONF.image.disk_formats[0]
-
- return container_format, disk_format
-
-
-class CreateRegisterImagesTest(base.BaseV1ImageTest):
- """Here we test the registration and creation of images."""
-
- @decorators.idempotent_id('3027f8e6-3492-4a11-8575-c3293017af4d')
- def test_register_then_upload(self):
- """Register, then upload an image"""
- properties = {'prop1': 'val1'}
- container_format, disk_format = get_container_and_disk_format()
- image = self.create_image(name='New Name',
- container_format=container_format,
- disk_format=disk_format,
- is_public=False,
- properties=properties)
- self.assertEqual('New Name', image.get('name'))
- self.assertFalse(image.get('is_public'))
- self.assertEqual('queued', image.get('status'))
- for key, val in properties.items():
- self.assertEqual(val, image.get('properties')[key])
-
- # Now try uploading an image file
- image_file = io.BytesIO(data_utils.random_bytes())
- body = self.client.update_image(image['id'], data=image_file)['image']
- self.assertIn('size', body)
- self.assertEqual(1024, body.get('size'))
-
- @decorators.idempotent_id('69da74d9-68a9-404b-9664-ff7164ccb0f5')
- def test_register_remote_image(self):
- """Register a new remote image"""
- container_format, disk_format = get_container_and_disk_format()
- body = self.create_image(name='New Remote Image',
- container_format=container_format,
- disk_format=disk_format, is_public=False,
- location=CONF.image.http_image,
- properties={'key1': 'value1',
- 'key2': 'value2'})
- self.assertEqual('New Remote Image', body.get('name'))
- self.assertFalse(body.get('is_public'))
- self.assertEqual('active', body.get('status'))
- properties = body.get('properties')
- self.assertEqual(properties['key1'], 'value1')
- self.assertEqual(properties['key2'], 'value2')
-
- @decorators.idempotent_id('6d0e13a7-515b-460c-b91f-9f4793f09816')
- def test_register_http_image(self):
- """Register a new image from an http image path url"""
- container_format, disk_format = get_container_and_disk_format()
- image = self.create_image(name='New Http Image',
- container_format=container_format,
- disk_format=disk_format, is_public=False,
- copy_from=CONF.image.http_image)
- self.assertEqual('New Http Image', image.get('name'))
- self.assertFalse(image.get('is_public'))
- waiters.wait_for_image_status(self.client, image['id'], 'active')
- self.client.show_image(image['id'])
-
- @decorators.idempotent_id('05b19d55-140c-40d0-b36b-fafd774d421b')
- def test_register_image_with_min_ram(self):
- """Register an image with min ram"""
- container_format, disk_format = get_container_and_disk_format()
- properties = {'prop1': 'val1'}
- body = self.create_image(name='New_image_with_min_ram',
- container_format=container_format,
- disk_format=disk_format,
- is_public=False,
- min_ram=40,
- properties=properties)
- self.assertEqual('New_image_with_min_ram', body.get('name'))
- self.assertFalse(body.get('is_public'))
- self.assertEqual('queued', body.get('status'))
- self.assertEqual(40, body.get('min_ram'))
- for key, val in properties.items():
- self.assertEqual(val, body.get('properties')[key])
- self.client.delete_image(body['id'])
-
-
-class ListImagesTest(base.BaseV1ImageTest):
- """Here we test the listing of image information"""
-
- @classmethod
- def skip_checks(cls):
- super(ListImagesTest, cls).skip_checks()
- if (len(CONF.image.container_formats) < 2 or
- len(CONF.image.disk_formats) < 2):
- skip_msg = ("%s skipped as multiple container formats "
- "or disk formats are not available." % cls.__name__)
- raise cls.skipException(skip_msg)
-
- @classmethod
- def resource_setup(cls):
- super(ListImagesTest, cls).resource_setup()
- # We add a few images here to test the listing functionality of
- # the images API
- a_formats = ['ami', 'ari', 'aki']
-
- (cls.container_format,
- container_format_alt) = CONF.image.container_formats[:2]
- cls.disk_format, cls.disk_format_alt = CONF.image.disk_formats[:2]
- if cls.container_format in a_formats:
- cls.disk_format = cls.container_format
- if container_format_alt in a_formats:
- cls.disk_format_alt = container_format_alt
-
- img1 = cls._create_remote_image('one', cls.container_format,
- cls.disk_format)
- img2 = cls._create_remote_image('two', container_format_alt,
- cls.disk_format_alt)
- img3 = cls._create_remote_image('dup', cls.container_format,
- cls.disk_format)
- img4 = cls._create_remote_image('dup', cls.container_format,
- cls.disk_format)
- img5 = cls._create_standard_image('1', container_format_alt,
- cls.disk_format_alt, 42)
- img6 = cls._create_standard_image('2', container_format_alt,
- cls.disk_format_alt, 142)
- img7 = cls._create_standard_image('33', cls.container_format,
- cls.disk_format, 142)
- img8 = cls._create_standard_image('33', cls.container_format,
- cls.disk_format, 142)
- cls.created_set = set(cls.created_images)
- # same container format
- cls.same_container_format_set = set((img1, img3, img4, img7, img8))
- # same disk format
- cls.same_disk_format_set = set((img2, img5, img6))
-
- # 1x with size 42
- cls.size42_set = set((img5,))
- # 3x with size 142
- cls.size142_set = set((img6, img7, img8,))
- # dup named
- cls.dup_set = set((img3, img4))
-
- @classmethod
- def _create_remote_image(cls, name, container_format, disk_format):
- """Create a new remote image and return newly-registered image-id"""
-
- name = 'New Remote Image %s' % name
- location = CONF.image.http_image
- image = cls.create_image(name=name,
- container_format=container_format,
- disk_format=disk_format,
- is_public=False,
- location=location)
- return image['id']
-
- @classmethod
- def _create_standard_image(cls, name, container_format,
- disk_format, size):
- """Create a new standard image and return newly-registered image-id
-
- Note that the size of the new image is a random number between
- 1024 and 4096
- """
- image_file = io.BytesIO(data_utils.random_bytes(size))
- name = 'New Standard Image %s' % name
- image = cls.create_image(name=name,
- container_format=container_format,
- disk_format=disk_format,
- is_public=False, data=image_file)
- return image['id']
-
- @decorators.idempotent_id('246178ab-3b33-4212-9a4b-a7fe8261794d')
- def test_index_no_params(self):
- """Simple test to see all fixture images returned"""
- images_list = self.client.list_images()['images']
- image_list = [image['id'] for image in images_list]
- for image_id in self.created_images:
- self.assertIn(image_id, image_list)
-
- @decorators.idempotent_id('f1755589-63d6-4468-b098-589820eb4031')
- def test_index_disk_format(self):
- """Test listing images by disk format"""
- images_list = self.client.list_images(
- disk_format=self.disk_format_alt)['images']
- for image in images_list:
- self.assertEqual(image['disk_format'], self.disk_format_alt)
- result_set = set(map(lambda x: x['id'], images_list))
- self.assertTrue(self.same_disk_format_set <= result_set)
- self.assertFalse(self.created_set - self.same_disk_format_set <=
- result_set)
-
- @decorators.idempotent_id('2143655d-96d9-4bec-9188-8674206b4b3b')
- def test_index_container_format(self):
- """Test listing images by container format"""
- images_list = self.client.list_images(
- container_format=self.container_format)['images']
- for image in images_list:
- self.assertEqual(image['container_format'], self.container_format)
- result_set = set(map(lambda x: x['id'], images_list))
- self.assertTrue(self.same_container_format_set <= result_set)
- self.assertFalse(self.created_set - self.same_container_format_set <=
- result_set)
-
- @decorators.idempotent_id('feb32ac6-22bb-4a16-afd8-9454bb714b14')
- def test_index_max_size(self):
- """Test listing images by max size"""
- images_list = self.client.list_images(size_max=42)['images']
- for image in images_list:
- self.assertLessEqual(image['size'], 42)
- result_set = set(map(lambda x: x['id'], images_list))
- self.assertTrue(self.size42_set <= result_set)
- self.assertFalse(self.created_set - self.size42_set <= result_set)
-
- @decorators.idempotent_id('6ffc16d0-4cbf-4401-95c8-4ac63eac34d8')
- def test_index_min_size(self):
- """Test listing images by min size"""
- images_list = self.client.list_images(size_min=142)['images']
- for image in images_list:
- self.assertGreaterEqual(image['size'], 142)
- result_set = set(map(lambda x: x['id'], images_list))
- self.assertTrue(self.size142_set <= result_set)
- self.assertFalse(self.size42_set <= result_set)
-
- @decorators.idempotent_id('e5dc26d9-9aa2-48dd-bda5-748e1445da98')
- def test_index_status_active_detail(self):
- """Test listing active images sorting by size in descending order"""
- images_list = self.client.list_images(detail=True,
- status='active',
- sort_key='size',
- sort_dir='desc')['images']
- top_size = images_list[0]['size'] # We have non-zero sized images
- for image in images_list:
- size = image['size']
- self.assertLessEqual(size, top_size)
- top_size = size
- self.assertEqual(image['status'], 'active')
-
- @decorators.idempotent_id('097af10a-bae8-4342-bff4-edf89969ed2a')
- def test_index_name(self):
- """Test listing images by its name"""
- images_list = self.client.list_images(
- detail=True,
- name='New Remote Image dup')['images']
- result_set = set(map(lambda x: x['id'], images_list))
- for image in images_list:
- self.assertEqual(image['name'], 'New Remote Image dup')
- self.assertTrue(self.dup_set <= result_set)
- self.assertFalse(self.created_set - self.dup_set <= result_set)
-
-
-class UpdateImageMetaTest(base.BaseV1ImageTest):
- """Test image metadata"""
-
- @classmethod
- def resource_setup(cls):
- super(UpdateImageMetaTest, cls).resource_setup()
- container_format, disk_format = get_container_and_disk_format()
- cls.image_id = cls._create_standard_image('1', container_format,
- disk_format, 42)
-
- @classmethod
- def _create_standard_image(cls, name, container_format,
- disk_format, size):
- """Create a new standard image and return newly-registered image-id"""
-
- image_file = io.BytesIO(data_utils.random_bytes(size))
- name = 'New Standard Image %s' % name
- image = cls.create_image(name=name,
- container_format=container_format,
- disk_format=disk_format,
- is_public=False, data=image_file,
- properties={'key1': 'value1'})
- return image['id']
-
- @decorators.idempotent_id('01752c1c-0275-4de3-9e5b-876e44541928')
- def test_list_image_metadata(self):
- """Test listing image metadata"""
- # All metadata key/value pairs for an image should be returned
- resp = self.client.check_image(self.image_id)
- resp_metadata = common_image.get_image_meta_from_headers(resp)
- expected = {'key1': 'value1'}
- self.assertEqual(expected, resp_metadata['properties'])
-
- @decorators.idempotent_id('d6d7649c-08ce-440d-9ea7-e3dda552f33c')
- def test_update_image_metadata(self):
- """Test updating image metadata"""
- # The metadata for the image should match the updated values
- req_metadata = {'key1': 'alt1', 'key2': 'value2'}
- resp = self.client.check_image(self.image_id)
- metadata = common_image.get_image_meta_from_headers(resp)
- self.assertEqual(metadata['properties'], {'key1': 'value1'})
- metadata['properties'].update(req_metadata)
- headers = common_image.image_meta_to_headers(
- properties=metadata['properties'])
- self.client.update_image(self.image_id, headers=headers)
- resp = self.client.check_image(self.image_id)
- resp_metadata = common_image.get_image_meta_from_headers(resp)
- self.assertEqual(req_metadata, resp_metadata['properties'])
diff --git a/tempest/api/image/v1/test_images_negative.py b/tempest/api/image/v1/test_images_negative.py
deleted file mode 100644
index 2af1288..0000000
--- a/tempest/api/image/v1/test_images_negative.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# 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.
-
-
-from tempest.api.image import base
-from tempest.lib.common.utils import data_utils
-from tempest.lib import decorators
-from tempest.lib import exceptions as lib_exc
-
-
-class CreateDeleteImagesNegativeTest(base.BaseV1ImageTest):
- """Here are negative tests for the deletion and creation of images."""
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('036ede36-6160-4463-8c01-c781eee6369d')
- def test_register_with_invalid_container_format(self):
- """Create image with invalid container format
-
- Negative tests for invalid data supplied to POST /images
- """
- self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- headers={'x-image-meta-name': 'test',
- 'x-image-meta-container_format': 'wrong',
- 'x-image-meta-disk_format': 'vhd'})
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('993face5-921d-4e84-aabf-c1bba4234a67')
- def test_register_with_invalid_disk_format(self):
- """Create image with invalid disk format"""
- self.assertRaises(lib_exc.BadRequest, self.client.create_image,
- headers={'x-image-meta-name': 'test',
- 'x-image-meta-container_format': 'bare',
- 'x-image-meta-disk_format': 'wrong'})
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('ec652588-7e3c-4b67-a2f2-0fa96f57c8fc')
- def test_delete_non_existent_image(self):
- """Return an error while trying to delete a non-existent image"""
-
- non_existent_image_id = data_utils.rand_uuid()
- self.assertRaises(lib_exc.NotFound, self.client.delete_image,
- non_existent_image_id)
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('04f72aa3-fcec-45a3-81a3-308ef7cc82bc')
- def test_delete_image_blank_id(self):
- """Return an error while trying to delete an image with blank Id"""
- self.assertRaises(lib_exc.NotFound, self.client.delete_image, '')
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('950e5054-a3c7-4dee-ada5-e576f1087abd')
- def test_delete_image_non_hex_string_id(self):
- """Return an error while trying to delete an image with non hex id"""
- invalid_image_id = data_utils.rand_uuid()[:-1] + "j"
- self.assertRaises(lib_exc.NotFound, self.client.delete_image,
- invalid_image_id)
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('4ed757cd-450c-44b1-9fd1-c819748c650d')
- def test_delete_image_negative_image_id(self):
- """Return an error while trying to delete an image with negative id"""
- self.assertRaises(lib_exc.NotFound, self.client.delete_image, -1)
-
- @decorators.attr(type=['negative'])
- @decorators.idempotent_id('a4a448ab-3db2-4d2d-b9b2-6a1271241dfe')
- def test_delete_image_id_over_character_limit(self):
- """Return an error while trying to delete image with id over limit"""
- overlimit_image_id = data_utils.rand_uuid() + "1"
- self.assertRaises(lib_exc.NotFound, self.client.delete_image,
- overlimit_image_id)
diff --git a/tempest/clients.py b/tempest/clients.py
index b640237..5b31cf8 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -83,8 +83,6 @@
def _set_image_clients(self):
if CONF.service_available.glance:
- self.image_client = self.image_v1.ImagesClient()
- self.image_member_client = self.image_v1.ImageMembersClient()
self.image_client_v2 = self.image_v2.ImagesClient()
self.image_member_client_v2 = self.image_v2.ImageMembersClient()
self.image_cache_client = self.image_v2.ImageCacheClient()
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 3d476b9..b105c70 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -118,25 +118,16 @@
# Since we want to verify that the configuration is correct, we cannot
# rely on a specific version of the API being available.
try:
- _, versions = os.image_v1.ImagesClient().get_versions()
+ versions = os.image_v2.VersionsClient().list_versions()['versions']
+ versions = [x['id'] for x in versions]
except lib_exc.NotFound:
- # If not found, we use v2. The assumption is that either v1 or v2
- # are available, since glance is marked as available in the catalog.
- # If not, glance should be disabled in Tempest conf.
- try:
- versions = os.image_v2.VersionsClient().list_versions()['versions']
- versions = [x['id'] for x in versions]
- except lib_exc.NotFound:
- msg = ('Glance is available in the catalog, but no known version, '
- '(v1.x or v2.x) of Glance could be found, so Glance should '
- 'be configured as not available')
- LOG.warning(msg)
- print_and_or_update('glance', 'service-available', False, update)
- return
+ msg = ('Glance is available in the catalog, but no known version, '
+ 'of Glance could be found, so Glance should '
+ 'be configured as not available')
+ LOG.warning(msg)
+ print_and_or_update('glance', 'service-available', False, update)
+ return
- if CONF.image_feature_enabled.api_v1 != contains_version('v1.', versions):
- print_and_or_update('api_v1', 'image-feature-enabled',
- not CONF.image_feature_enabled.api_v1, update)
if CONF.image_feature_enabled.api_v2 != contains_version('v2.', versions):
print_and_or_update('api_v2', 'image-feature-enabled',
not CONF.image_feature_enabled.api_v2, update)
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 291f201..d3be6fd 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -16,12 +16,10 @@
from oslo_log import log as logging
-from tempest.common import image as common_image
from tempest import config
from tempest import exceptions
from tempest.lib.common.utils import test_utils
from tempest.lib import exceptions as lib_exc
-from tempest.lib.services.image.v1 import images_client as images_v1_client
CONF = config.CONF
LOG = logging.getLogger(__name__)
@@ -156,17 +154,7 @@
The client should have a show_image(image_id) method to get the image.
The client should also have build_interval and build_timeout attributes.
"""
- if isinstance(client, images_v1_client.ImagesClient):
- # The 'check_image' method is used here because the show_image method
- # returns image details plus the image itself which is very expensive.
- # The 'check_image' method returns just image details.
- def _show_image_v1(image_id):
- resp = client.check_image(image_id)
- return common_image.get_image_meta_from_headers(resp)
-
- show_image = _show_image_v1
- else:
- show_image = client.show_image
+ show_image = client.show_image
current_status = 'An unknown status'
start = int(time.time())
diff --git a/tempest/config.py b/tempest/config.py
index 5107726..ee083d8 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -719,14 +719,6 @@
'are current one. In future, Tempest will '
'test v2 APIs only so this config option '
'will be removed.'),
- cfg.BoolOpt('api_v1',
- default=False,
- help="Is the v1 image API enabled",
- deprecated_for_removal=True,
- deprecated_reason='Glance v1 APIs are deprecated and v2 APIs '
- 'are current one. In future, Tempest will '
- 'test v2 APIs only so this config option '
- 'will be removed.'),
# Image import feature is setup in devstack victoria onwards.
# Once all stable branches setup the same via glance standalone
# mode or with uwsgi, we can remove this config option.
diff --git a/tempest/lib/services/clients.py b/tempest/lib/services/clients.py
index 8b5c758..86ce6ec 100644
--- a/tempest/lib/services/clients.py
+++ b/tempest/lib/services/clients.py
@@ -48,7 +48,6 @@
'placement': placement,
'identity.v2': identity.v2,
'identity.v3': identity.v3,
- 'image.v1': image.v1,
'image.v2': image.v2,
'network': network,
'object-storage': object_storage,
diff --git a/tempest/lib/services/image/__init__.py b/tempest/lib/services/image/__init__.py
index 4b01663..ee1c32c 100644
--- a/tempest/lib/services/image/__init__.py
+++ b/tempest/lib/services/image/__init__.py
@@ -12,7 +12,6 @@
# License for the specific language governing permissions and limitations under
# the License.
-from tempest.lib.services.image import v1
from tempest.lib.services.image import v2
-__all__ = ['v1', 'v2']
+__all__ = ['v2']
diff --git a/tempest/lib/services/image/v1/__init__.py b/tempest/lib/services/image/v1/__init__.py
deleted file mode 100644
index 1f33cef..0000000
--- a/tempest/lib/services/image/v1/__init__.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright (c) 2016 Hewlett-Packard Enterprise Development Company, L.P.
-#
-# 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 warnings
-
-from tempest.lib.services.image.v1.image_members_client import \
- ImageMembersClient
-from tempest.lib.services.image.v1.images_client import ImagesClient
-
-__all__ = ['ImageMembersClient', 'ImagesClient']
-
-
-warnings.warn(
- "The tempest.lib.services.image.v1 module (Image v1 APIs service "
- "clients) is deprecated in favor of tempest.lib.services.image.v2 "
- "(Image v2 APIs service clients) and will be removed once Tempest stop "
- "supporting stable Ussuri.", DeprecationWarning)
diff --git a/tempest/lib/services/image/v1/image_members_client.py b/tempest/lib/services/image/v1/image_members_client.py
deleted file mode 100644
index 7499ec0..0000000
--- a/tempest/lib/services/image/v1/image_members_client.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# 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 oslo_serialization import jsonutils as json
-
-from tempest.lib.common import rest_client
-
-
-class ImageMembersClient(rest_client.RestClient):
- api_version = "v1"
-
- def list_image_members(self, image_id):
- """List all members of an image."""
- url = 'images/%s/members' % image_id
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def list_shared_images(self, tenant_id):
- """List image memberships for the given tenant.
-
- For a full list of available parameters, please refer to the official
- API reference:
- https://docs.openstack.org/api-ref/image/v1/#list-shared-images
- """
-
- url = 'shared-images/%s' % tenant_id
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def create_image_member(self, image_id, member_id, **kwargs):
- """Add a member to an image.
-
- For a full list of available parameters, please refer to the official
- API reference:
- https://docs.openstack.org/api-ref/image/v1/#add-member-to-image
- """
- url = 'images/%s/members/%s' % (image_id, member_id)
- body = json.dumps({'member': kwargs})
- resp, __ = self.put(url, body)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
-
- def delete_image_member(self, image_id, member_id):
- """Removes a membership from the image.
-
- For a full list of available parameters, please refer to the official
- API reference:
- https://docs.openstack.org/api-ref/image/v1/#remove-member
- """
- url = 'images/%s/members/%s' % (image_id, member_id)
- resp, __ = self.delete(url)
- self.expected_success(204, resp.status)
- return rest_client.ResponseBody(resp)
diff --git a/tempest/lib/services/image/v1/images_client.py b/tempest/lib/services/image/v1/images_client.py
deleted file mode 100644
index c9a4a94..0000000
--- a/tempest/lib/services/image/v1/images_client.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# 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 functools
-from urllib import parse as urllib
-
-from oslo_serialization import jsonutils as json
-
-from tempest.lib.common import rest_client
-from tempest.lib import exceptions as lib_exc
-
-CHUNKSIZE = 1024 * 64 # 64kB
-
-
-class ImagesClient(rest_client.RestClient):
- api_version = "v1"
-
- def _create_with_data(self, headers, data):
- # We are going to do chunked transfert, so split the input data
- # info fixed-sized chunks.
- headers['Content-Type'] = 'application/octet-stream'
- data = iter(functools.partial(data.read, CHUNKSIZE), b'')
- resp, body = self.request('POST', 'images',
- headers=headers, body=data, chunked=True)
- self._error_checker(resp, body)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def _update_with_data(self, image_id, headers, data):
- # We are going to do chunked transfert, so split the input data
- # info fixed-sized chunks.
- headers['Content-Type'] = 'application/octet-stream'
- data = iter(functools.partial(data.read, CHUNKSIZE), b'')
- url = 'images/%s' % image_id
- resp, body = self.request('PUT', url, headers=headers,
- body=data, chunked=True)
- self._error_checker(resp, body)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- @property
- def http(self):
- if self._http is None:
- self._http = self._get_http()
- return self._http
-
- def create_image(self, data=None, headers=None):
- """Create an image.
-
- For a full list of available parameters, please refer to the official
- API reference:
- https://docs.openstack.org/api-ref/image/v1/index.html#create-image
- """
- if headers is None:
- headers = {}
-
- if data is not None:
- return self._create_with_data(headers, data)
-
- resp, body = self.post('images', None, headers)
- self.expected_success(201, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def update_image(self, image_id, data=None, headers=None):
- """Update an image.
-
- For a full list of available parameters, please refer to the official
- API reference:
- https://docs.openstack.org/api-ref/image/v1/index.html#update-image
- """
- if headers is None:
- headers = {}
-
- if data is not None:
- return self._update_with_data(image_id, headers, data)
-
- url = 'images/%s' % image_id
- resp, body = self.put(url, None, headers)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def delete_image(self, image_id):
- url = 'images/%s' % image_id
- resp, body = self.delete(url)
- self.expected_success(200, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def list_images(self, detail=False, **kwargs):
- """Return a list of all images filtered by input parameters.
-
- For a full list of available parameters, please refer to the official
- API reference:
- https://docs.openstack.org/api-ref/image/v1/#list-images
-
- Most parameters except the following are passed to the API without
- any changes.
- :param changes_since: The name is changed to changes-since
- """
- url = 'images'
-
- if detail:
- url += '/detail'
-
- if 'changes_since' in kwargs:
- kwargs['changes-since'] = kwargs.pop('changes_since')
-
- if kwargs:
- url += '?%s' % urllib.urlencode(kwargs)
-
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- body = json.loads(body)
- return rest_client.ResponseBody(resp, body)
-
- def check_image(self, image_id):
- """Check image metadata."""
- url = 'images/%s' % image_id
- resp, body = self.head(url)
- self.expected_success(200, resp.status)
- return rest_client.ResponseBody(resp, body)
-
- def show_image(self, image_id):
- """Get image details plus the image itself."""
- url = 'images/%s' % image_id
- resp, body = self.get(url)
- self.expected_success(200, resp.status)
- return rest_client.ResponseBodyData(resp, body)
-
- def is_resource_deleted(self, id):
- try:
- resp = self.check_image(id)
- if resp.response["x-image-meta-status"] == 'deleted':
- return True
- except lib_exc.NotFound:
- return True
- return False
-
- @property
- def resource_type(self):
- """Returns the primary type of resource this client works with."""
- return 'image_meta'
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 1469bcf..0450d94 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -25,7 +25,6 @@
from oslo_utils import netutils
from tempest.common import compute
-from tempest.common import image as common_image
from tempest.common.utils.linux import remote_client
from tempest.common.utils import net_utils
from tempest.common import waiters
@@ -124,15 +123,11 @@
"""This setup the service clients for the tests"""
super(ScenarioTest, cls).setup_clients()
if CONF.service_available.glance:
- # Check if glance v1 is available to determine which client to use.
- if CONF.image_feature_enabled.api_v1:
- cls.image_client = cls.os_primary.image_client
- elif CONF.image_feature_enabled.api_v2:
+ if CONF.image_feature_enabled.api_v2:
cls.image_client = cls.os_primary.image_client_v2
else:
raise lib_exc.InvalidConfiguration(
- 'Either api_v1 or api_v2 must be True in '
- '[image-feature-enabled].')
+ 'api_v2 must be True in [image-feature-enabled].')
cls.setup_compute_client(cls)
cls.setup_network_client(cls)
@@ -371,11 +366,7 @@
if size is None:
size = CONF.volume.volume_size
if imageRef:
- if CONF.image_feature_enabled.api_v1:
- resp = self.image_client.check_image(imageRef)
- image = common_image.get_image_meta_from_headers(resp)
- else:
- image = self.image_client.show_image(imageRef)
+ image = self.image_client.show_image(imageRef)
min_disk = image.get('min_disk')
size = max(size, min_disk)
if name is None:
@@ -796,27 +787,18 @@
'name': name,
'container_format': img_container_format,
'disk_format': img_disk_format or img_container_format,
+ 'visibility': 'private'
}
- if CONF.image_feature_enabled.api_v1:
- params['is_public'] = 'False'
- if img_properties:
- params['properties'] = img_properties
- params = {'headers': common_image.image_meta_to_headers(**params)}
- else:
- params['visibility'] = 'private'
- # Additional properties are flattened out in the v2 API.
- if img_properties:
- params.update(img_properties)
+ # Additional properties are flattened out in the v2 API.
+ if img_properties:
+ params.update(img_properties)
params.update(kwargs)
body = self.image_client.create_image(**params)
image = body['image'] if 'image' in body else body
self.addCleanup(self.image_client.delete_image, image['id'])
self.assertEqual("queued", image['status'])
with open(img_path, 'rb') as image_file:
- if CONF.image_feature_enabled.api_v1:
- self.image_client.update_image(image['id'], data=image_file)
- else:
- self.image_client.store_image_file(image['id'], image_file)
+ self.image_client.store_image_file(image['id'], image_file)
LOG.debug("image:%s", image['id'])
return image['id']
@@ -864,15 +846,9 @@
self.addCleanup(test_utils.call_and_ignore_notfound_exc,
_image_client.delete_image, image_id)
- if CONF.image_feature_enabled.api_v1:
- # In glance v1 the additional properties are stored in the headers
- resp = _image_client.check_image(image_id)
- snapshot_image = common_image.get_image_meta_from_headers(resp)
- image_props = snapshot_image.get('properties', {})
- else:
- # In glance v2 the additional properties are flattened.
- snapshot_image = _image_client.show_image(image_id)
- image_props = snapshot_image
+ # In glance v2 the additional properties are flattened.
+ snapshot_image = _image_client.show_image(image_id)
+ image_props = snapshot_image
bdm = image_props.get('block_device_mapping')
if bdm:
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 05ea84e..fa43e58 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -178,13 +178,13 @@
def test_verify_glance_version_no_v2_with_v1_1(self):
# This test verifies that wrong config api_v2 = True is detected
class FakeClient(object):
- def get_versions(self):
- return (None, ['v1.1'])
+ def list_versions(self):
+ return {'versions': [{'id': 'v1.1'}]}
fake_os = mock.MagicMock()
fake_module = mock.MagicMock()
- fake_module.ImagesClient = FakeClient
- fake_os.image_v1 = fake_module
+ fake_module.VersionsClient = FakeClient
+ fake_os.image_v2 = fake_module
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
@@ -194,53 +194,28 @@
def test_verify_glance_version_no_v2_with_v1_0(self):
# This test verifies that wrong config api_v2 = True is detected
class FakeClient(object):
- def get_versions(self):
- return (None, ['v1.0'])
+ def list_versions(self):
+ return {'versions': [{'id': 'v1.0'}]}
fake_os = mock.MagicMock()
fake_module = mock.MagicMock()
- fake_module.ImagesClient = FakeClient
- fake_os.image_v1 = fake_module
+ fake_module.VersionsClient = FakeClient
+ fake_os.image_v2 = fake_module
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_glance_api_versions(fake_os, True)
print_mock.assert_called_with('api_v2', 'image-feature-enabled',
False, True)
- def test_verify_glance_version_no_v1(self):
- # This test verifies that wrong config api_v1 = True is detected
- class FakeClient(object):
- def get_versions(self):
- raise lib_exc.NotFound()
-
- def list_versions(self):
- return {'versions': [{'id': 'v2.0'}]}
-
- fake_os = mock.MagicMock()
- fake_module = mock.MagicMock()
- fake_module.ImagesClient = FakeClient
- fake_module.VersionsClient = FakeClient
- fake_os.image_v1 = fake_module
- fake_os.image_v2 = fake_module
- with mock.patch.object(verify_tempest_config,
- 'print_and_or_update') as print_mock:
- verify_tempest_config.verify_glance_api_versions(fake_os, True)
- print_mock.assert_not_called()
-
def test_verify_glance_version_no_version(self):
- # This test verifies that wrong config api_v1 = True is detected
+ # This test verifies that wrong config api_v2 = True is detected
class FakeClient(object):
- def get_versions(self):
- raise lib_exc.NotFound()
-
def list_versions(self):
raise lib_exc.NotFound()
fake_os = mock.MagicMock()
fake_module = mock.MagicMock()
- fake_module.ImagesClient = FakeClient
fake_module.VersionsClient = FakeClient
- fake_os.image_v1 = fake_module
fake_os.image_v2 = fake_module
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
diff --git a/tempest/tests/lib/services/image/v1/__init__.py b/tempest/tests/lib/services/image/v1/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/tests/lib/services/image/v1/__init__.py
+++ /dev/null
diff --git a/tempest/tests/lib/services/image/v1/test_image_members_client.py b/tempest/tests/lib/services/image/v1/test_image_members_client.py
deleted file mode 100644
index a5a6128..0000000
--- a/tempest/tests/lib/services/image/v1/test_image_members_client.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright 2016 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.lib.services.image.v1 import image_members_client
-from tempest.tests.lib import fake_auth_provider
-from tempest.tests.lib.services import base
-
-
-class TestImageMembersClient(base.BaseServiceTest):
- FAKE_LIST_IMAGE_MEMBERS = {
- "members": [
- {
- "created_at": "2013-10-07T17:58:03Z",
- "image_id": "dbc999e3-c52f-4200-bedd-3b18fe7f87fe",
- "member_id": "123456789",
- "status": "pending",
- "updated_at": "2013-10-07T17:58:03Z"
- },
- {
- "created_at": "2013-10-07T17:58:55Z",
- "image_id": "dbc999e3-c52f-4200-bedd-3b18fe7f87fe",
- "member_id": "987654321",
- "status": "accepted",
- "updated_at": "2013-10-08T12:08:55Z"
- }
- ]
- }
-
- def setUp(self):
- super(TestImageMembersClient, self).setUp()
- fake_auth = fake_auth_provider.FakeAuthProvider()
- self.client = image_members_client.ImageMembersClient(fake_auth,
- 'image',
- 'regionOne')
-
- def _test_list_image_members(self, bytes_body=False):
- self.check_service_client_function(
- self.client.list_image_members,
- 'tempest.lib.common.rest_client.RestClient.get',
- self.FAKE_LIST_IMAGE_MEMBERS,
- bytes_body,
- image_id="0ae74cc5-5147-4239-9ce2-b0c580f7067e")
-
- def _test_create_image_member(self, bytes_body=False):
- self.check_service_client_function(
- self.client.create_image_member,
- 'tempest.lib.common.rest_client.RestClient.put',
- {},
- bytes_body,
- image_id="0ae74cc5-5147-4239-9ce2-b0c580f7067e",
- member_id="8989447062e04a818baf9e073fd04fa7",
- status=204)
-
- def test_list_image_members_with_str_body(self):
- self._test_list_image_members()
-
- def test_list_image_members_with_bytes_body(self):
- self._test_list_image_members(bytes_body=True)
-
- def test_create_image_member_with_str_body(self):
- self._test_create_image_member()
-
- def test_create_image_member_with_bytes_body(self):
- self._test_create_image_member(bytes_body=True)
-
- def test_delete_image_member(self):
- self.check_service_client_function(
- self.client.delete_image_member,
- 'tempest.lib.common.rest_client.RestClient.delete',
- {},
- image_id="0ae74cc5-5147-4239-9ce2-b0c580f7067e",
- member_id="8989447062e04a818baf9e073fd04fa7",
- status=204)
diff --git a/tempest/tests/lib/services/registry_fixture.py b/tempest/tests/lib/services/registry_fixture.py
index a368705..d722b06 100644
--- a/tempest/tests/lib/services/registry_fixture.py
+++ b/tempest/tests/lib/services/registry_fixture.py
@@ -37,7 +37,7 @@
def __init__(self):
"""Initialise the registry fixture"""
self.services = set(['compute', 'identity.v2', 'identity.v3',
- 'image.v1', 'image.v2', 'network', 'placement',
+ 'image.v2', 'network', 'placement',
'volume.v2', 'volume.v3', 'object-storage'])
def _setUp(self):