Merge "Add sqlalchemy migration utils.check_shadow_table method"

This commit is contained in:
Jenkins
2013-05-11 00:19:04 +00:00
committed by Gerrit Code Review
2 changed files with 86 additions and 8 deletions

View File

@@ -18,16 +18,24 @@
from migrate.changeset import UniqueConstraint from migrate.changeset import UniqueConstraint
from sqlalchemy import Integer, DateTime, String from sqlalchemy import Integer, DateTime, String
from sqlalchemy import MetaData, Table, Column from sqlalchemy import MetaData, Table, Column
from sqlalchemy.exc import NoSuchTableError
from sqlalchemy.exc import SAWarning from sqlalchemy.exc import SAWarning
from sqlalchemy.sql import select from sqlalchemy.sql import select
from sqlalchemy.types import UserDefinedType from sqlalchemy.types import UserDefinedType
from nova.db.sqlalchemy import api as db
from nova.db.sqlalchemy import utils from nova.db.sqlalchemy import utils
from nova import exception from nova import exception
from nova.tests import test_migrations from nova.tests import test_migrations
import warnings import warnings
class CustomType(UserDefinedType):
"""Dummy column type for testing unsupported types."""
def get_col_spec(self):
return "CustomType"
class TestMigrationUtils(test_migrations.BaseMigrationTestCase): class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
"""Class for testing utils that are used in db migrations.""" """Class for testing utils that are used in db migrations."""
@@ -75,11 +83,6 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
def test_util_drop_unique_constraint_with_not_supported_sqlite_type(self): def test_util_drop_unique_constraint_with_not_supported_sqlite_type(self):
class CustomType(UserDefinedType):
"""Dummy column type for testing unsupported types."""
def get_col_spec(self):
return "CustomType"
table_name = "__test_tmp_table__" table_name = "__test_tmp_table__"
uc_name = 'uniq_foo' uc_name = 'uniq_foo'
values = [ values = [
@@ -235,3 +238,77 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
len(values) - len(row_ids)) len(values) - len(row_ids))
for value in soft_deleted_values: for value in soft_deleted_values:
self.assertTrue(value['id'] in deleted_rows_ids) self.assertTrue(value['id'] in deleted_rows_ids)
def test_check_shadow_table(self):
table_name = 'abc'
for key, engine in self.engines.items():
meta = MetaData()
meta.bind = engine
table = Table(table_name, meta,
Column('id', Integer, primary_key=True),
Column('a', Integer),
Column('c', String(256)))
table.create()
#check missing shadow table
self.assertRaises(NoSuchTableError,
utils.check_shadow_table, engine, table_name)
shadow_table = Table(db._SHADOW_TABLE_PREFIX + table_name, meta,
Column('id', Integer),
Column('a', Integer))
shadow_table.create()
# check missing column
self.assertRaises(exception.NovaException,
utils.check_shadow_table, engine, table_name)
# check when all is ok
c = Column('c', String(256))
shadow_table.create_column(c)
self.assertTrue(utils.check_shadow_table(engine, table_name))
# check extra column
d = Column('d', Integer)
shadow_table.create_column(d)
self.assertRaises(exception.NovaException,
utils.check_shadow_table, engine, table_name)
def test_check_shadow_table_different_types(self):
table_name = 'abc'
for key, engine in self.engines.items():
meta = MetaData()
meta.bind = engine
table = Table(table_name, meta,
Column('id', Integer, primary_key=True),
Column('a', Integer))
table.create()
shadow_table = Table(db._SHADOW_TABLE_PREFIX + table_name, meta,
Column('id', Integer, primary_key=True),
Column('a', String(256)))
shadow_table.create()
self.assertRaises(exception.NovaException,
utils.check_shadow_table, engine, table_name)
def test_check_shadow_table_with_unsupported_type(self):
table_name = 'abc'
for key, engine in self.engines.items():
meta = MetaData()
meta.bind = engine
table = Table(table_name, meta,
Column('id', Integer, primary_key=True),
Column('a', Integer),
Column('c', CustomType))
table.create()
shadow_table = Table(db._SHADOW_TABLE_PREFIX + table_name, meta,
Column('id', Integer, primary_key=True),
Column('a', Integer),
Column('c', CustomType))
shadow_table.create()
self.assertTrue(utils.check_shadow_table(engine, table_name))

View File

@@ -56,6 +56,7 @@ from sqlalchemy.dialects import postgresql
from sqlalchemy.dialects import sqlite from sqlalchemy.dialects import sqlite
import sqlalchemy.exc import sqlalchemy.exc
from nova.db.sqlalchemy import api as db
import nova.db.sqlalchemy.migrate_repo import nova.db.sqlalchemy.migrate_repo
from nova.openstack.common import lockutils from nova.openstack.common import lockutils
from nova.openstack.common import log as logging from nova.openstack.common import log as logging
@@ -855,13 +856,13 @@ class TestNovaMigrations(BaseMigrationTestCase, CommonTestsMixIn):
meta.reflect(engine) meta.reflect(engine)
table_names = set(meta.tables.keys()) table_names = set(meta.tables.keys())
for table_name in table_names: for table_name in table_names:
if table_name.startswith("shadow_"): if table_name.startswith(db._SHADOW_TABLE_PREFIX):
shadow_name = table_name shadow_name = table_name
base_name = table_name.replace("shadow_", "") base_name = table_name.replace(db._SHADOW_TABLE_PREFIX, "")
self.assertIn(base_name, table_names) self.assertIn(base_name, table_names)
else: else:
base_name = table_name base_name = table_name
shadow_name = "shadow_" + table_name shadow_name = db._SHADOW_TABLE_PREFIX + table_name
self.assertIn(shadow_name, table_names) self.assertIn(shadow_name, table_names)
shadow_table = get_table(engine, shadow_name) shadow_table = get_table(engine, shadow_name)
base_table = get_table(engine, base_name) base_table = get_table(engine, base_name)