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.
Files changed (52) hide show
  1. data/.gitignore +17 -0
  2. data/.rake_commit +1 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +22 -0
  7. data/README.md +31 -0
  8. data/Rakefile +6 -0
  9. data/bin/litmus +6 -0
  10. data/bin/litmusctl +7 -0
  11. data/config.ru +5 -0
  12. data/lib/facts/loadaverage.rb +6 -0
  13. data/lib/litmus_paper/app.rb +63 -0
  14. data/lib/litmus_paper/cli/admin.rb +97 -0
  15. data/lib/litmus_paper/cli/server.rb +62 -0
  16. data/lib/litmus_paper/configuration.rb +27 -0
  17. data/lib/litmus_paper/dependency/http.rb +40 -0
  18. data/lib/litmus_paper/dependency/tcp.rb +24 -0
  19. data/lib/litmus_paper/forced_health.rb +18 -0
  20. data/lib/litmus_paper/health.rb +35 -0
  21. data/lib/litmus_paper/logger.rb +15 -0
  22. data/lib/litmus_paper/metric/available_memory.rb +36 -0
  23. data/lib/litmus_paper/metric/cpu_load.rb +26 -0
  24. data/lib/litmus_paper/service.rb +51 -0
  25. data/lib/litmus_paper/status_file.rb +26 -0
  26. data/lib/litmus_paper/version.rb +3 -0
  27. data/lib/litmus_paper.rb +51 -0
  28. data/litmus_paper.gemspec +26 -0
  29. data/spec/litmus_paper/app_spec.rb +246 -0
  30. data/spec/litmus_paper/cli/admin_spec.rb +64 -0
  31. data/spec/litmus_paper/cli/server_spec.rb +16 -0
  32. data/spec/litmus_paper/configuration_spec.rb +19 -0
  33. data/spec/litmus_paper/dependency/http_spec.rb +69 -0
  34. data/spec/litmus_paper/dependency/tcp_spec.rb +35 -0
  35. data/spec/litmus_paper/health_spec.rb +71 -0
  36. data/spec/litmus_paper/metric/available_memory_spec.rb +40 -0
  37. data/spec/litmus_paper/metric/cpu_load_spec.rb +46 -0
  38. data/spec/litmus_paper/service_spec.rb +65 -0
  39. data/spec/litmus_paper/status_file_spec.rb +39 -0
  40. data/spec/litmus_paper_spec.rb +39 -0
  41. data/spec/spec_helper.rb +46 -0
  42. data/spec/support/always_available_dependency.rb +9 -0
  43. data/spec/support/config.d/passing_test.config +6 -0
  44. data/spec/support/config.d/test.config +8 -0
  45. data/spec/support/constant_metric.rb +13 -0
  46. data/spec/support/http_test_server.rb +25 -0
  47. data/spec/support/http_test_server_config.ru +3 -0
  48. data/spec/support/never_available_dependency.rb +9 -0
  49. data/spec/support/stub_facter.rb +9 -0
  50. data/spec/support/test.config +13 -0
  51. data/spec/support/test.d.config +3 -0
  52. metadata +249 -0
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe LitmusPaper::Service do
4
+ describe "health" do
5
+ it "is the sum of all the metrics' weight" do
6
+ service = LitmusPaper::Service.new('test')
7
+ service.measure_health ConstantMetric, :weight => 50
8
+ service.measure_health ConstantMetric, :weight => 25
9
+
10
+ service.current_health.value.should == 75
11
+ end
12
+
13
+ it "is 0 when a dependency fails" do
14
+ service = LitmusPaper::Service.new('test')
15
+ service.depends NeverAvailableDependency
16
+ service.measure_health ConstantMetric, :weight => 50
17
+
18
+ service.current_health.value.should == 0
19
+ end
20
+
21
+ it "is 0 when a down file exists" do
22
+ service = LitmusPaper::Service.new('test')
23
+ service.depends AlwaysAvailableDependency
24
+ service.measure_health ConstantMetric, :weight => 50
25
+
26
+ LitmusPaper::StatusFile.new("down", "test").create("Down for testing")
27
+
28
+ service.current_health.value.should == 0
29
+ service.current_health.summary.should == "Down for testing"
30
+ end
31
+
32
+ it "is 0 when a global down file exists" do
33
+ service = LitmusPaper::Service.new('test')
34
+ service.depends AlwaysAvailableDependency
35
+ service.measure_health ConstantMetric, :weight => 50
36
+
37
+ LitmusPaper::StatusFile.new("down", "test").create("Down for testing")
38
+
39
+ service.current_health.value.should == 0
40
+ service.current_health.summary.should == "Down for testing"
41
+ end
42
+
43
+ it "is 100 when an up file exists" do
44
+ service = LitmusPaper::Service.new('test')
45
+ service.depends NeverAvailableDependency
46
+ service.measure_health ConstantMetric, :weight => 50
47
+
48
+ LitmusPaper::StatusFile.new("up", "test").create("Up for testing")
49
+
50
+ service.current_health.value.should == 100
51
+ service.current_health.summary.should == "Up for testing"
52
+ end
53
+
54
+ it "is 100 when a global up file exists" do
55
+ service = LitmusPaper::Service.new('test')
56
+ service.depends NeverAvailableDependency
57
+ service.measure_health ConstantMetric, :weight => 50
58
+
59
+ LitmusPaper::StatusFile.new("global_up").create("Up for testing")
60
+
61
+ service.current_health.value.should == 100
62
+ service.current_health.summary.should == "Up for testing"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe LitmusPaper::StatusFile do
4
+ describe "create" do
5
+ it "creates a nested file" do
6
+ status_file = LitmusPaper::StatusFile.new("foo", "bar")
7
+ status_file.create("for testing")
8
+
9
+ status_file.exists?.should == true
10
+ end
11
+
12
+ it "creates a file" do
13
+ status_file = LitmusPaper::StatusFile.new("foo")
14
+ status_file.create("for testing")
15
+
16
+ status_file.exists?.should == true
17
+ end
18
+
19
+ it "writes the content" do
20
+ status_file = LitmusPaper::StatusFile.new("foo")
21
+ status_file.create("for testing")
22
+
23
+ status_file.content.should == "for testing"
24
+ end
25
+ end
26
+
27
+ describe "delete" do
28
+ it "removes the file" do
29
+ status_file = LitmusPaper::StatusFile.new("foo")
30
+ status_file.create("for testing")
31
+
32
+ status_file.exists?.should be_true
33
+
34
+ status_file.delete
35
+
36
+ status_file.exists?.should be_false
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe LitmusPaper do
4
+ describe 'configure' do
5
+ it 'populates services from the config file' do
6
+ LitmusPaper.configure(TEST_CONFIG)
7
+ LitmusPaper.services.has_key?('test').should == true
8
+ end
9
+ end
10
+
11
+ describe "reload" do
12
+ it "will reconfigure the services" do
13
+ LitmusPaper.configure(TEST_CONFIG)
14
+ LitmusPaper.services["bar"] = :service
15
+
16
+ LitmusPaper.reload
17
+
18
+ LitmusPaper.services.has_key?('bar').should == false
19
+ LitmusPaper.services.has_key?('test').should == true
20
+ end
21
+
22
+ it "keeps the old config if there are errors in the new config" do
23
+ old_config_file = SpecHelper.create_temp_file(<<-END)
24
+ service :old_service do |s|
25
+ s.measure_health Metric::CPULoad, :weight => 100
26
+ end
27
+ END
28
+ new_bad_config_file = SpecHelper.create_temp_file(<<-END)
29
+ service :old_service do |s|
30
+ syntax error here
31
+ end
32
+ END
33
+ LitmusPaper.configure(old_config_file)
34
+ LitmusPaper.services.keys.should == ["old_service"]
35
+ LitmusPaper.configure(new_bad_config_file)
36
+ LitmusPaper.services.keys.should == ["old_service"]
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+
3
+ require 'rspec'
4
+ require 'rack/test'
5
+ require 'litmus_paper'
6
+ require 'tempfile'
7
+
8
+ Dir.glob("#{File.expand_path('support', File.dirname(__FILE__))}/**/*.rb").each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ config.expect_with :rspec
12
+ config.include Rack::Test::Methods
13
+
14
+ config.before :each do
15
+ FileUtils.rm_rf(LitmusPaper.config_dir)
16
+ LitmusPaper.reset
17
+ end
18
+ end
19
+
20
+ module SpecHelper
21
+ def self.create_temp_file(contents)
22
+ file = Tempfile.new 'litmus_paper'
23
+ file.write contents
24
+ file.close
25
+ file.path
26
+ end
27
+
28
+ def self.wait_for_service(options)
29
+ Timeout::timeout(options[:timeout] || 20) do
30
+ loop do
31
+ begin
32
+ socket = TCPSocket.new(options[:host], options[:port])
33
+ socket.close
34
+ return
35
+ rescue Exception
36
+ sleep 0.5
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ LitmusPaper.config_dir = "/tmp/litmus_paper"
44
+
45
+ TEST_CONFIG = File.expand_path('support/test.config', File.dirname(__FILE__))
46
+ TEST_D_CONFIG = File.expand_path('support/test.d.config', File.dirname(__FILE__))
@@ -0,0 +1,9 @@
1
+ class AlwaysAvailableDependency
2
+ def available?
3
+ true
4
+ end
5
+
6
+ def to_s
7
+ self.class.name
8
+ end
9
+ end
@@ -0,0 +1,6 @@
1
+ # vim: ft=ruby
2
+
3
+ service :passing_test do |s|
4
+ s.measure_health Metric::CPULoad, :weight => 50
5
+ s.measure_health Metric::AvailableMemory, :weight => 50
6
+ end
@@ -0,0 +1,8 @@
1
+ # vim: ft=ruby
2
+
3
+ service :test do |s|
4
+ s.depends Dependency::HTTP, "http://localhost/heartbeat"
5
+
6
+ s.measure_health Metric::CPULoad, :weight => 50
7
+ s.measure_health Metric::AvailableMemory, :weight => 50
8
+ end
@@ -0,0 +1,13 @@
1
+ class ConstantMetric
2
+ def initialize(constant)
3
+ @constant = constant
4
+ end
5
+
6
+ def current_health
7
+ @constant
8
+ end
9
+
10
+ def to_s
11
+ "#{self.class.name}(#{@constant})"
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ require 'sinatra/base'
2
+
3
+ class HttpTestServer < Sinatra::Base
4
+ get "/method" do
5
+ text 200, "GET"
6
+ end
7
+
8
+ post "/method" do
9
+ text 200, "POST"
10
+ end
11
+
12
+ get "/status/:response_status" do
13
+ if params[:response_status] =~ /\A\d+\z/
14
+ status = params[:response_status]
15
+ message = Rack::Utils::HTTP_STATUS_CODES[status.to_i] || "Unknown"
16
+ text status.to_i, "#{status} #{message}"
17
+ else
18
+ text 500, "Invalid Status"
19
+ end
20
+ end
21
+
22
+ def text(response_code, body, headers ={})
23
+ [response_code, { "Content-Type" => "text/plain" }.merge(headers), body]
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ require File.dirname(__FILE__) + '/http_test_server'
2
+
3
+ run HttpTestServer
@@ -0,0 +1,9 @@
1
+ class NeverAvailableDependency
2
+ def available?
3
+ false
4
+ end
5
+
6
+ def to_s
7
+ self.class.name
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class StubFacter
2
+ def initialize(values)
3
+ @values = values
4
+ end
5
+
6
+ def value(key)
7
+ @values[key]
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # vim: set ft=ruby
2
+
3
+ service :test do |s|
4
+ s.depends Dependency::HTTP, "http://localhost/heartbeat"
5
+
6
+ s.measure_health Metric::CPULoad, :weight => 50
7
+ s.measure_health Metric::AvailableMemory, :weight => 50
8
+ end
9
+
10
+ service :passing_test do |s|
11
+ s.measure_health Metric::CPULoad, :weight => 50
12
+ s.measure_health Metric::AvailableMemory, :weight => 50
13
+ end
@@ -0,0 +1,3 @@
1
+ # vim: ft=ruby
2
+
3
+ include_files 'config.d/*.config'
metadata ADDED
@@ -0,0 +1,249 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: litmus_paper
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 3
10
+ version: 0.0.3
11
+ platform: ruby
12
+ authors:
13
+ - Braintreeps
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-06-04 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: sinatra
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 31
30
+ segments:
31
+ - 1
32
+ - 3
33
+ - 2
34
+ version: 1.3.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: facter
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 1
46
+ segments:
47
+ - 1
48
+ - 6
49
+ - 7
50
+ version: 1.6.7
51
+ type: :runtime
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
54
+ name: SyslogLogger
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - "="
60
+ - !ruby/object:Gem::Version
61
+ hash: 5
62
+ segments:
63
+ - 1
64
+ - 4
65
+ - 1
66
+ version: 1.4.1
67
+ type: :runtime
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - "="
76
+ - !ruby/object:Gem::Version
77
+ hash: 43
78
+ segments:
79
+ - 2
80
+ - 9
81
+ - 0
82
+ version: 2.9.0
83
+ type: :development
84
+ version_requirements: *id004
85
+ - !ruby/object:Gem::Dependency
86
+ name: rack-test
87
+ prerelease: false
88
+ requirement: &id005 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - "="
92
+ - !ruby/object:Gem::Version
93
+ hash: 5
94
+ segments:
95
+ - 0
96
+ - 6
97
+ - 1
98
+ version: 0.6.1
99
+ type: :development
100
+ version_requirements: *id005
101
+ - !ruby/object:Gem::Dependency
102
+ name: rake
103
+ prerelease: false
104
+ requirement: &id006 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ hash: 3
110
+ segments:
111
+ - 0
112
+ version: "0"
113
+ type: :development
114
+ version_requirements: *id006
115
+ - !ruby/object:Gem::Dependency
116
+ name: rake_commit
117
+ prerelease: false
118
+ requirement: &id007 !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - "="
122
+ - !ruby/object:Gem::Version
123
+ hash: 17
124
+ segments:
125
+ - 0
126
+ - 13
127
+ version: "0.13"
128
+ type: :development
129
+ version_requirements: *id007
130
+ description: Backend health tester for HA Services
131
+ email:
132
+ - code@getbraintree.com
133
+ executables:
134
+ - litmus
135
+ - litmusctl
136
+ extensions: []
137
+
138
+ extra_rdoc_files: []
139
+
140
+ files:
141
+ - .gitignore
142
+ - .rake_commit
143
+ - .rvmrc
144
+ - .travis.yml
145
+ - Gemfile
146
+ - LICENSE
147
+ - README.md
148
+ - Rakefile
149
+ - bin/litmus
150
+ - bin/litmusctl
151
+ - config.ru
152
+ - lib/facts/loadaverage.rb
153
+ - lib/litmus_paper.rb
154
+ - lib/litmus_paper/app.rb
155
+ - lib/litmus_paper/cli/admin.rb
156
+ - lib/litmus_paper/cli/server.rb
157
+ - lib/litmus_paper/configuration.rb
158
+ - lib/litmus_paper/dependency/http.rb
159
+ - lib/litmus_paper/dependency/tcp.rb
160
+ - lib/litmus_paper/forced_health.rb
161
+ - lib/litmus_paper/health.rb
162
+ - lib/litmus_paper/logger.rb
163
+ - lib/litmus_paper/metric/available_memory.rb
164
+ - lib/litmus_paper/metric/cpu_load.rb
165
+ - lib/litmus_paper/service.rb
166
+ - lib/litmus_paper/status_file.rb
167
+ - lib/litmus_paper/version.rb
168
+ - litmus_paper.gemspec
169
+ - spec/litmus_paper/app_spec.rb
170
+ - spec/litmus_paper/cli/admin_spec.rb
171
+ - spec/litmus_paper/cli/server_spec.rb
172
+ - spec/litmus_paper/configuration_spec.rb
173
+ - spec/litmus_paper/dependency/http_spec.rb
174
+ - spec/litmus_paper/dependency/tcp_spec.rb
175
+ - spec/litmus_paper/health_spec.rb
176
+ - spec/litmus_paper/metric/available_memory_spec.rb
177
+ - spec/litmus_paper/metric/cpu_load_spec.rb
178
+ - spec/litmus_paper/service_spec.rb
179
+ - spec/litmus_paper/status_file_spec.rb
180
+ - spec/litmus_paper_spec.rb
181
+ - spec/spec_helper.rb
182
+ - spec/support/always_available_dependency.rb
183
+ - spec/support/config.d/passing_test.config
184
+ - spec/support/config.d/test.config
185
+ - spec/support/constant_metric.rb
186
+ - spec/support/http_test_server.rb
187
+ - spec/support/http_test_server_config.ru
188
+ - spec/support/never_available_dependency.rb
189
+ - spec/support/stub_facter.rb
190
+ - spec/support/test.config
191
+ - spec/support/test.d.config
192
+ has_rdoc: true
193
+ homepage: ""
194
+ licenses: []
195
+
196
+ post_install_message:
197
+ rdoc_options: []
198
+
199
+ require_paths:
200
+ - lib
201
+ required_ruby_version: !ruby/object:Gem::Requirement
202
+ none: false
203
+ requirements:
204
+ - - ">="
205
+ - !ruby/object:Gem::Version
206
+ hash: 3
207
+ segments:
208
+ - 0
209
+ version: "0"
210
+ required_rubygems_version: !ruby/object:Gem::Requirement
211
+ none: false
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ hash: 3
216
+ segments:
217
+ - 0
218
+ version: "0"
219
+ requirements: []
220
+
221
+ rubyforge_project:
222
+ rubygems_version: 1.3.7
223
+ signing_key:
224
+ specification_version: 3
225
+ summary: Backend health tester for HA Services
226
+ test_files:
227
+ - spec/litmus_paper/app_spec.rb
228
+ - spec/litmus_paper/cli/admin_spec.rb
229
+ - spec/litmus_paper/cli/server_spec.rb
230
+ - spec/litmus_paper/configuration_spec.rb
231
+ - spec/litmus_paper/dependency/http_spec.rb
232
+ - spec/litmus_paper/dependency/tcp_spec.rb
233
+ - spec/litmus_paper/health_spec.rb
234
+ - spec/litmus_paper/metric/available_memory_spec.rb
235
+ - spec/litmus_paper/metric/cpu_load_spec.rb
236
+ - spec/litmus_paper/service_spec.rb
237
+ - spec/litmus_paper/status_file_spec.rb
238
+ - spec/litmus_paper_spec.rb
239
+ - spec/spec_helper.rb
240
+ - spec/support/always_available_dependency.rb
241
+ - spec/support/config.d/passing_test.config
242
+ - spec/support/config.d/test.config
243
+ - spec/support/constant_metric.rb
244
+ - spec/support/http_test_server.rb
245
+ - spec/support/http_test_server_config.ru
246
+ - spec/support/never_available_dependency.rb
247
+ - spec/support/stub_facter.rb
248
+ - spec/support/test.config
249
+ - spec/support/test.d.config