is_it_working 1.0.11 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -6
- data/Appraisals +20 -0
- data/Gemfile +0 -2
- data/README.rdoc +4 -2
- data/Rakefile +20 -0
- data/gemfiles/rails_3.2.gemfile +8 -0
- data/gemfiles/rails_4.0.gemfile +8 -0
- data/gemfiles/rails_4.1.gemfile +8 -0
- data/gemfiles/rails_4.2.gemfile +8 -0
- data/is_it_working.gemspec +11 -8
- data/lib/is_it_working.rb +1 -2
- data/lib/is_it_working/handler.rb +0 -1
- data/lib/is_it_working/version.rb +1 -1
- data/spec/action_mailer_check_spec.rb +3 -3
- data/spec/active_record_check_spec.rb +58 -26
- data/spec/directory_check_spec.rb +6 -6
- data/spec/handler_spec.rb +117 -0
- data/spec/spec_helper.rb +0 -1
- metadata +51 -23
- data/lib/is_it_working/checks/memcache_check.rb +0 -46
- data/spec/memcache_check_spec.rb +0 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24d1e08e404f5b29ccadc89ac32bc444e8edefe4
|
4
|
+
data.tar.gz: c524afde649b57b1ec58453d52b537be0cb0dca3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cc739deb6a5cbe0b812a66fde0f086ab81cf5181cd23a3522297659cb0c8269258fb3485fe999c32a9a1dba0210e97099b45d75674d266372cd1701bf35d5264
|
7
|
+
data.tar.gz: 1ece61a2b88e08ca5e6b3009d67426c40e7954c4c094cad64eec105a6b071e9bcf9d6f4addab758a9f91ad472c66bfed3548c0f784278fb4407e2ff1abf7ca97
|
data/.gitignore
CHANGED
data/Appraisals
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# Install gems for all appraisal definitions:
|
2
|
+
#
|
3
|
+
# $ appraisal install
|
4
|
+
#
|
5
|
+
# To run tests on different versions:
|
6
|
+
#
|
7
|
+
# $ appraisal activerecord_x.x rspec spec
|
8
|
+
|
9
|
+
[
|
10
|
+
[ '3.2', '~> 3.2.0' ],
|
11
|
+
[ '4.0', '~> 4.0.0' ],
|
12
|
+
[ '4.1', '~> 4.1.0' ],
|
13
|
+
[ '4.2', '~> 4.2.0' ],
|
14
|
+
].each do |ver_name, ver_req|
|
15
|
+
appraise "rails_#{ver_name}" do
|
16
|
+
gem 'actionmailer', ver_req
|
17
|
+
gem 'activerecord', ver_req
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -25,8 +25,8 @@ A monitoring handler for this set up could be set up in <tt>config/initializers/
|
|
25
25
|
# Check the ActiveRecord database connection without spawning a new thread
|
26
26
|
h.check :active_record, :async => false
|
27
27
|
|
28
|
-
# Check the memcache servers used by Rails.cache if using the
|
29
|
-
h.check :
|
28
|
+
# Check the memcache servers used by Rails.cache if using the DalliStore implementation
|
29
|
+
h.check :dalli, :cache => Rails.cache if defined?(ActiveSupport::Cache::DalliStore) && Rails.cache.is_a?(ActiveSupport::Cache::DalliStore)
|
30
30
|
|
31
31
|
# Check that the web service is working by hitting a known URL with Basic authentication
|
32
32
|
h.check :url, :get => "http://api.example.com/version", :username => "appname", :password => "abc123"
|
@@ -50,6 +50,8 @@ A monitoring handler for this set up could be set up in <tt>config/initializers/
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
+
See <tt>IsItWorking::Handler#check</tt> for built-in handlers.
|
54
|
+
|
53
55
|
== Output
|
54
56
|
|
55
57
|
The response from the handler will be a plain text description of the checks that were run and the results of those checks. If all the checks passed, the response code will be 200. If any checks fail, the response code will be 500. The response will look something like this:
|
data/Rakefile
CHANGED
@@ -1 +1,21 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
|
+
require 'bundler/setup' # constrain rake version
|
3
|
+
|
4
|
+
# Note: if you get this error: "Bundler could not find compatible versions for gem ..."
|
5
|
+
# try deleting Gemfile.lock (usually happens when switching branches).
|
6
|
+
|
7
|
+
task default: :appraise_all
|
8
|
+
|
9
|
+
# This is slightly different from 'appraisal COMMAND' because it continues even if a definition fails.
|
10
|
+
desc "Run rspecs for all appraisals"
|
11
|
+
task :appraise_all do
|
12
|
+
success_map = {}
|
13
|
+
`bundle exec appraisal list`.lines.map(&:chomp).each do |appraise_def|
|
14
|
+
success = system('appraisal', appraise_def, 'rspec', 'spec')
|
15
|
+
success_map[appraise_def] = success
|
16
|
+
end
|
17
|
+
puts "\n===== Test Summary ====="
|
18
|
+
success_map.each do |appraise_def, success|
|
19
|
+
puts "#{appraise_def}: #{success ? 'no failures (but check pending)' : 'failed'}"
|
20
|
+
end
|
21
|
+
end
|
data/is_it_working.gemspec
CHANGED
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'is_it_working/version'
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'is_it_working'
|
7
|
-
spec.version = IsItWorking::VERSION
|
7
|
+
spec.version = IsItWorking::VERSION.dup # dup for ruby 1.9
|
8
8
|
spec.authors = ['Brian Durand', 'Milan Dobrota']
|
9
9
|
spec.email = ['mdobrota@tribpub.com']
|
10
10
|
spec.summary = 'Rack handler for monitoring several parts of a web application.'
|
@@ -16,12 +16,15 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
17
17
|
spec.require_paths = ['lib']
|
18
18
|
|
19
|
-
spec.add_development_dependency '
|
20
|
-
spec.add_development_dependency '
|
21
|
-
|
19
|
+
spec.add_development_dependency 'actionmailer', '>= 3.2', '< 4.3'
|
20
|
+
spec.add_development_dependency 'activerecord', '>= 3.2', '< 4.3'
|
21
|
+
|
22
22
|
spec.add_development_dependency 'dalli', '>= 0'
|
23
|
-
spec.add_development_dependency '
|
24
|
-
|
25
|
-
spec.add_development_dependency '
|
26
|
-
spec.add_development_dependency '
|
23
|
+
spec.add_development_dependency 'sqlite3'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'rspec' , '~> 2.99.0'
|
26
|
+
spec.add_development_dependency 'webmock' , '~> 1.7.7'
|
27
|
+
spec.add_development_dependency 'bundler' , '~> 1.7'
|
28
|
+
spec.add_development_dependency 'rake' , '~> 10.0'
|
29
|
+
spec.add_development_dependency 'appraisal', '~> 2.0'
|
27
30
|
end
|
data/lib/is_it_working.rb
CHANGED
@@ -12,7 +12,6 @@ module IsItWorking
|
|
12
12
|
autoload :ActiveRecordCheck, File.expand_path("../is_it_working/checks/active_record_check.rb", __FILE__)
|
13
13
|
autoload :DalliCheck, File.expand_path("../is_it_working/checks/dalli_check.rb", __FILE__)
|
14
14
|
autoload :DirectoryCheck, File.expand_path("../is_it_working/checks/directory_check.rb", __FILE__)
|
15
|
-
autoload :MemcacheCheck, File.expand_path("../is_it_working/checks/memcache_check.rb", __FILE__)
|
16
15
|
autoload :PingCheck, File.expand_path("../is_it_working/checks/ping_check.rb", __FILE__)
|
17
16
|
autoload :UrlCheck, File.expand_path("../is_it_working/checks/url_check.rb", __FILE__)
|
18
|
-
end
|
17
|
+
end
|
@@ -69,7 +69,6 @@ module IsItWorking
|
|
69
69
|
# * <tt>:active_record</tt> - Check if the database connection for an ActiveRecord class is up
|
70
70
|
# * <tt>:dalli</tt> - DalliCheck checks if all the servers in a MemCache cluster are available using dalli
|
71
71
|
# * <tt>:directory</tt> - DirectoryCheck checks for the accessibilty of a file system directory
|
72
|
-
# * <tt>:memcache</tt> - MemcacheCheck checks if all the servers in a MemCache cluster are available using memcache-client
|
73
72
|
# * <tt>:ping</tt> - Check if a host is reachable and accepting connections on a port
|
74
73
|
# * <tt>:url</tt> - Check if a getting a URL returns a success response
|
75
74
|
def check (name, *options_or_check, &block)
|
@@ -7,7 +7,7 @@ describe IsItWorking::ActionMailerCheck do
|
|
7
7
|
it "should succeed if the default mail host is accepting connections" do
|
8
8
|
ActionMailer::Base.smtp_settings[:address] = 'localhost'
|
9
9
|
ActionMailer::Base.smtp_settings[:port] = 25
|
10
|
-
TCPSocket.should_receive(:new).with('localhost', 25).and_return(
|
10
|
+
TCPSocket.should_receive(:new).with('localhost', 25).and_return(double(:socket, :close => true))
|
11
11
|
check = IsItWorking::ActionMailerCheck.new
|
12
12
|
check.call(status)
|
13
13
|
status.should be_success
|
@@ -30,7 +30,7 @@ describe IsItWorking::ActionMailerCheck do
|
|
30
30
|
|
31
31
|
IsItWorking::ActionMailerCheck::Tester.smtp_settings[:address] = 'mail.example.com'
|
32
32
|
IsItWorking::ActionMailerCheck::Tester.smtp_settings[:port] = 'smtp'
|
33
|
-
TCPSocket.should_receive(:new).with('mail.example.com', 'smtp').and_return(
|
33
|
+
TCPSocket.should_receive(:new).with('mail.example.com', 'smtp').and_return(double(:socket, :close => true))
|
34
34
|
check = IsItWorking::ActionMailerCheck.new(:class => IsItWorking::ActionMailerCheck::Tester)
|
35
35
|
check.call(status)
|
36
36
|
status.should be_success
|
@@ -40,7 +40,7 @@ describe IsItWorking::ActionMailerCheck do
|
|
40
40
|
it "should allow aliasing the ActionMailer host alias" do
|
41
41
|
ActionMailer::Base.smtp_settings[:address] = 'localhost'
|
42
42
|
ActionMailer::Base.smtp_settings[:port] = 25
|
43
|
-
TCPSocket.should_receive(:new).with('localhost', 25).and_return(
|
43
|
+
TCPSocket.should_receive(:new).with('localhost', 25).and_return(double(:socket, :close => true))
|
44
44
|
check = IsItWorking::ActionMailerCheck.new(:alias => "smtp host")
|
45
45
|
check.call(status)
|
46
46
|
status.should be_success
|
@@ -3,49 +3,81 @@ require 'spec_helper'
|
|
3
3
|
describe IsItWorking::ActiveRecordCheck do
|
4
4
|
|
5
5
|
let(:status){ IsItWorking::Status.new(:active_record) }
|
6
|
+
let(:abstract_conn) do
|
7
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.new(double(:connection))
|
8
|
+
end
|
6
9
|
|
7
10
|
class IsItWorking::TestActiveRecord < ActiveRecord::Base
|
8
11
|
end
|
9
12
|
|
10
|
-
it "
|
11
|
-
|
12
|
-
connection
|
13
|
-
ActiveRecord::Base.stub!(:connection).and_return(connection)
|
13
|
+
it "succeeds if the ActiveRecord connection is active" do
|
14
|
+
abstract_conn.stub(active?: true)
|
15
|
+
ActiveRecord::Base.stub(connection: abstract_conn)
|
14
16
|
check = IsItWorking::ActiveRecordCheck.new
|
15
17
|
check.call(status)
|
16
|
-
status.
|
17
|
-
status.messages.first.message.
|
18
|
+
expect(status).to be_success
|
19
|
+
expect(status.messages.first.message).to eq "ActiveRecord::Base.connection is active"
|
18
20
|
end
|
19
21
|
|
20
|
-
it "
|
21
|
-
|
22
|
-
connection
|
23
|
-
IsItWorking::TestActiveRecord.stub!(:connection).and_return(connection)
|
22
|
+
it "allows specifying the class to check the connection for" do
|
23
|
+
abstract_conn.stub(active?: true)
|
24
|
+
IsItWorking::TestActiveRecord.stub(connection: abstract_conn)
|
24
25
|
check = IsItWorking::ActiveRecordCheck.new(:class => IsItWorking::TestActiveRecord)
|
25
26
|
check.call(status)
|
26
|
-
status.
|
27
|
-
status.messages.first.message.
|
27
|
+
expect(status).to be_success
|
28
|
+
expect(status.messages.first.message).to eq "IsItWorking::TestActiveRecord.connection is active"
|
28
29
|
end
|
29
30
|
|
30
|
-
it "
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
it "succeeds if the ActiveRecord connection can be reconnected" do
|
32
|
+
# On Rails 4, calling `disconnect!` puts the adapter in a weird state that can't be restored with `verify!`. Using `reconnect!` is ok.
|
33
|
+
abstract_conn.reconnect!
|
34
|
+
abstract_conn.stub(active?: true)
|
35
|
+
ActiveRecord::Base.stub(connection: abstract_conn)
|
34
36
|
check = IsItWorking::ActiveRecordCheck.new
|
35
37
|
check.call(status)
|
36
|
-
status.
|
37
|
-
status.messages.first.message.
|
38
|
+
expect(status).to be_success
|
39
|
+
expect(status.messages.first.message).to eq "ActiveRecord::Base.connection is active"
|
38
40
|
end
|
39
41
|
|
40
|
-
it "
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
ActiveRecord::Base.stub!(:connection).and_return(connection)
|
42
|
+
it "fails if the ActiveRecord connection is not active" do
|
43
|
+
abstract_conn.disconnect!
|
44
|
+
abstract_conn.stub(:verify!)
|
45
|
+
ActiveRecord::Base.stub(connection: abstract_conn)
|
45
46
|
check = IsItWorking::ActiveRecordCheck.new
|
46
47
|
check.call(status)
|
47
|
-
status.
|
48
|
-
status.messages.first.message.
|
48
|
+
expect(status).not_to be_success
|
49
|
+
expect(status.messages.first.message).to eq "ActiveRecord::Base.connection is not active"
|
50
|
+
end
|
51
|
+
|
52
|
+
# Use a real database, with as little stubbing as possible
|
53
|
+
context "sqlite3" do
|
54
|
+
let(:model_class_name) { 'IsItWorkingTestModel'.freeze }
|
55
|
+
let(:model_class) { make_ar_klass }
|
56
|
+
|
57
|
+
def make_ar_klass(name = model_class_name)
|
58
|
+
klass = Class.new(ActiveRecord::Base) do |k|
|
59
|
+
def k.name; to_s; end
|
60
|
+
end
|
61
|
+
klass_name = name.to_s.dup.freeze
|
62
|
+
klass.define_singleton_method(:to_s) { klass_name }
|
63
|
+
klass.establish_connection(adapter: 'sqlite3', database: ':memory:')
|
64
|
+
klass
|
65
|
+
end
|
66
|
+
|
67
|
+
it "succeeds on active connection" do
|
68
|
+
check = IsItWorking::ActiveRecordCheck.new(class: model_class)
|
69
|
+
check.call(status)
|
70
|
+
expect(status).to be_success
|
71
|
+
expect(status.messages.first.message).to eq "#{model_class_name}.connection is active"
|
72
|
+
end
|
73
|
+
|
74
|
+
it "fails on dead connection" do
|
75
|
+
model_class.connection.disconnect!
|
76
|
+
model_class.connection.stub(:verify!)
|
77
|
+
check = IsItWorking::ActiveRecordCheck.new(class: model_class)
|
78
|
+
check.call(status)
|
79
|
+
expect(status).not_to be_success
|
80
|
+
expect(status.messages.first.message).to eq "#{model_class_name}.connection is not active"
|
81
|
+
end
|
49
82
|
end
|
50
|
-
|
51
83
|
end
|
@@ -21,7 +21,7 @@ describe IsItWorking::DirectoryCheck do
|
|
21
21
|
|
22
22
|
it "should succeed if a directory exists" do
|
23
23
|
check = IsItWorking::DirectoryCheck.new(:path => directory_path)
|
24
|
-
File.should_receive(:stat).with(directory_path).and_return(
|
24
|
+
File.should_receive(:stat).with(directory_path).and_return(double(:stat, :directory? => true, :readable? => false, :writable? => false))
|
25
25
|
check.call(status)
|
26
26
|
status.should be_success
|
27
27
|
status.messages.first.message.should include("exists")
|
@@ -29,7 +29,7 @@ describe IsItWorking::DirectoryCheck do
|
|
29
29
|
|
30
30
|
it "should fail if a directory is not readable" do
|
31
31
|
check = IsItWorking::DirectoryCheck.new(:path => directory_path, :permission => :read)
|
32
|
-
File.should_receive(:stat).with(directory_path).and_return(
|
32
|
+
File.should_receive(:stat).with(directory_path).and_return(double(:stat, :directory? => true, :readable? => false, :writable? => true))
|
33
33
|
check.call(status)
|
34
34
|
status.should_not be_success
|
35
35
|
status.messages.first.message.should include("is not readable")
|
@@ -37,7 +37,7 @@ describe IsItWorking::DirectoryCheck do
|
|
37
37
|
|
38
38
|
it "should fail if a directory is not writable" do
|
39
39
|
check = IsItWorking::DirectoryCheck.new(:path => directory_path, :permission => :write)
|
40
|
-
File.should_receive(:stat).with(directory_path).and_return(
|
40
|
+
File.should_receive(:stat).with(directory_path).and_return(double(:stat, :directory? => true, :readable? => true, :writable? => false))
|
41
41
|
check.call(status)
|
42
42
|
status.should_not be_success
|
43
43
|
status.messages.first.message.should include("is not writable")
|
@@ -45,7 +45,7 @@ describe IsItWorking::DirectoryCheck do
|
|
45
45
|
|
46
46
|
it "should succeed if a directory exists and is readable" do
|
47
47
|
check = IsItWorking::DirectoryCheck.new(:path => directory_path, :permission => :read)
|
48
|
-
File.should_receive(:stat).with(directory_path).and_return(
|
48
|
+
File.should_receive(:stat).with(directory_path).and_return(double(:stat, :directory? => true, :readable? => true, :writable? => false))
|
49
49
|
check.call(status)
|
50
50
|
status.should be_success
|
51
51
|
status.messages.first.message.should include("exists with")
|
@@ -53,7 +53,7 @@ describe IsItWorking::DirectoryCheck do
|
|
53
53
|
|
54
54
|
it "should succeed if a directory exists and is writable" do
|
55
55
|
check = IsItWorking::DirectoryCheck.new(:path => directory_path, :permission => :write)
|
56
|
-
File.should_receive(:stat).with(directory_path).and_return(
|
56
|
+
File.should_receive(:stat).with(directory_path).and_return(double(:stat, :directory? => true, :readable? => false, :writable? => true))
|
57
57
|
check.call(status)
|
58
58
|
status.should be_success
|
59
59
|
status.messages.first.message.should include("exists with")
|
@@ -61,7 +61,7 @@ describe IsItWorking::DirectoryCheck do
|
|
61
61
|
|
62
62
|
it "should succeed if a directory exists and is readable and writable" do
|
63
63
|
check = IsItWorking::DirectoryCheck.new(:path => directory_path, :permission => [:read, :write])
|
64
|
-
File.should_receive(:stat).with(directory_path).and_return(
|
64
|
+
File.should_receive(:stat).with(directory_path).and_return(double(:stat, :directory? => true, :readable? => true, :writable? => true))
|
65
65
|
check.call(status)
|
66
66
|
status.should be_success
|
67
67
|
status.messages.first.message.should include("exists with")
|
data/spec/handler_spec.rb
CHANGED
@@ -137,4 +137,121 @@ describe IsItWorking::Handler do
|
|
137
137
|
handler.hostname = "woot"
|
138
138
|
handler.call("PATH_INFO" => "/is_it_working").last.join("").should include("woot")
|
139
139
|
end
|
140
|
+
|
141
|
+
# NOTE: these tests are only to document existing behavior, not actual requirements.
|
142
|
+
context "Adding filters:" do
|
143
|
+
let(:handler) do
|
144
|
+
described_class.allocate.tap do |h|
|
145
|
+
h.instance_variable_set(:@filters, filters)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
let(:opts) { {myopt: 'myval'.freeze}.freeze }
|
149
|
+
let(:opts_with_async) { {async: true}.merge(opts).freeze }
|
150
|
+
let(:opts_without_async) { {async: false}.merge(opts).freeze }
|
151
|
+
let(:filters) { [] }
|
152
|
+
let(:ck_name) { :look_me_up }
|
153
|
+
let(:looked_up_check) { double(:looked_up_check) }
|
154
|
+
let(:example_full_desc) { RSpec.current_example.full_description.dup.freeze }
|
155
|
+
let(:passed_proc) { proc{|stat| example_full_desc } }
|
156
|
+
|
157
|
+
before :each do
|
158
|
+
handler.stub(:lookup_check) { raise 'Unexpected lookup_check call' }
|
159
|
+
end
|
160
|
+
|
161
|
+
context "check(name, &block)" do
|
162
|
+
it "uses block as check" do
|
163
|
+
handler.check(ck_name, &passed_proc)
|
164
|
+
expect(filters[0].name).to eq ck_name
|
165
|
+
expect(filters[0].instance_variable_get(:@check).call(nil)).to eq example_full_desc
|
166
|
+
expect(filters[0].async).to be true
|
167
|
+
end
|
168
|
+
|
169
|
+
context "check(name, options, &block)" do
|
170
|
+
it "allows disabling of async" do
|
171
|
+
handler.check(ck_name, async: false, &passed_proc)
|
172
|
+
expect(filters[0].name).to eq ck_name
|
173
|
+
expect(filters[0].instance_variable_get(:@check).call(nil)).to eq example_full_desc
|
174
|
+
expect(filters[0].async).to be false
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context "check(name, options)" do
|
180
|
+
it "uses looked-up class with passed-in options" do
|
181
|
+
handler.should_receive(:lookup_check).with(ck_name, opts_with_async).and_return looked_up_check
|
182
|
+
handler.check(ck_name, opts)
|
183
|
+
expect(filters[0].name).to eq ck_name
|
184
|
+
expect(filters[0].instance_variable_get(:@check)).to be looked_up_check
|
185
|
+
expect(filters[0].async).to be true
|
186
|
+
end
|
187
|
+
|
188
|
+
it "allows disabling of async" do
|
189
|
+
handler.should_receive(:lookup_check).with(ck_name, opts_without_async).and_return looked_up_check
|
190
|
+
handler.check(ck_name, opts_without_async)
|
191
|
+
expect(filters[0].name).to eq ck_name
|
192
|
+
expect(filters[0].instance_variable_get(:@check)).to be looked_up_check
|
193
|
+
expect(filters[0].async).to be false
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "check(name, check)" do
|
198
|
+
it "uses passed-in check" do
|
199
|
+
handler.check(ck_name, passed_proc)
|
200
|
+
expect(filters[0].name).to eq ck_name
|
201
|
+
expect(filters[0].instance_variable_get(:@check)).to be passed_proc
|
202
|
+
expect(filters[0].async).to be true
|
203
|
+
end
|
204
|
+
|
205
|
+
it "ignores block" do
|
206
|
+
handler.check(ck_name, passed_proc) { raise "don't call me" }
|
207
|
+
expect(filters[0].name).to eq ck_name
|
208
|
+
expect(filters[0].instance_variable_get(:@check)).to be passed_proc
|
209
|
+
expect(filters[0].async).to be true
|
210
|
+
end
|
211
|
+
|
212
|
+
context "check(name, check, options)" do
|
213
|
+
it "allows disabling of async" do
|
214
|
+
handler.check(ck_name, passed_proc, opts_without_async)
|
215
|
+
expect(filters[0].name).to eq ck_name
|
216
|
+
expect(filters[0].instance_variable_get(:@check)).to be passed_proc
|
217
|
+
expect(filters[0].async).to be false
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
|
224
|
+
context "lookup_check (non-public)" do
|
225
|
+
let(:handler) { described_class.allocate }
|
226
|
+
let(:check_data) do
|
227
|
+
[
|
228
|
+
[:action_mailer, IsItWorking::ActionMailerCheck],
|
229
|
+
[:active_record, IsItWorking::ActiveRecordCheck],
|
230
|
+
[:dalli, IsItWorking::DalliCheck ],
|
231
|
+
[:directory, IsItWorking::DirectoryCheck ],
|
232
|
+
[:ping, IsItWorking::PingCheck ],
|
233
|
+
[:url, IsItWorking::UrlCheck ],
|
234
|
+
].each_with_object(Hash.new) do |(ck_name, ck_class), map|
|
235
|
+
map[ck_name] = {
|
236
|
+
class: ck_class,
|
237
|
+
opts: double("#{ck_name} opts"),
|
238
|
+
instance: double("#{ck_class} instance")
|
239
|
+
}
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
it "works for built-in check classes" do
|
244
|
+
check_data.each do |ck_name, data|
|
245
|
+
data[:class].should_receive(:new).with(data[:opts]).and_return data[:instance]
|
246
|
+
end
|
247
|
+
|
248
|
+
check_data.each do |ck_name, data|
|
249
|
+
expect(handler.send(:lookup_check, ck_name, data[:opts])).to be data[:instance]
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
it "raises on undefined check class" do
|
254
|
+
expect{ handler.send(:lookup_check, :foobar, {}) }.to raise_error(/Check not defined FoobarCheck/i)
|
255
|
+
end
|
256
|
+
end
|
140
257
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: is_it_working
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Durand
|
@@ -9,38 +9,50 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-06-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: actionmailer
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '3.2'
|
21
|
+
- - "<"
|
19
22
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
23
|
+
version: '4.3'
|
21
24
|
type: :development
|
22
25
|
prerelease: false
|
23
26
|
version_requirements: !ruby/object:Gem::Requirement
|
24
27
|
requirements:
|
25
|
-
- - "
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '3.2'
|
31
|
+
- - "<"
|
26
32
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
33
|
+
version: '4.3'
|
28
34
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
35
|
+
name: activerecord
|
30
36
|
requirement: !ruby/object:Gem::Requirement
|
31
37
|
requirements:
|
32
|
-
- - "
|
38
|
+
- - ">="
|
33
39
|
- !ruby/object:Gem::Version
|
34
|
-
version:
|
40
|
+
version: '3.2'
|
41
|
+
- - "<"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '4.3'
|
35
44
|
type: :development
|
36
45
|
prerelease: false
|
37
46
|
version_requirements: !ruby/object:Gem::Requirement
|
38
47
|
requirements:
|
39
|
-
- - "
|
48
|
+
- - ">="
|
40
49
|
- !ruby/object:Gem::Version
|
41
|
-
version:
|
50
|
+
version: '3.2'
|
51
|
+
- - "<"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '4.3'
|
42
54
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
55
|
+
name: dalli
|
44
56
|
requirement: !ruby/object:Gem::Requirement
|
45
57
|
requirements:
|
46
58
|
- - ">="
|
@@ -54,7 +66,7 @@ dependencies:
|
|
54
66
|
- !ruby/object:Gem::Version
|
55
67
|
version: '0'
|
56
68
|
- !ruby/object:Gem::Dependency
|
57
|
-
name:
|
69
|
+
name: sqlite3
|
58
70
|
requirement: !ruby/object:Gem::Requirement
|
59
71
|
requirements:
|
60
72
|
- - ">="
|
@@ -68,33 +80,33 @@ dependencies:
|
|
68
80
|
- !ruby/object:Gem::Version
|
69
81
|
version: '0'
|
70
82
|
- !ruby/object:Gem::Dependency
|
71
|
-
name:
|
83
|
+
name: rspec
|
72
84
|
requirement: !ruby/object:Gem::Requirement
|
73
85
|
requirements:
|
74
86
|
- - "~>"
|
75
87
|
- !ruby/object:Gem::Version
|
76
|
-
version:
|
88
|
+
version: 2.99.0
|
77
89
|
type: :development
|
78
90
|
prerelease: false
|
79
91
|
version_requirements: !ruby/object:Gem::Requirement
|
80
92
|
requirements:
|
81
93
|
- - "~>"
|
82
94
|
- !ruby/object:Gem::Version
|
83
|
-
version:
|
95
|
+
version: 2.99.0
|
84
96
|
- !ruby/object:Gem::Dependency
|
85
|
-
name:
|
97
|
+
name: webmock
|
86
98
|
requirement: !ruby/object:Gem::Requirement
|
87
99
|
requirements:
|
88
100
|
- - "~>"
|
89
101
|
- !ruby/object:Gem::Version
|
90
|
-
version:
|
102
|
+
version: 1.7.7
|
91
103
|
type: :development
|
92
104
|
prerelease: false
|
93
105
|
version_requirements: !ruby/object:Gem::Requirement
|
94
106
|
requirements:
|
95
107
|
- - "~>"
|
96
108
|
- !ruby/object:Gem::Version
|
97
|
-
version:
|
109
|
+
version: 1.7.7
|
98
110
|
- !ruby/object:Gem::Dependency
|
99
111
|
name: bundler
|
100
112
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,6 +135,20 @@ dependencies:
|
|
123
135
|
- - "~>"
|
124
136
|
- !ruby/object:Gem::Version
|
125
137
|
version: '10.0'
|
138
|
+
- !ruby/object:Gem::Dependency
|
139
|
+
name: appraisal
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '2.0'
|
145
|
+
type: :development
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - "~>"
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '2.0'
|
126
152
|
description: Rack handler for monitoring several parts of a web application so one
|
127
153
|
request can determine which system or dependencies are down.
|
128
154
|
email:
|
@@ -132,17 +158,21 @@ extensions: []
|
|
132
158
|
extra_rdoc_files: []
|
133
159
|
files:
|
134
160
|
- ".gitignore"
|
161
|
+
- Appraisals
|
135
162
|
- Gemfile
|
136
163
|
- License.txt
|
137
164
|
- README.rdoc
|
138
165
|
- Rakefile
|
166
|
+
- gemfiles/rails_3.2.gemfile
|
167
|
+
- gemfiles/rails_4.0.gemfile
|
168
|
+
- gemfiles/rails_4.1.gemfile
|
169
|
+
- gemfiles/rails_4.2.gemfile
|
139
170
|
- is_it_working.gemspec
|
140
171
|
- lib/is_it_working.rb
|
141
172
|
- lib/is_it_working/checks/action_mailer_check.rb
|
142
173
|
- lib/is_it_working/checks/active_record_check.rb
|
143
174
|
- lib/is_it_working/checks/dalli_check.rb
|
144
175
|
- lib/is_it_working/checks/directory_check.rb
|
145
|
-
- lib/is_it_working/checks/memcache_check.rb
|
146
176
|
- lib/is_it_working/checks/ping_check.rb
|
147
177
|
- lib/is_it_working/checks/url_check.rb
|
148
178
|
- lib/is_it_working/filter.rb
|
@@ -155,7 +185,6 @@ files:
|
|
155
185
|
- spec/directory_check_spec.rb
|
156
186
|
- spec/filter_spec.rb
|
157
187
|
- spec/handler_spec.rb
|
158
|
-
- spec/memcache_check_spec.rb
|
159
188
|
- spec/ping_check_spec.rb
|
160
189
|
- spec/spec_helper.rb
|
161
190
|
- spec/status_spec.rb
|
@@ -190,7 +219,6 @@ test_files:
|
|
190
219
|
- spec/directory_check_spec.rb
|
191
220
|
- spec/filter_spec.rb
|
192
221
|
- spec/handler_spec.rb
|
193
|
-
- spec/memcache_check_spec.rb
|
194
222
|
- spec/ping_check_spec.rb
|
195
223
|
- spec/spec_helper.rb
|
196
224
|
- spec/status_spec.rb
|
@@ -1,46 +0,0 @@
|
|
1
|
-
require 'memcache'
|
2
|
-
|
3
|
-
module IsItWorking
|
4
|
-
class MemcacheCheck
|
5
|
-
# Check if all the memcached servers in a cluster are responding.
|
6
|
-
# The memcache cluster to check is specified with the <tt>:cache</tt> options. The
|
7
|
-
# value can be either a MemCache object (from the memcache-client gem) or an
|
8
|
-
# ActiveSupport::Cache::MemCacheStore (i.e. Rails.cache).
|
9
|
-
#
|
10
|
-
# If making the IP addresses of the memcache servers known to the world could
|
11
|
-
# pose a security risk because they are not on a private network behind a firewall,
|
12
|
-
# you can provide the <tt>:alias</tt> option to change the host names that are reported.
|
13
|
-
#
|
14
|
-
# === Example
|
15
|
-
#
|
16
|
-
# IsItWorking::Handler.new do |h|
|
17
|
-
# h.check :memcache, :cache => Rails.cache, :alias => "memcache server"
|
18
|
-
# end
|
19
|
-
def initialize(options={})
|
20
|
-
memcache = options[:cache]
|
21
|
-
raise ArgumentError.new(":cache not specified") unless memcache
|
22
|
-
unless memcache.is_a?(MemCache)
|
23
|
-
if defined?(ActiveSupport::Cache::MemCacheStore) && memcache.is_a?(ActiveSupport::Cache::MemCacheStore)
|
24
|
-
# Big hack to get the MemCache object from Rails.cache
|
25
|
-
@memcache = memcache.instance_variable_get(:@data)
|
26
|
-
else
|
27
|
-
raise ArgumentError.new("#{memcache} is not a MemCache")
|
28
|
-
end
|
29
|
-
else
|
30
|
-
@memcache = memcache
|
31
|
-
end
|
32
|
-
@alias = options[:alias]
|
33
|
-
end
|
34
|
-
|
35
|
-
def call(status)
|
36
|
-
@memcache.servers.each_with_index do |server, i|
|
37
|
-
public_host_name = @alias ? "#{@alias} #{i + 1}" : "#{server.host}:#{server.port}"
|
38
|
-
if server.alive?
|
39
|
-
status.ok("#{public_host_name} is available")
|
40
|
-
else
|
41
|
-
status.fail("#{public_host_name} is not available")
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
data/spec/memcache_check_spec.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe IsItWorking::MemcacheCheck do
|
4
|
-
|
5
|
-
let(:status){ IsItWorking::Status.new(:memcache) }
|
6
|
-
let(:memcache){ MemCache.new(['cache-1.example.com', 'cache-2.example.com']) }
|
7
|
-
let(:servers){ memcache.servers }
|
8
|
-
|
9
|
-
it "should succeed if all servers are responding" do
|
10
|
-
check = IsItWorking::MemcacheCheck.new(:cache => memcache)
|
11
|
-
servers.first.should_receive(:socket).and_return(mock(:socket))
|
12
|
-
servers.last.should_receive(:socket).and_return(mock(:socket))
|
13
|
-
check.call(status)
|
14
|
-
status.should be_success
|
15
|
-
status.messages.first.message.should == "cache-1.example.com:11211 is available"
|
16
|
-
status.messages.last.message.should == "cache-2.example.com:11211 is available"
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should fail if any server is not responding" do
|
20
|
-
check = IsItWorking::MemcacheCheck.new(:cache => memcache)
|
21
|
-
servers.first.should_receive(:socket).and_return(mock(:socket))
|
22
|
-
servers.last.should_receive(:socket).and_return(nil)
|
23
|
-
check.call(status)
|
24
|
-
status.should_not be_success
|
25
|
-
status.messages.first.message.should == "cache-1.example.com:11211 is available"
|
26
|
-
status.messages.last.message.should == "cache-2.example.com:11211 is not available"
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should be able to get the MemCache object from an ActiveSupport::Cache" do
|
30
|
-
require 'active_support/cache'
|
31
|
-
rails_cache = ActiveSupport::Cache::MemCacheStore.new(memcache)
|
32
|
-
check = IsItWorking::MemcacheCheck.new(:cache => rails_cache)
|
33
|
-
servers.first.should_receive(:socket).and_return(mock(:socket))
|
34
|
-
servers.last.should_receive(:socket).and_return(mock(:socket))
|
35
|
-
check.call(status)
|
36
|
-
status.should be_success
|
37
|
-
status.messages.first.message.should == "cache-1.example.com:11211 is available"
|
38
|
-
status.messages.last.message.should == "cache-2.example.com:11211 is available"
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should be able to alias the memcache host names in the output" do
|
42
|
-
check = IsItWorking::MemcacheCheck.new(:cache => memcache, :alias => "memcache")
|
43
|
-
servers.first.should_receive(:socket).and_return(mock(:socket))
|
44
|
-
servers.last.should_receive(:socket).and_return(mock(:socket))
|
45
|
-
check.call(status)
|
46
|
-
status.should be_success
|
47
|
-
status.messages.first.message.should == "memcache 1 is available"
|
48
|
-
status.messages.last.message.should == "memcache 2 is available"
|
49
|
-
end
|
50
|
-
|
51
|
-
end
|