diff options
author | melanie witt <melwittt@gmail.com> | 2021-01-29 23:42:23 +0000 |
---|---|---|
committer | melanie witt <melwittt@gmail.com> | 2021-04-06 23:00:27 +0000 |
commit | a8624cdaa292591db616b9ab17d27f2cd0bb00a7 (patch) | |
tree | 02c521c1a691593cffe52362153144c9b2422791 /nova | |
parent | c27149d950d9e079433250c229f0d59fe6e47096 (diff) | |
download | nova-a8624cdaa292591db616b9ab17d27f2cd0bb00a7.tar.gz |
Centralize sqlite FK constraint enforcement
There's a TODO in the code to centralize foreign key constraint
enforcement for sqlite for unit and functional tests and we're missing
enforcement of FK constraints in a couple of test classes that should
have it.
This resolves the TODO and turns on FK constraint enforcement where it
is missing. Do this to enhance testing in preparation for a proposed
change to the database archiving logic later in this patch series.
Change-Id: Idcf026d020e63e4e6ece1db46e4cdc7b7742b76f
(cherry picked from commit 172024db7174bdac05a3d3172c645b0db83ae41e)
(cherry picked from commit 382d64ea36e5cf3b47929fee0b93539d2f126975)
Diffstat (limited to 'nova')
-rw-r--r-- | nova/test.py | 18 | ||||
-rw-r--r-- | nova/tests/functional/db/test_archive.py | 18 | ||||
-rw-r--r-- | nova/tests/functional/test_nova_manage.py | 2 | ||||
-rw-r--r-- | nova/tests/unit/db/test_db_api.py | 14 |
4 files changed, 22 insertions, 30 deletions
diff --git a/nova/test.py b/nova/test.py index 6f5a8eebe3..4528eb73ca 100644 --- a/nova/test.py +++ b/nova/test.py @@ -50,10 +50,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 @@ -378,6 +380,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 8a6211cdcf..b38a3072da 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(test_servers.ServersTestBase): 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 811224e96e..65abb45241 100644 --- a/nova/tests/functional/test_nova_manage.py +++ b/nova/tests/functional/test_nova_manage.py @@ -1657,6 +1657,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)) @@ -1702,6 +1703,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(func_fixtures.PlacementFixture()) diff --git a/nova/tests/unit/db/test_db_api.py b/nova/tests/unit/db/test_db_api.py index a9943f1c37..352125b7a6 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 |