@@ -438,9 +438,9 @@ def test_call_rpc(self):
438438 self ._mock_http (d , status = (502 , "bad gateway" ))
439439 self .assertRaises (api .ProtocolError , self .sg ._call_rpc , "list" , a )
440440 self .assertEqual (
441- 4 ,
441+ self . sg . MAX_ATTEMPTS ,
442442 self .sg ._http_request .call_count ,
443- "Call is repeated up to 3 times" ,
443+ f "Call is repeated up to { self . sg . MAX_ATTEMPTS } times" ,
444444 )
445445
446446 # 504
@@ -449,9 +449,9 @@ def test_call_rpc(self):
449449 self ._mock_http (d , status = (504 , "gateway timeout" ))
450450 self .assertRaises (api .ProtocolError , self .sg ._call_rpc , "list" , a )
451451 self .assertEqual (
452- 4 ,
452+ self . sg . MAX_ATTEMPTS ,
453453 self .sg ._http_request .call_count ,
454- "Call is repeated up to 3 times" ,
454+ f "Call is repeated up to { self . sg . MAX_ATTEMPTS } times" ,
455455 )
456456
457457 def test_upload_s3_503 (self ):
@@ -462,7 +462,6 @@ def test_upload_s3_503(self):
462462 storage_url = "http://foo.com/"
463463 path = os .path .abspath (os .path .expanduser (
464464 os .path .join (this_dir , "sg_logo.jpg" )))
465- max_attempts = 4 # Max retries to S3 server attempts
466465 # Expected HTTPError exception error message
467466 expected = "The server is currently down or to busy to reply." \
468467 "Please try again later."
@@ -474,8 +473,8 @@ def test_upload_s3_503(self):
474473 self .sg ._upload_file_to_storage (path , storage_url )
475474 # Test the max retries attempt
476475 self .assertTrue (
477- max_attempts == self .sg ._make_upload_request .call_count ,
478- "Call is repeated up to 3 times" )
476+ self . sg . MAX_ATTEMPTS == self .sg ._make_upload_request .call_count ,
477+ f "Call is repeated up to { self . sg . MAX_ATTEMPTS } times" )
479478
480479 def test_upload_s3_500 (self ):
481480 """
@@ -486,7 +485,6 @@ def test_upload_s3_500(self):
486485 storage_url = "http://foo.com/"
487486 path = os .path .abspath (os .path .expanduser (
488487 os .path .join (this_dir , "sg_logo.jpg" )))
489- max_attempts = 4 # Max retries to S3 server attempts
490488 # Expected HTTPError exception error message
491489 expected = "The server is currently down or to busy to reply." \
492490 "Please try again later."
@@ -498,8 +496,70 @@ def test_upload_s3_500(self):
498496 self .sg ._upload_file_to_storage (path , storage_url )
499497 # Test the max retries attempt
500498 self .assertTrue (
501- max_attempts == self .sg ._make_upload_request .call_count ,
502- "Call is repeated up to 3 times" )
499+ self .sg .MAX_ATTEMPTS == self .sg ._make_upload_request .call_count ,
500+ f"Call is repeated up to { self .sg .MAX_ATTEMPTS } times" )
501+
502+ def test_upload_s3_urlerror__get_attachment_upload_info (self ):
503+ """
504+ Test URLError response is retried when invoking _send_form
505+ """
506+ mock_opener = mock .Mock ()
507+ mock_opener .return_value .open .side_effect = urllib .error .URLError (
508+ "[WinError 10054] An existing connection was forcibly closed by the remote host"
509+ )
510+ self .sg ._build_opener = mock_opener
511+ this_dir , _ = os .path .split (__file__ )
512+ path = os .path .abspath (
513+ os .path .expanduser (os .path .join (this_dir , "sg_logo.jpg" ))
514+ )
515+
516+ with self .assertRaises (api .ShotgunError ) as cm :
517+ self .sg ._get_attachment_upload_info (False , path , False )
518+
519+ # Test the max retries attempt
520+ self .assertEqual (
521+ self .sg .MAX_ATTEMPTS ,
522+ mock_opener .return_value .open .call_count ,
523+ f"Call is repeated up to { self .sg .MAX_ATTEMPTS } times"
524+ )
525+
526+ # Test the exception message
527+ the_exception = cm .exception
528+ self .assertEqual (str (the_exception ), "Max attemps limit reached." )
529+
530+ def test_upload_s3_urlerror__upload_to_storage (self ):
531+ """
532+ Test URLError response is retried when uploading to S3.
533+ """
534+ self .sg ._make_upload_request = mock .Mock (
535+ spec = api .Shotgun ._make_upload_request ,
536+ side_effect = urllib .error .URLError (
537+ "[Errno 104] Connection reset by peer" ,
538+ ),
539+ )
540+
541+ this_dir , _ = os .path .split (__file__ )
542+ storage_url = "http://foo.com/"
543+ path = os .path .abspath (
544+ os .path .expanduser (os .path .join (this_dir , "sg_logo.jpg" ))
545+ )
546+
547+ # Test the Internal function that is used to upload each
548+ # data part in the context of multi-part uploads to S3, we
549+ # simulate the HTTPError exception raised with 503 status errors
550+ with self .assertRaises (api .ShotgunError ) as cm :
551+ self .sg ._upload_file_to_storage (path , storage_url )
552+
553+ # Test the max retries attempt
554+ self .assertEqual (
555+ self .sg .MAX_ATTEMPTS ,
556+ self .sg ._make_upload_request .call_count ,
557+ f"Call is repeated up to { self .sg .MAX_ATTEMPTS } times"
558+ )
559+
560+ # Test the exception message
561+ the_exception = cm .exception
562+ self .assertEqual (str (the_exception ), "Max attemps limit reached." )
503563
504564 def test_transform_data (self ):
505565 """Outbound data is transformed"""
0 commit comments