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())

Reply via email to