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.
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