Fix cleanup for volume backup tests
Volume backup tests create a container when swift is used as a backup driver. This causes a failure of an object storage test [1] as it expects no containers being present before the testing. This patch fixes the cleanup of volume backup tests by making sure that containers created during testing are deleted. The containers cleanup is called only when swift is present. When Swift is not used as a back up driver but is present, the cleanup tries to delete the containers anyway. This will not cause a failure as the delete_containers function catches the NotFound [2] error. [1] https://opendev.org/openstack/tempest/src/tempest/api/object_storage/test_account_services.py#L67 [2] https://opendev.org/openstack/tempest/src/tempest/api/object_storage/base.py#L50 Closes-Bug: #2028671 Change-Id: If94facd5a926f7eadd092dfc8f0368d8e4b8d630
This commit is contained in:
@@ -18,6 +18,7 @@ import time
|
||||
from oslo_log import log
|
||||
|
||||
from tempest.common import custom_matchers
|
||||
from tempest.common import object_storage
|
||||
from tempest.common import waiters
|
||||
from tempest import config
|
||||
from tempest.lib.common.utils import data_utils
|
||||
@@ -28,51 +29,6 @@ CONF = config.CONF
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
def delete_containers(containers, container_client, object_client):
|
||||
"""Remove containers and all objects in them.
|
||||
|
||||
The containers should be visible from the container_client given.
|
||||
Will not throw any error if the containers don't exist.
|
||||
|
||||
:param containers: List of containers(or string of a container)
|
||||
to be deleted
|
||||
:param container_client: Client to be used to delete containers
|
||||
:param object_client: Client to be used to delete objects
|
||||
"""
|
||||
if isinstance(containers, str):
|
||||
containers = [containers]
|
||||
|
||||
for cont in containers:
|
||||
try:
|
||||
delete_objects(cont, container_client, object_client)
|
||||
container_client.delete_container(cont)
|
||||
container_client.wait_for_resource_deletion(cont)
|
||||
except lib_exc.NotFound:
|
||||
LOG.warning(f"Container {cont} wasn't deleted as it wasn't found.")
|
||||
|
||||
|
||||
def delete_objects(container, container_client, object_client):
|
||||
"""Remove all objects from container.
|
||||
|
||||
Will not throw any error if the objects do not exist
|
||||
|
||||
:param container: Name of the container that contains the objects to be
|
||||
deleted
|
||||
:param container_client: Client to be used to list objects in
|
||||
the container
|
||||
:param object_client: Client to be used to delete objects
|
||||
"""
|
||||
params = {'limit': 9999, 'format': 'json'}
|
||||
_, objlist = container_client.list_container_objects(container, params)
|
||||
|
||||
for obj in objlist:
|
||||
try:
|
||||
object_client.delete_object(container, obj['name'])
|
||||
object_client.wait_for_resource_deletion(obj['name'], container)
|
||||
except lib_exc.NotFound:
|
||||
LOG.warning(f"Object {obj} wasn't deleted as it wasn't found.")
|
||||
|
||||
|
||||
class BaseObjectTest(tempest.test.BaseTestCase):
|
||||
|
||||
credentials = [['operator', CONF.object_storage.operator_role]]
|
||||
@@ -160,7 +116,8 @@ class BaseObjectTest(tempest.test.BaseTestCase):
|
||||
container_client = cls.container_client
|
||||
if object_client is None:
|
||||
object_client = cls.object_client
|
||||
delete_containers(cls.containers, container_client, object_client)
|
||||
object_storage.delete_containers(cls.containers, container_client,
|
||||
object_client)
|
||||
|
||||
def assertHeaders(self, resp, target, method):
|
||||
"""Check the existence and the format of response headers"""
|
||||
|
||||
@@ -16,6 +16,7 @@ import tarfile
|
||||
import tempfile
|
||||
|
||||
from tempest.api.object_storage import base
|
||||
from tempest.common import object_storage
|
||||
from tempest.common import utils
|
||||
from tempest.lib import decorators
|
||||
|
||||
@@ -30,8 +31,9 @@ class BulkTest(base.BaseObjectTest):
|
||||
def tearDown(self):
|
||||
# NOTE(andreaf) BulkTests needs to cleanup containers after each
|
||||
# test is executed.
|
||||
base.delete_containers(self.containers, self.container_client,
|
||||
self.object_client)
|
||||
object_storage.delete_containers(self.containers,
|
||||
self.container_client,
|
||||
self.object_client)
|
||||
super(BulkTest, self).tearDown()
|
||||
|
||||
def _create_archive(self):
|
||||
|
||||
@@ -18,6 +18,7 @@ import testtools
|
||||
|
||||
from tempest.api.object_storage import base
|
||||
from tempest.common import custom_matchers
|
||||
from tempest.common import object_storage
|
||||
from tempest import config
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
@@ -43,7 +44,7 @@ class AccountTest(base.BaseObjectTest):
|
||||
for i in range(ord('a'), ord('f') + 1):
|
||||
name = data_utils.rand_name(name='%s-' % bytes((i,)))
|
||||
cls.container_client.update_container(name)
|
||||
cls.addClassResourceCleanup(base.delete_containers,
|
||||
cls.addClassResourceCleanup(object_storage.delete_containers,
|
||||
[name],
|
||||
cls.container_client,
|
||||
cls.object_client)
|
||||
|
||||
@@ -19,6 +19,7 @@ from urllib import parse as urlparse
|
||||
import testtools
|
||||
|
||||
from tempest.api.object_storage import base
|
||||
from tempest.common import object_storage
|
||||
from tempest import config
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
@@ -74,7 +75,7 @@ class ContainerSyncTest(base.BaseObjectTest):
|
||||
(cls.container_client_alt, cls.object_client_alt)
|
||||
for cont_name, client in cls.clients.items():
|
||||
client[0].create_container(cont_name)
|
||||
cls.addClassResourceCleanup(base.delete_containers,
|
||||
cls.addClassResourceCleanup(object_storage.delete_containers,
|
||||
cont_name,
|
||||
client[0],
|
||||
client[1])
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import testtools
|
||||
|
||||
from tempest.api.object_storage import base
|
||||
from tempest.common import object_storage
|
||||
from tempest import config
|
||||
from tempest.lib.common.utils import data_utils
|
||||
from tempest.lib import decorators
|
||||
@@ -53,7 +54,7 @@ class ContainerTest(base.BaseObjectTest):
|
||||
# create container
|
||||
vers_container_name = data_utils.rand_name(name='TestVersionContainer')
|
||||
resp, _ = self.container_client.update_container(vers_container_name)
|
||||
self.addCleanup(base.delete_containers,
|
||||
self.addCleanup(object_storage.delete_containers,
|
||||
[vers_container_name],
|
||||
self.container_client,
|
||||
self.object_client)
|
||||
@@ -65,7 +66,7 @@ class ContainerTest(base.BaseObjectTest):
|
||||
resp, _ = self.container_client.update_container(
|
||||
base_container_name,
|
||||
**headers)
|
||||
self.addCleanup(base.delete_containers,
|
||||
self.addCleanup(object_storage.delete_containers,
|
||||
[base_container_name],
|
||||
self.container_client,
|
||||
self.object_client)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
# under the License.
|
||||
|
||||
from tempest.common import compute
|
||||
from tempest.common import object_storage
|
||||
from tempest.common import waiters
|
||||
from tempest import config
|
||||
from tempest.lib.common import api_version_utils
|
||||
@@ -64,6 +65,8 @@ class BaseVolumeTest(api_version_utils.BaseMicroversionTest,
|
||||
if CONF.service_available.glance:
|
||||
cls.images_client = cls.os_primary.image_client_v2
|
||||
|
||||
cls.container_client = cls.os_primary.container_client
|
||||
cls.object_client = cls.os_primary.object_client
|
||||
cls.backups_client = cls.os_primary.backups_client_latest
|
||||
cls.volumes_client = cls.os_primary.volumes_client_latest
|
||||
cls.messages_client = cls.os_primary.volume_messages_client_latest
|
||||
@@ -170,16 +173,31 @@ class BaseVolumeTest(api_version_utils.BaseMicroversionTest,
|
||||
snapshot['id'], 'available')
|
||||
return snapshot
|
||||
|
||||
def create_backup(self, volume_id, backup_client=None, **kwargs):
|
||||
def create_backup(self, volume_id, backup_client=None, object_client=None,
|
||||
container_client=None, **kwargs):
|
||||
"""Wrapper utility that returns a test backup."""
|
||||
if backup_client is None:
|
||||
backup_client = self.backups_client
|
||||
if container_client is None:
|
||||
container_client = self.container_client
|
||||
if object_client is None:
|
||||
object_client = self.object_client
|
||||
if 'name' not in kwargs:
|
||||
name = data_utils.rand_name(self.__class__.__name__ + '-Backup')
|
||||
kwargs['name'] = name
|
||||
if 'container' not in kwargs:
|
||||
cont_name = self.__class__.__name__ + '-backup-container'
|
||||
cont = data_utils.rand_name(cont_name)
|
||||
kwargs['container'] = cont
|
||||
|
||||
backup = backup_client.create_backup(
|
||||
volume_id=volume_id, **kwargs)['backup']
|
||||
|
||||
if CONF.service_available.swift:
|
||||
self.addCleanup(object_storage.delete_containers,
|
||||
kwargs['container'], container_client,
|
||||
object_client)
|
||||
|
||||
# addCleanup uses list pop to cleanup. Wait should be added before
|
||||
# the backup is deleted
|
||||
self.addCleanup(backup_client.wait_for_resource_deletion,
|
||||
|
||||
@@ -77,11 +77,13 @@ class VolumesBackupsTest(base.BaseVolumeTest):
|
||||
# Create a backup
|
||||
backup_name = data_utils.rand_name(
|
||||
self.__class__.__name__ + '-Backup')
|
||||
container_name = data_utils.rand_name(
|
||||
self.__class__.__name__ + '-Backup-container')
|
||||
description = data_utils.rand_name("volume-backup-description")
|
||||
backup = self.create_backup(volume_id=volume['id'],
|
||||
name=backup_name,
|
||||
description=description,
|
||||
container='container')
|
||||
container=container_name)
|
||||
self.assertEqual(backup_name, backup['name'])
|
||||
waiters.wait_for_volume_resource_status(self.volumes_client,
|
||||
volume['id'], 'available')
|
||||
@@ -90,7 +92,7 @@ class VolumesBackupsTest(base.BaseVolumeTest):
|
||||
backup = self.backups_client.show_backup(backup['id'])['backup']
|
||||
self.assertEqual(backup_name, backup['name'])
|
||||
self.assertEqual(description, backup['description'])
|
||||
self.assertEqual('container', backup['container'])
|
||||
self.assertEqual(container_name, backup['container'])
|
||||
|
||||
# Get all backups with detail
|
||||
backups = self.backups_client.list_backups(detail=True)['backups']
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
# 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_log import log
|
||||
|
||||
from tempest import config
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
CONF = config.CONF
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
def delete_containers(containers, container_client, object_client):
|
||||
"""Remove containers and all objects in them.
|
||||
|
||||
The containers should be visible from the container_client given.
|
||||
Will not throw any error if the containers don't exist.
|
||||
|
||||
:param containers: List of containers(or string of a container)
|
||||
to be deleted
|
||||
:param container_client: Client to be used to delete containers
|
||||
:param object_client: Client to be used to delete objects
|
||||
"""
|
||||
if isinstance(containers, str):
|
||||
containers = [containers]
|
||||
|
||||
for cont in containers:
|
||||
try:
|
||||
delete_objects(cont, container_client, object_client)
|
||||
container_client.delete_container(cont)
|
||||
container_client.wait_for_resource_deletion(cont)
|
||||
except lib_exc.NotFound:
|
||||
LOG.warning(f"Container {cont} wasn't deleted as it wasn't found.")
|
||||
|
||||
|
||||
def delete_objects(container, container_client, object_client):
|
||||
"""Remove all objects from container.
|
||||
|
||||
Will not throw any error if the objects do not exist
|
||||
|
||||
:param container: Name of the container that contains the objects to be
|
||||
deleted
|
||||
:param container_client: Client to be used to list objects in
|
||||
the container
|
||||
:param object_client: Client to be used to delete objects
|
||||
"""
|
||||
params = {'limit': 9999, 'format': 'json'}
|
||||
_, objlist = container_client.list_container_objects(container, params)
|
||||
|
||||
for obj in objlist:
|
||||
try:
|
||||
object_client.delete_object(container, obj['name'])
|
||||
object_client.wait_for_resource_deletion(obj['name'], container)
|
||||
except lib_exc.NotFound:
|
||||
LOG.warning(f"Object {obj} wasn't deleted as it wasn't found.")
|
||||
Reference in New Issue
Block a user