Merge "FakeSwift: capture unexpected calls"
This commit is contained in:
commit
a2e8cf08d5
@ -125,7 +125,8 @@ class FakeSwift(object):
|
|||||||
container_existence_skip_cache = 0.0
|
container_existence_skip_cache = 0.0
|
||||||
account_existence_skip_cache = 0.0
|
account_existence_skip_cache = 0.0
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, capture_unexpected_calls=True):
|
||||||
|
self.capture_unexpected_calls = capture_unexpected_calls
|
||||||
self._calls = []
|
self._calls = []
|
||||||
self.req_bodies = []
|
self.req_bodies = []
|
||||||
self._unclosed_req_keys = defaultdict(int)
|
self._unclosed_req_keys = defaultdict(int)
|
||||||
@ -248,15 +249,20 @@ class FakeSwift(object):
|
|||||||
self.swift_sources.append(env.get('swift.source'))
|
self.swift_sources.append(env.get('swift.source'))
|
||||||
self.txn_ids.append(env.get('swift.trans_id'))
|
self.txn_ids.append(env.get('swift.trans_id'))
|
||||||
|
|
||||||
resp_class, headers, body = self._select_response(env)
|
|
||||||
|
|
||||||
# Capture the request before reading the body, in case the iter raises
|
# Capture the request before reading the body, in case the iter raises
|
||||||
# an exception.
|
# an exception.
|
||||||
# note: tests may assume this copy of req_headers is case insensitive
|
# note: tests may assume this copy of req_headers is case insensitive
|
||||||
# so we deliberately use a HeaderKeyDict
|
# so we deliberately use a HeaderKeyDict
|
||||||
req_headers_copy = HeaderKeyDict(req.headers)
|
req_headers_copy = HeaderKeyDict(req.headers)
|
||||||
self._calls.append(
|
call = FakeSwiftCall(method, path, req_headers_copy)
|
||||||
FakeSwiftCall(method, path, req_headers_copy))
|
try:
|
||||||
|
resp_class, headers, body = self._select_response(env)
|
||||||
|
except KeyError:
|
||||||
|
if self.capture_unexpected_calls:
|
||||||
|
self._calls.append(call)
|
||||||
|
raise
|
||||||
|
else:
|
||||||
|
self._calls.append(call)
|
||||||
|
|
||||||
req_body = None # generally, we don't care and let eventlet discard()
|
req_body = None # generally, we don't care and let eventlet discard()
|
||||||
if (cont and not obj and method == 'UPDATE') or (
|
if (cont and not obj and method == 'UPDATE') or (
|
||||||
|
@ -55,6 +55,28 @@ class TestFakeSwift(unittest.TestCase):
|
|||||||
do_test('PUT')
|
do_test('PUT')
|
||||||
do_test('DELETE')
|
do_test('DELETE')
|
||||||
|
|
||||||
|
def test_capture_unexpected_calls(self):
|
||||||
|
req = Request.blank('/v1/a/c/o')
|
||||||
|
req.method = 'GET'
|
||||||
|
swift = FakeSwift()
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
req.get_response(swift)
|
||||||
|
self.assertEqual([('GET', '/v1/a/c/o')], swift.calls)
|
||||||
|
|
||||||
|
req = Request.blank('/v1/a/c/o')
|
||||||
|
req.method = 'GET'
|
||||||
|
swift = FakeSwift(capture_unexpected_calls=True)
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
req.get_response(swift)
|
||||||
|
self.assertEqual([('GET', '/v1/a/c/o')], swift.calls)
|
||||||
|
|
||||||
|
req = Request.blank('/v1/a/c/o')
|
||||||
|
req.method = 'GET'
|
||||||
|
swift = FakeSwift(capture_unexpected_calls=False)
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
req.get_response(swift)
|
||||||
|
self.assertEqual([], swift.calls)
|
||||||
|
|
||||||
def test_GET_registered(self):
|
def test_GET_registered(self):
|
||||||
# verify that a single registered GET response is sufficient to handle
|
# verify that a single registered GET response is sufficient to handle
|
||||||
# GETs and HEADS, with and without query strings
|
# GETs and HEADS, with and without query strings
|
||||||
@ -110,16 +132,18 @@ class TestFakeSwift(unittest.TestCase):
|
|||||||
self.assertEqual(('HEAD', '/v1/a/c/o?p=q'), swift.calls[-1])
|
self.assertEqual(('HEAD', '/v1/a/c/o?p=q'), swift.calls[-1])
|
||||||
|
|
||||||
def test_GET_registered_with_query_string(self):
|
def test_GET_registered_with_query_string(self):
|
||||||
# verify that a single registered GET response is sufficient to handle
|
# verify that a registered GET response with query string only matches
|
||||||
# GETs and HEADS, with and without query strings
|
# a request with that query string
|
||||||
swift = FakeSwift()
|
swift = FakeSwift()
|
||||||
swift.register('GET', '/v1/a/c/o?p=q', HTTPOk,
|
swift.register('GET', '/v1/a/c/o?p=q', HTTPOk,
|
||||||
{'X-Foo': 'Bar'}, b'stuff')
|
{'X-Foo': 'Bar'}, b'stuff')
|
||||||
|
|
||||||
req = Request.blank('/v1/a/c/o')
|
req = Request.blank('/v1/a/c/o') # no query string
|
||||||
req.method = 'GET'
|
req.method = 'GET'
|
||||||
with self.assertRaises(KeyError):
|
with self.assertRaises(KeyError):
|
||||||
resp = req.get_response(swift)
|
req.get_response(swift)
|
||||||
|
self.assertEqual(1, swift.call_count)
|
||||||
|
self.assertEqual([('GET', '/v1/a/c/o')], swift.calls)
|
||||||
|
|
||||||
req.query_string = 'p=q'
|
req.query_string = 'p=q'
|
||||||
resp = req.get_response(swift)
|
resp = req.get_response(swift)
|
||||||
@ -129,8 +153,19 @@ class TestFakeSwift(unittest.TestCase):
|
|||||||
'X-Foo': 'Bar'},
|
'X-Foo': 'Bar'},
|
||||||
resp.headers)
|
resp.headers)
|
||||||
self.assertEqual(b'stuff', resp.body)
|
self.assertEqual(b'stuff', resp.body)
|
||||||
self.assertEqual(1, swift.call_count)
|
self.assertEqual(2, swift.call_count)
|
||||||
self.assertEqual(('GET', '/v1/a/c/o?p=q'), swift.calls[-1])
|
self.assertEqual([('GET', '/v1/a/c/o'),
|
||||||
|
('GET', '/v1/a/c/o?p=q')],
|
||||||
|
swift.calls)
|
||||||
|
|
||||||
|
req.query_string = 'p=z'
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
req.get_response(swift)
|
||||||
|
self.assertEqual(3, swift.call_count)
|
||||||
|
self.assertEqual([('GET', '/v1/a/c/o'),
|
||||||
|
('GET', '/v1/a/c/o?p=q'),
|
||||||
|
('GET', '/v1/a/c/o?p=z')],
|
||||||
|
swift.calls)
|
||||||
|
|
||||||
def test_GET_and_HEAD_registered(self):
|
def test_GET_and_HEAD_registered(self):
|
||||||
# verify that a registered HEAD response will be preferred over GET for
|
# verify that a registered HEAD response will be preferred over GET for
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
import json
|
import json
|
||||||
import numbers
|
import numbers
|
||||||
import shutil
|
import shutil
|
||||||
|
from functools import partial
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
@ -60,7 +61,8 @@ def container_resp_headers(**kwargs):
|
|||||||
class FakeStoragePolicySwift(object):
|
class FakeStoragePolicySwift(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.storage_policy = defaultdict(helpers.FakeSwift)
|
self.storage_policy = defaultdict(
|
||||||
|
partial(helpers.FakeSwift, capture_unexpected_calls=False))
|
||||||
self._mock_oldest_spi_map = {}
|
self._mock_oldest_spi_map = {}
|
||||||
|
|
||||||
def __getattribute__(self, name):
|
def __getattribute__(self, name):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user