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.
- 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,72 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class Alice
|
4
|
-
include Singleton
|
5
|
-
include RightSupport::Ruby::EasySingleton
|
6
|
-
|
7
|
-
def alice?
|
8
|
-
true
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
class Bob
|
13
|
-
include RightSupport::Ruby::EasySingleton
|
14
|
-
|
15
|
-
def bob?
|
16
|
-
true
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
class Charlie
|
21
|
-
include RightSupport::Ruby::EasySingleton
|
22
|
-
|
23
|
-
def charlie?(&block)
|
24
|
-
block.call("this is charlie") if block
|
25
|
-
true
|
26
|
-
end
|
27
|
-
|
28
|
-
def horse(x,y,z)
|
29
|
-
yield("this is horse") if block_given?
|
30
|
-
x+y+z
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
describe RightSupport::Ruby::EasySingleton do
|
35
|
-
context 'when mixed into a base class' do
|
36
|
-
it 'ensures the base is already a Singleton' do
|
37
|
-
Alice.ancestors.should include(Singleton)
|
38
|
-
Bob.ancestors.should include(Singleton)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'adds a class-level method_missing' do
|
42
|
-
Alice.alice?.should be_true
|
43
|
-
Bob.bob?.should be_true
|
44
|
-
|
45
|
-
lambda { Alice.bob? }.should raise_error(NoMethodError)
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'modifies class-level respond_to? to be truthful' do
|
49
|
-
Alice.respond_to?(:alice?).should be_true
|
50
|
-
Bob.respond_to?(:bob?).should be_true
|
51
|
-
Alice.respond_to?(:bob?).should be_false
|
52
|
-
Bob.respond_to?(:alice?).should be_false
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
context 'when proxying class-level method_missing to instance' do
|
57
|
-
it 'preserves parameters as passed' do
|
58
|
-
Charlie.horse(1,2,3).should == 6
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'preserves block semantics' do
|
62
|
-
charlie = nil
|
63
|
-
horse = nil
|
64
|
-
|
65
|
-
Charlie.charlie? { |x| charlie = x }
|
66
|
-
charlie.should == 'this is charlie'
|
67
|
-
|
68
|
-
Charlie.horse(1,2,3) { |x| horse = x }
|
69
|
-
horse.should == 'this is horse'
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
@@ -1,27 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Ruby::ObjectExtensions do
|
4
|
-
context :require_succeeds? do
|
5
|
-
it 'yields to its block when the require succeeds' do
|
6
|
-
@canary = false
|
7
|
-
|
8
|
-
# The 'set' source file ships with Ruby standard library and should
|
9
|
-
# always be available
|
10
|
-
if require_succeeds?('set')
|
11
|
-
@canary = true
|
12
|
-
end
|
13
|
-
|
14
|
-
@canary.should == true
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'does not yield when require fails for any reason' do
|
18
|
-
@canary = false
|
19
|
-
|
20
|
-
if require_succeeds?('a_source_file_with_a_wholly_improbable_name')
|
21
|
-
@canary = true
|
22
|
-
end
|
23
|
-
|
24
|
-
@canary.should == false
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2012 RightScale Inc
|
3
|
-
#
|
4
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
-
# a copy of this software and associated documentation files (the
|
6
|
-
# "Software"), to deal in the Software without restriction, including
|
7
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
-
# the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be
|
13
|
-
# included in all copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
-
|
23
|
-
require 'spec_helper'
|
24
|
-
|
25
|
-
describe RightSupport::Ruby::StringExtensions do
|
26
|
-
|
27
|
-
context ":snake_case" do
|
28
|
-
|
29
|
-
it "downcases single word" do
|
30
|
-
["FOO", "Foo", "foo"].each do |w|
|
31
|
-
w.snake_case.should == "foo"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
it "doesn't separate numbers from end of word" do
|
36
|
-
["Foo1234", "foo1234"].each do |w|
|
37
|
-
w.snake_case.should == "foo1234"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
it "doesn't separate numbers from word that starts with uppercase letter" do
|
42
|
-
"1234Foo".snake_case.should == "1234foo"
|
43
|
-
end
|
44
|
-
|
45
|
-
it "doesn't' separate numbers from word that starts with lowercase letter" do
|
46
|
-
"1234foo".snake_case.should == "1234foo"
|
47
|
-
end
|
48
|
-
|
49
|
-
it "downcases camel-cased words and connect with underscore" do
|
50
|
-
["FooBar", "fooBar"].each do |w|
|
51
|
-
w.snake_case.should == "foo_bar"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
it "starts new word with uppercase letter before lower case letter" do
|
56
|
-
["FooBARBaz", "fooBARBaz"].each do |w|
|
57
|
-
w.snake_case.should == "foo_bar_baz"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
|
63
|
-
context ":to_const_path" do
|
64
|
-
|
65
|
-
it "snakes-case the string" do
|
66
|
-
"Hello::World".to_const_path.should == "hello/world"
|
67
|
-
end
|
68
|
-
|
69
|
-
it "leaves (snake-cased) string without '::' unchanged" do
|
70
|
-
"hello".to_const_path.should == "hello"
|
71
|
-
end
|
72
|
-
|
73
|
-
it "replaces single '::' with '/'" do
|
74
|
-
"hello::world".to_const_path.should == "hello/world"
|
75
|
-
end
|
76
|
-
|
77
|
-
it "replaces multiple '::' with '/'" do
|
78
|
-
"hello::rightscale::world".to_const_path.should == "hello/rightscale/world"
|
79
|
-
end
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
context ':camelize' do
|
84
|
-
|
85
|
-
it 'camelizes the string' do
|
86
|
-
'hello/world_hello'.camelize.should == 'Hello::WorldHello'
|
87
|
-
end
|
88
|
-
|
89
|
-
it 'camelizes strings with integers' do
|
90
|
-
'1hel2lo3/4wor5ld6_7hel8lo9'.camelize.should == '1hel2lo3::4wor5ld67hel8lo9'
|
91
|
-
end
|
92
|
-
|
93
|
-
it 'leaves camelized strings alone' do
|
94
|
-
'1Hel2lo3::4Wor5ld67Hel8lo9'.camelize.should == '1Hel2lo3::4Wor5ld67Hel8lo9'
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,188 +0,0 @@
|
|
1
|
-
# Copyright (c) 2012- RightScale Inc
|
2
|
-
#
|
3
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
4
|
-
# a copy of this software and associated documentation files (the
|
5
|
-
# "Software"), to deal in the Software without restriction, including
|
6
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
# the following conditions:
|
10
|
-
#
|
11
|
-
# The above copyright notice and this permission notice shall be
|
12
|
-
# included in all copies or substantial portions of the Software.
|
13
|
-
#
|
14
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
-
|
22
|
-
require 'rubygems'
|
23
|
-
require 'bundler/setup'
|
24
|
-
require 'flexmock'
|
25
|
-
|
26
|
-
require 'simplecov'
|
27
|
-
|
28
|
-
$:.unshift(File.expand_path('../../../lib', __FILE__)) #ensure we load THIS project's code, not an installed gem
|
29
|
-
require 'right_support'
|
30
|
-
|
31
|
-
['pry', 'ruby-debug'].each do |debugger|
|
32
|
-
begin
|
33
|
-
require debugger
|
34
|
-
rescue LoadError
|
35
|
-
# ignore
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
RSpec.configure do |config|
|
40
|
-
config.mock_with :flexmock
|
41
|
-
end
|
42
|
-
|
43
|
-
def read_fixture(fn)
|
44
|
-
basedir = File.expand_path('../..', __FILE__)
|
45
|
-
fixtures_dir = File.join(basedir, 'spec', 'fixtures')
|
46
|
-
File.read(File.join(fixtures_dir, fn))
|
47
|
-
end
|
48
|
-
|
49
|
-
def corrupt(key, factor=4)
|
50
|
-
d = key.size / 2
|
51
|
-
|
52
|
-
key[0..(d-factor)] + key[d+factor..-1]
|
53
|
-
end
|
54
|
-
|
55
|
-
RSpec::Matchers.define :have_green_endpoint do |endpoint|
|
56
|
-
match do |balancer|
|
57
|
-
stack = balancer.instance_variable_get(:@stack)
|
58
|
-
state = stack.instance_variable_get(:@endpoints)
|
59
|
-
state = state[endpoint] if state.respond_to?(:[])
|
60
|
-
unless stack && state && state.key?(:n_level)
|
61
|
-
raise ArgumentError, "Custom matcher is incompatible with new HealthCheck implementation!"
|
62
|
-
end
|
63
|
-
state[:n_level] == 0
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
RSpec::Matchers.define :have_yellow_endpoint do |endpoint, n|
|
68
|
-
match do |balancer|
|
69
|
-
stack = balancer.instance_variable_get(:@stack)
|
70
|
-
max_n = stack.instance_variable_get(:@yellow_states)
|
71
|
-
state = stack.instance_variable_get(:@endpoints)
|
72
|
-
state = state[endpoint] if state.respond_to?(:[])
|
73
|
-
unless max_n && stack && state && state.key?(:n_level)
|
74
|
-
raise ArgumentError, "Custom matcher is incompatible with new HealthCheck implementation!"
|
75
|
-
end
|
76
|
-
|
77
|
-
if n
|
78
|
-
state[:n_level].should == n
|
79
|
-
else
|
80
|
-
(1...max_n).should include(state[:n_level])
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
RSpec::Matchers.define :have_red_endpoint do |endpoint|
|
86
|
-
match do |balancer|
|
87
|
-
stack = balancer.instance_variable_get(:@stack)
|
88
|
-
max_n = stack.instance_variable_get(:@yellow_states)
|
89
|
-
state = stack.instance_variable_get(:@endpoints)
|
90
|
-
state = state[endpoint] if state.respond_to?(:[])
|
91
|
-
unless max_n && stack && state && state.key?(:n_level)
|
92
|
-
raise ArgumentError, "Custom matcher is incompatible with new HealthCheck implementation!"
|
93
|
-
end
|
94
|
-
min = 1
|
95
|
-
state[:n_level].should == max_n
|
96
|
-
end
|
97
|
-
end
|
98
|
-
|
99
|
-
def find_empirical_distribution(trials=2500, list=[1,2,3,4,5])
|
100
|
-
seen = {}
|
101
|
-
|
102
|
-
trials.times do
|
103
|
-
value = yield
|
104
|
-
seen[value] ||= 0
|
105
|
-
seen[value] += 1
|
106
|
-
end
|
107
|
-
|
108
|
-
seen
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_random_distribution(trials=25000, list=[1,2,3,4,5], &block)
|
112
|
-
seen = find_empirical_distribution(trials, &block)
|
113
|
-
should_be_chosen_fairly(seen,trials,list.size)
|
114
|
-
end
|
115
|
-
|
116
|
-
def should_be_chosen_fairly(seen, trials, size)
|
117
|
-
#Load should be evenly distributed
|
118
|
-
chance = 1.0 / size
|
119
|
-
seen.each_pair do |_, count|
|
120
|
-
(Float(count) / Float(trials)).should be_within(0.025).of(chance) #allow 5% margin of error
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
RANDOM_KEY_CLASSES = [String, Integer, Float, TrueClass, FalseClass]
|
125
|
-
RANDOM_VALUE_CLASSES = RANDOM_KEY_CLASSES + [Array, Hash]
|
126
|
-
|
127
|
-
def random_value(klass=nil, depth=0)
|
128
|
-
if klass.nil?
|
129
|
-
if depth < 5
|
130
|
-
klasses = RANDOM_VALUE_CLASSES
|
131
|
-
else
|
132
|
-
klasses = RANDOM_KEY_CLASSES
|
133
|
-
end
|
134
|
-
|
135
|
-
klass = klasses[rand(klasses.size)]
|
136
|
-
end
|
137
|
-
|
138
|
-
if klass == String
|
139
|
-
result = ''
|
140
|
-
io = StringIO.new(result, 'w')
|
141
|
-
rand(40).times { io.write(0x61 + rand(26)) }
|
142
|
-
io.close
|
143
|
-
elsif klass == Integer
|
144
|
-
result = rand(0xffffff)
|
145
|
-
elsif klass == Float
|
146
|
-
result = rand(0xffffff) * rand
|
147
|
-
elsif klass == TrueClass
|
148
|
-
result = true
|
149
|
-
elsif klass == FalseClass
|
150
|
-
result = false
|
151
|
-
elsif klass == Array
|
152
|
-
result = []
|
153
|
-
rand(10).times { result << random_value(nil, depth+1) }
|
154
|
-
elsif klass == Hash
|
155
|
-
result = {}
|
156
|
-
key_type = RANDOM_KEY_CLASSES[rand(RANDOM_KEY_CLASSES.size)]
|
157
|
-
rand(10).times { result[random_value(key_type, depth+1)] = random_value(nil, depth+1) }
|
158
|
-
else
|
159
|
-
raise ArgumentError, "Unknown random value type #{klass}"
|
160
|
-
end
|
161
|
-
|
162
|
-
result
|
163
|
-
end
|
164
|
-
|
165
|
-
def mock_logger
|
166
|
-
logger = flexmock(Logger.new(StringIO.new))
|
167
|
-
end
|
168
|
-
|
169
|
-
module SpecHelper
|
170
|
-
module SocketMocking
|
171
|
-
def mock_getaddrinfo(hostname, result, times=1)
|
172
|
-
boring_args = [nil, Socket::AF_INET, Socket::SOCK_STREAM, Socket::IPPROTO_TCP]
|
173
|
-
|
174
|
-
if result.is_a?(Class) && result.ancestors.include?(Exception)
|
175
|
-
e = result.new("Mock exception raised by getaddrinfo")
|
176
|
-
flexmock(Socket).should_receive(:getaddrinfo).with(hostname, *boring_args).times(times).ordered.and_raise(e)
|
177
|
-
else
|
178
|
-
infos = []
|
179
|
-
|
180
|
-
result.each do |addr|
|
181
|
-
infos << [0,0,0,addr]
|
182
|
-
end
|
183
|
-
|
184
|
-
flexmock(Socket).should_receive(:getaddrinfo).with(hostname, *boring_args).times(times).ordered.and_return(infos)
|
185
|
-
end
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|