Merge "Make CacheIsolatingProxy public"

This commit is contained in:
Jenkins
2015-10-09 17:34:54 +00:00
committed by Gerrit Code Review
2 changed files with 72 additions and 25 deletions

70
oslo_cache/testing.py Normal file
View File

@@ -0,0 +1,70 @@
# Copyright 2013 Metacloud
#
# 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.
"""Items useful for external testing."""
import copy
from dogpile.cache import proxy
from oslo_cache import core as cache
__all__ = [
'CacheIsolatingProxy',
]
NO_VALUE = cache.NO_VALUE
def _copy_value(value):
if value is not NO_VALUE:
value = copy.deepcopy(value)
return value
# NOTE(morganfainberg): WARNING - It is not recommended to use the Memory
# backend for dogpile.cache in a real deployment under any circumstances. The
# backend does no cleanup of expired values and therefore will leak memory. The
# backend is not implemented in a way to share data across processes (e.g.
# Keystone in HTTPD. This proxy is a hack to get around the lack of isolation
# of values in memory. Currently it blindly stores and retrieves the values
# from the cache, and modifications to dicts/lists/etc returned can result in
# changes to the cached values. In short, do not use the dogpile.cache.memory
# backend unless you are running tests or expecting odd/strange results.
class CacheIsolatingProxy(proxy.ProxyBackend):
"""Proxy that forces a memory copy of stored values.
The default in-memory cache-region does not perform a copy on values it
is meant to cache. Therefore if the value is modified after set or after
get, the cached value also is modified. This proxy does a copy as the last
thing before storing data.
In your application's tests, you'll want to set this as a proxy for the
in-memory cache, like this::
self.config_fixture.config(
group='cache',
backend='dogpile.cache.memory',
enabled=True,
proxies=['oslo_cache.testing.CacheIsolatingProxy'])
"""
def get(self, key):
return _copy_value(self.proxied.get(key))
def set(self, key, value):
self.proxied.set(key, _copy_value(value))

View File

@@ -20,11 +20,11 @@ import uuid
from dogpile.cache import proxy
import mock
from oslo_config import cfg
from oslo_config import fixture as config_fixture
from oslotest import base
from oslo_cache import core as cache
from oslo_cache import exception
from oslo_config import fixture as config_fixture
NO_VALUE = cache.NO_VALUE
@@ -42,7 +42,7 @@ class BaseTestCase(base.BaseTestCase):
group='cache',
backend='dogpile.cache.memory',
enabled=True,
proxies=['oslo_cache.tests.test_cache.CacheIsolatingProxy'])
proxies=['oslo_cache.testing.CacheIsolatingProxy'])
def _copy_value(value):
@@ -51,29 +51,6 @@ def _copy_value(value):
return value
# NOTE(morganfainberg): WARNING - It is not recommended to use the Memory
# backend for dogpile.cache in a real deployment under any circumstances. The
# backend does no cleanup of expired values and therefore will leak memory. The
# backend is not implemented in a way to share data across processes (e.g.
# Keystone in HTTPD. This proxy is a hack to get around the lack of isolation
# of values in memory. Currently it blindly stores and retrieves the values
# from the cache, and modifications to dicts/lists/etc returned can result in
# changes to the cached values. In short, do not use the dogpile.cache.memory
# backend unless you are running tests or expecting odd/strange results.
class CacheIsolatingProxy(proxy.ProxyBackend):
"""Proxy that forces a memory copy of stored values.
The default in-memory cache-region does not perform a copy on values it
is meant to cache. Therefore if the value is modified after set or after
get, the cached value also is modified. This proxy does a copy as the last
thing before storing data.
"""
def get(self, key):
return _copy_value(self.proxied.get(key))
def set(self, key, value):
self.proxied.set(key, _copy_value(value))
class TestProxy(proxy.ProxyBackend):
def get(self, key):
value = _copy_value(self.proxied.get(key))