isolate cache

This commit is contained in:
chris meyers 2018-05-16 16:43:29 -04:00
parent 7f214f5ad2
commit 04767641af
12 changed files with 93 additions and 64 deletions

View File

View File

@ -0,0 +1,6 @@
# Ensure that our autouse overwrites are working
def test_cache(settings):
assert settings.CACHES['default']['BACKEND'] == 'django.core.cache.backends.locmem.LocMemCache'
assert settings.CACHES['default']['LOCATION'].startswith('unique-')

View File

@ -106,3 +106,21 @@ def get_ssh_version(mocker):
@pytest.fixture
def job_template_with_survey_passwords_unit(job_template_with_survey_passwords_factory):
return job_template_with_survey_passwords_factory(persisted=False)
@pytest.fixture
def mock_cache():
class MockCache(object):
cache = {}
def get(self, key, default=None):
return self.cache.get(key, default)
def set(self, key, value, timeout=60):
self.cache[key] = value
def delete(self, key):
del self.cache[key]
return MockCache()

View File

@ -9,7 +9,6 @@ from six.moves import xrange
# Django
from django.core.urlresolvers import resolve
from django.core.cache import cache
from django.utils.six.moves.urllib.parse import urlparse
from django.utils import timezone
from django.contrib.auth.models import User
@ -57,14 +56,6 @@ def swagger_autogen(requests=__SWAGGER_REQUESTS__):
return requests
@pytest.fixture(autouse=True)
def clear_cache():
'''
Clear cache (local memory) for each test to prevent using cached settings.
'''
cache.clear()
@pytest.fixture(scope="session", autouse=True)
def celery_memory_broker():
'''

View File

@ -241,15 +241,16 @@ def test_shared_dependencies_launch(default_instance_group, job_template_factory
@pytest.mark.django_db
def test_cleanup_interval():
assert cache.get('last_celery_task_cleanup') is None
def test_cleanup_interval(mock_cache):
with mock.patch.multiple('awx.main.scheduler.task_manager.cache', get=mock_cache.get, set=mock_cache.set):
assert mock_cache.get('last_celery_task_cleanup') is None
TaskManager().cleanup_inconsistent_celery_tasks()
last_cleanup = cache.get('last_celery_task_cleanup')
assert isinstance(last_cleanup, datetime)
TaskManager().cleanup_inconsistent_celery_tasks()
last_cleanup = mock_cache.get('last_celery_task_cleanup')
assert isinstance(last_cleanup, datetime)
TaskManager().cleanup_inconsistent_celery_tasks()
assert cache.get('last_celery_task_cleanup') == last_cleanup
TaskManager().cleanup_inconsistent_celery_tasks()
assert cache.get('last_celery_task_cleanup') == last_cleanup
class TestReaper():
@ -326,7 +327,8 @@ class TestReaper():
@pytest.mark.django_db
@mock.patch.object(JobNotificationMixin, 'send_notification_templates')
@mock.patch.object(TaskManager, 'get_active_tasks', lambda self: ([], []))
def test_cleanup_inconsistent_task(self, notify, active_tasks, considered_jobs, reapable_jobs, running_tasks, waiting_tasks, mocker):
def test_cleanup_inconsistent_task(self, notify, active_tasks, considered_jobs, reapable_jobs, running_tasks, waiting_tasks, mocker, settings):
settings.AWX_INCONSISTENT_TASK_INTERVAL = 0
tm = TaskManager()
tm.get_running_tasks = mocker.Mock(return_value=(running_tasks, waiting_tasks))

View File

@ -0,0 +1,6 @@
# Ensure that our autouse overwrites are working
def test_cache(settings):
assert settings.CACHES['default']['BACKEND'] == 'django.core.cache.backends.locmem.LocMemCache'
assert settings.CACHES['default']['LOCATION'].startswith('unique-')

View File

@ -253,7 +253,7 @@ def test_optional_survey_question_defaults(
('password', 'foo', 5, {'extra_vars': {'x': ''}}, {'x': ''}),
('password', ENCRYPTED_SECRET, 5, {'extra_vars': {'x': '$encrypted$'}}, {}),
('password', ENCRYPTED_SECRET, 10, {'extra_vars': {'x': '$encrypted$'}}, {'x': ENCRYPTED_SECRET}),
], ids=DistinctParametrize())
], ids=DistinctParametrize())
def test_survey_encryption_defaults(survey_spec_factory, question_type, default, maxlen, kwargs, expected):
spec = survey_spec_factory([
{

View File

@ -7,10 +7,10 @@ import pytest
from uuid import uuid4
import json
import yaml
import mock
from backports.tempfile import TemporaryDirectory
from django.conf import settings
from django.core.cache import cache
from rest_framework.exceptions import ParseError
@ -26,14 +26,6 @@ from awx.main.models import (
)
@pytest.fixture(autouse=True)
def clear_cache():
'''
Clear cache (local memory) for each test to prevent using cached settings.
'''
cache.clear()
@pytest.mark.parametrize('input_, output', [
({"foo": "bar"}, {"foo": "bar"}),
('{"foo": "bar"}', {"foo": "bar"}),
@ -114,46 +106,48 @@ def test_get_type_for_model(model, name):
@pytest.fixture
def memoized_function(mocker):
@common.memoize(track_function=True)
def myfunction(key, value):
if key not in myfunction.calls:
myfunction.calls[key] = 0
def memoized_function(mocker, mock_cache):
with mock.patch('awx.main.utils.common.get_memoize_cache', return_value=mock_cache):
@common.memoize(track_function=True)
def myfunction(key, value):
if key not in myfunction.calls:
myfunction.calls[key] = 0
myfunction.calls[key] += 1
myfunction.calls[key] += 1
if myfunction.calls[key] == 1:
return value
else:
return '%s called %s times' % (value, myfunction.calls[key])
myfunction.calls = dict()
return myfunction
if myfunction.calls[key] == 1:
return value
else:
return '%s called %s times' % (value, myfunction.calls[key])
myfunction.calls = dict()
return myfunction
def test_memoize_track_function(memoized_function):
def test_memoize_track_function(memoized_function, mock_cache):
assert memoized_function('scott', 'scotterson') == 'scotterson'
assert cache.get('myfunction') == {u'scott-scotterson': 'scotterson'}
assert mock_cache.get('myfunction') == {u'scott-scotterson': 'scotterson'}
assert memoized_function('scott', 'scotterson') == 'scotterson'
assert memoized_function.calls['scott'] == 1
assert memoized_function('john', 'smith') == 'smith'
assert cache.get('myfunction') == {u'scott-scotterson': 'scotterson', u'john-smith': 'smith'}
assert mock_cache.get('myfunction') == {u'scott-scotterson': 'scotterson', u'john-smith': 'smith'}
assert memoized_function('john', 'smith') == 'smith'
assert memoized_function.calls['john'] == 1
def test_memoize_delete(memoized_function):
def test_memoize_delete(memoized_function, mock_cache):
assert memoized_function('john', 'smith') == 'smith'
assert memoized_function('john', 'smith') == 'smith'
assert memoized_function.calls['john'] == 1
assert cache.get('myfunction') == {u'john-smith': 'smith'}
assert mock_cache.get('myfunction') == {u'john-smith': 'smith'}
common.memoize_delete('myfunction')
with mock.patch('awx.main.utils.common.memoize_delete', side_effect=mock_cache.delete):
common.memoize_delete('myfunction')
assert cache.get('myfunction') is None
assert mock_cache.get('myfunction') is None
assert memoized_function('john', 'smith') == 'smith called 2 times'
assert memoized_function.calls['john'] == 2

View File

@ -127,12 +127,16 @@ class IllegalArgumentError(ValueError):
pass
def get_memoize_cache():
from django.core.cache import cache
return cache
def memoize(ttl=60, cache_key=None, track_function=False):
'''
Decorator to wrap a function and cache its result.
'''
from django.core.cache import cache
cache = get_memoize_cache()
def _memoizer(f, *args, **kwargs):
if cache_key and track_function:
@ -160,8 +164,7 @@ def memoize(ttl=60, cache_key=None, track_function=False):
def memoize_delete(function_name):
from django.core.cache import cache
cache = get_memoize_cache()
return cache.delete(function_name)

View File

@ -537,19 +537,12 @@ ASGI_AMQP = {
}
# Django Caching Configuration
if is_testing():
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
},
}
else:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'memcached:11211',
},
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'memcached:11211',
},
}
# Social Auth configuration.
SOCIAL_AUTH_STRATEGY = 'social_django.strategy.DjangoStrategy'

View File

@ -9,6 +9,7 @@ import socket
import copy
import sys
import traceback
import random
# Centos-7 doesn't include the svg mime type
# /usr/lib64/python/mimetypes.py
@ -20,6 +21,15 @@ from split_settings.tools import optional, include
# Load default settings.
from defaults import * # NOQA
# don't use memcache when running tests
if "pytest" in sys.modules:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-{}'.format(random.randint(0, sys.maxint)),
},
}
# awx-manage shell_plus --notebook
NOTEBOOK_ARGUMENTS = [
'--NotebookApp.token=',

View File

@ -0,0 +1,6 @@
# Ensure that our autouse overwrites are working
def test_cache(settings):
assert settings.CACHES['default']['BACKEND'] == 'django.core.cache.backends.locmem.LocMemCache'
assert settings.CACHES['default']['LOCATION'].startswith('unique-')