Merge "Raise InstanceMappingNotFound if StaleDataError is encountered" into stable/ussuri

This commit is contained in:
Zuul 2021-04-11 15:35:28 +00:00 committed by Gerrit Code Review
commit 4fd78fb70f
2 changed files with 20 additions and 2 deletions

View File

@ -15,6 +15,7 @@ import collections
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import versionutils from oslo_utils import versionutils
import six import six
from sqlalchemy.orm import exc as orm_exc
from sqlalchemy.orm import joinedload from sqlalchemy.orm import joinedload
from sqlalchemy.sql import false from sqlalchemy.sql import false
from sqlalchemy.sql import func from sqlalchemy.sql import func
@ -161,8 +162,16 @@ class InstanceMapping(base.NovaTimestampObject, base.NovaObject):
def save(self): def save(self):
changes = self.obj_get_changes() changes = self.obj_get_changes()
changes = self._update_with_cell_id(changes) changes = self._update_with_cell_id(changes)
db_mapping = self._save_in_db(self._context, self.instance_uuid, try:
changes) db_mapping = self._save_in_db(self._context, self.instance_uuid,
changes)
except orm_exc.StaleDataError:
# NOTE(melwitt): If the instance mapping has been deleted out from
# under us by conductor (delete requested while booting), we will
# encounter a StaleDataError after we retrieved the row and try to
# update it after it's been deleted. We can treat this like an
# instance mapping not found and allow the caller to handle it.
raise exception.InstanceMappingNotFound(uuid=self.instance_uuid)
self._from_db_object(self._context, self, db_mapping) self._from_db_object(self._context, self, db_mapping)
self.obj_reset_changes() self.obj_reset_changes()

View File

@ -12,6 +12,7 @@
import mock import mock
from oslo_utils import uuidutils from oslo_utils import uuidutils
from sqlalchemy.orm import exc as orm_exc
from nova import exception from nova import exception
from nova import objects from nova import objects
@ -151,6 +152,14 @@ class _TestInstanceMappingObject(object):
comparators={ comparators={
'cell_mapping': self._check_cell_map_value}) 'cell_mapping': self._check_cell_map_value})
@mock.patch.object(instance_mapping.InstanceMapping, '_save_in_db')
def test_save_stale_data_error(self, save_in_db):
save_in_db.side_effect = orm_exc.StaleDataError
mapping_obj = objects.InstanceMapping(self.context)
mapping_obj.instance_uuid = uuidutils.generate_uuid()
self.assertRaises(exception.InstanceMappingNotFound, mapping_obj.save)
@mock.patch.object(instance_mapping.InstanceMapping, '_destroy_in_db') @mock.patch.object(instance_mapping.InstanceMapping, '_destroy_in_db')
def test_destroy(self, destroy_in_db): def test_destroy(self, destroy_in_db):
uuid = uuidutils.generate_uuid() uuid = uuidutils.generate_uuid()