summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--swiftclient/service.py12
-rw-r--r--tests/unit/test_service.py105
-rw-r--r--tests/unit/test_shell.py105
3 files changed, 168 insertions, 54 deletions
diff --git a/swiftclient/service.py b/swiftclient/service.py
index 492055d..20c023b 100644
--- a/swiftclient/service.py
+++ b/swiftclient/service.py
@@ -1162,11 +1162,15 @@ class SwiftService(object):
if fp is not None:
fp.close()
if 'x-object-meta-mtime' in headers and not no_file:
- mtime = float(headers['x-object-meta-mtime'])
- if options['out_file']:
- utime(options['out_file'], (mtime, mtime))
+ try:
+ mtime = float(headers['x-object-meta-mtime'])
+ except ValueError:
+ pass # no real harm; couldn't trust it anyway
else:
- utime(path, (mtime, mtime))
+ if options['out_file']:
+ utime(options['out_file'], (mtime, mtime))
+ else:
+ utime(path, (mtime, mtime))
res = {
'action': 'download_object',
diff --git a/tests/unit/test_service.py b/tests/unit/test_service.py
index 7522e65..64039ad 100644
--- a/tests/unit/test_service.py
+++ b/tests/unit/test_service.py
@@ -876,7 +876,7 @@ class TestServiceUpload(_TestServiceBase):
'status': 'uploaded',
'success': True,
}
- expected_mtime = float(os.path.getmtime(f.name))
+ expected_mtime = '%f' % os.path.getmtime(f.name)
mock_conn = mock.Mock()
mock_conn.put_object.return_value = ''
@@ -901,13 +901,13 @@ class TestServiceUpload(_TestServiceBase):
'use_slo': False,
'checksum': True})
- mtime = float(r['headers']['x-object-meta-mtime'])
- self.assertAlmostEqual(mtime, expected_mtime, delta=0.5)
+ mtime = r['headers']['x-object-meta-mtime']
+ self.assertEqual(expected_mtime, mtime)
del r['headers']['x-object-meta-mtime']
self.assertEqual(
'test_c_segments/%E3%83%86%E3%82%B9%E3%83%88/dummy.dat/' +
- '%f/30/10/' % mtime, r['headers']['x-object-manifest'])
+ '%s/30/10/' % mtime, r['headers']['x-object-manifest'])
del r['headers']['x-object-manifest']
self.assertEqual(r['path'], f.name)
@@ -1073,7 +1073,7 @@ class TestServiceUpload(_TestServiceBase):
'status': 'uploaded',
'success': True,
}
- expected_mtime = float(os.path.getmtime(f.name))
+ expected_mtime = '%f' % os.path.getmtime(f.name)
mock_conn = mock.Mock()
mock_conn.put_object.return_value = ''
@@ -1091,8 +1091,8 @@ class TestServiceUpload(_TestServiceBase):
'segment_size': 0,
'checksum': True})
- mtime = float(r['headers']['x-object-meta-mtime'])
- self.assertAlmostEqual(mtime, expected_mtime, delta=0.5)
+ mtime = r['headers']['x-object-meta-mtime']
+ self.assertEqual(expected_mtime, mtime)
del r['headers']['x-object-meta-mtime']
self.assertEqual(r['path'], f.name)
@@ -1535,6 +1535,97 @@ class TestServiceDownload(_TestServiceBase):
)
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):
mock_conn = self._get_mock_connection()
mock_conn.get_object = Mock(side_effect=self.exc)
diff --git a/tests/unit/test_shell.py b/tests/unit/test_shell.py
index 5313d41..c7bbf74 100644
--- a/tests/unit/test_shell.py
+++ b/tests/unit/test_shell.py
@@ -336,15 +336,17 @@ class TestShell(testtools.TestCase):
with mock.patch(BUILTIN_OPEN) as mock_open:
argv = ["", "download", "container"]
swiftclient.shell.main(argv)
- calls = [mock.call('container', 'object',
- headers={}, resp_chunk_size=65536,
- response_dict={}),
- mock.call('container', 'pseudo/',
- headers={}, resp_chunk_size=65536,
- response_dict={})]
- connection.return_value.get_object.assert_has_calls(
- calls, any_order=True)
- mock_open.assert_called_once_with('object', 'wb')
+ calls = [mock.call('container', 'object',
+ headers={}, resp_chunk_size=65536,
+ response_dict={}),
+ mock.call('container', 'pseudo/',
+ headers={}, resp_chunk_size=65536,
+ response_dict={})]
+ connection.return_value.get_object.assert_has_calls(
+ calls, any_order=True)
+ mock_open.assert_called_once_with('object', 'wb')
+ self.assertEqual([mock.call('pseudo')], makedirs.mock_calls)
+ makedirs.reset_mock()
# Test downloading single object
objcontent = six.BytesIO(b'objcontent')
@@ -356,10 +358,11 @@ class TestShell(testtools.TestCase):
with mock.patch(BUILTIN_OPEN) as mock_open:
argv = ["", "download", "container", "object"]
swiftclient.shell.main(argv)
- connection.return_value.get_object.assert_called_with(
- 'container', 'object', headers={}, resp_chunk_size=65536,
- response_dict={})
- mock_open.assert_called_with('object', 'wb')
+ connection.return_value.get_object.assert_called_with(
+ 'container', 'object', headers={}, resp_chunk_size=65536,
+ response_dict={})
+ mock_open.assert_called_with('object', 'wb')
+ self.assertEqual([], makedirs.mock_calls)
# Test downloading single object to stdout
objcontent = six.BytesIO(b'objcontent')
@@ -396,13 +399,18 @@ class TestShell(testtools.TestCase):
]
with mock.patch(BUILTIN_OPEN) as mock_open:
- argv = ["", "download", "--all"]
- swiftclient.shell.main(argv)
- self.assertEqual(3, mock_shuffle.call_count)
- mock_shuffle.assert_any_call(['container'])
- mock_shuffle.assert_any_call(['object'])
- mock_shuffle.assert_any_call(['pseudo/'])
- mock_open.assert_called_once_with('container/object', 'wb')
+ with mock.patch('swiftclient.service.makedirs') as mock_mkdir:
+ argv = ["", "download", "--all"]
+ swiftclient.shell.main(argv)
+ self.assertEqual(3, mock_shuffle.call_count)
+ mock_shuffle.assert_any_call(['container'])
+ mock_shuffle.assert_any_call(['object'])
+ mock_shuffle.assert_any_call(['pseudo/'])
+ mock_open.assert_called_once_with('container/object', 'wb')
+ self.assertEqual([
+ mock.call('container'),
+ mock.call('container/pseudo'),
+ ], mock_mkdir.mock_calls)
# Test that the container and object lists are not shuffled
mock_shuffle.reset_mock()
@@ -418,10 +426,15 @@ class TestShell(testtools.TestCase):
]
with mock.patch(BUILTIN_OPEN) as mock_open:
- argv = ["", "download", "--all", "--no-shuffle"]
- swiftclient.shell.main(argv)
- self.assertEqual(0, mock_shuffle.call_count)
- mock_open.assert_called_once_with('container/object', 'wb')
+ with mock.patch('swiftclient.service.makedirs') as mock_mkdir:
+ argv = ["", "download", "--all", "--no-shuffle"]
+ swiftclient.shell.main(argv)
+ self.assertEqual(0, mock_shuffle.call_count)
+ mock_open.assert_called_once_with('container/object', 'wb')
+ self.assertEqual([
+ mock.call('container'),
+ mock.call('container/pseudo'),
+ ], mock_mkdir.mock_calls)
@mock.patch('swiftclient.service.Connection')
def test_download_no_content_type(self, connection):
@@ -439,17 +452,21 @@ class TestShell(testtools.TestCase):
connection.return_value.attempts = 0
with mock.patch(BUILTIN_OPEN) as mock_open:
- argv = ["", "download", "container"]
- swiftclient.shell.main(argv)
- calls = [mock.call('container', 'object',
- headers={}, resp_chunk_size=65536,
- response_dict={}),
- mock.call('container', 'pseudo/',
- headers={}, resp_chunk_size=65536,
- response_dict={})]
- connection.return_value.get_object.assert_has_calls(
- calls, any_order=True)
- mock_open.assert_called_once_with('object', 'wb')
+ with mock.patch('swiftclient.service.makedirs') as mock_mkdir:
+ argv = ["", "download", "container"]
+ swiftclient.shell.main(argv)
+ calls = [mock.call('container', 'object',
+ headers={}, resp_chunk_size=65536,
+ response_dict={}),
+ mock.call('container', 'pseudo/',
+ headers={}, resp_chunk_size=65536,
+ response_dict={})]
+ connection.return_value.get_object.assert_has_calls(
+ calls, any_order=True)
+ mock_open.assert_called_once_with('object', 'wb')
+ self.assertEqual([
+ mock.call('pseudo'),
+ ], mock_mkdir.mock_calls)
@mock.patch('swiftclient.shell.walk')
@mock.patch('swiftclient.service.Connection')
@@ -734,14 +751,16 @@ class TestShell(testtools.TestCase):
argv = ["", "delete", "--all"]
connection.return_value.head_object.return_value = {}
swiftclient.shell.main(argv)
- self.assertEqual(
- connection.return_value.delete_object.mock_calls, [
- mock.call('container', 'object', query_string=None,
- response_dict={}),
- mock.call('container', 'obj\xe9ct2', query_string=None,
- response_dict={}),
- mock.call('container2', 'object', query_string=None,
- response_dict={})])
+ connection.return_value.delete_object.assert_has_calls([
+ mock.call('container', 'object', query_string=None,
+ response_dict={}),
+ mock.call('container', 'obj\xe9ct2', query_string=None,
+ response_dict={}),
+ mock.call('container2', 'object', query_string=None,
+ response_dict={})], any_order=True)
+ self.assertEqual(3, connection.return_value.delete_object.call_count,
+ 'Expected 3 calls but found\n%r'
+ % connection.return_value.delete_object.mock_calls)
self.assertEqual(
connection.return_value.delete_container.mock_calls, [
mock.call('container', response_dict={}),