Handle unicode when dealing with duplicate aggregate errors during migration
The AggregateNameExists message can be translated and have unicode in it so we can't cast it to a str in python 2.7 else we'll get a UnicodeEncodeError. That would break the online data migration for aggregates along with any other online data migrations that run after that one which impacts upgrades. This uses six.text_type rather than str for logging the error and adds a test to recreate the bug and show that it's fixed. Change-Id: I040db22ecbb9fabe5bbda8a3d9600cc9f76cb170 Closes-Bug: #1653261
This commit is contained in:
parent
8a4ab8ebcb
commit
504594afb8
@ -16,6 +16,7 @@ from oslo_db import exception as db_exc
|
||||
from oslo_log import log as logging
|
||||
from oslo_utils import excutils
|
||||
from oslo_utils import uuidutils
|
||||
import six
|
||||
from sqlalchemy.orm import contains_eager
|
||||
from sqlalchemy.orm import joinedload
|
||||
from sqlalchemy.sql import func
|
||||
@ -593,7 +594,7 @@ def migrate_aggregates(ctxt, count):
|
||||
_LW('Aggregate id %(id)i disappeared during migration'),
|
||||
{'id': aggregate_id})
|
||||
except (exception.AggregateNameExists) as e:
|
||||
LOG.error(str(e))
|
||||
LOG.error(six.text_type(e))
|
||||
|
||||
return count_all, count_hit
|
||||
|
||||
|
@ -635,3 +635,26 @@ class AggregateMigrationTestCase(test.TestCase):
|
||||
self.context, 0)
|
||||
self.assertEqual(0, match)
|
||||
self.assertEqual(0, done)
|
||||
|
||||
@mock.patch('nova.objects.aggregate.LOG.error')
|
||||
def test_migrate_aggregates_duplicate_unicode(self, mock_log_error):
|
||||
"""Tests that we handle a duplicate aggregate when migrating and that
|
||||
we handle when the exception message is in unicode.
|
||||
"""
|
||||
# First create an aggregate that will be migrated from main to API DB.
|
||||
create_aggregate(self.context, 1, in_api=False)
|
||||
# Now create that same aggregate in the API DB.
|
||||
create_aggregate(self.context, 1, in_api=True)
|
||||
# Now let's run the online data migration which will fail to create
|
||||
# a duplicate aggregate in the API database and will raise
|
||||
# AggregateNameExists which we want to modify to have a unicode
|
||||
# message.
|
||||
with mock.patch.object(exception.AggregateNameExists, 'msg_fmt',
|
||||
u'\xF0\x9F\x92\xA9'):
|
||||
match, done = aggregate_obj.migrate_aggregates(self.context, 50)
|
||||
# we found one
|
||||
self.assertEqual(1, match)
|
||||
# but we didn't migrate it
|
||||
self.assertEqual(0, done)
|
||||
# and we logged an error for the duplicate aggregate
|
||||
mock_log_error.assert_called()
|
||||
|
Loading…
Reference in New Issue
Block a user