Don't trust X-Object-Meta-Mtime
Still use it if we can, but stop throwing ValueErrors if it's garbage. Change-Id: I2cf25b535ad62cfacb7561954a92a4a73d91000a
This commit is contained in:
parent
6f431ee065
commit
337570a03a
@ -1162,11 +1162,15 @@ class SwiftService(object):
|
|||||||
if fp is not None:
|
if fp is not None:
|
||||||
fp.close()
|
fp.close()
|
||||||
if 'x-object-meta-mtime' in headers and not no_file:
|
if 'x-object-meta-mtime' in headers and not no_file:
|
||||||
mtime = float(headers['x-object-meta-mtime'])
|
try:
|
||||||
if options['out_file']:
|
mtime = float(headers['x-object-meta-mtime'])
|
||||||
utime(options['out_file'], (mtime, mtime))
|
except ValueError:
|
||||||
|
pass # no real harm; couldn't trust it anyway
|
||||||
else:
|
else:
|
||||||
utime(path, (mtime, mtime))
|
if options['out_file']:
|
||||||
|
utime(options['out_file'], (mtime, mtime))
|
||||||
|
else:
|
||||||
|
utime(path, (mtime, mtime))
|
||||||
|
|
||||||
res = {
|
res = {
|
||||||
'action': 'download_object',
|
'action': 'download_object',
|
||||||
|
@ -1535,6 +1535,97 @@ class TestServiceDownload(_TestServiceBase):
|
|||||||
)
|
)
|
||||||
self._assertDictEqual(expected_r, actual_r)
|
self._assertDictEqual(expected_r, actual_r)
|
||||||
|
|
||||||
|
def test_download_object_job_with_mtime(self):
|
||||||
|
mock_conn = self._get_mock_connection()
|
||||||
|
objcontent = six.BytesIO(b'objcontent')
|
||||||
|
mock_conn.get_object.side_effect = [
|
||||||
|
({'content-type': 'text/plain',
|
||||||
|
'etag': '2cbbfe139a744d6abbe695e17f3c1991',
|
||||||
|
'x-object-meta-mtime': '1454113727.682512'},
|
||||||
|
objcontent)
|
||||||
|
]
|
||||||
|
expected_r = self._get_expected({
|
||||||
|
'success': True,
|
||||||
|
'start_time': 1,
|
||||||
|
'finish_time': 2,
|
||||||
|
'headers_receipt': 3,
|
||||||
|
'auth_end_time': 4,
|
||||||
|
'read_length': len(b'objcontent'),
|
||||||
|
})
|
||||||
|
|
||||||
|
with mock.patch.object(builtins, 'open') as mock_open, \
|
||||||
|
mock.patch('swiftclient.service.utime') as mock_utime:
|
||||||
|
written_content = Mock()
|
||||||
|
mock_open.return_value = written_content
|
||||||
|
s = SwiftService()
|
||||||
|
_opts = self.opts.copy()
|
||||||
|
_opts['no_download'] = False
|
||||||
|
actual_r = s._download_object_job(
|
||||||
|
mock_conn, 'test_c', 'test_o', _opts)
|
||||||
|
actual_r = dict( # Need to override the times we got from the call
|
||||||
|
actual_r,
|
||||||
|
**{
|
||||||
|
'start_time': 1,
|
||||||
|
'finish_time': 2,
|
||||||
|
'headers_receipt': 3
|
||||||
|
}
|
||||||
|
)
|
||||||
|
mock_open.assert_called_once_with('test_o', 'wb')
|
||||||
|
mock_utime.assert_called_once_with(
|
||||||
|
'test_o', (1454113727.682512, 1454113727.682512))
|
||||||
|
written_content.write.assert_called_once_with(b'objcontent')
|
||||||
|
|
||||||
|
mock_conn.get_object.assert_called_once_with(
|
||||||
|
'test_c', 'test_o', resp_chunk_size=65536, headers={},
|
||||||
|
response_dict={}
|
||||||
|
)
|
||||||
|
self._assertDictEqual(expected_r, actual_r)
|
||||||
|
|
||||||
|
def test_download_object_job_bad_mtime(self):
|
||||||
|
mock_conn = self._get_mock_connection()
|
||||||
|
objcontent = six.BytesIO(b'objcontent')
|
||||||
|
mock_conn.get_object.side_effect = [
|
||||||
|
({'content-type': 'text/plain',
|
||||||
|
'etag': '2cbbfe139a744d6abbe695e17f3c1991',
|
||||||
|
'x-object-meta-mtime': 'foo'},
|
||||||
|
objcontent)
|
||||||
|
]
|
||||||
|
expected_r = self._get_expected({
|
||||||
|
'success': True,
|
||||||
|
'start_time': 1,
|
||||||
|
'finish_time': 2,
|
||||||
|
'headers_receipt': 3,
|
||||||
|
'auth_end_time': 4,
|
||||||
|
'read_length': len(b'objcontent'),
|
||||||
|
})
|
||||||
|
|
||||||
|
with mock.patch.object(builtins, 'open') as mock_open, \
|
||||||
|
mock.patch('swiftclient.service.utime') as mock_utime:
|
||||||
|
written_content = Mock()
|
||||||
|
mock_open.return_value = written_content
|
||||||
|
s = SwiftService()
|
||||||
|
_opts = self.opts.copy()
|
||||||
|
_opts['no_download'] = False
|
||||||
|
actual_r = s._download_object_job(
|
||||||
|
mock_conn, 'test_c', 'test_o', _opts)
|
||||||
|
actual_r = dict( # Need to override the times we got from the call
|
||||||
|
actual_r,
|
||||||
|
**{
|
||||||
|
'start_time': 1,
|
||||||
|
'finish_time': 2,
|
||||||
|
'headers_receipt': 3
|
||||||
|
}
|
||||||
|
)
|
||||||
|
mock_open.assert_called_once_with('test_o', 'wb')
|
||||||
|
self.assertEqual(0, len(mock_utime.mock_calls))
|
||||||
|
written_content.write.assert_called_once_with(b'objcontent')
|
||||||
|
|
||||||
|
mock_conn.get_object.assert_called_once_with(
|
||||||
|
'test_c', 'test_o', resp_chunk_size=65536, headers={},
|
||||||
|
response_dict={}
|
||||||
|
)
|
||||||
|
self._assertDictEqual(expected_r, actual_r)
|
||||||
|
|
||||||
def test_download_object_job_exception(self):
|
def test_download_object_job_exception(self):
|
||||||
mock_conn = self._get_mock_connection()
|
mock_conn = self._get_mock_connection()
|
||||||
mock_conn.get_object = Mock(side_effect=self.exc)
|
mock_conn.get_object = Mock(side_effect=self.exc)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user