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