right_support 2.11.3 → 2.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +4 -0
  3. data/VERSION +1 -1
  4. data/lib/right_support/notifiers/airbrake.rb +194 -0
  5. data/lib/right_support/notifiers/base.rb +73 -0
  6. data/lib/right_support/notifiers/blacklisters/base.rb +48 -0
  7. data/lib/right_support/notifiers/blacklisters/canonical.rb +60 -0
  8. data/lib/right_support/notifiers/blacklisters/regular_expression.rb +86 -0
  9. data/{features/support/file_utils_bundler_mixin.rb → lib/right_support/notifiers/blacklisters/simple.rb} +21 -20
  10. data/lib/right_support/notifiers/blacklisters/snake_case.rb +60 -0
  11. data/lib/right_support/notifiers/blacklisters/wildcard.rb +65 -0
  12. data/lib/right_support/notifiers/blacklisters.rb +34 -0
  13. data/lib/right_support/notifiers/logger.rb +94 -0
  14. data/lib/right_support/notifiers/notification.rb +57 -0
  15. data/lib/right_support/notifiers/utilities/backtrace_decoder.rb +234 -0
  16. data/lib/right_support/notifiers/utilities.rb +29 -0
  17. data/lib/right_support/notifiers.rb +32 -0
  18. data/lib/right_support/rack/request_logger.rb +13 -9
  19. data/lib/right_support.rb +1 -0
  20. data/right_support.gemspec +19 -70
  21. metadata +17 -69
  22. data/.coveralls.yml +0 -2
  23. data/.rspec +0 -3
  24. data/.simplecov +0 -6
  25. data/.travis.yml +0 -13
  26. data/Gemfile +0 -51
  27. data/Gemfile.lock +0 -153
  28. data/features/balancer_error_handling.feature +0 -34
  29. data/features/balancer_health_check.feature +0 -33
  30. data/features/hash_tools.feature +0 -27
  31. data/features/http_client_timeout.feature +0 -19
  32. data/features/serialization.feature +0 -113
  33. data/features/step_definitions/hash_tools_steps.rb +0 -41
  34. data/features/step_definitions/http_client_steps.rb +0 -27
  35. data/features/step_definitions/request_balancer_steps.rb +0 -93
  36. data/features/step_definitions/ruby_steps.rb +0 -176
  37. data/features/step_definitions/serialization_steps.rb +0 -133
  38. data/features/step_definitions/server_steps.rb +0 -134
  39. data/features/support/env.rb +0 -148
  40. data/right_support.rconf +0 -9
  41. data/spec/config/feature_set_spec.rb +0 -83
  42. data/spec/crypto/signed_hash_spec.rb +0 -73
  43. data/spec/data/hash_tools_spec.rb +0 -602
  44. data/spec/data/mash_spec.rb +0 -313
  45. data/spec/data/token_spec.rb +0 -21
  46. data/spec/data/uuid_spec.rb +0 -45
  47. data/spec/db/cassandra_model_part1_spec.rb +0 -84
  48. data/spec/db/cassandra_model_part2_spec.rb +0 -73
  49. data/spec/db/cassandra_model_spec.rb +0 -375
  50. data/spec/fixtures/encrypted_priv_rsa.pem +0 -30
  51. data/spec/fixtures/good_priv_dsa.pem +0 -12
  52. data/spec/fixtures/good_priv_rsa.pem +0 -15
  53. data/spec/fixtures/good_pub_dsa.ssh +0 -1
  54. data/spec/fixtures/good_pub_rsa.pem +0 -5
  55. data/spec/fixtures/good_pub_rsa.ssh +0 -1
  56. data/spec/log/exception_logger_spec.rb +0 -76
  57. data/spec/log/filter_logger_spec.rb +0 -66
  58. data/spec/log/mixin_spec.rb +0 -141
  59. data/spec/log/multiplexer_spec.rb +0 -54
  60. data/spec/log/null_logger_spec.rb +0 -36
  61. data/spec/log/step_level_logger_spec.rb +0 -49
  62. data/spec/log/system_logger_spec.rb +0 -172
  63. data/spec/net/address_helper_spec.rb +0 -57
  64. data/spec/net/dns_spec.rb +0 -187
  65. data/spec/net/http_client_spec.rb +0 -181
  66. data/spec/net/lb/health_check_spec.rb +0 -417
  67. data/spec/net/lb/round_robin_spec.rb +0 -15
  68. data/spec/net/lb/sticky_spec.rb +0 -92
  69. data/spec/net/request_balancer_spec.rb +0 -690
  70. data/spec/net/s3_helper_spec.rb +0 -160
  71. data/spec/net/ssl_spec.rb +0 -42
  72. data/spec/net/string_encoder_spec.rb +0 -58
  73. data/spec/rack/log_setter_spec.rb +0 -5
  74. data/spec/rack/request_logger_spec.rb +0 -225
  75. data/spec/rack/request_tracker_spec.rb +0 -115
  76. data/spec/rack/runtime_spec.rb +0 -49
  77. data/spec/ruby/easy_singleton_spec.rb +0 -72
  78. data/spec/ruby/object_extensions_spec.rb +0 -27
  79. data/spec/ruby/string_extensions_spec.rb +0 -98
  80. data/spec/spec_helper.rb +0 -188
  81. data/spec/stats/activity_spec.rb +0 -425
  82. data/spec/stats/exceptions_spec.rb +0 -247
  83. data/spec/stats/helpers_spec.rb +0 -685
  84. data/spec/validation/openssl_spec.rb +0 -37
  85. 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
@@ -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