/
timeout_performer_spec.rb
175 lines (139 loc) · 5.38 KB
/
timeout_performer_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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
require 'spec_helper'
describe StaleIfSlow::TimeoutPerformer do
describe "when generating performers" do
it "should generate a new instance of TimeoutPerformer" do
performer = StaleIfSlow::TimeoutPerformer.generate({})
performer.should be_an_instance_of StaleIfSlow::TimeoutPerformer
end
end
describe "when initializing" do
let :reference do
OpenStruct.new(method: 1)
end
let :original_impl do
lambda {}
end
subject do
StaleIfSlow::TimeoutPerformer.new reference: reference, method: :method, &original_impl
end
it "should keep a copy of reference" do
subject.reference.should eql reference
end
it "should keep a copy of method" do
subject.method.should eql :method
end
it "should keep a copy of the original implementation of method" do
subject.block.should eql original_impl
end
it "should create a new instance of KeyGenerator" do
subject.key_generator.should be_an_instance_of StaleIfSlow::KeyGenerator
end
describe "and retrieving options from StaleIfSlow.config" do
before do
StaleIfSlow.config.stub(:[])
end
after do
StaleIfSlow::TimeoutPerformer.new({}, &original_impl)
end
it "should retrieve cache_store configuration" do
StaleIfSlow.config.should_receive(:[]).with(:cache_store)
end
it "should retrieve timeout configuration" do
StaleIfSlow.config.should_receive(:[]).with(:timeout)
end
it "should retrieve content_timeout configuration" do
StaleIfSlow.config.should_receive(:[]).with(:content_timeout)
end
it "should retrieve stale_content_timeout configuration" do
StaleIfSlow.config.should_receive(:[]).with(:stale_content_timeout)
end
end
describe "and overriding some defaults" do
subject do
StaleIfSlow::TimeoutPerformer.new({
reference: reference,
method: :method,
opts: {timeout: 0.1, content_timeout: 30.seconds, stale_content_timeout: 5.minutes}
}, &original_impl)
end
it "should override timeout value" do
subject.timeout.should eql 0.1
end
it "should override content timeout value" do
subject.content_timeout.to_i.should eql 30.seconds.to_i
end
it "should override stale content timeout" do
subject.stale_content_timeout.to_i.should eql 5.minutes.to_i
end
end
end
describe "when execute method call" do
class Example4
include StaleIfSlow::API
stale_if_slow :get, :error
def get; 7 end
def error; raise "error"; end
end
let! :performer do
StaleIfSlow::TimeoutPerformer.new(reference: reference, method: :get) do
reference.send(original_method)
end
end
let :reference do
Example4.new
end
let :original_method do
"#{StaleIfSlow::API::PREFIX}get"
end
before do
StaleIfSlow::TimeoutPerformer.stub(:generate).and_return(performer)
StaleIfSlow.configure { logger_level Logger::ERROR }
reference.initialize_stale_if_slow
end
it "should return cached content if cache is still hot" do
reference.get.should eql 7
cache_key = performer.cache_key
performer.send(:read_referer, cache_key).should_not be_nil
performer.send(:read, cache_key).should_not be_nil
performer.cache_store.should_not_receive(:write)
reference.get.should eql 7
end
describe "and cache already expired" do
before do
reference.get
referer_key = performer.send(:slow_cache_referer, performer.cache_key)
performer.cache_store.delete(referer_key).should be_true
end
describe "and have cached content" do
before do
performer.cache_store.read(performer.cache_key).should_not be_nil
end
it "should wait the configured timeout and refresh the cache" do
Timeout.should_receive(:timeout).with(performer.timeout, StaleIfSlow::Error).and_return(7)
performer.should_receive(:write_content).with(performer.cache_key, 7)
reference.get
end
it "should return stale content if a StaleIfSlow::Error occur" do
performer.stub(:read_referer).and_return(nil)
performer.send(:write_content, performer.cache_key, "stale") # Overrides the stale value to guarantee that a cached
# value was received
Timeout.should_receive(:timeout).with(performer.timeout, StaleIfSlow::Error).and_raise(StaleIfSlow::Error)
performer.should_not_receive(:write_content)
reference.should_not_receive(original_method)
reference.get.should eql "stale"
end
it "should propagate the exception in case of error" do
reference.should_not_receive(original_method)
reference.stub(original_method).and_raise(StandardError.new("erro"))
expect { reference.get }.to raise_error
end
end
describe "and does not have cached content" do
it "should complete the call" do
reference.should_receive(original_method)
reference.get
end
end
end
end
end