diff --git a/nova/test.py b/nova/test.py index dd0fc4daa595..89e4bed0842a 100644 --- a/nova/test.py +++ b/nova/test.py @@ -51,10 +51,12 @@ from oslotest import base from oslotest import mock_fixture import six from six.moves import builtins +from sqlalchemy.dialects import sqlite import testtools from nova.compute import rpcapi as compute_rpcapi from nova import context +from nova.db.sqlalchemy import api as sqlalchemy_api from nova import exception from nova import objects from nova.objects import base as objects_base @@ -376,6 +378,22 @@ class TestCase(base.BaseTestCase): for k, v in kw.items(): CONF.set_override(k, v, group) + def enforce_fk_constraints(self, engine=None): + if engine is None: + engine = sqlalchemy_api.get_engine() + dialect = engine.url.get_dialect() + if dialect == sqlite.dialect: + # We're seeing issues with foreign key support in SQLite 3.6.20 + # SQLAlchemy doesn't support it at all with < SQLite 3.6.19 + # It works fine in SQLite 3.7. + # So return early to skip this test if running SQLite < 3.7 + import sqlite3 + tup = sqlite3.sqlite_version_info + if tup[0] < 3 or (tup[0] == 3 and tup[1] < 7): + self.skipTest( + 'sqlite version too old for reliable SQLA foreign_keys') + engine.connect().execute("PRAGMA foreign_keys = ON") + def start_service(self, name, host=None, cell_name=None, **kwargs): # Disallow starting multiple scheduler services if name == 'scheduler' and self._service_fixture_count[name]: diff --git a/nova/tests/functional/db/test_archive.py b/nova/tests/functional/db/test_archive.py index 68ddb327bae7..0b4f3534692b 100644 --- a/nova/tests/functional/db/test_archive.py +++ b/nova/tests/functional/db/test_archive.py @@ -17,7 +17,6 @@ import re from dateutil import parser as dateutil_parser from oslo_utils import timeutils -from sqlalchemy.dialects import sqlite from sqlalchemy import func from sqlalchemy import MetaData from sqlalchemy import select @@ -33,22 +32,7 @@ class TestDatabaseArchive(integrated_helpers._IntegratedTestBase): def setUp(self): super(TestDatabaseArchive, self).setUp() - # TODO(mriedem): pull this out so we can re-use it in - # test_archive_deleted_rows_fk_constraint - # SQLite doesn't enforce foreign key constraints without a pragma. - engine = sqlalchemy_api.get_engine() - dialect = engine.url.get_dialect() - if dialect == sqlite.dialect: - # We're seeing issues with foreign key support in SQLite 3.6.20 - # SQLAlchemy doesn't support it at all with < SQLite 3.6.19 - # It works fine in SQLite 3.7. - # So return early to skip this test if running SQLite < 3.7 - import sqlite3 - tup = sqlite3.sqlite_version_info - if tup[0] < 3 or (tup[0] == 3 and tup[1] < 7): - self.skipTest( - 'sqlite version too old for reliable SQLA foreign_keys') - engine.connect().execute("PRAGMA foreign_keys = ON") + self.enforce_fk_constraints() def test_archive_deleted_rows(self): # Boots a server, deletes it, and then tries to archive it. diff --git a/nova/tests/functional/test_nova_manage.py b/nova/tests/functional/test_nova_manage.py index 8c81ac1cf34f..311bc1b1cb35 100644 --- a/nova/tests/functional/test_nova_manage.py +++ b/nova/tests/functional/test_nova_manage.py @@ -1767,6 +1767,7 @@ class TestDBArchiveDeletedRows(integrated_helpers._IntegratedTestBase): def setUp(self): super(TestDBArchiveDeletedRows, self).setUp() + self.enforce_fk_constraints() self.cli = manage.DbCommands() self.output = StringIO() self.useFixture(fixtures.MonkeyPatch('sys.stdout', self.output)) @@ -1812,6 +1813,7 @@ class TestDBArchiveDeletedRowsMultiCell(integrated_helpers.InstanceHelperMixin, def setUp(self): super(TestDBArchiveDeletedRowsMultiCell, self).setUp() + self.enforce_fk_constraints() self.useFixture(nova_fixtures.NeutronFixture(self)) self.useFixture(nova_fixtures.GlanceFixture(self)) self.useFixture(func_fixtures.PlacementFixture()) diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index a9943f1c3711..352125b7a67a 100644 --- a/nova/tests/unit/db/test_db_api.py +++ b/nova/tests/unit/db/test_db_api.py @@ -39,7 +39,6 @@ from oslo_utils import uuidutils import six from six.moves import range from sqlalchemy import Column -from sqlalchemy.dialects import sqlite from sqlalchemy.exc import OperationalError from sqlalchemy.exc import SQLAlchemyError from sqlalchemy import inspect @@ -6440,18 +6439,7 @@ class ArchiveTestCase(test.TestCase, ModelsObjectComparatorMixin): def _check_sqlite_version_less_than_3_7(self): # SQLite doesn't enforce foreign key constraints without a pragma. - dialect = self.engine.url.get_dialect() - if dialect == sqlite.dialect: - # We're seeing issues with foreign key support in SQLite 3.6.20 - # SQLAlchemy doesn't support it at all with < SQLite 3.6.19 - # It works fine in SQLite 3.7. - # So return early to skip this test if running SQLite < 3.7 - import sqlite3 - tup = sqlite3.sqlite_version_info - if tup[0] < 3 or (tup[0] == 3 and tup[1] < 7): - self.skipTest( - 'sqlite version too old for reliable SQLA foreign_keys') - self.conn.execute("PRAGMA foreign_keys = ON") + self.enforce_fk_constraints(engine=self.engine) def test_archive_deleted_rows_for_migrations(self): # migrations.instance_uuid depends on instances.uuid