Add a test case for #1135.
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/0710d23d Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/0710d23d Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/0710d23d Branch: refs/heads/trunk Commit: 0710d23de52a1c2c4841937e4c7c17b81950b9ae Parents: f053297 Author: Tomaz Muraus <[email protected]> Authored: Mon Jan 8 11:58:10 2018 +0100 Committer: Tomaz Muraus <[email protected]> Committed: Mon Jan 8 12:00:17 2018 +0100 ---------------------------------------------------------------------- libcloud/test/storage/test_base.py | 44 +++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/libcloud/blob/0710d23d/libcloud/test/storage/test_base.py ---------------------------------------------------------------------- diff --git a/libcloud/test/storage/test_base.py b/libcloud/test/storage/test_base.py index 2f3b048..dabc0f5 100644 --- a/libcloud/test/storage/test_base.py +++ b/libcloud/test/storage/test_base.py @@ -14,10 +14,12 @@ # limitations under the License. import sys +import hashlib from libcloud.utils.py3 import httplib from io import BytesIO +import mock from mock import Mock from libcloud.utils.py3 import StringIO @@ -28,6 +30,7 @@ from libcloud.storage.base import DEFAULT_CONTENT_TYPE from libcloud.test import unittest from libcloud.test import MockHttp +from libcloud.test import BodyStream class BaseMockRawResponse(MockHttp): @@ -131,6 +134,47 @@ class BaseStorageTests(unittest.TestCase): request_path='/', stream=iterator) + @mock.patch('libcloud.utils.files.exhaust_iterator') + @mock.patch('libcloud.utils.files.read_in_chunks') + def test_upload_object_hash_calculation_is_efficient(self, mock_read_in_chunks, + mock_exhaust_iterator): + # Verify that we don't buffer whole file in memory when calculating + # object has when iterator has __next__ method, but instead read and calculate hash in chunks + size = 100 + + mock_read_in_chunks.return_value = 'a' * size + + iterator = BodyStream('a' * size) + + upload_func = Mock() + upload_func.return_value = True, '', size + + # strict_mode is disabled, default content type should be used + self.driver1.connection = Mock() + + self.assertEqual(mock_read_in_chunks.call_count, 0) + self.assertEqual(mock_exhaust_iterator.call_count, 0) + + result = self.driver1._upload_object(object_name='test', + content_type=None, + upload_func=upload_func, + upload_func_kwargs={}, + request_path='/', + stream=iterator) + + hasher = hashlib.md5() + hasher.update('a' * size) + expected_hash = hasher.hexdigest() + + self.assertEqual(result['data_hash'], expected_hash) + self.assertEqual(result['bytes_transferred'], size) + + headers = self.driver1.connection.request.call_args[-1]['headers'] + self.assertEqual(headers['Content-Type'], DEFAULT_CONTENT_TYPE) + + self.assertEqual(mock_read_in_chunks.call_count, 1) + self.assertEqual(mock_exhaust_iterator.call_count, 0) + if __name__ == '__main__': sys.exit(unittest.main())
