From a4057b10af44e7f21243e539dd2daad2ad61657b Mon Sep 17 00:00:00 2001 From: Lingxian Kong Date: Fri, 17 Apr 2020 15:14:54 +1200 Subject: Added checks for deleting datastore version * Hard delete the datastore_configuration_parameters table record. * Make 'datastore_version_id' nullable for 'instances' table. * Check if the datastore version is still being used before removal. Story: 2007563 Task: 39451 Change-Id: I84e4a31f14f9327cc01ff2d699167d91112e1565 --- .../notes/ussuri-fix-delete-datastore-version.yaml | 7 ++ tools/trove-pylint.config | 24 +++++++ trove/common/exception.py | 5 ++ trove/configuration/models.py | 77 ++++++---------------- .../versions/043_instance_ds_version_nullable.py | 50 ++++++++++++++ ...e_datastore_configuration_parameters_deleted.py | 37 +++++++++++ trove/extensions/mgmt/configuration/service.py | 6 +- trove/extensions/mgmt/configuration/views.py | 2 - trove/extensions/mgmt/datastores/service.py | 18 +++++ trove/extensions/mgmt/instances/models.py | 1 + trove/instance/models.py | 27 +++++--- trove/instance/views.py | 14 ++-- trove/taskmanager/models.py | 14 +++- trove/tests/api/configurations.py | 25 +++---- trove/tests/api/datastores.py | 8 +++ .../unittests/mgmt/test_datastore_controller.py | 43 +++++++++++- trove/tests/unittests/taskmanager/test_models.py | 3 +- 17 files changed, 269 insertions(+), 92 deletions(-) create mode 100644 releasenotes/notes/ussuri-fix-delete-datastore-version.yaml create mode 100644 trove/db/sqlalchemy/migrate_repo/versions/043_instance_ds_version_nullable.py create mode 100644 trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py diff --git a/releasenotes/notes/ussuri-fix-delete-datastore-version.yaml b/releasenotes/notes/ussuri-fix-delete-datastore-version.yaml new file mode 100644 index 00000000..3a73cadb --- /dev/null +++ b/releasenotes/notes/ussuri-fix-delete-datastore-version.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - Fixed the issue that datastore version cannot be deleted because of + dependency of deleted instances. Now, when instance or backup is + deleted, the datastore version attribute is set to NULL in database. + When datastore configuration parameter is deleted, the record is + deleted from database rather than only set 'deleted' field to 1. diff --git a/tools/trove-pylint.config b/tools/trove-pylint.config index 257b394e..7a773950 100644 --- a/tools/trove-pylint.config +++ b/tools/trove-pylint.config @@ -771,6 +771,30 @@ "Instance of 'Table' has no 'create_column' member", "upgrade" ], + [ + "trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py", + "E1101", + "Instance of 'Table' has no 'drop_column' member", + "upgrade" + ], + [ + "trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py", + "no-member", + "Instance of 'Table' has no 'drop_column' member", + "upgrade" + ], + [ + "trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py", + "E1120", + "No value for argument 'dml' in method call", + "upgrade" + ], + [ + "trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py", + "no-value-for-parameter", + "No value for argument 'dml' in method call", + "upgrade" + ], [ "trove/db/sqlalchemy/migration.py", "E0611", diff --git a/trove/common/exception.py b/trove/common/exception.py index 9413e65c..b7cc4fc8 100644 --- a/trove/common/exception.py +++ b/trove/common/exception.py @@ -188,6 +188,11 @@ class DatastoreVersionsExist(BadRequest): message = _("Datastore versions exist for datastore %(datastore)s.") +class DatastoreVersionsInUse(BadRequest): + + message = _("Datastore version is in use by %(resource)s.") + + class DatastoreDefaultDatastoreNotFound(TroveError): message = _("Please specify datastore. Default datastore " diff --git a/trove/configuration/models.py b/trove/configuration/models.py index 564f05fe..bd303e8b 100644 --- a/trove/configuration/models.py +++ b/trove/configuration/models.py @@ -189,7 +189,7 @@ class Configuration(object): id=self.configuration_id) LOG.debug("config_items: %s", config_items) detail_list = DatastoreConfigurationParameters.load_parameters( - datastore_v.id, show_deleted=True) + datastore_v.id) for i in config_items: LOG.debug("config item: %s", i) @@ -265,8 +265,6 @@ class DBDatastoreConfigurationParameters(dbmodels.DatabaseModelBase): 'max_size', 'min_size', 'data_type', - 'deleted', - 'deleted_at', ] _table_name = "datastore_configuration_parameters" @@ -287,22 +285,12 @@ class DatastoreConfigurationParameters(object): ds_v_id = kwargs.get('datastore_version_id') config_param_name = kwargs.get('name') try: - param = DatastoreConfigurationParameters.load_parameter_by_name( + DatastoreConfigurationParameters.load_parameter_by_name( ds_v_id, - config_param_name, - show_deleted=True) - if param.deleted == 1: - param.restart_required = kwargs.get('restart_required') - param.data_type = kwargs.get('data_type') - param.max_size = kwargs.get('max_size') - param.min_size = kwargs.get('min_size') - param.deleted = 0 - param.save() - return param - else: - raise exception.ConfigurationParameterAlreadyExists( - parameter_name=config_param_name, - datastore_version=ds_v_id) + config_param_name) + raise exception.ConfigurationParameterAlreadyExists( + parameter_name=config_param_name, + datastore_version=ds_v_id) except exception.NotFound: pass config_param = DBDatastoreConfigurationParameters.create( @@ -313,54 +301,29 @@ class DatastoreConfigurationParameters(object): def delete(version_id, config_param_name): config_param = DatastoreConfigurationParameters.load_parameter_by_name( version_id, config_param_name) - config_param.deleted = True - config_param.deleted_at = timeutils.utcnow() - config_param.save() + config_param.delete() @classmethod - def load_parameters(cls, datastore_version_id, show_deleted=False): - try: - if show_deleted: - return DBDatastoreConfigurationParameters.find_all( - datastore_version_id=datastore_version_id - ) - else: - return DBDatastoreConfigurationParameters.find_all( - datastore_version_id=datastore_version_id, - deleted=False - ) - except exception.NotFound: - raise exception.NotFound(uuid=datastore_version_id) + def load_parameters(cls, datastore_version_id): + return DBDatastoreConfigurationParameters.find_all( + datastore_version_id=datastore_version_id) @classmethod - def load_parameter(cls, config_id, show_deleted=False): + def load_parameter(cls, config_id): try: - if show_deleted: - return DBDatastoreConfigurationParameters.find_by( - id=config_id - ) - else: - return DBDatastoreConfigurationParameters.find_by( - id=config_id, deleted=False - ) + return DBDatastoreConfigurationParameters.find_by( + id=config_id, deleted=False + ) except exception.NotFound: raise exception.NotFound(uuid=config_id) @classmethod - def load_parameter_by_name(cls, datastore_version_id, config_param_name, - show_deleted=False): + def load_parameter_by_name(cls, datastore_version_id, config_param_name): try: - if show_deleted: - return DBDatastoreConfigurationParameters.find_by( - datastore_version_id=datastore_version_id, - name=config_param_name - ) - else: - return DBDatastoreConfigurationParameters.find_by( - datastore_version_id=datastore_version_id, - name=config_param_name, - deleted=False - ) + return DBDatastoreConfigurationParameters.find_by( + datastore_version_id=datastore_version_id, + name=config_param_name + ) except exception.NotFound: raise exception.NotFound(uuid=config_param_name) @@ -376,7 +339,7 @@ def create_or_update_datastore_configuration_parameter(name, datastore_version_id) try: config = DatastoreConfigurationParameters.load_parameter_by_name( - datastore_version_id, name, show_deleted=True) + datastore_version_id, name) config.restart_required = restart_required config.max_size = max_size config.min_size = min_size diff --git a/trove/db/sqlalchemy/migrate_repo/versions/043_instance_ds_version_nullable.py b/trove/db/sqlalchemy/migrate_repo/versions/043_instance_ds_version_nullable.py new file mode 100644 index 00000000..66e89880 --- /dev/null +++ b/trove/db/sqlalchemy/migrate_repo/versions/043_instance_ds_version_nullable.py @@ -0,0 +1,50 @@ +# Copyright 2012 OpenStack Foundation +# +# 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 sqlalchemy.schema import MetaData +from sqlalchemy import text + +from trove.db.sqlalchemy.migrate_repo.schema import Table +from trove.db.sqlalchemy import utils as db_utils + +meta = MetaData() + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + instance_table = Table('instances', meta, autoload=True) + datastore_versions_table = Table('datastore_versions', + meta, + autoload=True) + + constraint_names = db_utils.get_foreign_key_constraint_names( + engine=migrate_engine, + table='instances', + columns=[text('datastore_version_id')], + ref_table='datastore_versions', + ref_columns=[text('id')]) + db_utils.drop_foreign_key_constraints( + constraint_names=constraint_names, + columns=[instance_table.c.datastore_version_id], + ref_columns=[datastore_versions_table.c.id]) + + # Make datastore_version_id nullable so that this field could be set to + # NULL when instance is deleted. + instance_table.c.datastore_version_id.alter(nullable=True) + + db_utils.create_foreign_key_constraints( + constraint_names=constraint_names, + columns=[instance_table.c.datastore_version_id], + ref_columns=[datastore_versions_table.c.id]) diff --git a/trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py b/trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py new file mode 100644 index 00000000..7ce81d6a --- /dev/null +++ b/trove/db/sqlalchemy/migrate_repo/versions/044_remove_datastore_configuration_parameters_deleted.py @@ -0,0 +1,37 @@ +# Copyright 2012 OpenStack Foundation +# +# 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 sqlalchemy.schema import MetaData + +from trove.db.sqlalchemy.migrate_repo.schema import Table + +meta = MetaData() + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + ds_config_param = Table('datastore_configuration_parameters', meta, + autoload=True) + + # Remove records with deleted=1 + if 'deleted' in ds_config_param.c: + ds_config_param.delete(). \ + where(ds_config_param.c.deleted == 1). \ + execute() + + # Delete columns deleted and deleted_at + if migrate_engine.name != "sqlite": + ds_config_param.drop_column('deleted') + ds_config_param.drop_column('deleted_at') diff --git a/trove/extensions/mgmt/configuration/service.py b/trove/extensions/mgmt/configuration/service.py index 85de2c8b..bcf6b75e 100644 --- a/trove/extensions/mgmt/configuration/service.py +++ b/trove/extensions/mgmt/configuration/service.py @@ -38,8 +38,7 @@ class ConfigurationsParameterController(wsgi.Controller): """List all configuration parameters.""" ds_version = ds_models.DatastoreVersion.load_by_uuid(version_id) config_params = config_models.DatastoreConfigurationParameters - rules = config_params.load_parameters( - ds_version.id, show_deleted=True) + rules = config_params.load_parameters(ds_version.id) return wsgi.Result(views.MgmtConfigurationParametersView(rules).data(), 200) @@ -48,8 +47,7 @@ class ConfigurationsParameterController(wsgi.Controller): """Show a configuration parameter.""" ds_models.DatastoreVersion.load_by_uuid(version_id) config_params = config_models.DatastoreConfigurationParameters - rule = config_params.load_parameter_by_name( - version_id, id, show_deleted=True) + rule = config_params.load_parameter_by_name(version_id, id) return wsgi.Result(views.MgmtConfigurationParameterView(rule).data(), 200) diff --git a/trove/extensions/mgmt/configuration/views.py b/trove/extensions/mgmt/configuration/views.py index c55616fb..2a664881 100644 --- a/trove/extensions/mgmt/configuration/views.py +++ b/trove/extensions/mgmt/configuration/views.py @@ -31,8 +31,6 @@ class MgmtConfigurationParameterView(object): "datastore_version_id": self.config.datastore_version_id, "restart_required": restart_required, "type": self.config.data_type, - "deleted": self.config.deleted, - "deleted_at": self.config.deleted_at, } if self.config.max_size: ret["max_size"] = int(self.config.max_size) diff --git a/trove/extensions/mgmt/datastores/service.py b/trove/extensions/mgmt/datastores/service.py index e0f70772..c8d350f1 100644 --- a/trove/extensions/mgmt/datastores/service.py +++ b/trove/extensions/mgmt/datastores/service.py @@ -16,14 +16,17 @@ from glanceclient import exc as glance_exceptions from oslo_log import log as logging +from trove.backup import models as backup_model from trove.common import apischema from trove.common.auth import admin_context from trove.common import clients from trove.common import exception from trove.common import utils from trove.common import wsgi +from trove.configuration import models as config_model from trove.datastore import models from trove.extensions.mgmt.datastores import views +from trove.instance import models as instance_model LOG = logging.getLogger(__name__) @@ -140,6 +143,21 @@ class DatastoreVersionController(wsgi.Controller): @admin_context def delete(self, req, tenant_id, id): """Remove an existing datastore version.""" + instances = instance_model.DBInstance.find_all( + datastore_version_id=id, deleted=0).all() + if len(instances) > 0: + raise exception.DatastoreVersionsInUse(resource='instance') + + backups = backup_model.DBBackup.find_all( + datastore_version_id=id, deleted=0).all() + if len(backups) > 0: + raise exception.DatastoreVersionsInUse(resource='backup') + + configs = config_model.DBConfiguration.find_all( + datastore_version_id=id, deleted=0).all() + if len(configs) > 0: + raise exception.DatastoreVersionsInUse(resource='configuration') + datastore_version = models.DatastoreVersion.load_by_uuid(id) datastore = models.Datastore.load(datastore_version.datastore_id) diff --git a/trove/extensions/mgmt/instances/models.py b/trove/extensions/mgmt/instances/models.py index 35102c44..7bb8cceb 100644 --- a/trove/extensions/mgmt/instances/models.py +++ b/trove/extensions/mgmt/instances/models.py @@ -42,6 +42,7 @@ def load_mgmt_instances(context, deleted=None, client=None, args['deleted'] = deleted if not include_clustered: args['cluster_id'] = None + db_infos = instance_models.DBInstance.find_all(**args) instances = MgmtInstances.load_status_from_existing(context, db_infos, diff --git a/trove/instance/models.py b/trove/instance/models.py index 99cf7706..eda59e98 100644 --- a/trove/instance/models.py +++ b/trove/instance/models.py @@ -179,15 +179,17 @@ class SimpleInstance(object): self.root_pass = root_password self._fault = None self._fault_loaded = False - if ds_version is None: + self.ds_version = None + self.ds = None + self.locality = locality + self.slave_list = None + + if ds_version is None and self.db_info.datastore_version_id: self.ds_version = (datastore_models.DatastoreVersion. load_by_uuid(self.db_info.datastore_version_id)) - if ds is None: + if ds is None and self.ds_version: self.ds = (datastore_models.Datastore. load(self.ds_version.datastore_id)) - self.locality = locality - - self.slave_list = None def __repr__(self, *args, **kwargs): return "%s(%s)" % (self.name, self.id) @@ -410,11 +412,15 @@ class SimpleInstance(object): @property def volume_support(self): - return CONF.get(self.datastore_version.manager).volume_support + if self.datastore_version: + return CONF.get(self.datastore_version.manager).volume_support + return None @property def device_path(self): - return CONF.get(self.datastore_version.manager).device_path + if self.datastore_version: + return CONF.get(self.datastore_version.manager).device_path + return None @property def root_password(self): @@ -809,8 +815,13 @@ class BaseInstance(SimpleInstance): deleted_at = timeutils.utcnow() self._delete_resources(deleted_at) LOG.debug("Setting instance %s to be deleted.", self.id) + # Also set FOREIGN KEY fields to NULL self.update_db(deleted=True, deleted_at=deleted_at, - task_status=InstanceTasks.NONE) + task_status=InstanceTasks.NONE, + datastore_version_id=None, + configuration_id=None, + slave_of_id=None, + cluster_id=None) self.set_servicestatus_deleted() self.set_instance_fault_deleted() diff --git a/trove/instance/views.py b/trove/instance/views.py index e08368f2..a79b27b8 100644 --- a/trove/instance/views.py +++ b/trove/instance/views.py @@ -37,10 +37,14 @@ class InstanceView(object): "status": self.instance.status, "links": self._build_links(), "flavor": self._build_flavor_info(), - "datastore": {"type": self.instance.datastore.name, - "version": self.instance.datastore_version.name}, + "datastore": {"type": None, "version": None}, "region": self.instance.region_name } + if self.instance.datastore_version: + instance_dict['datastore'] = { + "type": self.instance.datastore.name, + "version": self.instance.datastore_version.name + } if self.context.is_admin: instance_dict['tenant_id'] = self.instance.tenant_id if self.instance.volume_support: @@ -94,8 +98,10 @@ class InstanceDetailView(InstanceView): result['instance']['service_status_updated'] = (self.instance. service_status_updated) - result['instance']['datastore']['version'] = (self.instance. - datastore_version.name) + result['instance']['datastore']['version'] = None + if self.instance.datastore_version: + result['instance']['datastore']['version'] = \ + self.instance.datastore_version.name if self.instance.fault: result['instance']['fault'] = self._build_fault_info() diff --git a/trove/taskmanager/models.py b/trove/taskmanager/models.py index 4c424f3b..da3ad45a 100755 --- a/trove/taskmanager/models.py +++ b/trove/taskmanager/models.py @@ -1427,6 +1427,14 @@ class BackupTasks(object): @classmethod def delete_backup(cls, context, backup_id): """Delete backup from swift.""" + def _delete(backup): + backup.deleted = True + backup.deleted_at = timeutils.utcnow() + # Set datastore_version_id to None so that datastore_version could + # be deleted. + backup.datastore_version_id = None + backup.save() + LOG.info("Deleting backup %s.", backup_id) backup = bkup_models.Backup.get_by_id(context, backup_id) try: @@ -1434,11 +1442,11 @@ class BackupTasks(object): if filename: BackupTasks.delete_files_from_swift(context, filename) except ValueError: - backup.delete() + _delete(backup) except ClientException as e: if e.http_status == 404: # Backup already deleted in swift - backup.delete() + _delete(backup) else: LOG.exception("Error occurred when deleting from swift. " "Details: %s", e) @@ -1447,7 +1455,7 @@ class BackupTasks(object): raise TroveError(_("Failed to delete swift object for backup " "%s.") % backup_id) else: - backup.delete() + _delete(backup) LOG.info("Deleted backup %s successfully.", backup_id) diff --git a/trove/tests/api/configurations.py b/trove/tests/api/configurations.py index 78352139..a961985a 100644 --- a/trove/tests/api/configurations.py +++ b/trove/tests/api/configurations.py @@ -633,18 +633,19 @@ class DeleteConfigurations(ConfigurationsTestBase): @after_class(always_run=True) def tearDown(self): # need to "undelete" the parameter that was deleted from the mgmt call - ds = instance_info.dbaas_datastore - ds_v = instance_info.dbaas_datastore_version - version = instance_info.dbaas.datastore_versions.get( - ds, ds_v) - client = instance_info.dbaas_admin.mgmt_configs - print(self.config_parameter_dict) - client.create(version.id, - self.config_parameter_dict['name'], - self.config_parameter_dict['restart_required'], - self.config_parameter_dict['type'], - self.config_parameter_dict['max'], - self.config_parameter_dict['min']) + if instance_info.dbaas: + ds = instance_info.dbaas_datastore + ds_v = instance_info.dbaas_datastore_version + version = instance_info.dbaas.datastore_versions.get( + ds, ds_v) + client = instance_info.dbaas_admin.mgmt_configs + print(self.config_parameter_dict) + client.create(version.id, + self.config_parameter_dict['name'], + self.config_parameter_dict['restart_required'], + self.config_parameter_dict['type'], + self.config_parameter_dict['max'], + self.config_parameter_dict['min']) @test def test_delete_invalid_configuration_not_found(self): diff --git a/trove/tests/api/datastores.py b/trove/tests/api/datastores.py index 5c0be738..ef8b00b7 100644 --- a/trove/tests/api/datastores.py +++ b/trove/tests/api/datastores.py @@ -85,6 +85,14 @@ class Datastores(object): @test def test_create_inactive_datastore_by_admin(self): + datastores = self.rd_client.datastores.list() + for ds in datastores: + if ds.name == test_config.dbaas_datastore_name_no_versions: + for version in ds.versions: + if version['name'] == 'inactive_version': + return + + # Get a valid image ID from a datastore version datastore = self.rd_client.datastores.get(test_config.dbaas_datastore) ds_version = self.rd_client.datastore_versions.list(datastore.id)[0] ds_version_info = self.rd_admin.datastore_versions.get_by_uuid( diff --git a/trove/tests/unittests/mgmt/test_datastore_controller.py b/trove/tests/unittests/mgmt/test_datastore_controller.py index 35e88178..a465692b 100644 --- a/trove/tests/unittests/mgmt/test_datastore_controller.py +++ b/trove/tests/unittests/mgmt/test_datastore_controller.py @@ -105,15 +105,56 @@ class TestDatastoreVersionController(trove_testtools.TestCase): self.controller.show(self.req, self.tenant_id, id) mock_ds_version_load.assert_called_with(id) + @patch('trove.configuration.models.DBConfiguration.find_all') + @patch('trove.backup.models.DBBackup.find_all') + @patch('trove.instance.models.DBInstance.find_all') @patch.object(datastore_models.Datastore, 'load') @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid') - def test_delete_ds_version(self, mock_ds_version_load, mock_ds_load): + def test_delete_ds_version(self, mock_ds_version_load, mock_ds_load, + mock_instance_find, mock_backup_find, + mock_config_find): ds_version_id = Mock() ds_version = Mock() mock_ds_version_load.return_value = ds_version self.controller.delete(self.req, self.tenant_id, ds_version_id) ds_version.delete.assert_called_with() + @patch('trove.instance.models.DBInstance.find_all') + def test_delete_ds_version_instance_in_use(self, mock_instance_find): + mock_instance_find.return_value.all.return_value = [Mock()] + + self.assertRaises( + exception.DatastoreVersionsInUse, + self.controller.delete, + self.req, self.tenant_id, 'fake_version_id' + ) + + @patch('trove.backup.models.DBBackup.find_all') + @patch('trove.instance.models.DBInstance.find_all') + def test_delete_ds_version_backup_in_use(self, mock_instance_find, + mock_backup_find): + mock_backup_find.return_value.all.return_value = [Mock()] + + self.assertRaises( + exception.DatastoreVersionsInUse, + self.controller.delete, + self.req, self.tenant_id, 'fake_version_id' + ) + + @patch('trove.configuration.models.DBConfiguration.find_all') + @patch('trove.backup.models.DBBackup.find_all') + @patch('trove.instance.models.DBInstance.find_all') + def test_delete_ds_version_config_in_use(self, mock_instance_find, + mock_backup_find, + mock_config_find): + mock_config_find.return_value.all.return_value = [Mock()] + + self.assertRaises( + exception.DatastoreVersionsInUse, + self.controller.delete, + self.req, self.tenant_id, 'fake_version_id' + ) + @patch.object(datastore_models.DatastoreVersion, 'load_by_uuid') @patch.object(datastore_models.DatastoreVersions, 'load_all') def test_index_ds_version(self, mock_ds_version_load_all, diff --git a/trove/tests/unittests/taskmanager/test_models.py b/trove/tests/unittests/taskmanager/test_models.py index 92c9fa5a..9ac99a69 100644 --- a/trove/tests/unittests/taskmanager/test_models.py +++ b/trove/tests/unittests/taskmanager/test_models.py @@ -1056,7 +1056,8 @@ class BackupTasksTest(trove_testtools.TestCase): self.backup.location = '' taskmanager_models.BackupTasks.delete_backup('dummy context', self.backup.id) - self.backup.delete.assert_any_call() + + self.assertTrue(self.backup.deleted) @patch('trove.taskmanager.models.LOG') @patch('trove.common.clients.create_swift_client') -- cgit v1.2.1