summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormelanie witt <melwittt@gmail.com>2021-01-29 23:42:23 +0000
committermelanie witt <melwittt@gmail.com>2021-04-06 23:00:27 +0000
commita8624cdaa292591db616b9ab17d27f2cd0bb00a7 (patch)
tree02c521c1a691593cffe52362153144c9b2422791
parentc27149d950d9e079433250c229f0d59fe6e47096 (diff)
downloadnova-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)
-rw-r--r--nova/test.py18
-rw-r--r--nova/tests/functional/db/test_archive.py18
-rw-r--r--nova/tests/functional/test_nova_manage.py2
-rw-r--r--nova/tests/unit/db/test_db_api.py14
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