lhc 12.1.3 → 13.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,7 +12,7 @@ describe LHC do
12
12
 
13
13
  def before_request
14
14
  if @@cached
15
- return LHC::Response.new(Typhoeus::Response.new(response_body: 'Im served from local cache'), nil)
15
+ return LHC::Response.new(Typhoeus::Response.new(response_code: 200, return_code: :ok, response_body: 'Im served from local cache'), nil)
16
16
  end
17
17
  end
18
18
  end
@@ -22,7 +22,7 @@ describe LHC do
22
22
 
23
23
  def before_request
24
24
  if request.response.nil?
25
- return LHC::Response.new(Typhoeus::Response.new(response_body: 'Im served from remote cache'), nil)
25
+ return LHC::Response.new(Typhoeus::Response.new(response_code: 200, return_code: :ok, response_body: 'Im served from remote cache'), nil)
26
26
  end
27
27
  end
28
28
  end
@@ -8,7 +8,7 @@ describe LHC do
8
8
  class CacheInterceptor < LHC::Interceptor
9
9
 
10
10
  def before_request
11
- LHC::Response.new(Typhoeus::Response.new(response_body: 'Im served from cache'), nil)
11
+ LHC::Response.new(Typhoeus::Response.new(response_code: 200, return_code: :ok, response_body: 'Im served from cache'), nil)
12
12
  end
13
13
  end
14
14
  LHC.configure { |c| c.interceptors = [CacheInterceptor] }
@@ -23,7 +23,7 @@ describe LHC do
23
23
  before(:each) do
24
24
  class AnotherInterceptor < LHC::Interceptor
25
25
  def before_request
26
- LHC::Response.new(Typhoeus::Response.new({}), nil)
26
+ LHC::Response.new(Typhoeus::Response.new(response_code: 200, return_code: :ok), nil)
27
27
  end
28
28
  end
29
29
  end
@@ -3,66 +3,64 @@
3
3
  require 'rails_helper'
4
4
 
5
5
  describe LHC::Throttle do
6
+ let(:options_break) { false }
7
+ let(:options_expires) { { header: 'reset' } }
8
+ let(:options_limit) { { header: 'limit' } }
9
+ let(:options_remaining) { { header: 'remaining' } }
6
10
  let(:provider) { 'local.ch' }
7
- let(:limit) { 10000 }
8
- let(:remaining) { 1900 }
11
+ let(:quota_limit) { 10_000 }
12
+ let(:quota_remaining) { 1900 }
13
+ let(:quota_reset) { (Time.zone.now + 1.hour).to_i }
9
14
  let(:options) do
10
15
  {
11
16
  throttle: {
12
17
  provider: provider,
13
18
  track: true,
14
- limit: limit_options,
15
- remaining: { header: 'Rate-Limit-Remaining' },
16
- expires: { header: 'Rate-Limit-Reset' },
17
- break: break_option
19
+ limit: options_limit,
20
+ remaining: options_remaining,
21
+ expires: options_expires,
22
+ break: options_break
18
23
  }
19
24
  }
20
25
  end
21
- let(:limit_options) { { header: 'Rate-Limit-Limit' } }
22
- let(:break_option) { false }
23
- let(:expires_in) { (Time.zone.now + 1.hour).to_i }
24
26
 
25
27
  before(:each) do
26
28
  LHC::Throttle.track = nil
27
29
  LHC.config.interceptors = [LHC::Throttle]
28
30
 
29
- stub_request(:get, 'http://local.ch')
30
- .to_return(
31
- headers: {
32
- 'Rate-Limit-Limit' => limit,
33
- 'Rate-Limit-Remaining' => remaining,
34
- 'Rate-Limit-Reset' => expires_in
35
- }
36
- )
31
+ stub_request(:get, 'http://local.ch').to_return(
32
+ headers: { 'limit' => quota_limit, 'remaining' => quota_remaining, 'reset' => quota_reset }
33
+ )
37
34
  end
38
35
 
39
36
  it 'tracks the request limits based on response data' do
40
37
  LHC.get('http://local.ch', options)
