Cleaning test DB without Alembic migrations
On the Fuel CI we have no rights to drop and create DB. In the tests we are downgrading and upgrading DB schema by Alembic migrations. In case of adding migrations in one review we had all other reviews broken due to Alembic failures on attempt to downgrade DB schema. As fix we are fallback to the cleaning DB without migrations in case of Alembic error on the schema downgrade. Change-Id: I65faf43c28427594495c67696ca190e7fe29f083 Closes-Bug: #1556876
This commit is contained in:
parent
e9ec2111a7
commit
ea6263af70
|
@ -68,20 +68,57 @@ class BaseTest(TestCase):
|
|||
|
||||
class DbTest(BaseTest):
|
||||
|
||||
def get_migrations_dir(self):
|
||||
return os.path.join(os.path.dirname(__file__),
|
||||
'..', 'api', 'db', 'migrations')
|
||||
|
||||
def setUp(self):
|
||||
super(DbTest, self).setUp()
|
||||
|
||||
# Connection must be closed before DB migration
|
||||
db.session.close()
|
||||
# Cleaning all changes from the previous test
|
||||
db.session.rollback()
|
||||
|
||||
# Cleaning DB. It useful in case of tests failure
|
||||
directory = os.path.join(os.path.dirname(__file__),
|
||||
'..', 'api', 'db', 'migrations')
|
||||
directory = self.get_migrations_dir()
|
||||
with app.app_context():
|
||||
try:
|
||||
flask_migrate.downgrade(directory=directory,
|
||||
revision='base')
|
||||
except CommandError:
|
||||
# Workaround for the first migration
|
||||
pass
|
||||
except CommandError as e:
|
||||
app.logger.debug("DB migration downgrade failed: %s", e)
|
||||
self.clean_db()
|
||||
flask_migrate.upgrade(directory=directory)
|
||||
|
||||
def clean_db(self):
|
||||
app.logger.debug("Cleaning DB without Alembic")
|
||||
|
||||
# Removing tables
|
||||
tables = db.session.execute(
|
||||
"SELECT table_name FROM information_schema.tables "
|
||||
"WHERE table_schema = 'public'")
|
||||
table_names = list(item[0] for item in tables)
|
||||
if table_names:
|
||||
app.logger.debug("Removing tables: %s", table_names)
|
||||
db.session.execute(
|
||||
"DROP TABLE {0} CASCADE".format(','.join(table_names)))
|
||||
|
||||
# Removing sequences
|
||||
sequences = list(item[0] for item in db.session.execute(
|
||||
"SELECT relname FROM pg_class WHERE relkind='S'"))
|
||||
sequence_names = list(item[0] for item in sequences)
|
||||
if sequence_names:
|
||||
app.logger.debug("Removing sequences: %s", sequence_names)
|
||||
db.session.execute(
|
||||
"DROP SEQUENCE {0}".format(','.join(sequences)))
|
||||
|
||||
# Removing enums
|
||||
enums = db.session.execute(
|
||||
"SELECT t.typname FROM pg_type t JOIN pg_catalog.pg_namespace n "
|
||||
"ON n.oid = t.typnamespace WHERE n.nspname='public'")
|
||||
enum_names = list(item[0] for item in enums)
|
||||
if enum_names:
|
||||
app.logger.debug("Removing types: %s", enum_names)
|
||||
db.session.execute(
|
||||
"DROP TYPE {0}".format(','.join(enum_names)))
|
||||
|
||||
# Committing DDL changes
|
||||
db.session.commit()
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# Copyright 2016 Mirantis, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from alembic.util import CommandError
|
||||
import flask_migrate
|
||||
|
||||
from collector.test.base import DbTest
|
||||
|
||||
from collector.api.app import app
|
||||
from collector.api.app import db
|
||||
|
||||
|
||||
class TestMigration(DbTest):
|
||||
|
||||
def test_clean_db(self):
|
||||
# Crashing alembic versions history
|
||||
db.session.execute("UPDATE alembic_version SET version_num='x'")
|
||||
db.session.commit()
|
||||
|
||||
migrations_dir = self.get_migrations_dir()
|
||||
with app.app_context():
|
||||
# Checking migrations are broken
|
||||
self.assertRaises(
|
||||
CommandError, flask_migrate.downgrade,
|
||||
directory=migrations_dir, revision='base'
|
||||
)
|
||||
|
||||
self.clean_db()
|
||||
|
||||
# Checking migrations flow is fixed
|
||||
flask_migrate.downgrade(directory=migrations_dir, revision='base')
|
||||
flask_migrate.upgrade(directory=migrations_dir)
|
Loading…
Reference in New Issue