@@ -882,6 +882,98 @@ def test_check_rst_stream_error(self):
882882
883883 self .assertEqual (test_api .test_fxn .call_count , 3 )
884884
885+ def test_retry_on_aborted_exception_with_success_after_first_aborted_retry (self ):
886+ from google .api_core .exceptions import Aborted
887+ import time
888+ from google .cloud .spanner_v1 ._helpers import _retry_on_aborted_exception
889+ import functools
890+
891+ test_api = mock .create_autospec (self .test_class )
892+ test_api .test_fxn .side_effect = [
893+ Aborted ("aborted exception" , errors = ("Aborted error" )),
894+ "true" ,
895+ ]
896+ deadline = time .time () + 30
897+ result_after_retry = _retry_on_aborted_exception (
898+ functools .partial (test_api .test_fxn ), deadline
899+ )
900+
901+ self .assertEqual (test_api .test_fxn .call_count , 2 )
902+ self .assertTrue (result_after_retry )
903+
904+ def test_retry_on_aborted_exception_with_success_after_three_retries (self ):
905+ from google .api_core .exceptions import Aborted
906+ from google .api_core .exceptions import InternalServerError
907+ import time
908+ from google .cloud .spanner_v1 ._helpers import _retry_on_aborted_exception
909+ import functools
910+
911+ test_api = mock .create_autospec (self .test_class )
912+ # Case where aborted exception is thrown after other generic exceptions
913+ test_api .test_fxn .side_effect = [
914+ InternalServerError ("testing" ),
915+ InternalServerError ("testing" ),
916+ Aborted ("aborted exception" , errors = ("Aborted error" )),
917+ "true" ,
918+ ]
919+ allowed_exceptions = {
920+ InternalServerError : lambda exc : None ,
921+ }
922+ deadline = time .time () + 30
923+ _retry_on_aborted_exception (
924+ functools .partial (test_api .test_fxn ),
925+ deadline = deadline ,
926+ allowed_exceptions = allowed_exceptions ,
927+ )
928+
929+ self .assertEqual (test_api .test_fxn .call_count , 4 )
930+
931+ def test_retry_on_aborted_exception_raises_aborted_if_deadline_expires (self ):
932+ from google .api_core .exceptions import Aborted
933+ import time
934+ from google .cloud .spanner_v1 ._helpers import _retry_on_aborted_exception
935+ import functools
936+
937+ test_api = mock .create_autospec (self .test_class )
938+ test_api .test_fxn .side_effect = [
939+ Aborted ("aborted exception" , errors = ("Aborted error" )),
940+ "true" ,
941+ ]
942+ deadline = time .time () + 0.1
943+ with self .assertRaises (Aborted ):
944+ _retry_on_aborted_exception (
945+ functools .partial (test_api .test_fxn ), deadline = deadline
946+ )
947+
948+ self .assertEqual (test_api .test_fxn .call_count , 1 )
949+
950+ def test_retry_on_aborted_exception_returns_response_after_internal_server_errors (
951+ self ,
952+ ):
953+ from google .api_core .exceptions import InternalServerError
954+ import time
955+ from google .cloud .spanner_v1 ._helpers import _retry_on_aborted_exception
956+ import functools
957+
958+ test_api = mock .create_autospec (self .test_class )
959+ test_api .test_fxn .side_effect = [
960+ InternalServerError ("testing" ),
961+ InternalServerError ("testing" ),
962+ "true" ,
963+ ]
964+ allowed_exceptions = {
965+ InternalServerError : lambda exc : None ,
966+ }
967+ deadline = time .time () + 30
968+ result_after_retries = _retry_on_aborted_exception (
969+ functools .partial (test_api .test_fxn ),
970+ deadline = deadline ,
971+ allowed_exceptions = allowed_exceptions ,
972+ )
973+
974+ self .assertEqual (test_api .test_fxn .call_count , 3 )
975+ self .assertTrue (result_after_retries )
976+
885977
886978class Test_metadata_with_leader_aware_routing (unittest .TestCase ):
887979 def _call_fut (self , * args , ** kw ):
0 commit comments