DBMS: Fix db_sync between N and N+1 releases

If we start cinderlib from the N release with the DBMS persistence
plugin on a DB where we have already run it with release N+1 then we'll
get an `oslo_db.exception.DBMigrationError` exception.

This is because cinderlib automatically does a `db_sync` on each
initialization, but on N this will fail because there will be unknown
(as in newer) migrations applied to the DB.

This patch takes this possibility and checks the exception raised by
`db_sync` and ignores it if the `migrate` package complains with a
VersionNotFoundError.

Closes-Bug: #1868145
Change-Id: I539919e01f603d19cde8750ad92e3d2b4ac2fbc7
This commit is contained in:
Gorka Eguileor
2020-03-19 14:54:31 +01:00
parent 18f85d8b25
commit 01dfcb172e
3 changed files with 43 additions and 1 deletions

View File

@@ -14,6 +14,7 @@
# under the License.
import tempfile
from unittest import mock
from cinder.db.sqlalchemy import api as sqla_api
from cinder import objects as cinder_ovos
@@ -121,5 +122,31 @@ class TestDBPersistence(base.BasePersistenceTest):
self.assertEqual('__DEFAULT__', self.persistence.DEFAULT_TYPE.name)
class TestDBPersistenceNewerSchema(base.helper.TestHelper):
"""Test DBMS plugin can start when the DB has a newer schema."""
CONNECTION = 'sqlite:///' + tempfile.NamedTemporaryFile().name
PERSISTENCE_CFG = {'storage': 'db',
'connection': CONNECTION}
@classmethod
def setUpClass(cls):
pass
def _raise_exc(self):
inner_exc = dbms.migrate.exceptions.VersionNotFoundError()
exc = dbms.exception.DBMigrationError(inner_exc)
self.original_db_sync()
raise(exc)
def test_newer_db_schema(self):
self.original_db_sync = dbms.migration.db_sync
with mock.patch.object(dbms.migration, 'db_sync',
side_effect=self._raise_exc) as db_sync_mock:
super(TestDBPersistenceNewerSchema, self).setUpClass()
db_sync_mock.assert_called_once()
self.assertIsInstance(cinderlib.Backend.persistence,
dbms.DBPersistence)
class TestMemoryDBPersistence(TestDBPersistence):
PERSISTENCE_CFG = {'storage': 'memory_db'}