@@ -68,7 +68,7 @@ def test_no_retry_on_parameter_invalid(self):
6868 self .assertTrue (isinstance (context .exception , ServerException ))
6969
7070 def test_retry_with_client_token (self ):
71- pass
71+ pass
7272
7373 def test_retry_with_client_token_set (self ):
7474 pass
@@ -107,7 +107,90 @@ def no_sleep(delay):
107107 self .assertEqual (8 , context .http_request .retries )
108108
109109 def test_retry_conditions (self ):
110- pass
110+ client = AcsClient (self .access_key_id , self .access_key_secret , self .region_id )
111+
112+ default_retry_policy = retry_policy .get_default_retry_policy ()
113+
114+ def CE (code ):
115+ return ClientException (code , "some error" )
116+
117+ def SE (code ):
118+ return ServerException (code , "some error" )
119+
120+ def _get_retryable (* conditions ):
121+ context = RetryPolicyContext (* conditions )
122+ return default_retry_policy .should_retry (context )
123+
124+ def _assert_not_retryable (* conditions ):
125+ retryable = _get_retryable (* conditions )
126+ self .assertTrue (retryable & RetryCondition .NO_RETRY )
127+
128+ def _assert_retryable (* conditions ):
129+ retryable = _get_retryable (* conditions )
130+ self .assertFalse (retryable & RetryCondition .NO_RETRY )
131+
132+ def _assert_retryable_with_client_token (request ):
133+ conditions = [request , SE ("InternalError" ), 0 , 500 ]
134+ retryable = _get_retryable (* conditions )
135+ self .assertTrue (retryable &
136+ RetryCondition .SHOULD_RETRY_WITH_THROTTLING_BACKOFF )
137+
138+ def _assert_not_retryable_with_client_token (request ):
139+ conditions = [request , SE ("InternalError" ), 0 , 500 ]
140+ retryable = _get_retryable (* conditions )
141+ self .assertFalse (retryable & RetryCondition .SHOULD_RETRY_WITH_THROTTLING_BACKOFF )
142+ # retryable
143+ acs_request = DescribeInstancesRequest ()
144+ retryable_request = client ._get_new_style_request (acs_request )
145+ config = client ._get_new_style_config (acs_request )
146+ retryable_client = client ._get_new_style_client (acs_request , config )
147+
148+ timeout_exception = CE (error_code .SDK_HTTP_ERROR )
149+ invalid_param_excpetion = SE ("MissingParameter" )
150+ unknown_error = SE (error_code .SDK_UNKNOWN_SERVER_ERROR )
151+ internal_error = SE ("InternalError" )
152+
153+ _assert_retryable (retryable_request , timeout_exception , 0 , 500 , retryable_client )
154+ _assert_retryable (retryable_request , timeout_exception , 2 , 500 , retryable_client )
155+ _assert_retryable (retryable_request , unknown_error , 0 , 500 , retryable_client )
156+ _assert_retryable (retryable_request , unknown_error , 0 , 502 , retryable_client )
157+ _assert_retryable (retryable_request , unknown_error , 0 , 503 , retryable_client )
158+ _assert_retryable (retryable_request , unknown_error , 0 , 504 , retryable_client )
159+ _assert_retryable (retryable_request , internal_error , 0 , 500 , retryable_client )
160+ _assert_retryable (retryable_request , SE ("Throttling" ), 0 , 400 , retryable_client )
161+ _assert_retryable (retryable_request , SE ("ServiceUnavailable" ), 0 , 503 , retryable_client )
162+ _assert_not_retryable (retryable_request , invalid_param_excpetion , 0 , 400 , retryable_client )
163+ _assert_not_retryable (retryable_request , timeout_exception , 3 , 500 , retryable_client )
164+ _assert_not_retryable (retryable_request , SE ("InvalidAccessKeyId.NotFound" ), 0 , 404 , retryable_client )
165+
166+ acs_request = DescribeInstanceHistoryEventsRequest ()
167+ request1 = client ._get_new_style_request (acs_request )
168+
169+ config = self .client ._get_new_style_config (acs_request )
170+ client1 = self .client ._get_new_style_client (acs_request , config )
171+ _assert_retryable (request1 , SE ("ServiceUnavailable" ), 0 , 503 , client1 )
172+
173+ acs_request = DescribeDisksRequest ()
174+ request2 = client ._get_new_style_request (acs_request )
175+
176+ config = self .client ._get_new_style_config (acs_request )
177+ client2 = self .client ._get_new_style_client (acs_request , config )
178+ _assert_retryable (request2 , SE ("ServiceUnavailable" ), 0 , 503 , client2 )
179+ # no_retry
180+ acs_request = AttachDiskRequest ()
181+ no_retry_request = client ._get_new_style_request (acs_request )
182+ config = self .client ._get_new_style_config (acs_request )
183+ no_retry_client = self .client ._get_new_style_client (acs_request , config )
184+
185+ _assert_not_retryable (no_retry_request , timeout_exception , 0 , 500 , no_retry_client )
186+ _assert_not_retryable (no_retry_request , unknown_error , 0 , 504 , no_retry_client )
187+ _assert_not_retryable (no_retry_request , invalid_param_excpetion , 0 , 400 , no_retry_client )
188+
189+ # _assert_retryable_with_client_token(CreateInstanceRequest())
190+ # _assert_retryable_with_client_token(CreateDiskRequest())
191+ # _assert_retryable_with_client_token(RunInstancesRequest())
192+ # _assert_not_retryable_with_client_token(AttachDiskRequest())
193+ # _assert_not_retryable_with_client_token(DescribeInstancesRequest())
111194
112195 def test_normal_backoff (self ):
113196 client = AcsClient (self .access_key_id ,
@@ -134,4 +217,52 @@ def record_sleep(delay):
134217 _test_compute_delay )
135218
136219 def test_throttled_backoff (self ):
137- pass
220+ # mock ServerErrorHandler的结果
221+ def _handle_response (context ):
222+ context .exception = ServerException ("Throttling" , "some error" )
223+ client = AcsClient (self .access_key_id ,
224+ self .access_key_secret ,
225+ self .region_id ,
226+ max_retry_time = 10 )
227+ acs_request = DescribeInstancesRequest ()
228+ api_request = client ._get_new_style_request (acs_request )
229+ config = client ._get_new_style_config (acs_request )
230+ new_style_client = client ._get_new_style_client (acs_request , config )
231+ globals ()["_test_compute_delay" ] = []
232+ def record_sleep (delay ):
233+ global _test_compute_delay
234+ _test_compute_delay .append (delay )
235+
236+ from alibabacloud .handlers .prepare_handler import PrepareHandler
237+ from alibabacloud .handlers .credentials_handler import CredentialsHandler
238+ from alibabacloud .handlers .signer_handler import SignerHandler
239+ from alibabacloud .handlers .timeout_config_reader import TimeoutConfigReader
240+ from alibabacloud .handlers .endpoint_handler import EndpointHandler
241+ from alibabacloud .handlers .log_handler import LogHandler
242+ from alibabacloud .handlers .retry_handler import RetryHandler
243+ from alibabacloud .handlers .server_error_handler import ServerErrorHandler
244+ from alibabacloud .handlers .http_handler import HttpHandler
245+
246+ DEFAULT_HANDLERS = [
247+ PrepareHandler (),
248+ CredentialsHandler (),
249+ SignerHandler (),
250+ TimeoutConfigReader (),
251+ LogHandler (),
252+ EndpointHandler (),
253+ RetryHandler (),
254+ ServerErrorHandler (),
255+ HttpHandler (),
256+ ]
257+
258+ new_style_client .handlers = DEFAULT_HANDLERS
259+
260+ with patch .object (time , "sleep" , wraps = record_sleep ) as monkey :
261+ with patch .object (ServerErrorHandler , "handle_response" , wraps = _handle_response ):
262+ try :
263+ new_style_client ._handle_request (api_request )
264+ assert False
265+ except ServerException as e :
266+ self .assertEqual ("Throttling" , e .get_error_code ())
267+ self .assertEqual (10 , monkey .call_count )
268+ self .assertEqual (10 , len (_test_compute_delay ))
0 commit comments