Merge "Add test for object updater user-agent header"

This commit is contained in:
Jenkins 2017-01-11 18:58:36 +00:00 committed by Gerrit Code Review
commit 652ec940dc

View File

@ -23,7 +23,7 @@ from contextlib import closing
from gzip import GzipFile from gzip import GzipFile
from tempfile import mkdtemp from tempfile import mkdtemp
from shutil import rmtree from shutil import rmtree
from test.unit import FakeLogger from test.unit import FakeLogger, make_timestamp_iter
from time import time from time import time
from distutils.dir_util import mkpath from distutils.dir_util import mkpath
@ -433,9 +433,10 @@ class TestObjectUpdater(unittest.TestCase):
'async_pendings': 1}) 'async_pendings': 1})
def test_obj_put_async_updates(self): def test_obj_put_async_updates(self):
ts = (normalize_timestamp(t) for t in ts_iter = make_timestamp_iter()
itertools.count(int(time()))) policies = list(POLICIES)
policy = random.choice(list(POLICIES)) random.shuffle(policies)
# setup updater # setup updater
conf = { conf = {
'devices': self.devices_dir, 'devices': self.devices_dir,
@ -443,46 +444,78 @@ class TestObjectUpdater(unittest.TestCase):
'swift_dir': self.testdir, 'swift_dir': self.testdir,
} }
daemon = object_updater.ObjectUpdater(conf, logger=self.logger) daemon = object_updater.ObjectUpdater(conf, logger=self.logger)
async_dir = os.path.join(self.sda1, get_async_dir(policy)) async_dir = os.path.join(self.sda1, get_async_dir(policies[0]))
os.mkdir(async_dir) os.mkdir(async_dir)
# write an async def do_test(headers_out, expected):
dfmanager = DiskFileManager(conf, daemon.logger) # write an async
account, container, obj = 'a', 'c', 'o' dfmanager = DiskFileManager(conf, daemon.logger)
op = 'PUT' account, container, obj = 'a', 'c', 'o'
headers_out = HeaderKeyDict({ op = 'PUT'
data = {'op': op, 'account': account, 'container': container,
'obj': obj, 'headers': headers_out}
dfmanager.pickle_async_update(self.sda1, account, container, obj,
data, next(ts_iter), policies[0])
request_log = []
def capture(*args, **kwargs):
request_log.append((args, kwargs))
# run once
fake_status_codes = [
200, # object update success
200, # object update success
200, # object update conflict
]
with mocked_http_conn(*fake_status_codes, give_connect=capture):
daemon.run_once()
self.assertEqual(len(fake_status_codes), len(request_log))
for request_args, request_kwargs in request_log:
ip, part, method, path, headers, qs, ssl = request_args
self.assertEqual(method, 'PUT')
self.assertDictEqual(expected, headers)
self.assertEqual(
daemon.logger.get_increment_counts(),
{'successes': 1, 'unlinks': 1, 'async_pendings': 1})
self.assertFalse(os.listdir(async_dir))
daemon.logger.clear()
ts = next(ts_iter)
# use a dict rather than HeaderKeyDict so we can vary the case of the
# pickled headers
headers_out = {
'x-size': 0, 'x-size': 0,
'x-content-type': 'text/plain', 'x-content-type': 'text/plain',
'x-etag': 'd41d8cd98f00b204e9800998ecf8427e', 'x-etag': 'd41d8cd98f00b204e9800998ecf8427e',
'x-timestamp': next(ts), 'x-timestamp': ts.normal,
'X-Backend-Storage-Policy-Index': int(policy), 'X-Backend-Storage-Policy-Index': int(policies[0]),
}) 'User-Agent': 'object-server %s' % os.getpid()
data = {'op': op, 'account': account, 'container': container, }
'obj': obj, 'headers': headers_out} expected = {
dfmanager.pickle_async_update(self.sda1, account, container, obj, 'X-Size': '0',
data, next(ts), policy) 'X-Content-Type': 'text/plain',
'X-Etag': 'd41d8cd98f00b204e9800998ecf8427e',
'X-Timestamp': ts.normal,
'X-Backend-Storage-Policy-Index': str(int(policies[0])),
'User-Agent': 'object-updater %s' % os.getpid()
}
do_test(headers_out, expected)
request_log = [] # updater should add policy header if missing
headers_out['X-Backend-Storage-Policy-Index'] = None
do_test(headers_out, expected)
def capture(*args, **kwargs): # updater should not overwrite a mismatched policy header
request_log.append((args, kwargs)) headers_out['X-Backend-Storage-Policy-Index'] = int(policies[1])
expected['X-Backend-Storage-Policy-Index'] = str(int(policies[1]))
do_test(headers_out, expected)
# run once # check for case insensitivity
fake_status_codes = [ headers_out['user-agent'] = headers_out.pop('User-Agent')
200, # object update success headers_out['x-backend-storage-policy-index'] = headers_out.pop(
200, # object update success 'X-Backend-Storage-Policy-Index')
200, # object update conflict do_test(headers_out, expected)
]
with mocked_http_conn(*fake_status_codes, give_connect=capture):
daemon.run_once()
self.assertEqual(len(fake_status_codes), len(request_log))
for request_args, request_kwargs in request_log:
ip, part, method, path, headers, qs, ssl = request_args
self.assertEqual(method, 'PUT')
self.assertEqual(headers['X-Backend-Storage-Policy-Index'],
str(int(policy)))
self.assertEqual(daemon.logger.get_increment_counts(),
{'successes': 1, 'unlinks': 1, 'async_pendings': 1})
if __name__ == '__main__': if __name__ == '__main__':