Add test for object updater user-agent header

Adds a test to test_updater.py in follow-up to [1].

[1] Related-Change: Ia624558395584457c718b311fe80e1a8406e22ad

Change-Id: I4f943b2626972d096ad3aeed647c8166b3bdd934
This commit is contained in:
Alistair Coles
2016-11-16 18:18:44 +00:00
parent e166e19b23
commit dfc8e61cf5

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
@@ -435,9 +435,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,
@@ -445,46 +446,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__':