41
- expect(LHC::Throttle.track[provider][:limit]).to eq limit
42
- expect(LHC::Throttle.track[provider][:remaining]).to eq remaining
38
+ expect(LHC::Throttle.track[provider][:limit]).to eq quota_limit
39
+ expect(LHC::Throttle.track[provider][:remaining]).to eq quota_remaining
43
40
  end
44
41
 
45
42
  context 'fix predefined integer for limit' do
46
- let(:limit_options) { 1000 }
43
+ let(:options_limit) { 1000 }
47
44
 
48
45
  it 'tracks the limit based on initialy provided data' do
49
46
  LHC.get('http://local.ch', options)
50
- expect(LHC::Throttle.track[provider][:limit]).to eq limit_options
47
+ expect(LHC::Throttle.track[provider][:limit]).to eq options_limit
51
48
  end
52
49
  end
53
50
 
54
51
  context 'breaks' do
55
- let(:break_option) { '80%' }
52
+ let(:options_break) { '80%' }
56
53
 
57
54
  it 'hit the breaks if throttling quota is reached' do
58
55
  LHC.get('http://local.ch', options)
59
- expect(-> {
60
- LHC.get('http://local.ch', options)
61
- }).to raise_error(LHC::Throttle::OutOfQuota, 'Reached predefined quota for local.ch')
56
+ expect { LHC.get('http://local.ch', options) }.to raise_error(
57
+ LHC::Throttle::OutOfQuota,
58
+ 'Reached predefined quota for local.ch'
59
+ )
62
60
  end
63
61
 
64
62
  context 'still within quota' do
65
- let(:break_option) { '90%' }
63
+ let(:options_break) { '90%' }
66
64
 
67
65
  it 'does not hit the breaks' do
68
66
  LHC.get('http://local.ch', options)
@@ -72,17 +70,14 @@ describe LHC::Throttle do
72
70
  end
73
71
 
74
72
  context 'no response headers' do
75
- before do
76
- stub_request(:get, 'http://local.ch')
77
- .to_return(status: 200)
78
- end
73
+ before { stub_request(:get, 'http://local.ch').to_return(status: 200) }
79
74
 
80
75
  it 'does not raise an exception' do
81
76
  LHC.get('http://local.ch', options)
82
77
  end
83
78
 
84
79
  context 'no remaining tracked, but break enabled' do
85
- let(:break_option) { '90%' }
80
+ let(:options_break) { '90%' }
86
81
 
87
82
  it 'does not fail if a remaining was not tracked yet' do
88
83
  LHC.get('http://local.ch', options)
@@ -92,15 +87,150 @@ describe LHC::Throttle do
92
87
  end
93
88
 
94
89
  context 'expires' do
95
- let(:break_option) { '80%' }
90
+ let(:options_break) { '80%' }
96
91
 
97
92
  it 'attempts another request if the quota expired' do
98
93
  LHC.get('http://local.ch', options)
99
- expect(-> {
100
- LHC.get('http://local.ch', options)
101
- }).to raise_error(LHC::Throttle::OutOfQuota, 'Reached predefined quota for local.ch')
94
+ expect { LHC.get('http://local.ch', options) }.to raise_error(
95
+ LHC::Throttle::OutOfQuota,
96
+ 'Reached predefined quota for local.ch'
97
+ )
102
98
  Timecop.travel(Time.zone.now + 2.hours)
103
99
  LHC.get('http://local.ch', options)
104
100
  end
105
101
  end
