Refactor memcache config and MemcacheRing loading

The loading and creation of the Memcache ring in the middleware is
rather interesting. It not only reads the config file, but also may
look for a `/etc/swift/memcache.conf`. Further, we are know are
looking at using the MemcacheRing client in more places.

So this patch moves the config reading from the middleware and
into a `load_memcache` helper method in swift/common/memcached.py.

Drive-by: cleanup unused stuff in middleware test module

Change-Id: I028722facfbe3ff8092b6bdcc931887a169cc49a
This commit is contained in:
Matthew Oliver 2021-12-07 13:24:19 +11:00 committed by Alistair Coles
parent 51730f1273
commit a8516e1510
4 changed files with 332 additions and 307 deletions

View File

@ -44,18 +44,20 @@ version is at:
http://github.com/memcached/memcached/blob/1.4.2/doc/protocol.txt
"""
import os
import six
import json
import logging
import time
from bisect import bisect
from eventlet.green import socket
from eventlet.green import socket, ssl
from eventlet.pools import Pool
from eventlet import Timeout
from six.moves import range
from six.moves.configparser import ConfigParser, NoSectionError, NoOptionError
from swift.common import utils
from swift.common.utils import md5, human_readable
from swift.common.utils import md5, human_readable, config_true_value
DEFAULT_MEMCACHED_PORT = 11211
@ -204,6 +206,10 @@ class MemcacheRing(object):
self.logger = logger
self.item_size_warning_threshold = item_size_warning_threshold
@property
def memcache_servers(self):
return list(self._client_cache.keys())
def _exception_occurred(self, server, e, action='talking',
sock=None, fp=None, got_connection=True):
if isinstance(e, Timeout):
@ -554,3 +560,96 @@ class MemcacheRing(object):
return values
except (Exception, Timeout) as e:
self._exception_occurred(server, e, sock=sock, fp=fp)
def load_memcache(conf, logger):
"""
Build a MemcacheRing object from the given config. It will also use the
passed in logger.
:param conf: a dict, the config options
:param logger: a logger
"""
memcache_servers = conf.get('memcache_servers')
try:
# Originally, while we documented using memcache_max_connections
# we only accepted max_connections
max_conns = int(conf.get('memcache_max_connections',
conf.get('max_connections', 0)))
except ValueError:
max_conns = 0
memcache_options = {}
if (not memcache_servers
or max_conns <= 0):
path = os.path.join(conf.get('swift_dir', '/etc/swift'),
'memcache.conf')
memcache_conf = ConfigParser()
if memcache_conf.read(path):
# if memcache.conf exists we'll start with those base options
try:
memcache_options = dict(memcache_conf.items('memcache'))
except NoSectionError:
pass
if not memcache_servers:
try:
memcache_servers = \
memcache_conf.get('memcache', 'memcache_servers')
except (NoSectionError, NoOptionError):
pass
if max_conns <= 0:
try:
new_max_conns = \
memcache_conf.get('memcache',
'memcache_max_connections')
max_conns = int(new_max_conns)
except (NoSectionError, NoOptionError, ValueError):
pass
# while memcache.conf options are the base for the memcache
# middleware, if you set the same option also in the filter
# section of the proxy config it is more specific.
memcache_options.update(conf)
connect_timeout = float(memcache_options.get(
'connect_timeout', CONN_TIMEOUT))
pool_timeout = float(memcache_options.get(
'pool_timeout', POOL_TIMEOUT))
tries = int(memcache_options.get('tries', TRY_COUNT))
io_timeout = float(memcache_options.get('io_timeout', IO_TIMEOUT))
if config_true_value(memcache_options.get('tls_enabled', 'false')):
tls_cafile = memcache_options.get('tls_cafile')
tls_certfile = memcache_options.get('tls_certfile')
tls_keyfile = memcache_options.get('tls_keyfile')
tls_context = ssl.create_default_context(
cafile=tls_cafile)
if tls_certfile:
tls_context.load_cert_chain(tls_certfile, tls_keyfile)
else:
tls_context = None
error_suppression_interval = float(memcache_options.get(
'error_suppression_interval', ERROR_LIMIT_TIME))
error_suppression_limit = float(memcache_options.get(
'error_suppression_limit', ERROR_LIMIT_COUNT))
item_size_warning_threshold = int(memcache_options.get(
'item_size_warning_threshold', DEFAULT_ITEM_SIZE_WARNING_THRESHOLD))
if not memcache_servers:
memcache_servers = '127.0.0.1:11211'
if max_conns <= 0:
max_conns = 2
return MemcacheRing(
[s.strip() for s in memcache_servers.split(',')
if s.strip()],
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
tries=tries,
io_timeout=io_timeout,
max_conns=max_conns,
tls_context=tls_context,
logger=logger,
error_limit_count=error_suppression_limit,
error_limit_time=error_suppression_interval,
error_limit_duration=error_suppression_interval,
item_size_warning_threshold=item_size_warning_threshold)

View File

@ -13,15 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import os
from eventlet.green import ssl
from six.moves.configparser import ConfigParser, NoSectionError, NoOptionError
from swift.common.memcached import (
MemcacheRing, CONN_TIMEOUT, POOL_TIMEOUT, IO_TIMEOUT, TRY_COUNT,
ERROR_LIMIT_COUNT, ERROR_LIMIT_TIME, DEFAULT_ITEM_SIZE_WARNING_THRESHOLD)
from swift.common.utils import get_logger, config_true_value
from swift.common.memcached import load_memcache
from swift.common.utils import get_logger
class MemcacheMiddleware(object):
@ -32,90 +25,7 @@ class MemcacheMiddleware(object):
def __init__(self, app, conf):
self.app = app
self.logger = get_logger(conf, log_route='memcache')
self.memcache_servers = conf.get('memcache_servers')
try:
# Originally, while we documented using memcache_max_connections
# we only accepted max_connections
max_conns = int(conf.get('memcache_max_connections',
conf.get('max_connections', 0)))
except ValueError:
max_conns = 0
memcache_options = {}
if (not self.memcache_servers
or max_conns <= 0):
path = os.path.join(conf.get('swift_dir', '/etc/swift'),
'memcache.conf')
memcache_conf = ConfigParser()
if memcache_conf.read(path):
# if memcache.conf exists we'll start with those base options
try:
memcache_options = dict(memcache_conf.items('memcache'))
except NoSectionError:
pass
if not self.memcache_servers:
try:
self.memcache_servers = \
memcache_conf.get('memcache', 'memcache_servers')
except (NoSectionError, NoOptionError):
pass
if max_conns <= 0:
try:
new_max_conns = \
memcache_conf.get('memcache',
'memcache_max_connections')
max_conns = int(new_max_conns)
except (NoSectionError, NoOptionError, ValueError):
pass
# while memcache.conf options are the base for the memcache
# middleware, if you set the same option also in the filter
# section of the proxy config it is more specific.
memcache_options.update(conf)
connect_timeout = float(memcache_options.get(
'connect_timeout', CONN_TIMEOUT))
pool_timeout = float(memcache_options.get(
'pool_timeout', POOL_TIMEOUT))
tries = int(memcache_options.get('tries', TRY_COUNT))
io_timeout = float(memcache_options.get('io_timeout', IO_TIMEOUT))
if config_true_value(memcache_options.get('tls_enabled', 'false')):
tls_cafile = memcache_options.get('tls_cafile')
tls_certfile = memcache_options.get('tls_certfile')
tls_keyfile = memcache_options.get('tls_keyfile')
self.tls_context = ssl.create_default_context(
cafile=tls_cafile)
if tls_certfile:
self.tls_context.load_cert_chain(tls_certfile,
tls_keyfile)
else:
self.tls_context = None
error_suppression_interval = float(memcache_options.get(
'error_suppression_interval', ERROR_LIMIT_TIME))
error_suppression_limit = float(memcache_options.get(
'error_suppression_limit', ERROR_LIMIT_COUNT))
item_size_warning_threshold = int(memcache_options.get(
'item_size_warning_threshold',
DEFAULT_ITEM_SIZE_WARNING_THRESHOLD))
if not self.memcache_servers:
self.memcache_servers = '127.0.0.1:11211'
if max_conns <= 0:
max_conns = 2
self.memcache = MemcacheRing(
[s.strip() for s in self.memcache_servers.split(',') if s.strip()],
connect_timeout=connect_timeout,
pool_timeout=pool_timeout,
tries=tries,
io_timeout=io_timeout,
max_conns=max_conns,
tls_context=self.tls_context,
logger=self.logger,
error_limit_count=error_suppression_limit,
error_limit_time=error_suppression_interval,
error_limit_duration=error_suppression_interval,
item_size_warning_threshold=item_size_warning_threshold)
self.memcache = load_memcache(conf, self.logger)
def __call__(self, env, start_response):
env['swift.cache'] = self.memcache

View File

@ -19,7 +19,6 @@ import unittest
from eventlet.green import ssl
import mock
from six.moves.configparser import NoSectionError, NoOptionError
from swift.common.middleware import memcache
from swift.common.memcached import MemcacheRing
@ -34,63 +33,6 @@ class FakeApp(object):
return env
class ExcConfigParser(object):
def read(self, path):
raise RuntimeError('read called with %r' % path)
class EmptyConfigParser(object):
def read(self, path):
return False
def get_config_parser(memcache_servers='1.2.3.4:5',
memcache_max_connections='4',
section='memcache',
item_size_warning_threshold='75'):
_srvs = memcache_servers
_maxc = memcache_max_connections
_section = section
_warn_threshold = item_size_warning_threshold
class SetConfigParser(object):
def items(self, section_name):
if section_name != section:
raise NoSectionError(section_name)
return {
'memcache_servers': memcache_servers,
'memcache_max_connections': memcache_max_connections
}
def read(self, path):
return True
def get(self, section, option):
if _section == section:
if option == 'memcache_servers':
if _srvs == 'error':
raise NoOptionError(option, section)
return _srvs
elif option in ('memcache_max_connections',
'max_connections'):
if _maxc == 'error':
raise NoOptionError(option, section)
return _maxc
elif option == 'item_size_warning_threshold':
if _warn_threshold == 'error':
raise NoOptionError(option, section)
return _warn_threshold
else:
raise NoOptionError(option, section)
else:
raise NoSectionError(option)
return SetConfigParser
def start_response(*args):
pass
@ -106,165 +48,13 @@ class TestCacheMiddleware(unittest.TestCase):
self.assertTrue('swift.cache' in resp)
self.assertTrue(isinstance(resp['swift.cache'], MemcacheRing))
def test_conf_default_read(self):
with mock.patch.object(memcache, 'ConfigParser', ExcConfigParser):
for d in ({},
{'memcache_servers': '6.7.8.9:10'},
{'memcache_max_connections': '30'},
{'item_size_warning_threshold': 75},
{'memcache_servers': '6.7.8.9:10',
'item_size_warning_threshold': '75'},
{'item_size_warning_threshold': '75',
'memcache_max_connections': '30'},
):
with self.assertRaises(RuntimeError) as catcher:
memcache.MemcacheMiddleware(FakeApp(), d)
self.assertEqual(
str(catcher.exception),
"read called with '/etc/swift/memcache.conf'")
def test_conf_set_no_read(self):
with mock.patch.object(memcache, 'ConfigParser', ExcConfigParser):
memcache.MemcacheMiddleware(
FakeApp(), {'memcache_servers': '1.2.3.4:5',
'memcache_max_connections': '30',
'item_size_warning_threshold': '80'})
def test_conf_default(self):
with mock.patch.object(memcache, 'ConfigParser', EmptyConfigParser):
app = memcache.MemcacheMiddleware(FakeApp(), {})
self.assertEqual(app.memcache_servers, '127.0.0.1:11211')
self.assertEqual(
app.memcache._client_cache['127.0.0.1:11211'].max_size, 2)
self.assertEqual(app.memcache.item_size_warning_threshold, -1)
def test_conf_inline(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
app = memcache.MemcacheMiddleware(
FakeApp(),
{'memcache_servers': '6.7.8.9:10',
'memcache_max_connections': '5',
'item_size_warning_threshold': '75'})
self.assertEqual(app.memcache_servers, '6.7.8.9:10')
self.assertEqual(
app.memcache._client_cache['6.7.8.9:10'].max_size, 5)
self.assertEqual(app.memcache.item_size_warning_threshold, 75)
def test_conf_inline_ratelimiting(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
app = memcache.MemcacheMiddleware(
FakeApp(),
{'error_suppression_limit': '5',
'error_suppression_interval': '2.5'})
self.assertEqual(app.memcache._error_limit_count, 5)
self.assertEqual(app.memcache._error_limit_time, 2.5)
self.assertEqual(app.memcache._error_limit_duration, 2.5)
def test_conf_inline_tls(self):
fake_context = mock.Mock()
with mock.patch.object(ssl, 'create_default_context',
return_value=fake_context):
with mock.patch.object(memcache, 'ConfigParser',
get_config_parser()):
memcache.MemcacheMiddleware(
FakeApp(),
{'tls_enabled': 'true',
'tls_cafile': 'cafile',
'tls_certfile': 'certfile',
'tls_keyfile': 'keyfile'})
ssl.create_default_context.assert_called_with(cafile='cafile')
fake_context.load_cert_chain.assert_called_with('certfile',
'keyfile')
def test_conf_extra_no_section(self):
with mock.patch.object(memcache, 'ConfigParser',
get_config_parser(section='foobar')):
app = memcache.MemcacheMiddleware(FakeApp(), {})
self.assertEqual(app.memcache_servers, '127.0.0.1:11211')
self.assertEqual(
app.memcache._client_cache['127.0.0.1:11211'].max_size, 2)
def test_conf_extra_no_option(self):
replacement_parser = get_config_parser(
memcache_servers='error',
memcache_max_connections='error')
with mock.patch.object(memcache, 'ConfigParser', replacement_parser):
app = memcache.MemcacheMiddleware(FakeApp(), {})
self.assertEqual(app.memcache_servers, '127.0.0.1:11211')
self.assertEqual(
app.memcache._client_cache['127.0.0.1:11211'].max_size, 2)
def test_conf_inline_other_max_conn(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
app = memcache.MemcacheMiddleware(
FakeApp(),
{'memcache_servers': '6.7.8.9:10',
'max_connections': '5'})
self.assertEqual(app.memcache_servers, '6.7.8.9:10')
self.assertEqual(
app.memcache._client_cache['6.7.8.9:10'].max_size, 5)
def test_conf_inline_bad_max_conn(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
app = memcache.MemcacheMiddleware(
FakeApp(),
{'memcache_servers': '6.7.8.9:10',
'max_connections': 'bad42'})
self.assertEqual(app.memcache_servers, '6.7.8.9:10')
self.assertEqual(
app.memcache._client_cache['6.7.8.9:10'].max_size, 4)
def test_conf_inline_bad_item_warning_threshold(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
with self.assertRaises(ValueError) as err:
memcache.MemcacheMiddleware(
FakeApp(),
{'memcache_servers': '6.7.8.9:10',
'memcache_serialization_support': '0',
'item_size_warning_threshold': 'bad42'})
self.assertIn('invalid literal for int() with base 10:',
str(err.exception))
def test_conf_from_extra_conf(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
app = memcache.MemcacheMiddleware(FakeApp(), {})
self.assertEqual(app.memcache_servers, '1.2.3.4:5')
self.assertEqual(
app.memcache._client_cache['1.2.3.4:5'].max_size, 4)
def test_conf_from_extra_conf_bad_max_conn(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser(
memcache_max_connections='bad42')):
app = memcache.MemcacheMiddleware(FakeApp(), {})
self.assertEqual(app.memcache_servers, '1.2.3.4:5')
self.assertEqual(
app.memcache._client_cache['1.2.3.4:5'].max_size, 2)
def test_conf_from_inline_and_maxc_from_extra_conf(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
app = memcache.MemcacheMiddleware(
FakeApp(),
{'memcache_servers': '6.7.8.9:10'})
self.assertEqual(app.memcache_servers, '6.7.8.9:10')
self.assertEqual(
app.memcache._client_cache['6.7.8.9:10'].max_size, 4)
def test_conf_from_inline_and_sers_from_extra_conf(self):
with mock.patch.object(memcache, 'ConfigParser', get_config_parser()):
app = memcache.MemcacheMiddleware(
FakeApp(),
{'memcache_servers': '6.7.8.9:10',
'memcache_max_connections': '42'})
self.assertEqual(app.memcache_servers, '6.7.8.9:10')
self.assertEqual(
app.memcache._client_cache['6.7.8.9:10'].max_size, 42)
def test_filter_factory(self):
factory = memcache.filter_factory({'max_connections': '3'},
memcache_servers='10.10.10.10:10')
thefilter = factory('myapp')
self.assertEqual(thefilter.app, 'myapp')
self.assertEqual(thefilter.memcache_servers, '10.10.10.10:10')
self.assertEqual(thefilter.memcache.memcache_servers,
['10.10.10.10:10'])
self.assertEqual(
thefilter.memcache._client_cache['10.10.10.10:10'].max_size, 3)

View File

@ -27,9 +27,11 @@ from uuid import uuid4
import os
import mock
from six.moves.configparser import NoSectionError, NoOptionError
from eventlet import GreenPool, sleep, Queue
from eventlet.pools import Pool
from eventlet.green import ssl
from swift.common import memcached
from swift.common.memcached import MemcacheConnectionError
@ -1047,5 +1049,229 @@ class TestMemcached(unittest.TestCase):
do_test('1' * 2048576, 1000000, True)
class ExcConfigParser(object):
def read(self, path):
raise Exception('read called with %r' % path)
class EmptyConfigParser(object):
def read(self, path):
return False
def get_config_parser(memcache_servers='1.2.3.4:5',
memcache_max_connections='4',
section='memcache',
item_size_warning_threshold='75'):
_srvs = memcache_servers
_maxc = memcache_max_connections
_section = section
_warn_threshold = item_size_warning_threshold
class SetConfigParser(object):
def items(self, section_name):
if section_name != section:
raise NoSectionError(section_name)
return {
'memcache_servers': memcache_servers,
'memcache_max_connections': memcache_max_connections
}
def read(self, path):
return True
def get(self, section, option):
if _section == section:
if option == 'memcache_servers':
if _srvs == 'error':
raise NoOptionError(option, section)
return _srvs
elif option in ('memcache_max_connections',
'max_connections'):
if _maxc == 'error':
raise NoOptionError(option, section)
return _maxc
elif option == 'item_size_warning_threshold':
if _warn_threshold == 'error':
raise NoOptionError(option, section)
return _warn_threshold
else:
raise NoOptionError(option, section)
else:
raise NoSectionError(option)
return SetConfigParser
def start_response(*args):
pass
class TestLoadMemcache(unittest.TestCase):
def setUp(self):
self.logger = debug_logger()
def test_conf_default_read(self):
with mock.patch.object(memcached, 'ConfigParser', ExcConfigParser):
for d in ({},
{'memcache_servers': '6.7.8.9:10'},
{'memcache_max_connections': '30'},
{'item_size_warning_threshold': 75},
{'memcache_servers': '6.7.8.9:10',
'item_size_warning_threshold': '75'},
{'item_size_warning_threshold': '75',
'memcache_max_connections': '30'},
):
with self.assertRaises(Exception) as catcher:
memcached.load_memcache(d, self.logger)
self.assertEqual(
str(catcher.exception),
"read called with '/etc/swift/memcache.conf'")
def test_conf_set_no_read(self):
with mock.patch.object(memcached, 'ConfigParser', ExcConfigParser):
exc = None
try:
memcached.load_memcache({
'memcache_servers': '1.2.3.4:5',
'memcache_max_connections': '30',
'item_size_warning_threshold': '80'
}, self.logger)
except Exception as err:
exc = err
self.assertIsNone(exc)
def test_conf_default(self):
with mock.patch.object(memcached, 'ConfigParser', EmptyConfigParser):
memcache = memcached.load_memcache({}, self.logger)
self.assertEqual(memcache.memcache_servers, ['127.0.0.1:11211'])
self.assertEqual(
memcache._client_cache['127.0.0.1:11211'].max_size, 2)
self.assertEqual(memcache.item_size_warning_threshold, -1)
def test_conf_inline(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
memcache = memcached.load_memcache({
'memcache_servers': '6.7.8.9:10',
'memcache_max_connections': '5',
'item_size_warning_threshold': '75'
}, self.logger)
self.assertEqual(memcache.memcache_servers, ['6.7.8.9:10'])
self.assertEqual(
memcache._client_cache['6.7.8.9:10'].max_size, 5)
self.assertEqual(memcache.item_size_warning_threshold, 75)
def test_conf_inline_ratelimiting(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
memcache = memcached.load_memcache({
'error_suppression_limit': '5',
'error_suppression_interval': '2.5',
}, self.logger)
self.assertEqual(memcache._error_limit_count, 5)
self.assertEqual(memcache._error_limit_time, 2.5)
self.assertEqual(memcache._error_limit_duration, 2.5)
def test_conf_inline_tls(self):
fake_context = mock.Mock()
with mock.patch.object(ssl, 'create_default_context',
return_value=fake_context):
with mock.patch.object(memcached, 'ConfigParser',
get_config_parser()):
memcached.load_memcache({
'tls_enabled': 'true',
'tls_cafile': 'cafile',
'tls_certfile': 'certfile',
'tls_keyfile': 'keyfile',
}, self.logger)
ssl.create_default_context.assert_called_with(cafile='cafile')
fake_context.load_cert_chain.assert_called_with('certfile',
'keyfile')
def test_conf_extra_no_section(self):
with mock.patch.object(memcached, 'ConfigParser',
get_config_parser(section='foobar')):
memcache = memcached.load_memcache({}, self.logger)
self.assertEqual(memcache.memcache_servers, ['127.0.0.1:11211'])
self.assertEqual(
memcache._client_cache['127.0.0.1:11211'].max_size, 2)
def test_conf_extra_no_option(self):
replacement_parser = get_config_parser(
memcache_servers='error',
memcache_max_connections='error')
with mock.patch.object(memcached, 'ConfigParser', replacement_parser):
memcache = memcached.load_memcache({}, self.logger)
self.assertEqual(memcache.memcache_servers, ['127.0.0.1:11211'])
self.assertEqual(
memcache._client_cache['127.0.0.1:11211'].max_size, 2)
def test_conf_inline_other_max_conn(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
memcache = memcached.load_memcache({
'memcache_servers': '6.7.8.9:10',
'max_connections': '5'
}, self.logger)
self.assertEqual(memcache.memcache_servers, ['6.7.8.9:10'])
self.assertEqual(
memcache._client_cache['6.7.8.9:10'].max_size, 5)
def test_conf_inline_bad_max_conn(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
memcache = memcached.load_memcache({
'memcache_servers': '6.7.8.9:10',
'max_connections': 'bad42',
}, self.logger)
self.assertEqual(memcache.memcache_servers, ['6.7.8.9:10'])
self.assertEqual(
memcache._client_cache['6.7.8.9:10'].max_size, 4)
def test_conf_inline_bad_item_warning_threshold(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
with self.assertRaises(ValueError) as err:
memcached.load_memcache({
'memcache_servers': '6.7.8.9:10',
'item_size_warning_threshold': 'bad42',
}, self.logger)
self.assertIn('invalid literal for int() with base 10:',
str(err.exception))
def test_conf_from_extra_conf(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
memcache = memcached.load_memcache({}, self.logger)
self.assertEqual(memcache.memcache_servers, ['1.2.3.4:5'])
self.assertEqual(
memcache._client_cache['1.2.3.4:5'].max_size, 4)
def test_conf_from_extra_conf_bad_max_conn(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser(
memcache_max_connections='bad42')):
memcache = memcached.load_memcache({}, self.logger)
self.assertEqual(memcache.memcache_servers, ['1.2.3.4:5'])
self.assertEqual(
memcache._client_cache['1.2.3.4:5'].max_size, 2)
def test_conf_from_inline_and_maxc_from_extra_conf(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
memcache = memcached.load_memcache({
'memcache_servers': '6.7.8.9:10'}, self.logger)
self.assertEqual(memcache.memcache_servers, ['6.7.8.9:10'])
self.assertEqual(
memcache._client_cache['6.7.8.9:10'].max_size, 4)
def test_conf_from_inline_and_sers_from_extra_conf(self):
with mock.patch.object(memcached, 'ConfigParser', get_config_parser()):
memcache = memcached.load_memcache({
'memcache_servers': '6.7.8.9:10',
'memcache_max_connections': '42',
}, self.logger)
self.assertEqual(memcache.memcache_servers, ['6.7.8.9:10'])
self.assertEqual(
memcache._client_cache['6.7.8.9:10'].max_size, 42)
if __name__ == '__main__':
unittest.main()