Merge "tests: Improve FakeMemcache call tracking"
This commit is contained in:
commit
96b7980196
@ -401,6 +401,13 @@ class FabricatedRing(Ring):
|
||||
self._update_bookkeeping()
|
||||
|
||||
|
||||
def track(f):
|
||||
def wrapper(self, *a, **kw):
|
||||
self.calls.append(getattr(mocklib.call, f.__name__)(*a, **kw))
|
||||
return f(self, *a, **kw)
|
||||
return wrapper
|
||||
|
||||
|
||||
class FakeMemcache(object):
|
||||
|
||||
def __init__(self):
|
||||
@ -412,19 +419,16 @@ class FakeMemcache(object):
|
||||
def clear_calls(self):
|
||||
del self.calls[:]
|
||||
|
||||
def _called(self, method, key=None, value=None, time=None):
|
||||
self.calls.append((method, key, value, time))
|
||||
|
||||
@track
|
||||
def get(self, key):
|
||||
self._called('get', key)
|
||||
return self.store.get(key)
|
||||
|
||||
@property
|
||||
def keys(self):
|
||||
self._called('keys')
|
||||
return self.store.keys()
|
||||
return self.store.keys
|
||||
|
||||
@track
|
||||
def set(self, key, value, serialize=True, time=0):
|
||||
self._called('set', key, value, time)
|
||||
if serialize:
|
||||
value = json.loads(json.dumps(value))
|
||||
else:
|
||||
@ -432,8 +436,8 @@ class FakeMemcache(object):
|
||||
self.store[key] = value
|
||||
return True
|
||||
|
||||
@track
|
||||
def incr(self, key, delta=1, time=0):
|
||||
self._called('incr', key, time=time)
|
||||
if self.error_on_incr:
|
||||
raise MemcacheConnectionError('Memcache restarting')
|
||||
if self.init_incr_return_neg:
|
||||
@ -445,6 +449,7 @@ class FakeMemcache(object):
|
||||
self.store[key] = 0
|
||||
return self.store[key]
|
||||
|
||||
# tracked via incr()
|
||||
def decr(self, key, delta=1, time=0):
|
||||
return self.incr(key, delta=-delta, time=time)
|
||||
|
||||
@ -452,8 +457,8 @@ class FakeMemcache(object):
|
||||
def soft_lock(self, key, timeout=0, retries=5):
|
||||
yield True
|
||||
|
||||
@track
|
||||
def delete(self, key):
|
||||
self._called('delete', key)
|
||||
try:
|
||||
del self.store[key]
|
||||
except Exception:
|
||||
@ -464,6 +469,11 @@ class FakeMemcache(object):
|
||||
self.store.clear()
|
||||
|
||||
|
||||
# This decorator only makes sense in the context of FakeMemcache;
|
||||
# may as well clean it up now
|
||||
del track
|
||||
|
||||
|
||||
class FakeIterable(object):
|
||||
def __init__(self, values):
|
||||
self.next_call_count = 0
|
||||
|
@ -2110,14 +2110,13 @@ class TestContainerController(TestRingBase):
|
||||
'X-Backend-Record-Type': 'shard',
|
||||
'X-Backend-Sharding-State': sharding_state})
|
||||
self.assertEqual(
|
||||
[('get', 'container/a/c', None, None),
|
||||
('set', 'shard-listing/a/c', self.sr_dicts,
|
||||
exp_recheck_listing),
|
||||
('set', 'container/a/c', mock.ANY, 60)],
|
||||
[mock.call.get('container/a/c'),
|
||||
mock.call.set('shard-listing/a/c', self.sr_dicts,
|
||||
time=exp_recheck_listing),
|
||||
mock.call.set('container/a/c', mock.ANY, time=60)],
|
||||
self.memcache.calls)
|
||||
self.assertEqual(self.sr_dicts, self.memcache.calls[1][2])
|
||||
self.assertEqual(sharding_state,
|
||||
self.memcache.calls[2][2]['sharding_state'])
|
||||
self.memcache.calls[2][1][1]['sharding_state'])
|
||||
self.assertIn('swift.infocache', req.environ)
|
||||
self.assertIn('shard-listing/a/c', req.environ['swift.infocache'])
|
||||
self.assertEqual(tuple(self.sr_dicts),
|
||||
@ -2134,8 +2133,8 @@ class TestContainerController(TestRingBase):
|
||||
'X-Backend-Record-Type': 'shard',
|
||||
'X-Backend-Sharding-State': sharding_state})
|
||||
self.assertEqual(
|
||||
[('get', 'container/a/c', None, None),
|
||||
('get', 'shard-listing/a/c', None, None)],
|
||||
[mock.call.get('container/a/c'),
|
||||
mock.call.get('shard-listing/a/c')],
|
||||
self.memcache.calls)
|
||||
self.assertIn('swift.infocache', req.environ)
|
||||
self.assertIn('shard-listing/a/c', req.environ['swift.infocache'])
|
||||
@ -2151,8 +2150,8 @@ class TestContainerController(TestRingBase):
|
||||
self._capture_backend_request(req, 204, b'', {},
|
||||
num_resp=self.CONTAINER_REPLICAS)
|
||||
self.assertEqual(
|
||||
[('delete', 'container/a/c', None, None),
|
||||
('delete', 'shard-listing/a/c', None, None)],
|
||||
[mock.call.delete('container/a/c'),
|
||||
mock.call.delete('shard-listing/a/c')],
|
||||
self.memcache.calls)
|
||||
|
||||
def test_get_from_shards_add_root_spi(self):
|
||||
@ -2281,11 +2280,11 @@ class TestContainerController(TestRingBase):
|
||||
# Note: container metadata is updated in cache but shard ranges are not
|
||||
# deleted from cache
|
||||
self.assertEqual(
|
||||
[('get', 'container/a/c', None, None),
|
||||
('get', 'shard-listing/a/c', None, None),
|
||||
('set', 'container/a/c', mock.ANY, 6.0)],
|
||||
[mock.call.get('container/a/c'),
|
||||
mock.call.get('shard-listing/a/c'),
|
||||
mock.call.set('container/a/c', mock.ANY, time=6.0)],
|
||||
self.memcache.calls)
|
||||
self.assertEqual(404, self.memcache.calls[2][2]['status'])
|
||||
self.assertEqual(404, self.memcache.calls[2][1][1]['status'])
|
||||
self.assertEqual(b'', resp.body)
|
||||
self.assertEqual(404, resp.status_int)
|
||||
|
||||
@ -2304,8 +2303,8 @@ class TestContainerController(TestRingBase):
|
||||
req = self._build_request(req_hdrs, params, {})
|
||||
resp = req.get_response(self.app)
|
||||
self.assertEqual(
|
||||
[('get', 'container/a/c', None, None),
|
||||
('get', 'shard-listing/a/c', None, None)],
|
||||
[mock.call.get('container/a/c'),
|
||||
mock.call.get('shard-listing/a/c')],
|
||||
self.memcache.calls)
|
||||
return resp
|
||||
|
||||
@ -2387,14 +2386,13 @@ class TestContainerController(TestRingBase):
|
||||
expected_hdrs = {'X-Backend-Recheck-Container-Existence': '60'}
|
||||
expected_hdrs.update(resp_hdrs)
|
||||
self.assertEqual(
|
||||
[('get', 'container/a/c', None, None),
|
||||
('set', 'shard-listing/a/c', self.sr_dicts, 600),
|
||||
('set', 'container/a/c', mock.ANY, 60)],
|
||||
[mock.call.get('container/a/c'),
|
||||
mock.call.set('shard-listing/a/c', self.sr_dicts, time=600),
|
||||
mock.call.set('container/a/c', mock.ANY, time=60)],
|
||||
self.memcache.calls)
|
||||
# shards were cached
|
||||
self.assertEqual(self.sr_dicts, self.memcache.calls[1][2])
|
||||
self.assertEqual('sharded',
|
||||
self.memcache.calls[2][2]['sharding_state'])
|
||||
self.memcache.calls[2][1][1]['sharding_state'])
|
||||
return resp
|
||||
|
||||
def test_GET_shard_ranges_write_to_cache(self):
|
||||
@ -2480,12 +2478,11 @@ class TestContainerController(TestRingBase):
|
||||
expected_hdrs.update(resp_hdrs)
|
||||
self._check_response(resp, self.sr_dicts, expected_hdrs)
|
||||
self.assertEqual(
|
||||
[('set', 'shard-listing/a/c', self.sr_dicts, 600),
|
||||
('set', 'container/a/c', mock.ANY, 60)],
|
||||
[mock.call.set('shard-listing/a/c', self.sr_dicts, time=600),
|
||||
mock.call.set('container/a/c', mock.ANY, time=60)],
|
||||
self.memcache.calls)
|
||||
self.assertEqual(self.sr_dicts, self.memcache.calls[0][2])
|
||||
self.assertEqual('sharded',
|
||||
self.memcache.calls[1][2]['sharding_state'])
|
||||
self.memcache.calls[1][1][1]['sharding_state'])
|
||||
|
||||
def _do_test_GET_shard_ranges_no_cache_write(self, resp_hdrs):
|
||||
# verify that there is a cache lookup to check container info but then
|
||||
@ -2516,11 +2513,11 @@ class TestContainerController(TestRingBase):
|
||||
# container metadata is looked up in memcache for sharding state
|
||||
# container metadata is set in memcache
|
||||
self.assertEqual(
|
||||
[('get', 'container/a/c', None, None),
|
||||
('set', 'container/a/c', mock.ANY, 60)],
|
||||
[mock.call.get('container/a/c'),
|
||||
mock.call.set('container/a/c', mock.ANY, time=60)],
|
||||
self.memcache.calls)
|
||||
self.assertEqual(resp.headers.get('X-Backend-Sharding-State'),
|
||||
self.memcache.calls[1][2]['sharding_state'])
|
||||
self.memcache.calls[1][1][1]['sharding_state'])
|
||||
self.memcache.delete_all()
|
||||
|
||||
def test_GET_shard_ranges_no_cache_write_with_cached_container_info(self):
|
||||
@ -2650,11 +2647,11 @@ class TestContainerController(TestRingBase):
|
||||
# container metadata is looked up in memcache for sharding state
|
||||
# container metadata is set in memcache
|
||||
self.assertEqual(
|
||||
[('get', 'container/a/c', None, None),
|
||||
('set', 'container/a/c', mock.ANY, 60)],
|
||||
[mock.call.get('container/a/c'),
|
||||
mock.call.set('container/a/c', mock.ANY, time=60)],
|
||||
self.memcache.calls)
|
||||
self.assertEqual(resp.headers.get('X-Backend-Sharding-State'),
|
||||
self.memcache.calls[1][2]['sharding_state'])
|
||||
self.memcache.calls[1][1][1]['sharding_state'])
|
||||
self.memcache.delete_all()
|
||||
|
||||
def test_GET_shard_ranges_bad_response_body(self):
|
||||
@ -2703,10 +2700,10 @@ class TestContainerController(TestRingBase):
|
||||
'X-Backend-Sharding-State': sharding_state})
|
||||
# container metadata from backend response is set in memcache
|
||||
self.assertEqual(
|
||||
[('set', 'container/a/c', mock.ANY, 60)],
|
||||
[mock.call.set('container/a/c', mock.ANY, time=60)],
|
||||
self.memcache.calls)
|
||||
self.assertEqual(sharding_state,
|
||||
self.memcache.calls[0][2]['sharding_state'])
|
||||
self.memcache.calls[0][1][1]['sharding_state'])
|
||||
|
||||
def test_GET_shard_ranges_no_cache_recheck_listing_shard_ranges(self):
|
||||
# verify that a GET for shards does not lookup or store in cache when
|
||||
@ -2773,10 +2770,10 @@ class TestContainerController(TestRingBase):
|
||||
'X-Backend-Sharding-State': 'sharded'})
|
||||
# container metadata from backend response is set in memcache
|
||||
self.assertEqual(
|
||||
[('set', 'container/a/c', mock.ANY, 60)],
|
||||
[mock.call.set('container/a/c', mock.ANY, time=60)],
|
||||
self.memcache.calls)
|
||||
self.assertEqual('sharded',
|
||||
self.memcache.calls[0][2]['sharding_state'])
|
||||
self.memcache.calls[0][1][1]['sharding_state'])
|
||||
|
||||
def test_GET_shard_ranges_no_memcache_available(self):
|
||||
self._setup_shard_range_stubs()
|
||||
|
Loading…
x
Reference in New Issue
Block a user