summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBoris Pavlovic <boris@pavlovic.me>2013-05-22 16:57:47 +0400
committerBoris Pavlovic <boris@pavlovic.me>2013-05-24 14:57:27 +0400
commit7238438ef218d79a31acb07ea004fca8c2e78798 (patch)
tree6424423d6c16a18004601ad62bfc87f6a97b72f9
parent05be719ec76adf60a151b56d695c59fd832cb22b (diff)
Fix tests for sqlalchemy utils
This fix tests to be able to run it with postgresql and mysql. Some tests should be run only on sqlite Method create_shadow_tables raises different exception in different backends (when we try to create duplicate table): In postgresql it is ProgrammingError In sqlite and mysql it is OperationalError So create new Exception that will be raised in both cases. bp db-common-migration-and-utils Change-Id: I11be23106bc01bd3c72dad30edfb31a17177bb34
-rw-r--r--nova/db/sqlalchemy/utils.py18
-rw-r--r--nova/exception.py4
-rw-r--r--nova/tests/test_migration_utils.py154
3 files changed, 92 insertions, 84 deletions
diff --git a/nova/db/sqlalchemy/utils.py b/nova/db/sqlalchemy/utils.py
index f0eece661..84a24b94f 100644
--- a/nova/db/sqlalchemy/utils.py
+++ b/nova/db/sqlalchemy/utils.py
@@ -16,12 +16,18 @@
# under the License.
from migrate.changeset import UniqueConstraint
+from sqlalchemy import Column
from sqlalchemy.engine import reflection
+from sqlalchemy.exc import OperationalError
+from sqlalchemy.exc import ProgrammingError
from sqlalchemy.ext.compiler import compiles
from sqlalchemy import func
-from sqlalchemy import MetaData, Table, Column, Index
-from sqlalchemy.sql.expression import UpdateBase, literal_column
+from sqlalchemy import Index
+from sqlalchemy import MetaData
+from sqlalchemy.sql.expression import literal_column
+from sqlalchemy.sql.expression import UpdateBase
from sqlalchemy.sql import select
+from sqlalchemy import Table
from sqlalchemy.types import NullType
from nova.db.sqlalchemy import api as db
@@ -256,11 +262,15 @@ def create_shadow_table(migrate_engine, table_name=None, table=None,
else:
columns.append(column.copy())
- shadow_table = Table(db._SHADOW_TABLE_PREFIX + table.name, meta, *columns,
+ shadow_table_name = db._SHADOW_TABLE_PREFIX + table.name
+ shadow_table = Table(shadow_table_name, meta, *columns,
mysql_engine='InnoDB')
try:
shadow_table.create()
+ except (OperationalError, ProgrammingError):
+ LOG.info(repr(shadow_table))
+ LOG.exception(_('Exception while creating table.'))
+ raise exception.ShadowTableExists(name=shadow_table_name)
except Exception:
LOG.info(repr(shadow_table))
LOG.exception(_('Exception while creating table.'))
- raise
diff --git a/nova/exception.py b/nova/exception.py
index dfa31941a..a763fbcb6 100644
--- a/nova/exception.py
+++ b/nova/exception.py
@@ -1203,6 +1203,10 @@ class RescheduledException(NovaException):
"%(reason)s")
+class ShadowTableExists(NovaException):
+ message = _("Shadow table with name %(name)s already exists.")
+
+
class InstanceFaultRollback(NovaException):
def __init__(self, inner_exception=None):
message = _("Instance rollback performed due to: %s")
diff --git a/nova/tests/test_migration_utils.py b/nova/tests/test_migration_utils.py
index d6e1ee568..5155dba8f 100644
--- a/nova/tests/test_migration_utils.py
+++ b/nova/tests/test_migration_utils.py
@@ -19,7 +19,6 @@ 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 OperationalError
from sqlalchemy.exc import SAWarning
from sqlalchemy.sql import select
from sqlalchemy.types import UserDefinedType
@@ -92,54 +91,51 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
{'id': 3, 'a': 1, 'foo': 30}
]
- for key, engine in self.engines.items():
- meta = MetaData()
- meta.bind = engine
- test_table = Table(table_name, meta,
- Column('id', Integer, primary_key=True,
- nullable=False),
- Column('a', Integer),
- Column('foo', CustomType, default=0),
- UniqueConstraint('a', name='uniq_a'),
- UniqueConstraint('foo', name=uc_name))
- test_table.create()
-
- engine.execute(test_table.insert(), values)
- if key == "sqlite":
- warnings.simplefilter("ignore", SAWarning)
- # NOTE(boris-42): Missing info about column `foo` that has
- # unsupported type CustomType.
- self.assertRaises(exception.NovaException,
- utils.drop_unique_constraint,
- engine, table_name, uc_name, 'foo')
-
- # NOTE(boris-42): Wrong type of foo instance. it should be
- # instance of sqlalchemy.Column.
- self.assertRaises(exception.NovaException,
- utils.drop_unique_constraint,
- engine, table_name, uc_name, 'foo',
- foo=Integer())
-
- foo = Column('foo', CustomType, default=0)
- utils.drop_unique_constraint(engine, table_name, uc_name, 'foo',
- foo=foo)
-
- s = test_table.select().order_by(test_table.c.id)
- rows = engine.execute(s).fetchall()
+ engine = self.engines['sqlite']
+ meta = MetaData(bind=engine)
- for i in xrange(0, len(values)):
- v = values[i]
- self.assertEqual((v['id'], v['a'], v['foo']), rows[i])
+ test_table = Table(table_name, meta,
+ Column('id', Integer, primary_key=True,
+ nullable=False),
+ Column('a', Integer),
+ Column('foo', CustomType, default=0),
+ UniqueConstraint('a', name='uniq_a'),
+ UniqueConstraint('foo', name=uc_name))
+ test_table.create()
- # NOTE(boris-42): Update data about Table from DB.
- meta = MetaData()
- meta.bind = engine
- test_table = Table(table_name, meta, autoload=True)
- constraints = filter(lambda c: c.name == uc_name,
- test_table.constraints)
- self.assertEqual(len(constraints), 0)
- self.assertEqual(len(test_table.constraints), 1)
- test_table.drop()
+ engine.execute(test_table.insert(), values)
+ warnings.simplefilter("ignore", SAWarning)
+ # NOTE(boris-42): Missing info about column `foo` that has
+ # unsupported type CustomType.
+ self.assertRaises(exception.NovaException,
+ utils.drop_unique_constraint,
+ engine, table_name, uc_name, 'foo')
+
+ # NOTE(boris-42): Wrong type of foo instance. it should be
+ # instance of sqlalchemy.Column.
+ self.assertRaises(exception.NovaException,
+ utils.drop_unique_constraint,
+ engine, table_name, uc_name, 'foo', foo=Integer())
+
+ foo = Column('foo', CustomType, default=0)
+ utils.drop_unique_constraint(engine, table_name, uc_name, 'foo',
+ foo=foo)
+
+ s = test_table.select().order_by(test_table.c.id)
+ rows = engine.execute(s).fetchall()
+
+ for i in xrange(0, len(values)):
+ v = values[i]
+ self.assertEqual((v['id'], v['a'], v['foo']), rows[i])
+
+ # NOTE(boris-42): Update data about Table from DB.
+ meta = MetaData(bind=engine)
+ test_table = Table(table_name, meta, autoload=True)
+ constraints = filter(lambda c: c.name == uc_name,
+ test_table.constraints)
+ self.assertEqual(len(constraints), 0)
+ self.assertEqual(len(test_table.constraints), 1)
+ test_table.drop()
def _populate_db_for_drop_duplicate_entries(self, engine, meta,
table_name):
@@ -160,7 +156,7 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
nullable=False),
Column('a', Integer),
Column('b', Integer),
- Column('c', String),
+ Column('c', String(255)),
Column('deleted', Integer, default=0),
Column('deleted_at', DateTime),
Column('updated_at', DateTime))
@@ -296,22 +292,21 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
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))
+ engine = self.engines['sqlite']
+ meta = MetaData(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))
def test_create_shadow_table_by_table_instance(self):
table_name = 'abc'
@@ -342,21 +337,20 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
def test_create_shadow_table_not_supported_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', CustomType))
- table.create()
- self.assertRaises(exception.NovaException,
- utils.create_shadow_table,
- engine, table_name=table_name)
-
- utils.create_shadow_table(engine, table_name=table_name,
- a=Column('a', CustomType()))
- self.assertTrue(utils.check_shadow_table(engine, table_name))
+ engine = self.engines['sqlite']
+ meta = MetaData()
+ meta.bind = engine
+ table = Table(table_name, meta,
+ Column('id', Integer, primary_key=True),
+ Column('a', CustomType))
+ table.create()
+ self.assertRaises(exception.NovaException,
+ utils.create_shadow_table,
+ engine, table_name=table_name)
+
+ utils.create_shadow_table(engine, table_name=table_name,
+ a=Column('a', CustomType()))
+ self.assertTrue(utils.check_shadow_table(engine, table_name))
def test_create_shadow_both_table_and_table_name_are_none(self):
for key, engine in self.engines.items():
@@ -388,6 +382,6 @@ class TestMigrationUtils(test_migrations.BaseMigrationTestCase):
Column('a', Integer))
table.create()
utils.create_shadow_table(engine, table_name=table_name)
- self.assertRaises(OperationalError,
+ self.assertRaises(exception.ShadowTableExists,
utils.create_shadow_table,
engine, table_name=table_name)