diff options
author | Stephen Finucane <stephenfin@redhat.com> | 2021-12-24 11:24:08 +0000 |
---|---|---|
committer | Stephen Finucane <stephenfin@redhat.com> | 2022-01-05 18:29:43 +0000 |
commit | 771c943ad2116193e7bb118c74993c829d93bd71 (patch) | |
tree | ea705aa9fef728195f3aab45bcc149c0d0a90fbd | |
parent | 03238e343a595e1cb4fd43a84062db72b094c832 (diff) | |
download | keystone-771c943ad2116193e7bb118c74993c829d93bd71.tar.gz |
Add 'WarningsFixture'
This duplicates what exists in nova and various other projects. The
important difference between this and what we're doing currently is that
it *restores*, rather than reset, the warning filters. There are more
various warning filters pre-configured in a typical Python environment,
including a few from third-party libraries such as requests [1][2] and
urllib3 [3] as well as stdlib [4]. By calling 'warnings.resetwarnings', we
*reset* all the warning filters [5]. This is clearly not something we want to
do, and resulted in tests puking warnings after the initial test run.
[1] https://github.com/psf/requests/blob/v2.26.0/requests/__init__.py#L127
[2] https://github.com/psf/requests/blob/v2.26.0/requests/__init__.py#L152
[3] https://github.com/urllib3/urllib3/blob/1.26.7/src/urllib3/__init__.py#L68-L78
[4] https://docs.python.org/3.8/library/warnings.html#default-warning-filter
[5] https://docs.python.org/3.8/library/warnings.html#warnings.resetwarnings
Change-Id: Ia2046dc32e3ac270b1dbcf2fe540104c1a8d95d8
Signed-off-by: Stephen Finucane <stephenfin@redhat.com>
-rw-r--r-- | keystone/tests/unit/core.py | 14 | ||||
-rw-r--r-- | keystone/tests/unit/ksfixtures/__init__.py | 1 | ||||
-rw-r--r-- | keystone/tests/unit/ksfixtures/warnings.py | 54 |
3 files changed, 57 insertions, 12 deletions
diff --git a/keystone/tests/unit/core.py b/keystone/tests/unit/core.py index 5e93b842f..3e873dbba 100644 --- a/keystone/tests/unit/core.py +++ b/keystone/tests/unit/core.py @@ -11,6 +11,7 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. + import atexit import base64 import contextlib @@ -24,7 +25,6 @@ import shutil import socket import sys import uuid -import warnings import fixtures import flask @@ -36,7 +36,6 @@ from oslo_context import fixture as oslo_ctx_fixture from oslo_log import fixture as log_fixture from oslo_log import log from oslo_utils import timeutils -from sqlalchemy import exc import testtools from testtools import testcase @@ -678,17 +677,8 @@ class BaseTestCase(testtools.TestCase): self.useFixture(fixtures.MockPatchObject(sys, 'exit', side_effect=UnexpectedExit)) self.useFixture(log_fixture.get_logging_handle_error_fixture()) + self.useFixture(ksfixtures.WarningsFixture()) - warnings.filterwarnings('error', category=DeprecationWarning, - module='^keystone\\.') - warnings.filterwarnings( - 'ignore', category=DeprecationWarning, - message=r"Using function/method 'db_version\(\)' is deprecated") - warnings.simplefilter('error', exc.SAWarning) - if hasattr(exc, "RemovedIn20Warning"): - warnings.simplefilter('ignore', exc.RemovedIn20Warning) - - self.addCleanup(warnings.resetwarnings) # Ensure we have an empty threadlocal context at the start of each # test. self.assertIsNone(oslo_context.get_current()) diff --git a/keystone/tests/unit/ksfixtures/__init__.py b/keystone/tests/unit/ksfixtures/__init__.py index 7a92c42cd..a76e5e5a9 100644 --- a/keystone/tests/unit/ksfixtures/__init__.py +++ b/keystone/tests/unit/ksfixtures/__init__.py @@ -17,3 +17,4 @@ from keystone.tests.unit.ksfixtures.cache import Cache # noqa from keystone.tests.unit.ksfixtures.jws_key_repository import JWSKeyRepository # noqa from keystone.tests.unit.ksfixtures.key_repository import KeyRepository # noqa from keystone.tests.unit.ksfixtures.policy import Policy # noqa +from keystone.tests.unit.ksfixtures.warnings import WarningsFixture # noqa diff --git a/keystone/tests/unit/ksfixtures/warnings.py b/keystone/tests/unit/ksfixtures/warnings.py new file mode 100644 index 000000000..11d69567c --- /dev/null +++ b/keystone/tests/unit/ksfixtures/warnings.py @@ -0,0 +1,54 @@ +# 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. + +import warnings + +import fixtures +from sqlalchemy import exc as sqla_exc + + +class WarningsFixture(fixtures.Fixture): + """Filters out warnings during test runs.""" + + def setUp(self): + super().setUp() + + self._original_warning_filters = warnings.filters[:] + + # NOTE(stephenfin): Make deprecation warnings only happen once. + # Otherwise this gets kind of crazy given the way that upstream python + # libs use this. + warnings.simplefilter('once', DeprecationWarning) + + warnings.filterwarnings( + 'error', + category=DeprecationWarning, + module='^keystone\\.', + ) + + # TODO(stephenfin): This will be fixed once we drop sqlalchemy-migrate + warnings.filterwarnings( + 'ignore', + category=DeprecationWarning, + message=r"Using function/method 'db_version\(\)' is deprecated", + ) + + # TODO(stephenfin): We should filter on the specific RemovedIn20Warning + # warnings that affect us, so that we can slowly start addressing them + warnings.simplefilter('error', sqla_exc.SAWarning) + if hasattr(sqla_exc, 'RemovedIn20Warning'): + warnings.simplefilter('ignore', sqla_exc.RemovedIn20Warning) + + self.addCleanup(self._reset_warning_filters) + + def _reset_warning_filters(self): + warnings.filters[:] = self._original_warning_filters |