@@ -381,11 +381,102 @@ def _check_session_mocks(self, client, fake_session_factory,
381381 'GET' , expected_url , data = None , headers = headers )
382382 self .assertEqual (fake_transport .request .mock_calls , [call , call ])
383383
384+ def test__do_download_simple (self ):
385+ from io import BytesIO
386+ from six .moves import http_client
387+
388+ blob_name = 'blob-name'
389+ # Create a fake client/bucket and use them in the Blob() constructor.
390+ client = mock .Mock (
391+ _credentials = _make_credentials (), spec = ['_credentials' ])
392+ bucket = _Bucket (client )
393+ blob = self ._make_one (blob_name , bucket = bucket )
394+
395+ # Make sure this will not be chunked.
396+ self .assertIsNone (blob .chunk_size )
397+
398+ transport = mock .Mock (spec = ['request' ])
399+ transport .request .return_value = self ._mock_requests_response (
400+ http_client .OK ,
401+ {'content-length' : '6' , 'content-range' : 'bytes 0-5/6' },
402+ content = b'abcdef' )
403+ file_obj = BytesIO ()
404+ download_url = 'http://test.invalid'
405+ headers = {}
406+ blob ._do_download (transport , file_obj , download_url , headers )
407+ # Make sure the download was as expected.
408+ self .assertEqual (file_obj .getvalue (), b'abcdef' )
409+
410+ transport .request .assert_called_once_with (
411+ 'GET' , download_url , data = None , headers = headers )
412+
413+ def test__do_download_chunked (self ):
414+ from io import BytesIO
415+
416+ blob_name = 'blob-name'
417+ # Create a fake client/bucket and use them in the Blob() constructor.
418+ client = mock .Mock (
419+ _credentials = _make_credentials (), spec = ['_credentials' ])
420+ bucket = _Bucket (client )
421+ blob = self ._make_one (blob_name , bucket = bucket )
422+
423+ # Modify the blob so there there will be 2 chunks of size 3.
424+ blob ._CHUNK_SIZE_MULTIPLE = 1
425+ blob .chunk_size = 3
426+
427+ transport = self ._mock_transport ()
428+ file_obj = BytesIO ()
429+ download_url = 'http://test.invalid'
430+ headers = {}
431+ blob ._do_download (transport , file_obj , download_url , headers )
432+ # Make sure the download was as expected.
433+ self .assertEqual (file_obj .getvalue (), b'abcdef' )
434+
435+ # Check that the transport was called exactly twice.
436+ self .assertEqual (transport .request .call_count , 2 )
437+ # ``headers`` was modified (in place) once for each API call.
438+ self .assertEqual (headers , {'range' : 'bytes=3-5' })
439+ call = mock .call (
440+ 'GET' , download_url , data = None , headers = headers )
441+ self .assertEqual (transport .request .mock_calls , [call , call ])
442+
443+ @mock .patch ('google.auth.transport.requests.AuthorizedSession' )
444+ def test_download_to_file_with_failure (self , fake_session_factory ):
445+ from io import BytesIO
446+ from six .moves import http_client
447+ from google .cloud import exceptions
448+
449+ blob_name = 'blob-name'
450+ transport = mock .Mock (spec = ['request' ])
451+ bad_response_headers = {
452+ 'Content-Length' : '9' ,
453+ 'Content-Type' : 'text/html; charset=UTF-8' ,
454+ }
455+ transport .request .return_value = self ._mock_requests_response (
456+ http_client .NOT_FOUND , bad_response_headers , content = b'Not found' )
457+ fake_session_factory .return_value = transport
458+ # Create a fake client/bucket and use them in the Blob() constructor.
459+ client = mock .Mock (
460+ _credentials = _make_credentials (), spec = ['_credentials' ])
461+ bucket = _Bucket (client )
462+ blob = self ._make_one (blob_name , bucket = bucket )
463+ # Set the media link on the blob
464+ blob ._properties ['mediaLink' ] = 'http://test.invalid'
465+
466+ file_obj = BytesIO ()
467+ with self .assertRaises (exceptions .NotFound ):
468+ blob .download_to_file (file_obj )
469+
470+ self .assertEqual (file_obj .tell (), 0 )
471+ # Check that exactly one transport was created.
472+ fake_session_factory .assert_called_once_with (client ._credentials )
473+ # Check that the transport was called once.
474+ transport .request .assert_called_once_with (
475+ 'GET' , blob .media_link , data = None , headers = {})
476+
384477 @mock .patch ('google.auth.transport.requests.AuthorizedSession' )
385478 def test_download_to_file_wo_media_link (self , fake_session_factory ):
386479 from io import BytesIO
387- from six .moves .http_client import OK
388- from six .moves .http_client import PARTIAL_CONTENT
389480
390481 blob_name = 'blob-name'
391482 fake_session_factory .return_value = self ._mock_transport ()
@@ -413,7 +504,6 @@ def test_download_to_file_wo_media_link(self, fake_session_factory):
413504 def _download_to_file_helper (self , fake_session_factory , use_chunks = False ):
414505 from io import BytesIO
415506 from six .moves .http_client import OK
416- from six .moves .http_client import PARTIAL_CONTENT
417507
418508 blob_name = 'blob-name'
419509 fake_transport = self ._mock_transport ()
@@ -459,8 +549,6 @@ def test_download_to_file_with_chunk_size(self):
459549 def test_download_to_filename (self , fake_session_factory ):
460550 import os
461551 import time
462- from six .moves .http_client import OK
463- from six .moves .http_client import PARTIAL_CONTENT
464552 from google .cloud ._testing import _NamedTemporaryFile
465553
466554 blob_name = 'blob-name'
@@ -493,8 +581,6 @@ def test_download_to_filename(self, fake_session_factory):
493581 def test_download_to_filename_w_key (self , fake_session_factory ):
494582 import os
495583 import time
496- from six .moves .http_client import OK
497- from six .moves .http_client import PARTIAL_CONTENT
498584 from google .cloud ._testing import _NamedTemporaryFile
499585
500586 blob_name = 'blob-name'
@@ -535,9 +621,6 @@ def test_download_to_filename_w_key(self, fake_session_factory):
535621
536622 @mock .patch ('google.auth.transport.requests.AuthorizedSession' )
537623 def test_download_as_string (self , fake_session_factory ):
538- from six .moves .http_client import OK
539- from six .moves .http_client import PARTIAL_CONTENT
540-
541624 blob_name = 'blob-name'
542625 fake_session_factory .return_value = self ._mock_transport ()
543626 # Create a fake client/bucket and use them in the Blob() constructor.
0 commit comments