Fix bug, None was used instead of empty for DB outage (#14463)

This commit is contained in:
Alan Rominger
2023-09-21 14:30:25 -04:00
committed by GitHub
parent 3e607f8964
commit 29ad6e1eaa
2 changed files with 20 additions and 0 deletions

View File

@@ -418,6 +418,10 @@ class SettingsWrapper(UserSettingsHolder):
"""Get value while accepting the in-memory cache if key is available""" """Get value while accepting the in-memory cache if key is available"""
with _ctit_db_wrapper(trans_safe=True): with _ctit_db_wrapper(trans_safe=True):
return self._get_local(name) return self._get_local(name)
# If the last line did not return, that means we hit a database error
# in that case, we should not have a local cache value
# thus, return empty as a signal to use the default
return empty
def __getattr__(self, name): def __getattr__(self, name):
value = empty value = empty

View File

@@ -13,6 +13,7 @@ from unittest import mock
from django.conf import LazySettings from django.conf import LazySettings
from django.core.cache.backends.locmem import LocMemCache from django.core.cache.backends.locmem import LocMemCache
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
from django.db.utils import Error as DBError
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
import pytest import pytest
@@ -331,3 +332,18 @@ def test_in_memory_cache_works(settings):
with mock.patch.object(settings, '_get_local') as mock_get: with mock.patch.object(settings, '_get_local') as mock_get:
assert settings.AWX_VAR == 'DEFAULT' assert settings.AWX_VAR == 'DEFAULT'
mock_get.assert_not_called() mock_get.assert_not_called()
@pytest.mark.defined_in_file(AWX_VAR=[])
def test_getattr_with_database_error(settings):
"""
If a setting is defined via the registry and has a null-ish default which is not None
then referencing that setting during a database outage should give that default
this is regression testing for a bug where it would return None
"""
settings.registry.register('AWX_VAR', field_class=fields.StringListField, default=[], category=_('System'), category_slug='system')
settings._awx_conf_memoizedcache.clear()
with mock.patch('django.db.backends.base.base.BaseDatabaseWrapper.ensure_connection') as mock_ensure:
mock_ensure.side_effect = DBError('for test')
assert settings.AWX_VAR == []