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)
downloadnova-7238438ef218d79a31acb07ea004fca8c2e78798.tar.gz
nova-7238438ef218d79a31acb07ea004fca8c2e78798.tar.xz
nova-7238438ef218d79a31acb07ea004fca8c2e78798.zip
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)