From 586e5b0a75167b20882728f642c8a81195afb71d Mon Sep 17 00:00:00 2001 From: Stephen Finucane Date: Thu, 23 Mar 2023 11:20:51 +0000 Subject: [PATCH] tests: Enable SQLAlchemy 2.0 deprecation warnings Well, sort of. We enable them but immediately filter out the ones we're actually seeing, the rationale being that we can address these in a piecemeal fashion without the risk of introducing new issues. There's a lot more to be done here. However, the work done in oslo.db [1], nova [2], cinder [2] etc. should provide a guide for how to resolve the outstanding issues. [1] https://review.opendev.org/q/topic:sqlalchemy-20+project:openstack/oslo.db [2] https://review.opendev.org/q/topic:sqlalchemy-20+project:openstack/nova [3] https://review.opendev.org/q/topic:sqlalchemy-20+project:openstack/cinder Signed-off-by: Stephen Finucane Change-Id: I5877aa495486ba28519b51d800c0474fd72859a5 --- heat/tests/common.py | 6 ++- heat/tests/utils.py | 108 +++++++++++++++++++++++++++++++++++++++++++ tox.ini | 8 ++-- 3 files changed, 117 insertions(+), 5 deletions(-) diff --git a/heat/tests/common.py b/heat/tests/common.py index baafe94be7..3013a14991 100644 --- a/heat/tests/common.py +++ b/heat/tests/common.py @@ -82,9 +82,11 @@ class HeatTestCase(testscenarios.WithScenarios, def setUp(self, mock_keystone=True, mock_resource_policy=True, quieten_logging=True, mock_find_file=True): - super(HeatTestCase, self).setUp() + super().setUp() self.setup_logging(quieten=quieten_logging) - self.warnings = self.useFixture(fixtures.WarningsCapture()) + + self.useFixture(utils.WarningsFixture()) + scheduler.ENABLE_SLEEP = False self.useFixture(fixtures.MonkeyPatch( 'heat.common.exception._FATAL_EXCEPTION_FORMAT_ERRORS', diff --git a/heat/tests/utils.py b/heat/tests/utils.py index 19fc1a06fc..ea9aa6329c 100644 --- a/heat/tests/utils.py +++ b/heat/tests/utils.py @@ -14,12 +14,14 @@ import random import string import uuid +import warnings import fixtures from oslo_config import cfg from oslo_db import options from oslo_serialization import jsonutils import sqlalchemy +from sqlalchemy import exc as sqla_exc from heat.common import context from heat.db.sqlalchemy import api as db_api @@ -235,6 +237,112 @@ class ForeignKeyConstraintFixture(fixtures.Fixture): self.addCleanup(disable_fks) +class WarningsFixture(fixtures.Fixture): + """Filters out warnings during test runs.""" + + def setUp(self): + super().setUp() + + self._original_warning_filters = warnings.filters[:] + + warnings.simplefilter("once", DeprecationWarning) + + # Enable deprecation warnings for heat itself to capture upcoming + # SQLAlchemy changes + + warnings.filterwarnings( + 'ignore', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'error', + module='heat', + category=sqla_exc.SADeprecationWarning, + ) + + # ...but filter everything out until we get around to fixing them + # TODO(stephenfin): Fix all of these + + warnings.filterwarnings( + 'ignore', + module='heat', + message=r'The Engine.execute\(\) method is considered legacy ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message='The current statement is being autocommitted using ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message='Using strings to indicate column or relationship paths ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message=r'The Query.get\(\) method is considered legacy ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message='The Session.transaction attribute is considered legacy ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message='The Session.begin.subtransactions flag is deprecated ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message='The autoload parameter is deprecated ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message='The ``bind`` argument for schema methods that invoke ', + category=sqla_exc.SADeprecationWarning, + ) + + warnings.filterwarnings( + 'ignore', + module='heat', + message=r'The legacy calling style of select\(\) is deprecated ', + category=sqla_exc.SADeprecationWarning, + ) + + # Enable general SQLAlchemy warnings also to ensure we're not doing + # silly stuff. It's possible that we'll need to filter things out here + # with future SQLAlchemy versions, but that's a good thing + + warnings.filterwarnings( + 'error', + module='heat', + category=sqla_exc.SAWarning, + ) + + self.addCleanup(self._reset_warning_filters) + + def _reset_warning_filters(self): + warnings.filters[:] = self._original_warning_filters + + class AnyInstance(object): """Comparator for validating allowed instance type.""" diff --git a/tox.ini b/tox.ini index 4998edd17d..1e1b7c174e 100644 --- a/tox.ini +++ b/tox.ini @@ -5,9 +5,11 @@ minversion = 3.18.0 [testenv] basepython = python3 -setenv = VIRTUAL_ENV={envdir} - PYTHONWARNINGS=default::DeprecationWarning - OS_TEST_PATH=heat/tests +setenv = + OS_TEST_PATH=heat/tests + PYTHONDONTWRITEBYTECODE=1 +# TODO(stephenfin): Remove once we bump our upper-constraint to SQLAlchemy 2.0 + SQLALCHEMY_WARN_20=1 usedevelop = True deps = -c{env:TOX_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master} -r{toxinidir}/requirements.txt