litmus_paper 0.0.3
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.
- data/.gitignore +17 -0
- data/.rake_commit +1 -0
- data/.rvmrc +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +31 -0
- data/Rakefile +6 -0
- data/bin/litmus +6 -0
- data/bin/litmusctl +7 -0
- data/config.ru +5 -0
- data/lib/facts/loadaverage.rb +6 -0
- data/lib/litmus_paper/app.rb +63 -0
- data/lib/litmus_paper/cli/admin.rb +97 -0
- data/lib/litmus_paper/cli/server.rb +62 -0
- data/lib/litmus_paper/configuration.rb +27 -0
- data/lib/litmus_paper/dependency/http.rb +40 -0
- data/lib/litmus_paper/dependency/tcp.rb +24 -0
- data/lib/litmus_paper/forced_health.rb +18 -0
- data/lib/litmus_paper/health.rb +35 -0
- data/lib/litmus_paper/logger.rb +15 -0
- data/lib/litmus_paper/metric/available_memory.rb +36 -0
- data/lib/litmus_paper/metric/cpu_load.rb +26 -0
- data/lib/litmus_paper/service.rb +51 -0
- data/lib/litmus_paper/status_file.rb +26 -0
- data/lib/litmus_paper/version.rb +3 -0
- data/lib/litmus_paper.rb +51 -0
- data/litmus_paper.gemspec +26 -0
- data/spec/litmus_paper/app_spec.rb +246 -0
- data/spec/litmus_paper/cli/admin_spec.rb +64 -0
- data/spec/litmus_paper/cli/server_spec.rb +16 -0
- data/spec/litmus_paper/configuration_spec.rb +19 -0
- data/spec/litmus_paper/dependency/http_spec.rb +69 -0
- data/spec/litmus_paper/dependency/tcp_spec.rb +35 -0
- data/spec/litmus_paper/health_spec.rb +71 -0
- data/spec/litmus_paper/metric/available_memory_spec.rb +40 -0
- data/spec/litmus_paper/metric/cpu_load_spec.rb +46 -0
- data/spec/litmus_paper/service_spec.rb +65 -0
- data/spec/litmus_paper/status_file_spec.rb +39 -0
- data/spec/litmus_paper_spec.rb +39 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/always_available_dependency.rb +9 -0
- data/spec/support/config.d/passing_test.config +6 -0
- data/spec/support/config.d/test.config +8 -0
- data/spec/support/constant_metric.rb +13 -0
- data/spec/support/http_test_server.rb +25 -0
- data/spec/support/http_test_server_config.ru +3 -0
- data/spec/support/never_available_dependency.rb +9 -0
- data/spec/support/stub_facter.rb +9 -0
- data/spec/support/test.config +13 -0
- data/spec/support/test.d.config +3 -0
- metadata +249 -0
data/lib/litmus_paper.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
require 'forwardable'
|
5
|
+
|
6
|
+
require 'sinatra/base'
|
7
|
+
require 'facter'
|
8
|
+
require 'syslog_logger'
|
9
|
+
|
10
|
+
require 'facts/loadaverage'
|
11
|
+
|
12
|
+
require 'litmus_paper/app'
|
13
|
+
require 'litmus_paper/configuration'
|
14
|
+
require 'litmus_paper/dependency/http'
|
15
|
+
require 'litmus_paper/dependency/tcp'
|
16
|
+
require 'litmus_paper/health'
|
17
|
+
require 'litmus_paper/forced_health'
|
18
|
+
require 'litmus_paper/logger'
|
19
|
+
require 'litmus_paper/metric/available_memory'
|
20
|
+
require 'litmus_paper/metric/cpu_load'
|
21
|
+
require 'litmus_paper/service'
|
22
|
+
require 'litmus_paper/status_file'
|
23
|
+
|
24
|
+
module LitmusPaper
|
25
|
+
class << self
|
26
|
+
attr_reader :services, :config_dir
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.configure(filename)
|
30
|
+
@config_file = filename
|
31
|
+
|
32
|
+
begin
|
33
|
+
@services = LitmusPaper::Configuration.new(filename).evaluate
|
34
|
+
rescue Exception
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.config_dir=(path)
|
39
|
+
@config_dir = Pathname.new(path)
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.reload
|
43
|
+
configure(@config_file)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.reset
|
47
|
+
@services = {}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
Signal.trap("HUP") { LitmusPaper.reload }
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/litmus_paper/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Braintreeps"]
|
6
|
+
gem.email = ["code@getbraintree.com"]
|
7
|
+
gem.description = %q{Backend health tester for HA Services}
|
8
|
+
gem.summary = %q{Backend health tester for HA Services}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "litmus_paper"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = LitmusPaper::VERSION
|
17
|
+
|
18
|
+
gem.add_dependency "sinatra", "~> 1.3.2"
|
19
|
+
gem.add_dependency "facter", "~> 1.6.7"
|
20
|
+
gem.add_dependency "SyslogLogger", "1.4.1"
|
21
|
+
|
22
|
+
gem.add_development_dependency "rspec", "2.9.0"
|
23
|
+
gem.add_development_dependency "rack-test", "0.6.1"
|
24
|
+
gem.add_development_dependency "rake"
|
25
|
+
gem.add_development_dependency "rake_commit", "0.13"
|
26
|
+
end
|
@@ -0,0 +1,246 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::App do
|
4
|
+
def app
|
5
|
+
LitmusPaper::App
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "GET /" do
|
9
|
+
it "returns the list of services litmus monitors" do
|
10
|
+
LitmusPaper.services['test'] = LitmusPaper::Service.new('test')
|
11
|
+
LitmusPaper.services['another'] = LitmusPaper::Service.new('another')
|
12
|
+
|
13
|
+
get "/"
|
14
|
+
|
15
|
+
last_response.status.should == 200
|
16
|
+
last_response.body.should include('test')
|
17
|
+
last_response.body.should include('another')
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "POST /force/*" do
|
22
|
+
it "creates a global upfile" do
|
23
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
24
|
+
LitmusPaper.services['test'] = test_service
|
25
|
+
|
26
|
+
post "/force/up", :reason => "up for testing"
|
27
|
+
last_response.status.should == 201
|
28
|
+
|
29
|
+
get "/test/status"
|
30
|
+
last_response.status.should == 200
|
31
|
+
last_response.body.should match(/up for testing/)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "creates a global downfile" do
|
35
|
+
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [ConstantMetric.new(100)])
|
36
|
+
LitmusPaper.services['test'] = test_service
|
37
|
+
|
38
|
+
post "/force/down", :reason => "down for testing"
|
39
|
+
last_response.status.should == 201
|
40
|
+
|
41
|
+
get "/test/status"
|
42
|
+
last_response.status.should == 503
|
43
|
+
last_response.body.should match(/down for testing/)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "creates a service specific upfile" do
|
47
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
48
|
+
LitmusPaper.services['test'] = test_service
|
49
|
+
|
50
|
+
post "/force/up/test", :reason => "up for testing"
|
51
|
+
last_response.status.should == 201
|
52
|
+
|
53
|
+
get "/test/status"
|
54
|
+
last_response.status.should == 200
|
55
|
+
last_response.body.should match(/up for testing/)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "DELETE /force/*" do
|
60
|
+
it "removes the global upfile" do
|
61
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
62
|
+
LitmusPaper.services['test'] = test_service
|
63
|
+
|
64
|
+
post "/force/up", :reason => "up for testing"
|
65
|
+
last_response.status.should == 201
|
66
|
+
|
67
|
+
get "/test/status"
|
68
|
+
last_response.status.should == 200
|
69
|
+
|
70
|
+
delete "/force/up"
|
71
|
+
last_response.status.should == 200
|
72
|
+
|
73
|
+
get "/test/status"
|
74
|
+
last_response.status.should == 503
|
75
|
+
last_response.body.should_not match(/up for testing/)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "removes the global downfile" do
|
79
|
+
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [ConstantMetric.new(100)])
|
80
|
+
LitmusPaper.services['test'] = test_service
|
81
|
+
|
82
|
+
post "/force/down", :reason => "down for testing"
|
83
|
+
last_response.status.should == 201
|
84
|
+
|
85
|
+
get "/test/status"
|
86
|
+
last_response.status.should == 503
|
87
|
+
|
88
|
+
delete "/force/down"
|
89
|
+
last_response.status.should == 200
|
90
|
+
|
91
|
+
get "/test/status"
|
92
|
+
last_response.should be_ok
|
93
|
+
last_response.body.should_not match(/down for testing/)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "removes a service specific upfile" do
|
97
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
98
|
+
LitmusPaper.services['test'] = test_service
|
99
|
+
|
100
|
+
post "/force/up/test", :reason => "up for testing"
|
101
|
+
last_response.status.should == 201
|
102
|
+
|
103
|
+
get "/test/status"
|
104
|
+
last_response.status.should == 200
|
105
|
+
last_response.body.should match(/up for testing/)
|
106
|
+
|
107
|
+
delete "/force/up/test"
|
108
|
+
last_response.status.should == 200
|
109
|
+
|
110
|
+
get "/test/status"
|
111
|
+
last_response.status.should == 503
|
112
|
+
end
|
113
|
+
|
114
|
+
it "404s if there is no upfile" do
|
115
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
116
|
+
|
117
|
+
delete "/up"
|
118
|
+
|
119
|
+
last_response.status.should == 404
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
describe "GET /:service/status" do
|
124
|
+
it "is successful when the service is passing" do
|
125
|
+
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [ConstantMetric.new(100)])
|
126
|
+
LitmusPaper.services['test'] = test_service
|
127
|
+
|
128
|
+
get "/test/status"
|
129
|
+
|
130
|
+
last_response.should be_ok
|
131
|
+
last_response.header["Content-Type"].should == "text/plain"
|
132
|
+
last_response.header["X-Health"].should == "100"
|
133
|
+
last_response.body.should match(/Health: 100/)
|
134
|
+
last_response.body.should match(/AlwaysAvailableDependency: OK/)
|
135
|
+
last_response.body.should include("ConstantMetric(100): 100")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "is 'service unavailable' when the check fails" do
|
139
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
140
|
+
LitmusPaper.services['test'] = test_service
|
141
|
+
|
142
|
+
get "/test/status"
|
143
|
+
|
144
|
+
last_response.status.should == 503
|
145
|
+
last_response.header["Content-Type"].should == "text/plain"
|
146
|
+
last_response.header["X-Health"].should == "0"
|
147
|
+
last_response.body.should match(/Health: 0/)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "is 'not found' when the service is unknown" do
|
151
|
+
get "/unknown/status"
|
152
|
+
|
153
|
+
last_response.status.should == 404
|
154
|
+
last_response.header["Content-Type"].should == "text/plain"
|
155
|
+
end
|
156
|
+
|
157
|
+
it "is 'service unavailable' when an up file and down file exists" do
|
158
|
+
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [ConstantMetric.new(100)])
|
159
|
+
LitmusPaper.services['test'] = test_service
|
160
|
+
|
161
|
+
LitmusPaper::StatusFile.new("up", "test").create("Up for testing")
|
162
|
+
LitmusPaper::StatusFile.new("down", "test").create("Down for testing")
|
163
|
+
|
164
|
+
get "/test/status"
|
165
|
+
|
166
|
+
last_response.status.should == 503
|
167
|
+
last_response.body.should match(/Down for testing/)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "is 'service available' when an up file exists" do
|
171
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
172
|
+
LitmusPaper.services['test'] = test_service
|
173
|
+
|
174
|
+
LitmusPaper::StatusFile.new("up", "test").create("Up for testing")
|
175
|
+
|
176
|
+
get "/test/status"
|
177
|
+
|
178
|
+
last_response.status.should == 200
|
179
|
+
last_response.body.should match(/Up for testing/)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "is 'service available' when an up file exists" do
|
183
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
184
|
+
LitmusPaper.services['test'] = test_service
|
185
|
+
|
186
|
+
LitmusPaper::StatusFile.new("up", "test").create("Up for testing")
|
187
|
+
|
188
|
+
get "/test/status"
|
189
|
+
|
190
|
+
last_response.status.should == 200
|
191
|
+
last_response.body.should match(/Up for testing/)
|
192
|
+
end
|
193
|
+
|
194
|
+
it "is 'service unavailable' when a global down file and up file exists" do
|
195
|
+
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [ConstantMetric.new(100)])
|
196
|
+
LitmusPaper.services['test'] = test_service
|
197
|
+
|
198
|
+
LitmusPaper::StatusFile.new("global_down").create("Down for testing")
|
199
|
+
LitmusPaper::StatusFile.new("global_up").create("Up for testing")
|
200
|
+
|
201
|
+
get "/test/status"
|
202
|
+
|
203
|
+
last_response.status.should == 503
|
204
|
+
last_response.body.should match(/Down for testing/)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "is 'service unavailable' when a global down file exists" do
|
208
|
+
test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [ConstantMetric.new(100)])
|
209
|
+
LitmusPaper.services['test'] = test_service
|
210
|
+
|
211
|
+
LitmusPaper::StatusFile.new("global_down").create("Down for testing")
|
212
|
+
|
213
|
+
get "/test/status"
|
214
|
+
|
215
|
+
last_response.status.should == 503
|
216
|
+
last_response.body.should match(/Down for testing/)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "is successful when a global up file exists" do
|
220
|
+
test_service = LitmusPaper::Service.new('test', [NeverAvailableDependency.new], [ConstantMetric.new(100)])
|
221
|
+
LitmusPaper.services['test'] = test_service
|
222
|
+
|
223
|
+
LitmusPaper::StatusFile.new("global_up").create("Up for testing")
|
224
|
+
|
225
|
+
get "/test/status"
|
226
|
+
|
227
|
+
last_response.status.should == 200
|
228
|
+
last_response.body.should match(/Up for testing/)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe "server errors" do
|
233
|
+
it "responds with a text/plain 500 response" do
|
234
|
+
old_environment = :test
|
235
|
+
begin
|
236
|
+
app.environment = :production
|
237
|
+
get "/test/error"
|
238
|
+
last_response.status.should == 500
|
239
|
+
last_response.headers["Content-Type"].should == "text/plain"
|
240
|
+
last_response.body.should == "Server Error"
|
241
|
+
ensure
|
242
|
+
app.environment = old_environment
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
|
4
|
+
describe 'litmusctl' do
|
5
|
+
def _litmusctl(args)
|
6
|
+
`bundle exec ruby -I lib bin/litmusctl #{args} -p 9293`
|
7
|
+
end
|
8
|
+
|
9
|
+
before(:all) do
|
10
|
+
system "bundle exec ruby -I lib bin/litmus -p 9293 -d -D /tmp/litmus_paper -c #{TEST_CONFIG} -P /tmp/litmus.pid"
|
11
|
+
end
|
12
|
+
|
13
|
+
after(:all) do
|
14
|
+
system "kill -9 `cat /tmp/litmus.pid`"
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'list' do
|
18
|
+
it "returns the list of services running" do
|
19
|
+
_litmusctl('list').should match("test")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe 'status' do
|
24
|
+
it 'returns the status of a service' do
|
25
|
+
_litmusctl('status test').should match("Health: 0")
|
26
|
+
_litmusctl('status passing_test').should match(/Health: \d\d/)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "returns 'NOT FOUND' for a service that doesn't exist" do
|
30
|
+
_litmusctl('status unknown').should match('NOT FOUND')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "force" do
|
35
|
+
it "can create a global downfile" do
|
36
|
+
_litmusctl('force down -r "for testing"').should match("File created")
|
37
|
+
|
38
|
+
status = _litmusctl('status test')
|
39
|
+
status.should match(/Health: 0/)
|
40
|
+
status.should match(/for testing/)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "creates a downfile" do
|
44
|
+
_litmusctl('force down test -r "for testing"').should match("File created")
|
45
|
+
|
46
|
+
status = _litmusctl('status test')
|
47
|
+
status.should match(/Health: 0/)
|
48
|
+
status.should match(/for testing/)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'removes an upfile for the service' do
|
52
|
+
_litmusctl('force up test -r "for testing"').should match("File created")
|
53
|
+
_litmusctl('force up test -d').should match("File deleted")
|
54
|
+
|
55
|
+
status = _litmusctl('status passing_test')
|
56
|
+
status.should match(/Health: \d\d/)
|
57
|
+
status.should_not match(/for testing/)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "returns not found if downfile doesn't exist" do
|
61
|
+
_litmusctl('force down test -d').should match("NOT FOUND")
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'litmus_paper/cli/server'
|
3
|
+
|
4
|
+
describe LitmusPaper::CLI::Server do
|
5
|
+
describe 'parse!' do
|
6
|
+
it 'parses litmus config file options' do
|
7
|
+
options = LitmusPaper::CLI::Server::Options.new.parse!(['-c', 'foo.conf'])
|
8
|
+
options[:litmus_config].should == 'foo.conf'
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'parses the config dir options' do
|
12
|
+
options = LitmusPaper::CLI::Server::Options.new.parse!(['-D', '/tmp/foo'])
|
13
|
+
options[:config_dir].should == '/tmp/foo'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Configuration do
|
4
|
+
describe "evaluate" do
|
5
|
+
it "configures a service" do
|
6
|
+
config = LitmusPaper::Configuration.new(TEST_CONFIG)
|
7
|
+
services = config.evaluate
|
8
|
+
services.has_key?('test').should == true
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "include_files" do
|
13
|
+
it "configures a dir glob of services" do
|
14
|
+
config = LitmusPaper::Configuration.new(TEST_D_CONFIG)
|
15
|
+
services = config.evaluate
|
16
|
+
services.has_key?('test').should == true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Dependency::HTTP do
|
4
|
+
before(:all) do
|
5
|
+
server_start = system "bundle exec rackup spec/support/http_test_server_config.ru --port 9294 --pid /tmp/http-test-server.pid --daemonize"
|
6
|
+
SpecHelper.wait_for_service :host => '127.0.0.1', :port => 9294
|
7
|
+
@url = "http://127.0.0.1:9294"
|
8
|
+
end
|
9
|
+
|
10
|
+
after(:all) do
|
11
|
+
system "kill -9 `cat /tmp/http-test-server.pid`"
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#available?" do
|
15
|
+
context "http method" do
|
16
|
+
it "uses the given http method when making the request" do
|
17
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/method", :method => "GET", :content => "POST")
|
18
|
+
check.should_not be_available
|
19
|
+
|
20
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/method", :method => "POST", :content => "POST")
|
21
|
+
check.should be_available
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
it "is true when response is 200" do
|
26
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/200")
|
27
|
+
check.should be_available
|
28
|
+
end
|
29
|
+
|
30
|
+
it "is true when response is 200 and expected content matches" do
|
31
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/200", :content => "200 OK")
|
32
|
+
check.should be_available
|
33
|
+
end
|
34
|
+
|
35
|
+
it "is false when response is 200, but does not match content" do
|
36
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/200", :content => "some text not in the response")
|
37
|
+
check.should_not be_available
|
38
|
+
end
|
39
|
+
|
40
|
+
it "is true when response is any 200 level response" do
|
41
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/201")
|
42
|
+
check.should be_available
|
43
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/202")
|
44
|
+
check.should be_available
|
45
|
+
end
|
46
|
+
|
47
|
+
it "is false when response is 500 " do
|
48
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/500")
|
49
|
+
check.should_not be_available
|
50
|
+
end
|
51
|
+
|
52
|
+
it "is false when the response is 404" do
|
53
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/404")
|
54
|
+
check.should_not be_available
|
55
|
+
end
|
56
|
+
|
57
|
+
it "is false when the dependency is not available" do
|
58
|
+
check = LitmusPaper::Dependency::HTTP.new('http://127.0.0.1:7777')
|
59
|
+
check.should_not be_available
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "to_s" do
|
64
|
+
it "is the name of the class and the url" do
|
65
|
+
check = LitmusPaper::Dependency::HTTP.new("#{@url}/status/500")
|
66
|
+
check.to_s.should == "Dependency::HTTP(http://127.0.0.1:9294/status/500)"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Dependency::TCP do
|
4
|
+
before(:all) do
|
5
|
+
@server = TCPServer.new 3333
|
6
|
+
end
|
7
|
+
|
8
|
+
after(:all) do
|
9
|
+
@server.close
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#available?" do
|
13
|
+
it "is true when it's able to reach the ip and port" do
|
14
|
+
check = LitmusPaper::Dependency::TCP.new("127.0.0.1", 3333)
|
15
|
+
check.should be_available
|
16
|
+
end
|
17
|
+
|
18
|
+
it "is false when the ip is not available" do
|
19
|
+
check = LitmusPaper::Dependency::TCP.new("10.254.254.254", 3333)
|
20
|
+
check.should_not be_available
|
21
|
+
end
|
22
|
+
|
23
|
+
it "is false when the port is not available" do
|
24
|
+
check = LitmusPaper::Dependency::TCP.new("127.0.0.1", 3334)
|
25
|
+
check.should_not be_available
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "to_s" do
|
30
|
+
it "is the name of the class and the ip and port" do
|
31
|
+
check = LitmusPaper::Dependency::TCP.new("127.0.0.1", 3333)
|
32
|
+
check.to_s.should == "Dependency::TCP(tcp://127.0.0.1:3333)"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Health do
|
4
|
+
describe "ok?" do
|
5
|
+
it "is true when health is greater than 0" do
|
6
|
+
health = LitmusPaper::Health.new
|
7
|
+
health.perform(ConstantMetric.new(50))
|
8
|
+
health.should be_ok
|
9
|
+
end
|
10
|
+
|
11
|
+
it "is false when health is 0" do
|
12
|
+
health = LitmusPaper::Health.new
|
13
|
+
health.perform(ConstantMetric.new(0))
|
14
|
+
health.should_not be_ok
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "perform" do
|
19
|
+
it "executes the check and adds its value to its health" do
|
20
|
+
health = LitmusPaper::Health.new
|
21
|
+
health.perform(ConstantMetric.new(50))
|
22
|
+
health.perform(ConstantMetric.new(25))
|
23
|
+
health.value.should == 75
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "ensure" do
|
28
|
+
it "checks the dependency and modifies the value accordingly" do
|
29
|
+
health = LitmusPaper::Health.new
|
30
|
+
health.ensure(NeverAvailableDependency.new)
|
31
|
+
health.perform(ConstantMetric.new(50))
|
32
|
+
health.value.should == 0
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "summary" do
|
37
|
+
it "includes the availablilty of dependencies" do
|
38
|
+
health = LitmusPaper::Health.new
|
39
|
+
health.ensure(NeverAvailableDependency.new)
|
40
|
+
health.ensure(AlwaysAvailableDependency.new)
|
41
|
+
|
42
|
+
health.summary.should match(/NeverAvailableDependency: FAIL/)
|
43
|
+
health.summary.should match(/AlwaysAvailableDependency: OK/)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "includes the health of individual metrics" do
|
47
|
+
health = LitmusPaper::Health.new
|
48
|
+
health.perform(ConstantMetric.new(12))
|
49
|
+
health.perform(ConstantMetric.new(34))
|
50
|
+
|
51
|
+
health.summary.should include("ConstantMetric(12): 12")
|
52
|
+
health.summary.should include("ConstantMetric(34): 34")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "only runs each metric once" do
|
56
|
+
health = LitmusPaper::Health.new
|
57
|
+
metric = ConstantMetric.new(12)
|
58
|
+
metric.should_receive(:current_health).once.and_return(12)
|
59
|
+
|
60
|
+
health.perform(metric)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "only runs each dependency once" do
|
64
|
+
health = LitmusPaper::Health.new
|
65
|
+
dependency = AlwaysAvailableDependency.new
|
66
|
+
dependency.should_receive(:available?).once.and_return(true)
|
67
|
+
|
68
|
+
health.ensure(dependency)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Metric::AvailableMemory do
|
4
|
+
describe "#current_health" do
|
5
|
+
it "multiplies weight by memory available" do
|
6
|
+
facter = StubFacter.new({"memorytotal" => "10 GB", "memoryfree" => "5 GB"})
|
7
|
+
memory = LitmusPaper::Metric::AvailableMemory.new(50, facter)
|
8
|
+
memory.current_health.should == 25
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#memory_total" do
|
12
|
+
it "is a positive integer" do
|
13
|
+
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
14
|
+
metric.memory_total.should > 1_000
|
15
|
+
end
|
16
|
+
|
17
|
+
it "is cached" do
|
18
|
+
Facter.should_receive(:value).once.and_return("10 MB")
|
19
|
+
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
20
|
+
metric.memory_total
|
21
|
+
metric.memory_total
|
22
|
+
metric.memory_total
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe "#memory_free" do
|
27
|
+
it "is a positive integer" do
|
28
|
+
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
29
|
+
metric.memory_free.should > 100
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#to_s" do
|
34
|
+
it "is the name of the check and the max weight" do
|
35
|
+
metric = LitmusPaper::Metric::AvailableMemory.new(50)
|
36
|
+
metric.to_s.should == "Metric::AvailableMemory(50)"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LitmusPaper::Metric::CPULoad do
|
4
|
+
describe "#current_health" do
|
5
|
+
it "is the percent of available cpu capacity" do
|
6
|
+
facter = StubFacter.new({"processorcount" => "4", "loadaverage" => "1.00 0.40 0.10"})
|
7
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(40, facter)
|
8
|
+
cpu_load.current_health.should == 30
|
9
|
+
end
|
10
|
+
|
11
|
+
it "is zero when the load is above one per core" do
|
12
|
+
facter = StubFacter.new({"processorcount" => "4", "loadaverage" => "20.00 11.40 10.00"})
|
13
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(50, facter)
|
14
|
+
cpu_load.current_health.should == 0
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#processor_count" do
|
19
|
+
it "is a positive integer" do
|
20
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
21
|
+
cpu_load.processor_count.should > 0
|
22
|
+
end
|
23
|
+
|
24
|
+
it "is cached" do
|
25
|
+
Facter.should_receive(:value).once.and_return("10")
|
26
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
27
|
+
cpu_load.processor_count
|
28
|
+
cpu_load.processor_count
|
29
|
+
cpu_load.processor_count
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#load_average" do
|
34
|
+
it "is a floating point" do
|
35
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
36
|
+
cpu_load.load_average.should > 0.0
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#to_s" do
|
41
|
+
it "is the check name and the maximum weight" do
|
42
|
+
cpu_load = LitmusPaper::Metric::CPULoad.new(50)
|
43
|
+
cpu_load.to_s.should == "Metric::CPULoad(50)"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|