Merge "Unit test for checking cross-version migrations compatibility"
This commit is contained in:
commit
720b83ffd1
162
keystone/tests/unit/test_sql_banned_operations.py
Normal file
162
keystone/tests/unit/test_sql_banned_operations.py
Normal file
@ -0,0 +1,162 @@
|
||||
# Copyright 2016 Intel Corporation
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
import os
|
||||
|
||||
import fixtures
|
||||
from migrate.versioning import repository
|
||||
from oslo_db.sqlalchemy import test_base
|
||||
from oslo_db.sqlalchemy import test_migrations
|
||||
import sqlalchemy
|
||||
import testtools
|
||||
|
||||
from keystone.common.sql import migrate_repo
|
||||
|
||||
|
||||
class DBOperationNotAllowed(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class BannedDBSchemaOperations(fixtures.Fixture):
|
||||
"""Ban some operations for migrations."""
|
||||
|
||||
def __init__(self, banned_resources=None):
|
||||
super(BannedDBSchemaOperations, self).__init__()
|
||||
self._banned_resources = banned_resources or []
|
||||
|
||||
@staticmethod
|
||||
def _explode(resource, op):
|
||||
raise DBOperationNotAllowed(
|
||||
'Operation %s.%s() is not allowed in a database migration' % (
|
||||
resource, op))
|
||||
|
||||
def setUp(self):
|
||||
super(BannedDBSchemaOperations, self).setUp()
|
||||
for resource in self._banned_resources:
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'sqlalchemy.%s.drop' % resource,
|
||||
lambda *a, **k: self._explode(resource, 'drop')))
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'sqlalchemy.%s.alter' % resource,
|
||||
lambda *a, **k: self._explode(resource, 'alter')))
|
||||
|
||||
|
||||
class TestBannedDBSchemaOperations(testtools.TestCase):
|
||||
"""Test the BannedDBSchemaOperations fixture."""
|
||||
|
||||
def test_column(self):
|
||||
"""Test column drops and alters raise DBOperationNotAllowed."""
|
||||
column = sqlalchemy.Column()
|
||||
with BannedDBSchemaOperations(banned_resources=['Column']):
|
||||
self.assertRaises(DBOperationNotAllowed, column.drop)
|
||||
self.assertRaises(DBOperationNotAllowed, column.alter)
|
||||
|
||||
def test_table(self):
|
||||
"""Test table drops and alters raise DBOperationNotAllowed."""
|
||||
table = sqlalchemy.Table()
|
||||
with BannedDBSchemaOperations(banned_resources=['Table']):
|
||||
self.assertRaises(DBOperationNotAllowed, table.drop)
|
||||
self.assertRaises(DBOperationNotAllowed, table.alter)
|
||||
|
||||
|
||||
class KeystoneMigrationsCheckers(test_migrations.WalkVersionsMixin):
|
||||
"""Walk over and test all sqlalchemy-migrate migrations."""
|
||||
|
||||
@property
|
||||
def INIT_VERSION(self):
|
||||
return migrate_repo.DB_INIT_VERSION
|
||||
|
||||
@property
|
||||
def REPOSITORY(self):
|
||||
migrate_file = migrate_repo.__file__
|
||||
return repository.Repository(
|
||||
os.path.abspath(os.path.dirname(migrate_file))
|
||||
)
|
||||
|
||||
@property
|
||||
def migration_api(self):
|
||||
temp = __import__('oslo_db.sqlalchemy.migration', globals(),
|
||||
locals(), ['versioning_api'], 0)
|
||||
return temp.versioning_api
|
||||
|
||||
@property
|
||||
def migrate_engine(self):
|
||||
return self.engine
|
||||
|
||||
def migrate_up(self, version, with_data=False):
|
||||
"""Check that migrations don't cause downtime.
|
||||
|
||||
Schema migrations can be done online, allowing for rolling upgrades.
|
||||
"""
|
||||
# NOTE(xek):
|
||||
# This is a list of migrations where we allow dropping and altering
|
||||
# things. The rules for adding exceptions are very specific:
|
||||
#
|
||||
# 1) Migrations which don't cause incompatibilities are allowed,
|
||||
# for example dropping an index or constraint.
|
||||
#
|
||||
# 2) Migrations removing structures not used in the previous version
|
||||
# are allowed (we keep compatibility between releases), ex.:
|
||||
#
|
||||
# a) feature is deprecated according to the deprecation policies
|
||||
# (release 1),
|
||||
#
|
||||
# b) code supporting the feature is removed the following release
|
||||
# (release 2),
|
||||
#
|
||||
# c) table can be dropped a release after the code has been removed
|
||||
# (i.e. in release 3).
|
||||
#
|
||||
# 3) Any other changes which don't pass this test are disallowed.
|
||||
#
|
||||
# Please follow the guidelines outlined at:
|
||||
# http://docs.openstack.org/developer/keystone/developing.html#online-migration
|
||||
|
||||
exceptions = [
|
||||
# NOTE(xek): Reviewers: DO NOT ALLOW THINGS TO BE ADDED HERE
|
||||
]
|
||||
|
||||
# NOTE(xek): We start requiring things be additive in Mitaka, so
|
||||
# ignore all migrations before that point.
|
||||
MITAKA_START = 81
|
||||
|
||||
if version >= MITAKA_START and version not in exceptions:
|
||||
banned = ['Table', 'Column']
|
||||
else:
|
||||
banned = None
|
||||
with BannedDBSchemaOperations(banned):
|
||||
super(KeystoneMigrationsCheckers,
|
||||
self).migrate_up(version, with_data)
|
||||
|
||||
snake_walk = False
|
||||
downgrade = False
|
||||
|
||||
def test_walk_versions(self):
|
||||
self.walk_versions(self.snake_walk, self.downgrade)
|
||||
|
||||
|
||||
class TestKeystoneMigrationsMySQL(
|
||||
KeystoneMigrationsCheckers, test_base.MySQLOpportunisticTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestKeystoneMigrationsPostgreSQL(
|
||||
KeystoneMigrationsCheckers, test_base.PostgreSQLOpportunisticTestCase):
|
||||
pass
|
||||
|
||||
|
||||
class TestKeystoneMigrationsSQLite(
|
||||
KeystoneMigrationsCheckers, test_base.DbTestCase):
|
||||
pass
|
@ -37,3 +37,6 @@ tempest-lib>=0.13.0 # Apache-2.0
|
||||
|
||||
# Functional tests.
|
||||
requests!=2.9.0,>=2.8.1 # Apache-2.0
|
||||
|
||||
# For fixtures from oslo.db
|
||||
testresources>=0.2.4 # Apache-2.0/BSD
|
||||
|
Loading…
Reference in New Issue
Block a user