102
+
103
+ describe 'configuration values as Procs' do
104
+ describe 'calculate "limit" in proc' do
105
+ let(:options_limit) do
106
+ ->(*) { 10_000 }
107
+ end
108
+
109
+ before(:each) do
110
+ LHC.get('http://local.ch', options)
111
+ end
112
+
113
+ context 'breaks' do
114
+ let(:options_break) { '80%' }
115
+
116
+ it 'hit the breaks if throttling quota is reached' do
117
+ expect { LHC.get('http://local.ch', options) }.to raise_error(
118
+ LHC::Throttle::OutOfQuota,
119
+ 'Reached predefined quota for local.ch'
120
+ )
121
+ end
122
+
123
+ context 'still within quota' do
124
+ let(:options_break) { '90%' }
125
+
126
+ it 'does not hit the breaks' do
127
+ LHC.get('http://local.ch', options)
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ describe 'calculate "remaining" in proc' do
134
+ let(:quota_current) { 8100 }
135
+ let(:options_remaining) do
136
+ ->(response) { (response.headers['limit']).to_i - (response.headers['current']).to_i }
137
+ end
138
+
139
+ before(:each) do
140
+ stub_request(:get, 'http://local.ch').to_return(
141
+ headers: { 'limit' => quota_limit, 'current' => quota_current, 'reset' => quota_reset }
142
+ )
143
+ LHC.get('http://local.ch', options)
144
+ end
145
+
146
+ context 'breaks' do
147
+ let(:options_break) { '80%' }
148
+
149
+ it 'hit the breaks if throttling quota is reached' do
150
+ expect { LHC.get('http://local.ch', options) }.to raise_error(
151
+ LHC::Throttle::OutOfQuota,
152
+ 'Reached predefined quota for local.ch'
153
+ )
154
+ end
155
+
156
+ context 'still within quota' do
157
+ let(:options_break) { '90%' }
158
+
159
+ it 'does not hit the breaks' do
160
+ LHC.get('http://local.ch', options)
161
+ end
162
+ end
163
+ end
164
+ end
165
+
166
+ describe 'calculate "reset" in proc' do
167
+ let(:options_expires) { ->(*) { Time.zone.now + 1.second } }
168
+
169
+ before(:each) do
170
+ stub_request(:get, 'http://local.ch').to_return(
171
+ headers: { 'limit' => quota_limit, 'remaining' => quota_remaining }
172
+ )
173
+ LHC.get('http://local.ch', options)
174
+ end
175
+
176
+ context 'breaks' do
177
+ let(:options_break) { '80%' }
178
+
179
+ it 'hit the breaks if throttling quota is reached' do
180
+ expect { LHC.get('http://local.ch', options) }.to raise_error(
181
+ LHC::Throttle::OutOfQuota,
182
+ 'Reached predefined quota for local.ch'
183
+ )
184
+ end
185
+
186
+ context 'still within quota' do
187
+ let(:options_break) { '90%' }
188
+
189
+ it 'does not hit the breaks' do
190
+ LHC.get('http://local.ch', options)
191
+ end
192
+ end
193
+ end
194
+ end
195
+ end
196
+
197
+ describe 'parsing reset time given in prose' do
198
+ let(:quota_reset) { (Time.zone.now + 1.day).strftime('%A, %B %d, %Y 12:00:00 AM GMT').to_s }
199
+
200
+ before { LHC.get('http://local.ch', options) }
201
+
202
+ context 'breaks' do
203
+ let(:options_break) { '80%' }
204
+
205
+ it 'hit the breaks if throttling quota is reached' do
206
+ expect { LHC.get('http://local.ch', options) }.to raise_error(
207
+ LHC::Throttle::OutOfQuota,
208
+ 'Reached predefined quota for local.ch'
209
+ )
210
+ end
211
+
212
+ context 'still within quota' do
213
+ let(:options_break) { '90%' }
214
+
215
+ it 'does not hit the breaks' do
216
+ LHC.get('http://local.ch', options)
217
+ end
218
+ end
219
+ end
220
+ end
221
+
222
+ context 'when value is empty' do
223
+ let(:quota_reset) { nil }
224
+
225
+ before do
226
+ stub_request(:get, 'http://local.ch').to_return(
227
+ headers: { 'limit' => quota_limit, 'remaining' => quota_remaining }
228
+ )
229
+ LHC.get('http://local.ch', options)
230
+ end
231
+
232
+ it 'still runs' do
233
+ LHC.get('http://local.ch', options)
234
+ end
235
+ end
106
236
  end
@@ -3,6 +3,7 @@
3
3
  require 'pry'
4
4
  require 'webmock/rspec'
5
5
  require 'lhc'
6
+ require 'lhc/rspec'
6
7
  require 'timecop'
7
8
 
8
9
  Dir[File.join(__dir__, "support/**/*.rb")].each { |f| require f }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lhc
3
3
  version: !ruby/object:Gem::Version
