Merge "FakeSwift: capture unexpected calls"

This commit is contained in:
Zuul 2024-10-12 04:47:47 +00:00 committed by Gerrit Code Review
commit a2e8cf08d5
3 changed files with 55 additions and 12 deletions

View File

@ -125,7 +125,8 @@ class FakeSwift(object):
container_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.req_bodies = []
self._unclosed_req_keys = defaultdict(int)
@ -248,15 +249,20 @@ class FakeSwift(object):
self.swift_sources.append(env.get('swift.source'))
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
# an exception.
# note: tests may assume this copy of req_headers is case insensitive
# so we deliberately use a HeaderKeyDict
req_headers_copy = HeaderKeyDict(req.headers)
self._calls.append(
FakeSwiftCall(method, path, req_headers_copy))
call = 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()
if (cont and not obj and method == 'UPDATE') or (

View File

@ -55,6 +55,28 @@ class TestFakeSwift(unittest.TestCase):
do_test('PUT')
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):
# verify that a single registered GET response is sufficient to handle
# 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])
def test_GET_registered_with_query_string(self):
# verify that a single registered GET response is sufficient to handle
# GETs and HEADS, with and without query strings
# verify that a registered GET response with query string only matches
# a request with that query string
swift = FakeSwift()
swift.register('GET', '/v1/a/c/o?p=q', HTTPOk,
{'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'
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'
resp = req.get_response(swift)
@ -129,8 +153,19 @@ class TestFakeSwift(unittest.TestCase):
'X-Foo': 'Bar'},
resp.headers)
self.assertEqual(b'stuff', resp.body)
self.assertEqual(1, swift.call_count)
self.assertEqual(('GET', '/v1/a/c/o?p=q'), swift.calls[-1])
self.assertEqual(2, swift.call_count)
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):
# verify that a registered HEAD response will be preferred over GET for

View File

@ -14,6 +14,7 @@
import json
import numbers
import shutil
from functools import partial
from tempfile import mkdtemp
import mock
@ -60,7 +61,8 @@ def container_resp_headers(**kwargs):
class FakeStoragePolicySwift(object):
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 = {}
def __getattribute__(self, name):