Merge "Add sqlalchemy migration utils.check_shadow_table method"
This commit is contained in:
@@ -18,16 +18,24 @@
|
||||
from migrate.changeset import UniqueConstraint
|
||||
from sqlalchemy import Integer, DateTime, String
|
||||
from sqlalchemy import MetaData, Table, Column
|
||||
from sqlalchemy.exc import NoSuchTableError
|
||||
from sqlalchemy.exc import SAWarning
|
||||
from sqlalchemy.sql import select
|
||||
from sqlalchemy.types import UserDefinedType
|
||||
|
||||
from nova.db.sqlalchemy import api as db
|
||||
from nova.db.sqlalchemy import utils
|
||||
from nova import exception
|
||||
from nova.tests import test_migrations
|
||||
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 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):
|
||||
|
||||
class CustomType(UserDefinedType):
|
||||
"""Dummy column type for testing unsupported types."""
|
||||
def get_col_spec(self):
|
||||
return "CustomType"
|
||||
|
||||
table_name = "__test_tmp_table__"
|
||||
uc_name = 'uniq_foo'
|
||||
values = [
|
||||
@@ -235,3 +238,77 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
|
||||
len(values) - len(row_ids))
|
||||
for value in soft_deleted_values:
|
||||
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))
|
||||
|
@@ -56,6 +56,7 @@ from sqlalchemy.dialects import postgresql
|
||||
from sqlalchemy.dialects import sqlite
|
||||
import sqlalchemy.exc
|
||||
|
||||
from nova.db.sqlalchemy import api as db
|
||||
import nova.db.sqlalchemy.migrate_repo
|
||||
from nova.openstack.common import lockutils
|
||||
from nova.openstack.common import log as logging
|
||||
@@ -855,13 +856,13 @@ class TestNovaMigrations(BaseMigrationTestCase, CommonTestsMixIn):
|
||||
meta.reflect(engine)
|
||||
table_names = set(meta.tables.keys())
|
||||
for table_name in table_names:
|
||||
if table_name.startswith("shadow_"):
|
||||
if table_name.startswith(db._SHADOW_TABLE_PREFIX):
|
||||
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)
|
||||
else:
|
||||
base_name = table_name
|
||||
shadow_name = "shadow_" + table_name
|
||||
shadow_name = db._SHADOW_TABLE_PREFIX + table_name
|
||||
self.assertIn(shadow_name, table_names)
|
||||
shadow_table = get_table(engine, shadow_name)
|
||||
base_table = get_table(engine, base_name)
|
||||
|
Reference in New Issue
Block a user