right_support 2.11.3 → 2.12.1
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.
- checksums.yaml +4 -4
- data/Rakefile +4 -0
- data/VERSION +1 -1
- data/lib/right_support/notifiers/airbrake.rb +194 -0
- data/lib/right_support/notifiers/base.rb +73 -0
- data/lib/right_support/notifiers/blacklisters/base.rb +48 -0
- data/lib/right_support/notifiers/blacklisters/canonical.rb +60 -0
- data/lib/right_support/notifiers/blacklisters/regular_expression.rb +86 -0
- data/{features/support/file_utils_bundler_mixin.rb → lib/right_support/notifiers/blacklisters/simple.rb} +21 -20
- data/lib/right_support/notifiers/blacklisters/snake_case.rb +60 -0
- data/lib/right_support/notifiers/blacklisters/wildcard.rb +65 -0
- data/lib/right_support/notifiers/blacklisters.rb +34 -0
- data/lib/right_support/notifiers/logger.rb +94 -0
- data/lib/right_support/notifiers/notification.rb +57 -0
- data/lib/right_support/notifiers/utilities/backtrace_decoder.rb +234 -0
- data/lib/right_support/notifiers/utilities.rb +29 -0
- data/lib/right_support/notifiers.rb +32 -0
- data/lib/right_support/rack/request_logger.rb +13 -9
- data/lib/right_support.rb +1 -0
- data/right_support.gemspec +19 -70
- metadata +17 -69
- data/.coveralls.yml +0 -2
- data/.rspec +0 -3
- data/.simplecov +0 -6
- data/.travis.yml +0 -13
- data/Gemfile +0 -51
- data/Gemfile.lock +0 -153
- data/features/balancer_error_handling.feature +0 -34
- data/features/balancer_health_check.feature +0 -33
- data/features/hash_tools.feature +0 -27
- data/features/http_client_timeout.feature +0 -19
- data/features/serialization.feature +0 -113
- data/features/step_definitions/hash_tools_steps.rb +0 -41
- data/features/step_definitions/http_client_steps.rb +0 -27
- data/features/step_definitions/request_balancer_steps.rb +0 -93
- data/features/step_definitions/ruby_steps.rb +0 -176
- data/features/step_definitions/serialization_steps.rb +0 -133
- data/features/step_definitions/server_steps.rb +0 -134
- data/features/support/env.rb +0 -148
- data/right_support.rconf +0 -9
- data/spec/config/feature_set_spec.rb +0 -83
- data/spec/crypto/signed_hash_spec.rb +0 -73
- data/spec/data/hash_tools_spec.rb +0 -602
- data/spec/data/mash_spec.rb +0 -313
- data/spec/data/token_spec.rb +0 -21
- data/spec/data/uuid_spec.rb +0 -45
- data/spec/db/cassandra_model_part1_spec.rb +0 -84
- data/spec/db/cassandra_model_part2_spec.rb +0 -73
- data/spec/db/cassandra_model_spec.rb +0 -375
- data/spec/fixtures/encrypted_priv_rsa.pem +0 -30
- data/spec/fixtures/good_priv_dsa.pem +0 -12
- data/spec/fixtures/good_priv_rsa.pem +0 -15
- data/spec/fixtures/good_pub_dsa.ssh +0 -1
- data/spec/fixtures/good_pub_rsa.pem +0 -5
- data/spec/fixtures/good_pub_rsa.ssh +0 -1
- data/spec/log/exception_logger_spec.rb +0 -76
- data/spec/log/filter_logger_spec.rb +0 -66
- data/spec/log/mixin_spec.rb +0 -141
- data/spec/log/multiplexer_spec.rb +0 -54
- data/spec/log/null_logger_spec.rb +0 -36
- data/spec/log/step_level_logger_spec.rb +0 -49
- data/spec/log/system_logger_spec.rb +0 -172
- data/spec/net/address_helper_spec.rb +0 -57
- data/spec/net/dns_spec.rb +0 -187
- data/spec/net/http_client_spec.rb +0 -181
- data/spec/net/lb/health_check_spec.rb +0 -417
- data/spec/net/lb/round_robin_spec.rb +0 -15
- data/spec/net/lb/sticky_spec.rb +0 -92
- data/spec/net/request_balancer_spec.rb +0 -690
- data/spec/net/s3_helper_spec.rb +0 -160
- data/spec/net/ssl_spec.rb +0 -42
- data/spec/net/string_encoder_spec.rb +0 -58
- data/spec/rack/log_setter_spec.rb +0 -5
- data/spec/rack/request_logger_spec.rb +0 -225
- data/spec/rack/request_tracker_spec.rb +0 -115
- data/spec/rack/runtime_spec.rb +0 -49
- data/spec/ruby/easy_singleton_spec.rb +0 -72
- data/spec/ruby/object_extensions_spec.rb +0 -27
- data/spec/ruby/string_extensions_spec.rb +0 -98
- data/spec/spec_helper.rb +0 -188
- data/spec/stats/activity_spec.rb +0 -425
- data/spec/stats/exceptions_spec.rb +0 -247
- data/spec/stats/helpers_spec.rb +0 -685
- data/spec/validation/openssl_spec.rb +0 -37
- data/spec/validation/ssh_spec.rb +0 -39
@@ -1,181 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Net::HTTPClient do
|
4
|
-
it 'has a distinct method for common HTTP verbs' do
|
5
|
-
@http_client = RightSupport::Net::HTTPClient.new()
|
6
|
-
@http_client.should respond_to(:get)
|
7
|
-
@http_client.should respond_to(:post)
|
8
|
-
@http_client.should respond_to(:put)
|
9
|
-
@http_client.should respond_to(:delete)
|
10
|
-
end
|
11
|
-
|
12
|
-
context 'with defaults passed to initializer' do
|
13
|
-
before(:all) do
|
14
|
-
@http_client = RightSupport::Net::HTTPClient.new(:open_timeout=>999, :timeout=>101010,
|
15
|
-
:headers=>{:moo=>:bah})
|
16
|
-
end
|
17
|
-
|
18
|
-
context :process_query_string do
|
19
|
-
it 'process nil url and params' do
|
20
|
-
@http_client.instance_eval { process_query_string }.should == ''
|
21
|
-
end
|
22
|
-
it 'process empty String params' do
|
23
|
-
url = '/moo'
|
24
|
-
params = ''
|
25
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo'
|
26
|
-
end
|
27
|
-
it 'process params just with question mark' do
|
28
|
-
url = '/moo'
|
29
|
-
params = '?'
|
30
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo'
|
31
|
-
end
|
32
|
-
it 'process String params with question mark in the beginning' do
|
33
|
-
url = '/moo'
|
34
|
-
params = '?a=b'
|
35
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a=b'
|
36
|
-
end
|
37
|
-
it 'process String params without question mark in the beginning' do
|
38
|
-
url = '/moo'
|
39
|
-
params = 'a=b&c=d'
|
40
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a=b&c=d'
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'when converting with Addressable::URI' do
|
44
|
-
it 'process raw Hash params' do
|
45
|
-
url = '/moo'
|
46
|
-
params = {:a=>:b}
|
47
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a=b'
|
48
|
-
end
|
49
|
-
it 'process Hash params with hash inside' do
|
50
|
-
url = '/moo'
|
51
|
-
params = {:a=>{:b=>:c}}
|
52
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a[b]=c'
|
53
|
-
end
|
54
|
-
it 'process Hash params with array inside' do
|
55
|
-
url = '/moo'
|
56
|
-
params = {:a=>['b','c']}
|
57
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a[0]=b&a[1]=c'
|
58
|
-
end
|
59
|
-
it 'process Hash params with nested array inside' do
|
60
|
-
url = '/moo'
|
61
|
-
params = {:a=>{:b=>:c,:d=>['e','f'],:g=>{:h=>'i'}},:j=>'k'}
|
62
|
-
@http_client.instance_eval { process_query_string(url, params) }.should ==
|
63
|
-
'/moo?a[b]=c&a[d][0]=e&a[d][1]=f&a[g][h]=i&j=k'
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'when converting directly' do
|
68
|
-
before(:each) do
|
69
|
-
flexmock(@http_client).should_receive(:require_succeeds?).with('addressable/uri').and_return(false)
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'process raw Hash params' do
|
73
|
-
url = '/moo'
|
74
|
-
params = {:a=>:b}
|
75
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a=b'
|
76
|
-
end
|
77
|
-
it 'process Hash params with hash inside' do
|
78
|
-
url = '/moo'
|
79
|
-
params = {:a=>{:b=>:c}}
|
80
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a%5Bb%5D=c'
|
81
|
-
end
|
82
|
-
it 'process Hash params with array inside' do
|
83
|
-
url = '/moo'
|
84
|
-
params = {:a=>['b','c']}
|
85
|
-
@http_client.instance_eval { process_query_string(url, params) }.should == '/moo?a%5B%5D=b&a%5B%5D=c'
|
86
|
-
end
|
87
|
-
it 'process Hash params with nested array inside' do
|
88
|
-
url = '/moo'
|
89
|
-
params = {:a=>{:b=>:c,:d=>['e','f'],:g=>{:h=>'i'}},:j=>'k'}
|
90
|
-
@http_client.instance_eval { process_query_string(url, params) }.should ==
|
91
|
-
'/moo?a%5Bb%5D=c&a%5Bd%5D%5B%5D=e&a%5Bd%5D%5B%5D=f&a%5Bg%5D%5Bh%5D=i&j=k'
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context :request do
|
97
|
-
it 'uses default options on every request' do
|
98
|
-
p = {:method=>:get,
|
99
|
-
:timeout=>101010,
|
100
|
-
:ssl_version=>'TLSv1',
|
101
|
-
:open_timeout=>999,
|
102
|
-
:url=>'/moo', :headers=>{:moo=>:bah}}
|
103
|
-
flexmock(RestClient::Request).should_receive(:execute).with(p)
|
104
|
-
@http_client.get('/moo')
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'allows defaults to be overridden' do
|
108
|
-
p = {:method=>:get,
|
109
|
-
:timeout=>101010,
|
110
|
-
:ssl_version=>'SSLv3',
|
111
|
-
:open_timeout=>3,
|
112
|
-
:url=>'/moo', :headers=>{:joe=>:blow}}
|
113
|
-
flexmock(RestClient::Request).should_receive(:execute).with(p)
|
114
|
-
@http_client.get('/moo', :ssl_version => 'SSLv3', :open_timeout=>3, :headers=>{:joe=>:blow})
|
115
|
-
end
|
116
|
-
end
|
117
|
-
end
|
118
|
-
|
119
|
-
context :request do
|
120
|
-
before(:each) do
|
121
|
-
r = 'this is a short mock REST response'
|
122
|
-
flexmock(RestClient::Request).should_receive(:execute).and_return(r).by_default
|
123
|
-
@http_client = RightSupport::Net::HTTPClient.new()
|
124
|
-
end
|
125
|
-
|
126
|
-
context 'given just a URL' do
|
127
|
-
it 'succeeds' do
|
128
|
-
p = {:method=>:get,
|
129
|
-
:timeout=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:timeout],
|
130
|
-
:ssl_version=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:ssl_version],
|
131
|
-
:open_timeout=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:open_timeout],
|
132
|
-
:url=>'/moo', :headers=>{}}
|
133
|
-
flexmock(RestClient::Request).should_receive(:execute).with(p)
|
134
|
-
|
135
|
-
@http_client.get('/moo')
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
context 'given a URL and headers' do
|
140
|
-
it 'succeeds' do
|
141
|
-
p = {:method=>:get,
|
142
|
-
:timeout=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:timeout],
|
143
|
-
:ssl_version=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:ssl_version],
|
144
|
-
:open_timeout=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:open_timeout],
|
145
|
-
:url=>'/moo', :headers=>{:mrm=>1, :blah=>:foo}}
|
146
|
-
flexmock(RestClient::Request).should_receive(:execute).with(p)
|
147
|
-
|
148
|
-
@http_client.get('/moo', {:headers => {:mrm=>1, :blah=>:foo}})
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
|
153
|
-
context 'given a timeout, no headers, and a URL' do
|
154
|
-
it 'succeeds' do
|
155
|
-
p = {:method=>:get,
|
156
|
-
:timeout=>42,
|
157
|
-
:ssl_version=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:ssl_version],
|
158
|
-
:open_timeout => RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:open_timeout],
|
159
|
-
:url=>'/moo', :headers=>{}}
|
160
|
-
flexmock(RestClient::Request).should_receive(:execute).with(p)
|
161
|
-
|
162
|
-
@http_client.get('/moo', {:timeout => 42})
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
context 'given a URL and any other parameters' do
|
167
|
-
it 'succeeds' do
|
168
|
-
p = { :method=>:get,
|
169
|
-
:timeout=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:timeout],
|
170
|
-
:ssl_version=>RightSupport::Net::HTTPClient::DEFAULT_OPTIONS[:ssl_version],
|
171
|
-
:url=>'/moo',
|
172
|
-
:headers=>{},
|
173
|
-
:open_timeout => 1,
|
174
|
-
:payload=>{:foo => :bar} }
|
175
|
-
flexmock(RestClient::Request).should_receive(:execute).with(p)
|
176
|
-
|
177
|
-
@http_client.get('/moo', :open_timeout => 1, :payload=>{:foo => :bar})
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
@@ -1,417 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Net::LB::HealthCheck do
|
4
|
-
context :initialize do
|
5
|
-
|
6
|
-
end
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
@endpoints = [1,2,3,4,5]
|
10
|
-
@yellow_states = 4
|
11
|
-
@reset_time = 60
|
12
|
-
@policy = RightSupport::Net::LB::HealthCheck.new(
|
13
|
-
:yellow_states => @yellow_states,
|
14
|
-
:reset_time => @reset_time,
|
15
|
-
:health_check => lambda { |ep| true })
|
16
|
-
@policy.set_endpoints(@endpoints)
|
17
|
-
@trials = 2500
|
18
|
-
end
|
19
|
-
|
20
|
-
context :initialize do
|
21
|
-
it 'starts endpoints in yellow-1 state' do
|
22
|
-
stats = @policy.get_stats
|
23
|
-
@endpoints.each { |ep| stats[ep].should == 'yellow-1' }
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context :good do
|
28
|
-
context 'given a red server' do
|
29
|
-
before(:each) do
|
30
|
-
@red = @endpoints.first
|
31
|
-
@yellow_states.times { @policy.bad(@red, 0, Time.now) }
|
32
|
-
@policy.should have_red_endpoint(@red)
|
33
|
-
end
|
34
|
-
|
35
|
-
it "changes to yellow-N" do
|
36
|
-
@policy.good(@red, 0, Time.now)
|
37
|
-
@policy.should have_yellow_endpoint(@red, @yellow_states-1)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'given a yellow-N server' do
|
42
|
-
before(:each) do
|
43
|
-
@yellow = @endpoints.first
|
44
|
-
(@yellow_states-1).times { @policy.bad(@yellow, 0, Time.now) }
|
45
|
-
@policy.should have_yellow_endpoint(@yellow, @yellow_states)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'decreases the yellow level to N-1' do
|
49
|
-
@policy.good(@yellow, 0, Time.now)
|
50
|
-
@policy.should have_yellow_endpoint(@yellow, @yellow_states-1)
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'when N == 1' do
|
54
|
-
before(:each) do
|
55
|
-
@yellow = @endpoints[1] #this should be yellow-1 since we haven't tampered with it yet
|
56
|
-
@policy.get_stats[@yellow].should == 'yellow-1'
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'changes to green' do
|
60
|
-
@policy.should have_yellow_endpoint(@yellow, 1)
|
61
|
-
@policy.good(@yellow, 0, Time.now)
|
62
|
-
@policy.should have_green_endpoint(@yellow)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'when on_health_change callback is enabled' do
|
68
|
-
before(:each) do
|
69
|
-
@yellow_states = 3
|
70
|
-
@health_updates = []
|
71
|
-
@policy = RightSupport::Net::LB::HealthCheck.new(
|
72
|
-
:yellow_states => @yellow_states,
|
73
|
-
:reset_time => @reset_time,
|
74
|
-
:on_health_change => lambda { |health| @health_updates << health },
|
75
|
-
:health_check => lambda { |ep| true })
|
76
|
-
@policy.set_endpoints(@endpoints)
|
77
|
-
|
78
|
-
# put everyone into green state, then forget all health updates. this helps us write an
|
79
|
-
# easier test.
|
80
|
-
@endpoints.each { |ep| @policy.good(ep, 0, Time.now) }
|
81
|
-
@health_updates = []
|
82
|
-
end
|
83
|
-
|
84
|
-
it "notifies of overall improving health only at transition points" do
|
85
|
-
endpoints = @endpoints.shuffle
|
86
|
-
endpoints.shuffle.each { |ep| @policy.bad(ep, 0, Time.now) }
|
87
|
-
endpoints.shuffle.each { |ep| @policy.bad(ep, 0, Time.now) }
|
88
|
-
endpoints.shuffle.each { |ep| @policy.bad(ep, 0, Time.now) }
|
89
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red']
|
90
|
-
@policy.good(endpoints[0], 0, Time.now)
|
91
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2']
|
92
|
-
endpoints[1..-1].each { |ep| @policy.good(ep, 0, Time.now) }
|
93
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2']
|
94
|
-
@policy.good(endpoints[0], 0, Time.now)
|
95
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2', 'yellow-1']
|
96
|
-
@policy.bad(endpoints[0], 0, Time.now)
|
97
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2', 'yellow-1', 'yellow-2']
|
98
|
-
@policy.good(endpoints[0], 0, Time.now)
|
99
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2', 'yellow-1', 'yellow-2', 'yellow-1']
|
100
|
-
2.times { @policy.good(endpoints[1], 0, Time.now) }
|
101
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2', 'yellow-1', 'yellow-2', 'yellow-1', 'green']
|
102
|
-
endpoints.each { |ep| @policy.good(ep, 0, Time.now) }
|
103
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2', 'yellow-1', 'yellow-2', 'yellow-1', 'green']
|
104
|
-
endpoints.each { |ep| @policy.good(ep, 0, Time.now) }
|
105
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red', 'yellow-2', 'yellow-1', 'yellow-2', 'yellow-1', 'green']
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
context :bad do
|
111
|
-
context 'given a green server' do
|
112
|
-
before(:each) do
|
113
|
-
@green = @endpoints.first
|
114
|
-
@policy.good(@green, 0, Time.now)
|
115
|
-
@policy.should have_green_endpoint(@green)
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'changes to yellow-1' do
|
119
|
-
@policy.bad(@green, 0, Time.now)
|
120
|
-
@policy.should have_yellow_endpoint(@green, 1)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
context 'given a yellow-N server' do
|
125
|
-
before(:each) do
|
126
|
-
@yellow = @endpoints.first
|
127
|
-
end
|
128
|
-
|
129
|
-
it 'increases the yellow level to N+1' do
|
130
|
-
@policy.bad(@yellow, 0, Time.now)
|
131
|
-
@policy.should have_yellow_endpoint(@yellow, 2)
|
132
|
-
end
|
133
|
-
|
134
|
-
context 'when N == yellow_states-1' do
|
135
|
-
before(:each) do
|
136
|
-
n = @yellow_states - 2
|
137
|
-
n.times { @policy.bad(@yellow, 0, Time.now) }
|
138
|
-
@policy.should have_yellow_endpoint(@yellow, n+1)
|
139
|
-
end
|
140
|
-
|
141
|
-
it 'changes to red' do
|
142
|
-
@policy.bad(@yellow, 0, Time.now)
|
143
|
-
@policy.should have_red_endpoint(@yellow)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
|
-
context 'given a red server' do
|
149
|
-
it 'does nothing' do
|
150
|
-
@red = @endpoints.first
|
151
|
-
@yellow_states.times { @policy.bad(@red, 0, Time.now) }
|
152
|
-
@policy.should have_red_endpoint(@red)
|
153
|
-
|
154
|
-
@policy.bad(@red, 0, Time.now)
|
155
|
-
@policy.should have_red_endpoint(@red)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
|
159
|
-
context 'when on_health_change callback is enabled' do
|
160
|
-
before(:each) do
|
161
|
-
@yellow_states = 3
|
162
|
-
@health_updates = []
|
163
|
-
@policy = RightSupport::Net::LB::HealthCheck.new(
|
164
|
-
:yellow_states => @yellow_states, :reset_time => @reset_time,
|
165
|
-
:on_health_change => lambda { |health| @health_updates << health },
|
166
|
-
:health_check => lambda { |ep| true })
|
167
|
-
@policy.set_endpoints(@endpoints)
|
168
|
-
|
169
|
-
# put everyone into green state, then forget all health updates. this helps us write an
|
170
|
-
# easier test.
|
171
|
-
@endpoints.each { |ep| @policy.good(ep, 0, Time.now) }
|
172
|
-
@health_updates = []
|
173
|
-
end
|
174
|
-
|
175
|
-
it "notifies of overall worsening health only at transition points" do
|
176
|
-
# make most endpoints yellow-1
|
177
|
-
endpoints = @endpoints.shuffle
|
178
|
-
endpoints[1..-1].each { |ep| @policy.bad(ep, 0, Time.now) }
|
179
|
-
@policy.bad(endpoints[0], 0, Time.now)
|
180
|
-
@health_updates.should == ['yellow-1']
|
181
|
-
endpoints.each { |ep| @policy.bad(ep, 0, Time.now) }
|
182
|
-
@health_updates.should == ['yellow-1', 'yellow-2']
|
183
|
-
endpoints[1..-1].each { |ep| @policy.bad(ep, 0, Time.now) }
|
184
|
-
@health_updates.should == ['yellow-1', 'yellow-2']
|
185
|
-
@policy.bad(endpoints[0], 0, Time.now)
|
186
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red']
|
187
|
-
@policy.bad(endpoints[0], 0, Time.now)
|
188
|
-
@health_updates.should == ['yellow-1', 'yellow-2', 'red']
|
189
|
-
end
|
190
|
-
end
|
191
|
-
end
|
192
|
-
|
193
|
-
context :next do
|
194
|
-
|
195
|
-
context 'given all green servers' do
|
196
|
-
it 'chooses fairly' do
|
197
|
-
test_random_distribution do
|
198
|
-
@policy.next
|
199
|
-
end
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
context 'given all red servers' do
|
204
|
-
it 'returns nil to indicate no servers are available' do
|
205
|
-
@endpoints.each do |endpoint|
|
206
|
-
@yellow_states.times { @policy.bad(endpoint, 0, Time.now) }
|
207
|
-
@policy.should have_red_endpoint(endpoint)
|
208
|
-
end
|
209
|
-
@policy.next.should be_nil
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
context 'given a mixture of servers' do
|
214
|
-
it 'never chooses red servers' do
|
215
|
-
@red = @endpoints.first
|
216
|
-
@yellow_states.times { @policy.bad(@red, 0, Time.now) }
|
217
|
-
@policy.should have_red_endpoint(@red)
|
218
|
-
|
219
|
-
seen = find_empirical_distribution(@trials,@endpoints) do
|
220
|
-
@policy.next
|
221
|
-
end
|
222
|
-
|
223
|
-
seen.include?(@red).should be_false
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'chooses fairly from the green and yellow servers' do
|
227
|
-
@red = @endpoints.first
|
228
|
-
@yellow_states.times { @policy.bad(@red, 0, Time.now) }
|
229
|
-
@policy.should have_red_endpoint(@red)
|
230
|
-
|
231
|
-
seen = find_empirical_distribution(@trials,@endpoints) do
|
232
|
-
@policy.next
|
233
|
-
end
|
234
|
-
|
235
|
-
seen.include?(@red).should be_false
|
236
|
-
should_be_chosen_fairly(seen, @trials, @endpoints.size - 1)
|
237
|
-
end
|
238
|
-
|
239
|
-
it "eliminates bad endpoints during round robin selection" do
|
240
|
-
endpoints = [1, 2, 3, 4, 5]
|
241
|
-
policy = RightSupport::Net::LB::HealthCheck.new(
|
242
|
-
:yellow_states => 2,
|
243
|
-
:health_check => lambda { |ep| true })
|
244
|
-
policy.set_endpoints(endpoints)
|
245
|
-
policy.instance_variable_set(:@counter, 0)
|
246
|
-
breaking_bad = lambda { |ep| ep < 4 }
|
247
|
-
|
248
|
-
# first pass; initially all green, mark some yellow.
|
249
|
-
expected = [1, 2, 3, 4, 5]
|
250
|
-
actual = []
|
251
|
-
endpoints.size.times do
|
252
|
-
endpoint, need_health_check = policy.next
|
253
|
-
need_health_check.should be_false
|
254
|
-
if breaking_bad.call(endpoint)
|
255
|
-
policy.bad(endpoint, 0, Time.now) # go yellow
|
256
|
-
end
|
257
|
-
actual << endpoint
|
258
|
-
end
|
259
|
-
actual.should == expected
|
260
|
-
|
261
|
-
# second pass; some yellow, others green. yellows go red after being
|
262
|
-
# selected and are eliminated from subsequent round-robin selection.
|
263
|
-
expected = [1, 4, 5, 2, 3]
|
264
|
-
actual = []
|
265
|
-
endpoints.size.times do
|
266
|
-
endpoint, need_health_check = policy.next
|
267
|
-
if breaking_bad.call(endpoint)
|
268
|
-
# yellow is still viable but a health-check is requested.
|
269
|
-
need_health_check.should be_true
|
270
|
-
policy.bad(endpoint, 0, Time.now) # go red
|
271
|
-
else
|
272
|
-
need_health_check.should be_false
|
273
|
-
end
|
274
|
-
actual << endpoint
|
275
|
-
end
|
276
|
-
actual.should == expected
|
277
|
-
|
278
|
-
# third pass; green or red, no more yellow.
|
279
|
-
expected = [4, 5, 4, 5, 4]
|
280
|
-
actual = []
|
281
|
-
endpoints.size.times do
|
282
|
-
endpoint, need_health_check = policy.next
|
283
|
-
need_health_check.should be_false
|
284
|
-
actual << endpoint
|
285
|
-
end
|
286
|
-
actual.should == expected
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
context 'given a red server' do
|
291
|
-
before(:each) do
|
292
|
-
@red = @endpoints.first
|
293
|
-
(@yellow_states-1).times { @policy.bad(@red, 0, Time.now - 60) }
|
294
|
-
end
|
295
|
-
|
296
|
-
context 'when @reset_time passes' do
|
297
|
-
it 'resets the server to yellow' do
|
298
|
-
@policy.should have_red_endpoint(@red)
|
299
|
-
@policy.next
|
300
|
-
@policy.should have_yellow_endpoint(@red, @yellow_states-1)
|
301
|
-
end
|
302
|
-
end
|
303
|
-
|
304
|
-
end
|
305
|
-
|
306
|
-
context 'given a yellow-2 server' do
|
307
|
-
before(:each) do
|
308
|
-
@yellow = @endpoints.first
|
309
|
-
@policy.bad(@yellow, 0, Time.now - 60)
|
310
|
-
@policy.should have_yellow_endpoint(@yellow, 2)
|
311
|
-
end
|
312
|
-
|
313
|
-
context 'when @reset_time passes' do
|
314
|
-
it 'decreases the yellow level to N-1' do
|
315
|
-
@policy.next
|
316
|
-
@policy.should have_yellow_endpoint(@yellow, 1)
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
context 'given a yellow-1 server' do
|
322
|
-
before(:each) do
|
323
|
-
@yellow = @endpoints.first
|
324
|
-
@policy.good(@yellow, 0, Time.now - 60)
|
325
|
-
@policy.bad(@yellow, 0, Time.now - 60)
|
326
|
-
@policy.should have_yellow_endpoint(@yellow, 1)
|
327
|
-
end
|
328
|
-
|
329
|
-
context 'when @reset_time passes' do
|
330
|
-
it 'resets the server to green' do
|
331
|
-
@policy.next
|
332
|
-
@policy.should have_green_endpoint(@yellow)
|
333
|
-
end
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
context :get_stats do
|
339
|
-
context 'given all green servers' do
|
340
|
-
before(:each) do
|
341
|
-
@endpoints.each { |ep| @policy.good(ep, 0, Time.now) }
|
342
|
-
end
|
343
|
-
|
344
|
-
it 'reports all endpoints as green' do
|
345
|
-
expected_stats = {}
|
346
|
-
@endpoints.each { |ep| expected_stats[ep] = 'green' }
|
347
|
-
|
348
|
-
@policy.get_stats.should_not be_nil
|
349
|
-
@policy.get_stats.should == expected_stats
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
context 'given all red servers' do
|
354
|
-
it 'reports all endpoints as red' do
|
355
|
-
expected_stats = {}
|
356
|
-
@endpoints.each { |ep| expected_stats[ep] = 'red' }
|
357
|
-
|
358
|
-
@endpoints.each do |endpoint|
|
359
|
-
@yellow_states.times { @policy.bad(endpoint, 0, Time.now) }
|
360
|
-
end
|
361
|
-
|
362
|
-
@policy.get_stats.should_not be_nil
|
363
|
-
@policy.get_stats.should == expected_stats
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
context 'given all yellow-N servers' do
|
368
|
-
it 'reports all endpoints as yellow-N' do
|
369
|
-
expected_stats = {}
|
370
|
-
@endpoints.each { |ep| expected_stats[ep] = "yellow-#{@yellow_states - 1}" }
|
371
|
-
|
372
|
-
@endpoints.each do |endpoint|
|
373
|
-
@yellow_states.times { @policy.bad(endpoint, 0, Time.now) }
|
374
|
-
@policy.good(endpoint, 0, Time.now)
|
375
|
-
end
|
376
|
-
|
377
|
-
@policy.get_stats.should_not be_nil
|
378
|
-
@policy.get_stats.should == expected_stats
|
379
|
-
end
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
context :set_endpoints do
|
384
|
-
context 'given endpoints stack does not exist' do
|
385
|
-
before(:each) do
|
386
|
-
@policy = RightSupport::Net::LB::HealthCheck.new(
|
387
|
-
:yellow_states => @yellow_states,
|
388
|
-
:reset_time => @reset_time,
|
389
|
-
:health_check => lambda { |ep| true })
|
390
|
-
end
|
391
|
-
|
392
|
-
it 'acts as initializer' do
|
393
|
-
@policy.set_endpoints(@endpoints)
|
394
|
-
@endpoints.include?(@policy.next.first).should be_true
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
context 'given an existing endpoints stack' do
|
399
|
-
it 'updates composition and saves previous statuses of endpoints' do
|
400
|
-
expected_stats = {}
|
401
|
-
@endpoints.each { |ep| expected_stats[ep] = "yellow-#{@yellow_states - 1}" }
|
402
|
-
|
403
|
-
@endpoints.each do |endpoint|
|
404
|
-
@yellow_states.times { @policy.bad(endpoint, 0, Time.now) }
|
405
|
-
@policy.good(endpoint, 0, Time.now)
|
406
|
-
end
|
407
|
-
|
408
|
-
@new_endpoins = [6,7]
|
409
|
-
@new_endpoins.each { |ep| expected_stats[ep] = "yellow-1" }
|
410
|
-
|
411
|
-
@updated_endpoints = @endpoints + @new_endpoins
|
412
|
-
@policy.set_endpoints(@updated_endpoints)
|
413
|
-
@policy.get_stats.should eql(expected_stats)
|
414
|
-
end
|
415
|
-
end
|
416
|
-
end #:set_endpoints
|
417
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Net::LB::RoundRobin do
|
4
|
-
before(:each) do
|
5
|
-
@endpoints = [1,2,3,4,5]
|
6
|
-
@policy = RightSupport::Net::LB::RoundRobin.new()
|
7
|
-
@policy.set_endpoints(@endpoints)
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'chooses fairly' do
|
11
|
-
test_random_distribution do
|
12
|
-
@policy.next
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
data/spec/net/lb/sticky_spec.rb
DELETED
@@ -1,92 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Net::LB::Sticky do
|
4
|
-
|
5
|
-
before(:all) do
|
6
|
-
@endpoints = [1,2,3,4,5]
|
7
|
-
@trials = 2500
|
8
|
-
end
|
9
|
-
|
10
|
-
before(:each) do
|
11
|
-
@policy = RightSupport::Net::LB::Sticky.new({})
|
12
|
-
end
|
13
|
-
|
14
|
-
context :initialize do
|
15
|
-
it 'creates policy with an empty list of endpoints' do
|
16
|
-
@policy.next.should be_nil
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
context :next do
|
21
|
-
|
22
|
-
before(:each) do
|
23
|
-
@policy.set_endpoints(@endpoints)
|
24
|
-
end
|
25
|
-
|
26
|
-
context 'given all servers are healthy' do
|
27
|
-
it 'sticks to chosen one' do
|
28
|
-
chance = 1.0
|
29
|
-
seen = find_empirical_distribution(@trials,@endpoints) do
|
30
|
-
@policy.next
|
31
|
-
end
|
32
|
-
seen.each_pair do |_, count|
|
33
|
-
(Float(count) / Float(@trials)).should be_within(0.025).of(chance) #allow 5% margin of error
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context 'given a chosen server becomes unavailable' do
|
39
|
-
it 'chooses the next server and sticks to it' do
|
40
|
-
@ep1 = @policy.next.first
|
41
|
-
|
42
|
-
seen = find_empirical_distribution(@trials,@endpoints) do
|
43
|
-
@policy.next
|
44
|
-
end
|
45
|
-
seen[[@ep1,false]].should eql(@trials)
|
46
|
-
|
47
|
-
@policy.bad(@chosen,0,0)
|
48
|
-
@ep2 = @policy.next.first
|
49
|
-
|
50
|
-
seen = find_empirical_distribution(@trials,@endpoints) do
|
51
|
-
@policy.next
|
52
|
-
end
|
53
|
-
seen[[@ep1,false]].should be_nil
|
54
|
-
seen[[@ep2,false]].should eql(@trials)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
context :set_endpoints do
|
60
|
-
context 'given an empty list of endpoints' do
|
61
|
-
it 'acts as initializer' do
|
62
|
-
@policy.next.should be_nil
|
63
|
-
@policy.set_endpoints(@endpoints)
|
64
|
-
@endpoints.include?(@policy.next.first).should be_true
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
context 'given an existing list endpoints' do
|
69
|
-
before(:each) do
|
70
|
-
@policy.set_endpoints(@endpoints)
|
71
|
-
end
|
72
|
-
|
73
|
-
context 'and updated list of endpoints contains a chosen server' do
|
74
|
-
it 'updates composition, but still using chosen server' do
|
75
|
-
@chosen_endpoint = @policy.next.first
|
76
|
-
@updated_endpoints = @endpoints + [6,7]
|
77
|
-
@policy.set_endpoints(@updated_endpoints)
|
78
|
-
@policy.next.first.should be_eql(@chosen_endpoint)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'and updated list of endpoints does not contain a chosen server' do
|
83
|
-
it 'updates composition and chooses new server' do
|
84
|
-
@chosen_endpoint = @policy.next.first
|
85
|
-
@updated_endpoints = @endpoints - [@chosen_endpoint]
|
86
|
-
@policy.set_endpoints(@updated_endpoints)
|
87
|
-
@policy.next.first.should_not be_eql(@chosen_endpoint)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end #:set_endpoints
|
92
|
-
end
|