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
data/spec/log/mixin_spec.rb
DELETED
@@ -1,141 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
class InnocentVictim
|
4
|
-
include RightSupport::Log::Mixin
|
5
|
-
end
|
6
|
-
|
7
|
-
class Bystander < InnocentVictim
|
8
|
-
end
|
9
|
-
|
10
|
-
module Parasite
|
11
|
-
include RightSupport::Log::Mixin
|
12
|
-
end
|
13
|
-
|
14
|
-
class Host
|
15
|
-
include Parasite
|
16
|
-
end
|
17
|
-
|
18
|
-
describe RightSupport::Log::Mixin do
|
19
|
-
context 'when mixed into a module' do
|
20
|
-
before(:each) do
|
21
|
-
@victim = Host.new
|
22
|
-
end
|
23
|
-
|
24
|
-
it 'provides instance-level accesssor to hosts' do
|
25
|
-
@victim.should respond_to(:logger)
|
26
|
-
@victim.should respond_to(:logger=)
|
27
|
-
@victim.logger.info 'haha'
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'provides a module-method-level accessor' do
|
31
|
-
Parasite.should respond_to(:logger)
|
32
|
-
Parasite.should respond_to(:logger=)
|
33
|
-
Parasite.logger.info 'haha'
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
context 'when mixed into a base class' do
|
38
|
-
before(:each) do
|
39
|
-
@victim = InnocentVictim.new
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'provides a class-level accessor' do
|
43
|
-
@victim.class.should respond_to(:logger)
|
44
|
-
@victim.class.should respond_to(:logger=)
|
45
|
-
@victim.class.logger.info 'haha'
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'provides an instance-level accessor' do
|
49
|
-
@victim.should respond_to(:logger)
|
50
|
-
@victim.should respond_to(:logger=)
|
51
|
-
@victim.logger.info 'haha'
|
52
|
-
end
|
53
|
-
|
54
|
-
context :logger do
|
55
|
-
context 'without a logger' do
|
56
|
-
before(:each) do
|
57
|
-
@victim.class.logger = nil
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'uses the default logger' do
|
61
|
-
flexmock(RightSupport::Log::Mixin.default_logger).should_receive(:info).twice.and_return(true)
|
62
|
-
@victim.class.logger.info('lalalala').should be_true
|
63
|
-
@victim.logger.info('lalalala').should be_true
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
context 'with class logger' do
|
68
|
-
before(:each) do
|
69
|
-
@logger = mock_logger
|
70
|
-
@victim.class.logger = @logger
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'uses class logger' do
|
74
|
-
@logger.should_receive(:info).and_return(true).twice
|
75
|
-
@victim.class.logger.info('lalalala').should be_true
|
76
|
-
@victim.logger.info('lalalala').should be_true
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'with instance logger' do
|
80
|
-
before(:each) do
|
81
|
-
@instance_logger = mock_logger
|
82
|
-
@victim.logger = @instance_logger
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'uses instance logger' do
|
86
|
-
@instance_logger.should_receive(:info).and_return(true).once
|
87
|
-
@logger.should_receive(:info).never
|
88
|
-
@victim.logger.info('lalalala').should be_true
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
context 'when inherited from a base class' do
|
96
|
-
let(:base_logger) { flexmock('base-class logger') }
|
97
|
-
let(:subclass_logger) { flexmock('derived-class logger') }
|
98
|
-
|
99
|
-
after(:each) do
|
100
|
-
InnocentVictim.logger = nil
|
101
|
-
Bystander.logger = nil
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'delegates to base class' do
|
105
|
-
InnocentVictim.logger = base_logger
|
106
|
-
base_logger.should_receive(:error).with('foo').once
|
107
|
-
|
108
|
-
Bystander.logger.error('foo')
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'allows override in child class' do
|
112
|
-
InnocentVictim.logger = base_logger
|
113
|
-
Bystander.logger = subclass_logger
|
114
|
-
base_logger.should_receive(:error).never
|
115
|
-
subclass_logger.should_receive(:error).with('foo').once
|
116
|
-
|
117
|
-
Bystander.logger.error('foo')
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'given someone has defined Class#logger' do
|
122
|
-
before(:all) do
|
123
|
-
InnocentVictim.logger = nil
|
124
|
-
class Class
|
125
|
-
def logger
|
126
|
-
raise "THIS SHOULD NEVER BE CALLED"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
after(:all) do
|
132
|
-
class Class
|
133
|
-
remove_method :logger
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
it 'should never delegate to Class#logger' do
|
138
|
-
InnocentVictim.logger.info 'test log'
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
@@ -1,54 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright (c) 2009-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::Log::Multiplexer do
|
26
|
-
|
27
|
-
before(:all) do
|
28
|
-
@target1 = RightSupport::Log::NullLogger.new
|
29
|
-
@target2 = RightSupport::Log::NullLogger.new
|
30
|
-
@target3 = RightSupport::Log::NullLogger.new
|
31
|
-
@multiplexer = RightSupport::Log::Multiplexer.new(@target1, @target2, @target3)
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'multiplexes method calls to all callers' do
|
35
|
-
flexmock(@target1).should_receive(:some_method).with('arg', 'arg2').once
|
36
|
-
flexmock(@target2).should_receive(:some_method).with('arg', 'arg2').once
|
37
|
-
flexmock(@target3).should_receive(:some_method).with('arg', 'arg2').once
|
38
|
-
@multiplexer.some_method('arg', 'arg2')
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'returns the result returned by the first target' do
|
42
|
-
flexmock(@target1).should_receive(:some_method).with('arg', 'arg2').and_return('res1').once
|
43
|
-
flexmock(@target2).should_receive(:some_method).with('arg', 'arg2').and_return('res2').once
|
44
|
-
flexmock(@target3).should_receive(:some_method).with('arg', 'arg2').and_return('res3').once
|
45
|
-
@multiplexer.some_method('arg', 'arg2').should == 'res1'
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'multiplexes #warn by undefining Object#warn' do
|
49
|
-
flexmock(@target1).should_receive(:warn).with('arg').and_return('res1')
|
50
|
-
flexmock(@target2).should_receive(:warn).with('arg').and_return('res2')
|
51
|
-
flexmock(@target3).should_receive(:warn).with('arg').and_return('res3')
|
52
|
-
@multiplexer.warn('arg').should == 'res1'
|
53
|
-
end
|
54
|
-
end
|
@@ -1,36 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Log::NullLogger do
|
4
|
-
before(:each) do
|
5
|
-
@logger = RightSupport::Log::NullLogger.new
|
6
|
-
end
|
7
|
-
|
8
|
-
context 'log levels' do
|
9
|
-
[:debug, :info, :warn, :error, :fatal].each do |method|
|
10
|
-
it "responds to ##{method}" do
|
11
|
-
block_called = false
|
12
|
-
@logger.__send__(method, 'lalalala').should be_true
|
13
|
-
@logger.__send__(method) { block_called = true ; 'lalalala' }.should be_true
|
14
|
-
block_called.should be_true
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
context '<< method' do
|
20
|
-
it 'responds like Logger' do
|
21
|
-
(@logger << 'lalalala').should == 8
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
context :close do
|
26
|
-
it 'responds' do
|
27
|
-
@logger.close.should be_nil
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'is idempotent' do
|
31
|
-
@logger.close.should be_nil
|
32
|
-
@logger.close.should be_nil
|
33
|
-
@logger.close.should be_nil
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require ::File.expand_path('../../spec_helper', __FILE__)
|
2
|
-
require 'stringio'
|
3
|
-
|
4
|
-
describe RightSupport::Log::StepLevelLogger do
|
5
|
-
context 'with a decorated logger' do
|
6
|
-
let(:buffer) { ::StringIO.new }
|
7
|
-
|
8
|
-
let(:decorated_logger) { ::Logger.new(buffer) }
|
9
|
-
|
10
|
-
def try_all_levels(l)
|
11
|
-
l.debug('debug')
|
12
|
-
l.info('info')
|
13
|
-
l.warn('warn')
|
14
|
-
l.error('error')
|
15
|
-
l.fatal('fatal')
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'with default level' do
|
19
|
-
subject { described_class.new(decorated_logger) }
|
20
|
-
|
21
|
-
it 'passes all messages' do
|
22
|
-
try_all_levels(subject)
|
23
|
-
buffer.string.should =~ /debug.+info.+warn.+error.+fatal/m
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
context 'with error level' do
|
28
|
-
subject do
|
29
|
-
s = described_class.new(decorated_logger)
|
30
|
-
s.level = ::Logger::ERROR
|
31
|
-
s
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'passes error and fatal messages' do
|
35
|
-
try_all_levels(subject)
|
36
|
-
buffer.string.should_not =~ /debug/
|
37
|
-
buffer.string.should_not =~ /info/
|
38
|
-
buffer.string.should_not =~ /warn/
|
39
|
-
buffer.string.should =~ /error.+fatal/m
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'does not change level of decorated logger' do
|
43
|
-
try_all_levels(decorated_logger)
|
44
|
-
buffer.string.should =~ /debug.+info.+warn.+error.+fatal/m
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
end
|
49
|
-
end
|
@@ -1,172 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'socket'
|
3
|
-
|
4
|
-
# NOTE: this spec does not get defined or executed unless SystemLogger
|
5
|
-
# is defined, which only happens if Ruby standard-library 'syslog' module is
|
6
|
-
# available at runtime. Thus, the spec does not run on Windows.
|
7
|
-
#
|
8
|
-
# The selective execution is accomplished with a trailing 'if' for this
|
9
|
-
# outermost describe block. Crude but effective. You have been warned!
|
10
|
-
describe 'RightSupport::Log::SystemLogger' do
|
11
|
-
subject { RightSupport::Log::SystemLogger }
|
12
|
-
|
13
|
-
# Duplicate constants for easier reading
|
14
|
-
SEVERITY_MAP = RightSupport::Log::SystemLogger::SEVERITY_MAP
|
15
|
-
FACILITY_MAP = RightSupport::Log::SystemLogger::FACILITY_MAP
|
16
|
-
|
17
|
-
after(:each) do
|
18
|
-
subject.instance_eval { class_variable_set(:@@syslog, nil) }
|
19
|
-
end
|
20
|
-
|
21
|
-
context :local do
|
22
|
-
before(:each) do
|
23
|
-
@mock_syslog = flexmock(Syslog)
|
24
|
-
#indicates we sent a bogus severity to syslog!
|
25
|
-
@mock_syslog.should_receive(SEVERITY_MAP[Logger::UNKNOWN]).never
|
26
|
-
flexmock(Syslog).should_receive(:open).and_return(@mock_syslog).by_default
|
27
|
-
@mock_syslog.should_receive(:info).with('Connected to syslog: :local').once
|
28
|
-
end
|
29
|
-
|
30
|
-
context :initialize do
|
31
|
-
context 'with :facility option' do
|
32
|
-
FACILITY_MAP.each_pair do |name, const|
|
33
|
-
it "should handle #{name}" do
|
34
|
-
@mock_syslog.should_receive(:open).with('unit tests', nil, const).and_return(@mock_syslog)
|
35
|
-
subject.new('unit tests', :facility=>name, :connection=>:local)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
context :add do
|
42
|
-
context 'severity levels' do
|
43
|
-
levels = { :debug=>:debug,
|
44
|
-
:info=>:info, :warn=>:notice,
|
45
|
-
:error=>:warning, :fatal=>:err }
|
46
|
-
|
47
|
-
levels.each_pair do |logger_method, syslog_method|
|
48
|
-
it "translates Logger##{logger_method} to Syslog##{syslog_method}" do
|
49
|
-
@logger = subject.new('spec', :connection=>:local)
|
50
|
-
@mock_syslog.should_receive(syslog_method).with('moo bah oink')
|
51
|
-
@logger.__send__(logger_method, 'moo bah oink')
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'escapes % characters to avoid confusing printf()' do
|
57
|
-
@logger = subject.new('spec', :connection=>:local)
|
58
|
-
@mock_syslog.should_receive(:info).with('All systems 100%% -- %%licious!')
|
59
|
-
|
60
|
-
@logger.info('All systems 100% -- %licious!')
|
61
|
-
end
|
62
|
-
|
63
|
-
context 'given :split option' do
|
64
|
-
it 'when true, splits multi-line messages' do
|
65
|
-
@logger = subject.new('spec', :split=>true, :connection=>:local)
|
66
|
-
|
67
|
-
actual = []
|
68
|
-
@mock_syslog.should_receive(:info).and_return do |message|
|
69
|
-
actual << message
|
70
|
-
true
|
71
|
-
end
|
72
|
-
|
73
|
-
@logger.info("This is a\nmulti line\r\nlog message\n\rwith all kinds\n\n\rof stuff")
|
74
|
-
actual.should == ["This is a", "multi line", "log message", "with all kinds", "of stuff"]
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'when false, passes through multi-line messages' do
|
78
|
-
@logger = subject.new('spec', :split=>false, :connection=>:local)
|
79
|
-
|
80
|
-
actual = []
|
81
|
-
@mock_syslog.should_receive(:info).and_return do |message|
|
82
|
-
actual << message
|
83
|
-
true
|
84
|
-
end
|
85
|
-
|
86
|
-
msg = "This is a\nmulti line\r\nlog message\n\rwith all kinds\n\n\rof stuff"
|
87
|
-
@logger.info(msg)
|
88
|
-
actual.should == [msg]
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'given :color option' do
|
93
|
-
it 'when true, passes through ANSI color codes' do
|
94
|
-
@logger = subject.new('spec', :color=>true, :connection=>:local)
|
95
|
-
|
96
|
-
actual = []
|
97
|
-
@mock_syslog.should_receive(:info).and_return do |message|
|
98
|
-
actual << message
|
99
|
-
true
|
100
|
-
end
|
101
|
-
|
102
|
-
msg = "This has \e[16;32mcolor\e[7;0m inside it!"
|
103
|
-
@logger.info(msg)
|
104
|
-
actual.should == [msg]
|
105
|
-
end
|
106
|
-
|
107
|
-
it 'when false, strips out ANSI color codes' do
|
108
|
-
@logger = subject.new('spec', :color=>false, :connection=>:local)
|
109
|
-
|
110
|
-
actual = []
|
111
|
-
@mock_syslog.should_receive(:info).and_return do |message|
|
112
|
-
actual << message
|
113
|
-
true
|
114
|
-
end
|
115
|
-
|
116
|
-
@logger.info("This has \e[16;32mcolor\e[7;0m inside it!")
|
117
|
-
actual.should == ['This has color inside it!']
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
context :remote do
|
124
|
-
it 'sends protocol-formatted messages to a syslog service' do
|
125
|
-
server = ::TCPServer.new(2345)
|
126
|
-
data = nil
|
127
|
-
::Thread.start do
|
128
|
-
client = server.accept
|
129
|
-
data = client.readline
|
130
|
-
client.close
|
131
|
-
end
|
132
|
-
logger = subject.new('spec', :connection=>'tcp://localhost:2345')
|
133
|
-
stop_time = ::Time.now + 3
|
134
|
-
while data.nil?
|
135
|
-
sleep(0.1)
|
136
|
-
fail 'Did not receive expected data' if ::Time.now >= stop_time
|
137
|
-
end
|
138
|
-
|
139
|
-
# example: "<134> Sep 23 13:45:42 ubuntu spec[3891]: Connected to syslog: \"tcp://localhost:2345\"\n"
|
140
|
-
regex = /^<134> \w+ \d+ \d+:\d+:\d+ .+ spec\[\d+\]: Connected to syslog: \"tcp:\/\/localhost:2345\"$/
|
141
|
-
data.chomp.should match(regex)
|
142
|
-
|
143
|
-
# attempt to reconnect to closed server.
|
144
|
-
server.close
|
145
|
-
server = nil
|
146
|
-
data = nil
|
147
|
-
::Thread.start do
|
148
|
-
sleep 1 # should cause 1-2 reconnect error(s) to appear in STDERR
|
149
|
-
server = ::TCPServer.new(2345)
|
150
|
-
client = server.accept
|
151
|
-
data = client.readline
|
152
|
-
client.close
|
153
|
-
server.close
|
154
|
-
server = nil
|
155
|
-
end
|
156
|
-
|
157
|
-
# explicitly reconnect and send with delayed server restart. reconnection
|
158
|
-
# happens automagically (only for remote) but explicit reconnection will
|
159
|
-
# reestablish the PID, etc., which is useful for forking.
|
160
|
-
logger.reconnect
|
161
|
-
logger.debug("Hello syslog")
|
162
|
-
stop_time = ::Time.now + 3
|
163
|
-
while data.nil?
|
164
|
-
sleep(0.1)
|
165
|
-
fail 'Did not receive expected data' if ::Time.now >= stop_time
|
166
|
-
end
|
167
|
-
regex = /^<135> \w+ \d+ \d+:\d+:\d+ .+ spec\[\d+\]: Hello syslog$/
|
168
|
-
data.chomp.should match(regex)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
end if defined?(RightSupport::Log::SystemLogger)
|
@@ -1,57 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Net::AddressHelper do
|
4
|
-
class AddressHelperTarget
|
5
|
-
include RightSupport::Net::AddressHelper
|
6
|
-
end
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
@helper = AddressHelperTarget.new
|
10
|
-
end
|
11
|
-
|
12
|
-
describe :my_ipv4_addresses do
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
describe :my_ipv4_address do
|
17
|
-
it 'consistently chooses the lowest-numbered address' do
|
18
|
-
p = ['10.0.1.17', '192.168.7.5', '192.168.4.2', '127.0.0.1']
|
19
|
-
flexmock(@helper).should_receive(:local_routable_address).with(Socket::AF_INET).and_return(p[0])
|
20
|
-
flexmock(@helper).should_receive(:local_hostname_addresses).with(Socket::AF_INET).once.ordered.and_return([ p[3], p[2] ])
|
21
|
-
flexmock(@helper).should_receive(:local_hostname_addresses).with(Socket::AF_INET).once.ordered.and_return([ p[1], p[2] ])
|
22
|
-
|
23
|
-
one = @helper.my_ipv4_address(:private)
|
24
|
-
two = @helper.my_ipv4_address(:private)
|
25
|
-
one.should == p[0]
|
26
|
-
two.should == p[0]
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe :my_ipv4_addresses do
|
31
|
-
before(:each) do
|
32
|
-
routable_addr = '67.2.204.5'
|
33
|
-
hostname_addrs = ['127.0.0.1', '10.0.0.15', '67.2.204.5']
|
34
|
-
flexmock(@helper).should_receive(:local_routable_address).with(Socket::AF_INET).and_return(routable_addr)
|
35
|
-
flexmock(@helper).should_receive(:local_hostname_addresses).with(Socket::AF_INET).and_return(hostname_addrs)
|
36
|
-
flexmock(@helper).should_receive(:local_hostname_addresses).with(Socket::AF_INET).and_return(hostname_addrs)
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'with :loopback option' do
|
40
|
-
it 'returns only loopback addresses' do
|
41
|
-
@helper.my_ipv4_addresses(:loopback).should == ['127.0.0.1']
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context 'with :private option' do
|
46
|
-
it 'returns only private addresses' do
|
47
|
-
@helper.my_ipv4_addresses(:private).should == ['10.0.0.15']
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
context 'with :public option' do
|
52
|
-
it 'returns only public addresses' do
|
53
|
-
@helper.my_ipv4_addresses(:public).should == ['67.2.204.5']
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
data/spec/net/dns_spec.rb
DELETED
@@ -1,187 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe RightSupport::Net::DNS do
|
4
|
-
include SpecHelper::SocketMocking
|
5
|
-
|
6
|
-
subject { RightSupport::Net::DNS } #the module itself
|
7
|
-
|
8
|
-
context :resolve_all_ip_addresses do
|
9
|
-
before(:all) do
|
10
|
-
@hostnames = ['1.1.1.1', '2.2.2.2', '3.3.3.3']
|
11
|
-
@hostnames .each do |hostname|
|
12
|
-
flexmock(Socket).should_receive(:getaddrinfo).with(hostname, 443, Socket::AF_INET, Socket::SOCK_STREAM, Socket::IPPROTO_TCP).once.and_return([[0,0,0,hostname]])
|
13
|
-
end
|
14
|
-
end
|
15
|
-
it 'resolves all ip addresses for specified array of endpoints' do
|
16
|
-
@resolved_hostnames = subject.resolve_all_ip_addresses(@hostnames)
|
17
|
-
(@resolved_hostnames - @hostnames).should be_eql([])
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
|
22
|
-
context :resolve do
|
23
|
-
context 'given default :retry => 3' do
|
24
|
-
let(:endpoint) { 'www.example.com' }
|
25
|
-
let(:output) { [RightSupport::Net::ResolvedEndpoint.new(['1.1.1.1', '2.2.2.2'])] }
|
26
|
-
|
27
|
-
it 'retries SocketError' do
|
28
|
-
mock_getaddrinfo('www.example.com', SocketError)
|
29
|
-
mock_getaddrinfo('www.example.com', ['1.1.1.1', '2.2.2.2'])
|
30
|
-
|
31
|
-
subject.resolve(endpoint).should == output
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'stops retrying SocketError after three attempts' do
|
35
|
-
mock_getaddrinfo('www.example.com', SocketError, 3)
|
36
|
-
|
37
|
-
expect { subject.resolve(endpoint) }.to raise_error(SocketError)
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'does not rescue other exceptions' do
|
41
|
-
mock_getaddrinfo('www.example.com', ArgumentError)
|
42
|
-
|
43
|
-
expect { subject.resolve(endpoint) }.to raise_error(ArgumentError)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context 'given :retry => 0' do
|
48
|
-
it 'does not retry SocketError' do
|
49
|
-
mock_getaddrinfo('www.example.com', SocketError)
|
50
|
-
|
51
|
-
expect { subject.resolve('www.example.com', :retry=>0) }.to raise_error(SocketError)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
context 'given various endpoint formats' do
|
56
|
-
context 'e.g. a DNS hostname' do
|
57
|
-
let(:endpoint) { 'www.example.com' }
|
58
|
-
let(:output) { [RightSupport::Net::ResolvedEndpoint.new(['1.1.1.1', '2.2.2.2'])] }
|
59
|
-
|
60
|
-
it 'resolves to IP addresses' do
|
61
|
-
mock_getaddrinfo('www.example.com', ['1.1.1.1', '2.2.2.2'])
|
62
|
-
subject.resolve(endpoint).should == output
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context 'e.g. an IPv4 address' do
|
67
|
-
let(:endpoint) { '127.0.0.1' }
|
68
|
-
let(:output) { [RightSupport::Net::ResolvedEndpoint.new(['127.0.0.1'])] }
|
69
|
-
|
70
|
-
it 'resolves to the same address' do
|
71
|
-
mock_getaddrinfo('127.0.0.1', ['127.0.0.1'])
|
72
|
-
subject.resolve(endpoint).should == output
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
context 'e.g. an HTTP URL' do
|
77
|
-
let(:endpoint) { 'http://www.example.com' }
|
78
|
-
let(:output) { ['http://1.1.1.1', 'http://2.2.2.2'] }
|
79
|
-
|
80
|
-
it 'resolves to URLs with addresses substituted' do
|
81
|
-
mock_getaddrinfo('www.example.com', ['1.1.1.1', '2.2.2.2'])
|
82
|
-
subject.resolve(endpoint).first.addrs.should == output
|
83
|
-
end
|
84
|
-
|
85
|
-
context 'with a path component' do
|
86
|
-
let(:endpoint) { 'http://www.example.com/foo/bar' }
|
87
|
-
let(:output) { ['http://1.1.1.1/foo/bar', 'http://2.2.2.2/foo/bar'] }
|
88
|
-
|
89
|
-
it 'resolves to URLs with path component preserved' do
|
90
|
-
mock_getaddrinfo('www.example.com', ['1.1.1.1', '2.2.2.2'])
|
91
|
-
subject.resolve(endpoint).first.addrs.should == output
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# The double slash in a URI indicates that an authority follows. The authority
|
97
|
-
# is interpreted as a hostname for most URL schemes we are interested in. We
|
98
|
-
# can't deal with URLs unless they have a clear authority/hostname that we
|
99
|
-
# can substitute.
|
100
|
-
#
|
101
|
-
# For more information, see: http://tools.ietf.org/html/rfc3986#section-3
|
102
|
-
context 'e.g. a URI without an authority' do
|
103
|
-
let(:endpoint) { 'urn:uuid:6e8bc430-9c3a-11d9-9669-0800200c9a66' }
|
104
|
-
|
105
|
-
it 'raises URI::InvalidURIError' do
|
106
|
-
lambda do
|
107
|
-
subject.resolve(endpoint)
|
108
|
-
end.should raise_error(URI::InvalidURIError)
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
context 'e.g. several hostnames' do
|
113
|
-
let(:endpoints) { ['www.example.com', 'www.example.net'] }
|
114
|
-
let(:output) { [RightSupport::Net::ResolvedEndpoint.new(['1.1.1.1', '2.2.2.2']), RightSupport::Net::ResolvedEndpoint.new(['3.3.3.3', '4.4.4.4'])] }
|
115
|
-
|
116
|
-
it 'resolves to IP addresses' do
|
117
|
-
mock_getaddrinfo('www.example.com', ['1.1.1.1', '2.2.2.2'])
|
118
|
-
mock_getaddrinfo('www.example.net', ['3.3.3.3', '4.4.4.4'])
|
119
|
-
|
120
|
-
subject.resolve(endpoints).should == output
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
context 'e.g. several HTTP URLs' do
|
125
|
-
let(:endpoints) { ['http://www.example.com', 'http://www.example.net'] }
|
126
|
-
let(:output) { ['http://1.1.1.1', 'http://2.2.2.2', 'http://3.3.3.3', 'http://4.4.4.4'] }
|
127
|
-
|
128
|
-
it 'resolves to URLs with addresses substituted' do
|
129
|
-
mock_getaddrinfo('www.example.com', ['1.1.1.1', '2.2.2.2'])
|
130
|
-
mock_getaddrinfo('www.example.net', ['3.3.3.3', '4.4.4.4'])
|
131
|
-
|
132
|
-
subject.resolve(endpoints).map {|ep| ep.addrs}.flatten == output
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context 'requesting CIDR blocks' do
|
138
|
-
context 'DNS resolvable addresses' do
|
139
|
-
let(:endpoint) { 'www.example.com' }
|
140
|
-
let(:output) { ['1.1.1.1/32', '2.2.2.2/32'] }
|
141
|
-
|
142
|
-
it 'resolves hostname to CIDR /32 blocks' do
|
143
|
-
mock_getaddrinfo('www.example.com', ['1.1.1.1', '2.2.2.2'])
|
144
|
-
subject.resolve(endpoint).first.blocks.should == output
|
145
|
-
end
|
146
|
-
|
147
|
-
it 'resolves IP addresses to CIDR /32 blocks' do
|
148
|
-
mock_getaddrinfo('1.1.1.1', ['1.1.1.1'])
|
149
|
-
mock_getaddrinfo('2.2.2.2', ['2.2.2.2'])
|
150
|
-
subject.resolve(['1.1.1.1', '2.2.2.2']).map {|endpoint| endpoint.blocks}.flatten.should =~ output
|
151
|
-
end
|
152
|
-
|
153
|
-
it 'refuses to resolve a URI having a CIDR block < /32' do
|
154
|
-
lambda do
|
155
|
-
subject.resolve("http://cf-mirror.rightscale.com")
|
156
|
-
end.should raise_error(URI::InvalidURIError)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
context 'Static CIDR blocks' do
|
161
|
-
let(:endpoint) { 'cf-mirror.rightscale.com' }
|
162
|
-
|
163
|
-
it 'resolves hostname to static CIDR blocks' do
|
164
|
-
subject.resolve(endpoint).first.blocks.each do |addr|
|
165
|
-
# Addresses should all be in CIDR form and not single /32 addresses
|
166
|
-
addr.should =~ /^\d+(?:\.\d+){3}\/(?:#{1.upto(31).to_a.join('|')})$/
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
context :resolve_with_hostnames do
|
174
|
-
context 'given common inputs' do
|
175
|
-
let(:endpoints) { ['www.example1.com','www.example2.com'] }
|
176
|
-
let(:output) { {'www.example1.com'=>RightSupport::Net::ResolvedEndpoint.new(['1.1.1.1', '2.2.2.2']),
|
177
|
-
'www.example2.com'=>RightSupport::Net::ResolvedEndpoint.new(['3.3.3.3', '4.4.4.4'])} }
|
178
|
-
|
179
|
-
it 'resolves to IP addresses' do
|
180
|
-
mock_getaddrinfo('www.example1.com', ['1.1.1.1', '2.2.2.2'])
|
181
|
-
mock_getaddrinfo('www.example2.com', ['3.3.3.3', '4.4.4.4'])
|
182
|
-
subject.resolve_with_hostnames(endpoints).should == output
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
end
|