Skip to content

Commit 4a5322f

Browse files
author
wallisyan
committed
modify retry timeout test
1 parent 4ad4b61 commit 4a5322f

File tree

4 files changed

+211
-11
lines changed

4 files changed

+211
-11
lines changed

aliyun-python-sdk-core/alibabacloud/client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from alibabacloud.handlers.http_handler import HttpHandler
2727
from alibabacloud.request import HTTPRequest
2828
import alibabacloud.retry.retry_policy as retry_policy
29-
29+
from alibabacloud.utils.ini_helper import load_config
3030

3131
DEFAULT_HANDLERS = [
3232
PrepareHandler(),
@@ -115,7 +115,6 @@ def read_from_env(self):
115115
def read_from_profile(self):
116116
profile = {}
117117
# TODO read from profile
118-
from alibabacloud.utils.ini_helper import load_config
119118
if self.config_file is None:
120119
# 没有指定file
121120
if self.ENV_NAME_FOR_CONFIG_FILE in os.environ:

aliyun-python-sdk-core/alibabacloud/handlers/timeout_config_reader.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,6 @@ def handle_request(self, context):
2727
context.http_request.timeout = (self._connection_timeout(context.config),
2828
self._read_timeout(context))
2929

30-
def handle_response(self, context):
31-
# context 实际是request
32-
pass
33-
3430
@staticmethod
3531
def _connection_timeout(config):
3632
return config.connection_timeout or DEFAULT_CONNECTION_TIMEOUT
@@ -46,4 +42,4 @@ def _read_timeout(context):
4642
path = '"{0}"."{1}"."{2}"'.format(product_code.lower(), product_version,
4743
action_name)
4844
file_read_timeout = jmespath.search(path, _api_timeout_config_data)
49-
return file_read_timeout or context.config.read_timeout or DEFAULT_READ_TIMEOUT
45+
return context.config.read_timeout or file_read_timeout or DEFAULT_READ_TIMEOUT

python-function-test-alibabacloud/retry_test.py

Lines changed: 134 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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))

python-function-test-alibabacloud/timeout_test.py

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,82 @@
2727
from aliyunsdkcore.acs_exception.exceptions import ClientException
2828
from aliyunsdkcore.acs_exception.exceptions import ServerException
2929

30+
from alibabacloud.handlers.timeout_config_reader import TimeoutConfigReader
31+
3032

3133
class TimeoutTest(SDKTestBase):
3234

35+
def _patch_context(self, client, acs_request):
36+
api_request = client._get_new_style_request(acs_request)
37+
config = client._get_new_style_config(acs_request)
38+
new_style_client = client._get_new_style_client(acs_request, config)
39+
40+
from alibabacloud.handlers import RequestContext
41+
from alibabacloud.request import HTTPRequest
42+
43+
context = RequestContext(api_request=api_request, http_request=HTTPRequest(),
44+
config=new_style_client.config, client=new_style_client,
45+
retry_flag=False)
46+
return context
47+
48+
def test_default_timeout(self):
49+
client = AcsClient(self.access_key_id,
50+
self.access_key_secret,
51+
self.region_id,
52+
auto_retry=False)
53+
acs_request = DescribeInstancesRequest()
54+
55+
context = self._patch_context(client, acs_request)
56+
57+
timeout_handler = TimeoutConfigReader()
58+
timeout_handler.handle_request(context)
59+
60+
self.assertEqual((5, 10), context.http_request.timeout)
61+
3362
def test_client_customized_timeout(self):
34-
pass
63+
client = AcsClient(self.access_key_id, self.access_key_secret, self.region_id,
64+
timeout=7, connect_timeout=8, auto_retry=False)
65+
acs_request = DescribeInstancesRequest()
66+
67+
context = self._patch_context(client, acs_request)
68+
69+
timeout_handler = TimeoutConfigReader()
70+
timeout_handler.handle_request(context)
71+
72+
self.assertEqual((8, 7), context.http_request.timeout)
73+
74+
def test_read_timeout_priority(self):
75+
# read config
76+
client = AcsClient(self.access_key_id, self.access_key_secret, self.region_id,
77+
timeout=20, auto_retry=False)
78+
acs_request = RunInstancesRequest()
79+
context = self._patch_context(client, acs_request)
80+
timeout_handler = TimeoutConfigReader()
81+
timeout_handler.handle_request(context)
82+
self.assertEqual((5, 20), context.http_request.timeout)
83+
# read file
84+
client = AcsClient(self.access_key_id, self.access_key_secret, self.region_id,
85+
auto_retry=False)
86+
acs_request = RunInstancesRequest()
87+
context = self._patch_context(client, acs_request)
88+
timeout_handler = TimeoutConfigReader()
89+
timeout_handler.handle_request(context)
90+
self.assertEqual((5, 86), context.http_request.timeout)
91+
92+
def test_connect_timeout_priority(self):
93+
# read config
94+
client = AcsClient(self.access_key_id, self.access_key_secret, self.region_id,
95+
connect_timeout=20, auto_retry=False)
96+
acs_request = RunInstancesRequest()
97+
context = self._patch_context(client, acs_request)
98+
timeout_handler = TimeoutConfigReader()
99+
timeout_handler.handle_request(context)
100+
self.assertEqual((20, 86), context.http_request.timeout)
101+
# read file
102+
client = AcsClient(self.access_key_id, self.access_key_secret, self.region_id,
103+
auto_retry=False)
104+
acs_request = RunInstancesRequest()
105+
context = self._patch_context(client, acs_request)
106+
timeout_handler = TimeoutConfigReader()
107+
timeout_handler.handle_request(context)
108+
self.assertEqual((5, 86), context.http_request.timeout)

0 commit comments

Comments
 (0)