-
Notifications
You must be signed in to change notification settings - Fork 96
/
Copy pathretryer_spec.rb
109 lines (92 loc) · 2.48 KB
/
retryer_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
require 'temporal/client/retryer'
require 'temporal/metadata'
require 'time'
describe Temporal::Client::Retryer do
before do
# Skip sleeps during retries to speed up the test.
allow(Temporal::Client::Retryer).to receive(:sleep).and_return(nil)
end
it 'backs off and stops retrying eventually' do
sleep_amounts = []
expect(described_class).to receive(:sleep).exactly(10).times do |amount|
sleep_amounts << amount
end
expect do
described_class.with_retries(times: 10) do
raise 'try again'
end
end.to raise_error(StandardError)
# Test backoff
initial_interval = 0.2
backoff = 1.2
sleep_amounts.each_with_index do |sleep_amount, i|
expect(sleep_amount).to be_within(0.01).of(initial_interval * (backoff**i))
end
end
it 'caps out amount slept' do
expect(described_class).to receive(:sleep).at_least(10).times do |amount|
expect(amount).to be <= 6.0 # At most 6 seconds between retries.
end
expect do
described_class.with_retries do
raise 'try again'
end
end.to raise_error(StandardError)
end
it 'can succeed' do
result = described_class.with_retries do
5
end
expect(result).to eq(5)
end
it 'can succeed after retries' do
i = 0
result = described_class.with_retries do
if i < 2
i += 1
raise "keep trying"
else
6
end
end
expect(result).to eq(6)
end
it 'executes the on_retry callback' do
i = 0
on_retry_calls = 0
retries = 2
on_retry = Proc.new {
on_retry_calls += 1
}
result = described_class.with_retries(on_retry: on_retry) do
if i < retries
i += 1
raise "keep trying"
else
6
end
end
expect(on_retry_calls).to equal(retries)
end
described_class::DO_NOT_RETRY_ERRORS.each do |error_class|
context "when #{error_class} is raised" do
let(:error) { error_class.new('nope') }
let(:on_retry) { Proc.new {} }
it 'does not retry' do
calls = 0
expect do
described_class.with_retries do
calls += 1
raise error
end
end.to raise_error(error)
expect(calls).to eq(1)
end
it 'does not call on_retry' do
allow(on_retry).to receive(:call).and_call_original
described_class.with_retries(on_retry: on_retry) { raise error } rescue nil
expect(on_retry).not_to have_received(:call)
end
end
end
end