4
- version: 12.1.3
4
+ version: 13.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - https://github.com/local-ch/lhc/contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-08-20 00:00:00.000000000 Z
11
+ date: 2020-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '4.2'
19
+ version: '5.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '4.2'
26
+ version: '5.2'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: addressable
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +100,28 @@ dependencies:
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: '4.2'
103
+ version: '5.2'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: '4.2'
110
+ version: '5.2'
111
+ - !ruby/object:Gem::Dependency
112
+ name: redis
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: rspec-rails
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -193,7 +207,6 @@ files:
193
207
  - ".rubocop.yml"
194
208
  - ".ruby-version"
195
209
  - Gemfile
196
- - Gemfile.activesupport4
197
210
  - Gemfile.activesupport5
198
211
  - Gemfile.activesupport6
199
212
  - LICENSE
@@ -203,7 +216,6 @@ files:
203
216
  - cider-ci/bin/bundle
204
217
  - cider-ci/bin/ruby_install
205
218
  - cider-ci/bin/ruby_version
206
- - cider-ci/jobs/rspec-activesupport-4.yml
207
219
  - cider-ci/jobs/rspec-activesupport-5.yml
208
220
  - cider-ci/jobs/rspec-activesupport-6.yml
209
221
  - cider-ci/jobs/rubocop.yml
@@ -335,6 +347,7 @@ files:
335
347
  - spec/interceptors/caching/hydra_spec.rb
336
348
  - spec/interceptors/caching/main_spec.rb
337
349
  - spec/interceptors/caching/methods_spec.rb
350
+ - spec/interceptors/caching/multilevel_cache_spec.rb
338
351
  - spec/interceptors/caching/options_spec.rb
339
352
  - spec/interceptors/caching/parameters_spec.rb
340
353
  - spec/interceptors/caching/response_status_spec.rb
@@ -344,6 +357,7 @@ files:
344
357
  - spec/interceptors/define_spec.rb
345
358
  - spec/interceptors/dup_spec.rb
346
359
  - spec/interceptors/logging/main_spec.rb
360
+ - spec/interceptors/monitoring/caching_spec.rb
347
361
  - spec/interceptors/monitoring/main_spec.rb
348
362
  - spec/interceptors/prometheus_spec.rb
349
363
  - spec/interceptors/response_competition_spec.rb
@@ -488,6 +502,7 @@ test_files:
488
502
  - spec/interceptors/caching/hydra_spec.rb
489
503
  - spec/interceptors/caching/main_spec.rb
490
504
  - spec/interceptors/caching/methods_spec.rb
505
+ - spec/interceptors/caching/multilevel_cache_spec.rb
491
506
  - spec/interceptors/caching/options_spec.rb
492
507
  - spec/interceptors/caching/parameters_spec.rb
493
508
  - spec/interceptors/caching/response_status_spec.rb
@@ -497,6 +512,7 @@ test_files:
497
512
  - spec/interceptors/define_spec.rb
498
513
  - spec/interceptors/dup_spec.rb
499
514
  - spec/interceptors/logging/main_spec.rb
515
+ - spec/interceptors/monitoring/caching_spec.rb
500
516
  - spec/interceptors/monitoring/main_spec.rb
501
517
  - spec/interceptors/prometheus_spec.rb
502
518
  - spec/interceptors/response_competition_spec.rb
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org/'
2
-
3
- gemspec
4
- gem 'activesupport', '~> 4.2.11'
@@ -1,28 +0,0 @@
1
- rspec-active-support-v4:
2
- name: 'rspec with ActiveSupport v4'
3
-
4
- run_when:
5
- 'some HEAD has been updated':
6
- type: branch
7
- include_match: ^.*$
8
-
9
- context:
10
-
11
- script_defaults:
12
- template_environment_variables: true
13
-
14
- task_defaults:
15
- environment_variables:
16
- ACTIVESUPPORT: '4'
17
- BUNDLER: '_1.17.3_'
18
-
19
- max_trials: 2
20
- dispatch_storm_delay_duration: 1 Seconds
21
- include:
22
- - cider-ci/task_components/ruby.yml
23
- - cider-ci/task_components/bundle.yml
24
- - cider-ci/task_components/rspec.yml
25
-
26
- tasks:
27
- all-rspec:
28
- name: All rspec tests, using ActiveSupport v4