Skip to content

Commit c591160

Browse files
authored
Add extra tests for retry behavior (#3131)
1 parent 0fc4c41 commit c591160

File tree

2 files changed

+77
-10
lines changed

2 files changed

+77
-10
lines changed

gems/aws-sdk-core/spec/aws/plugins/retry_errors_spec.rb

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,62 @@ module Plugins
272272
handle_with_retry(test_case_def)
273273
end
274274

275+
it 'fails due to retry quota bucket exhaustion' do
276+
config.max_attempts = 5
277+
config.retry_quota.instance_variable_set(:@available_capacity, 10)
278+
279+
test_case_def = [
280+
{
281+
response: { status_code: 500, error: service_error },
282+
expect: { available_capacity: 5, retries: 1, delay: 1 }
283+
},
284+
{
285+
response: { status_code: 502, error: service_error },
286+
expect: { available_capacity: 0, retries: 2, delay: 2 }
287+
},
288+
{
289+
response: { status_code: 503, error: service_error },
290+
expect: { available_capacity: 0, retries: 2 }
291+
}
292+
]
293+
294+
handle_with_retry(test_case_def)
295+
end
296+
297+
it 'recovers after successful responses' do
298+
config.max_attempts = 5
299+
config.retry_quota.instance_variable_set(:@available_capacity, 15)
300+
301+
test_case_def = [
302+
{
303+
response: { status_code: 500, error: service_error },
304+
expect: { available_capacity: 10, retries: 1, delay: 1 }
305+
},
306+
{
307+
response: { status_code: 502, error: service_error },
308+
expect: { available_capacity: 5, retries: 2, delay: 2 }
309+
},
310+
{
311+
response: { status_code: 200, error: nil },
312+
expect: { available_capacity: 10, retries: 2 }
313+
}
314+
]
315+
handle_with_retry(test_case_def)
316+
317+
test_case_post_success = [
318+
{
319+
response: { status_code: 500, error: service_error },
320+
expect: { available_capacity: 5, retries: 1, delay: 1 }
321+
},
322+
{
323+
response: { status_code: 200, error: nil },
324+
expect: { available_capacity: 10, retries: 1 }
325+
}
326+
]
327+
reset_request
328+
handle_with_retry(test_case_post_success)
329+
end
330+
275331
it 'corrects and retries clock skew errors' do
276332
clock_skew_error = RetryErrorsSvc::Errors::RequestTimeTooSkewed
277333
.new(nil, nil)

gems/aws-sdk-core/spec/retry_errors_helper.rb

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,10 @@ def handle(send_handler = nil, &block)
1717
# expect: delay, available_capacity, retries, calculated_rate,
1818
# measured_tx_rate, fill_rate
1919
def handle_with_retry(test_cases)
20-
# Apply delay expectations first
21-
test_cases.each do |test_case|
22-
if test_case[:expect][:delay]
23-
expect(Kernel).to receive(:sleep).with(test_case[:expect][:delay])
24-
end
25-
end
26-
2720
i = 0
2821
handle do |_context|
29-
apply_expectations(test_cases[i - 1]) if i > 0
22+
apply_delay(test_cases[i])
23+
apply_expectations(test_cases[i - 1]) if i.positive?
3024

3125
# Setup the next response
3226
setup_next_response(test_cases[i])
@@ -38,15 +32,30 @@ def handle_with_retry(test_cases)
3832

3933
expect(i).to(
4034
eq(test_cases.size),
41-
"Wrong number of retries. Handler was called #{i} times but "\
35+
"Wrong number of retries. Handler was called #{i} times but " \
4236
"#{test_cases.size} test cases were defined."
4337
)
4438

4539
# Handle has finished called. Apply final expectations.
4640
apply_expectations(test_cases[i - 1])
4741
end
4842

49-
# apply the expectations from a test case
43+
# Reset the request context for a subsequent call
44+
def reset_request
45+
resp.context.retries = 0
46+
resp.context.metadata[:retries] = {}
47+
end
48+
49+
# apply a delay to the current test case
50+
# See handle_with_retry for test case definition
51+
def apply_delay(test_case)
52+
expected = test_case[:expect]
53+
return unless expected[:delay]
54+
55+
expect(Kernel).to receive(:sleep).with(expected[:delay])
56+
end
57+
58+
# apply the expectations from a previous test case
5059
# See handle_with_retry for test case definition
5160
def apply_expectations(test_case)
5261
expected = test_case[:expect]
@@ -95,6 +104,8 @@ def apply_expectations(test_case)
95104
end
96105
end
97106

107+
# setup the next response for the handler
108+
# See handle_with_retry for test case definition
98109
def setup_next_response(test_case)
99110
response = test_case[:response]
100111
resp.context.http_response.status_code = response[:status_code]

0 commit comments

Comments
 (0)