@@ -418,15 +418,18 @@ def test_upload_from_file_size_failure(self):
418418 def _upload_from_file_simple_test_helper (self , properties = None ,
419419 content_type_arg = None ,
420420 expected_content_type = None ,
421- chunk_size = 5 ):
421+ chunk_size = 5 ,
422+ status = None ):
422423 from six .moves .http_client import OK
423424 from six .moves .urllib .parse import parse_qsl
424425 from six .moves .urllib .parse import urlsplit
425426 from gcloud ._testing import _NamedTemporaryFile
426427
427428 BLOB_NAME = 'blob-name'
428429 DATA = b'ABCDEF'
429- response = {'status' : OK }
430+ if status is None :
431+ status = OK
432+ response = {'status' : status }
430433 connection = _Connection (
431434 (response , b'{}' ),
432435 )
@@ -463,6 +466,12 @@ def test_upload_from_file_simple(self):
463466 self ._upload_from_file_simple_test_helper (
464467 expected_content_type = 'application/octet-stream' )
465468
469+ def test_upload_from_file_simple_not_found (self ):
470+ from six .moves .http_client import NOT_FOUND
471+ from gcloud .exceptions import NotFound
472+ with self .assertRaises (NotFound ):
473+ self ._upload_from_file_simple_test_helper (status = NOT_FOUND )
474+
466475 def test_upload_from_file_simple_w_chunk_size_None (self ):
467476 self ._upload_from_file_simple_test_helper (
468477 expected_content_type = 'application/octet-stream' ,
@@ -572,6 +581,60 @@ def test_upload_from_file_resumable(self):
572581 'redirections' : 5 ,
573582 })
574583
584+ def test_upload_from_file_resumable_w_error (self ):
585+ from six .moves .http_client import NOT_FOUND
586+ from six .moves .urllib .parse import parse_qsl
587+ from six .moves .urllib .parse import urlsplit
588+ from gcloud ._testing import _Monkey
589+ from gcloud ._testing import _NamedTemporaryFile
590+ from gcloud .streaming import transfer
591+ from gcloud .streaming .exceptions import HttpError
592+
593+ BLOB_NAME = 'blob-name'
594+ DATA = b'ABCDEF'
595+ loc_response = {'status' : NOT_FOUND }
596+ connection = _Connection (
597+ (loc_response , b'{"error": "no such bucket"}' ),
598+ )
599+ client = _Client (connection )
600+ bucket = _Bucket (client )
601+ blob = self ._makeOne (BLOB_NAME , bucket = bucket )
602+ blob ._CHUNK_SIZE_MULTIPLE = 1
603+ blob .chunk_size = 5
604+
605+ # Set the threshhold low enough that we force a resumable uploada.
606+ with _Monkey (transfer , RESUMABLE_UPLOAD_THRESHOLD = 5 ):
607+ with _NamedTemporaryFile () as temp :
608+ with open (temp .name , 'wb' ) as file_obj :
609+ file_obj .write (DATA )
610+ with open (temp .name , 'rb' ) as file_obj :
611+ with self .assertRaises (HttpError ):
612+ blob .upload_from_file (file_obj , rewind = True )
613+
614+ rq = connection .http ._requested
615+ self .assertEqual (len (rq ), 1 )
616+
617+ # Requested[0]
618+ headers = dict (
619+ [(x .title (), str (y )) for x , y in rq [0 ].pop ('headers' ).items ()])
620+ self .assertEqual (headers ['X-Upload-Content-Length' ], '6' )
621+ self .assertEqual (headers ['X-Upload-Content-Type' ],
622+ 'application/octet-stream' )
623+
624+ uri = rq [0 ].pop ('uri' )
625+ scheme , netloc , path , qs , _ = urlsplit (uri )
626+ self .assertEqual (scheme , 'http' )
627+ self .assertEqual (netloc , 'example.com' )
628+ self .assertEqual (path , '/b/name/o' )
629+ self .assertEqual (dict (parse_qsl (qs )),
630+ {'uploadType' : 'resumable' , 'name' : BLOB_NAME })
631+ self .assertEqual (rq [0 ], {
632+ 'method' : 'POST' ,
633+ 'body' : '' ,
634+ 'connection_type' : None ,
635+ 'redirections' : 5 ,
636+ })
637+
575638 def test_upload_from_file_w_slash_in_name (self ):
576639 from six .moves .http_client import OK
577640 from six .moves .urllib .parse import parse_qsl
0 commit comments