litmus_paper 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,11 +28,10 @@ module LitmusPaper
28
28
  end
29
29
 
30
30
  get "/:service/status" do
31
- service = LitmusPaper.services[params[:service]]
32
- if service.nil?
31
+ health = LitmusPaper.check_service(params[:service])
32
+ if health.nil?
33
33
  text 404, "NOT FOUND", { "X-Health" => "0" }
34
34
  else
35
- health = service.current_health
36
35
  response_code = health.ok? ? 200 : 503
37
36
  body = "Health: #{health.value}\n"
38
37
  body << health.summary
@@ -3,9 +3,10 @@ require 'csv'
3
3
  module LitmusPaper
4
4
  module Dependency
5
5
  class HaproxyBackends
6
- def initialize(domain_socket, cluster)
6
+ def initialize(domain_socket, cluster, options = {})
7
7
  @domain_socket = domain_socket
8
8
  @cluster = cluster
9
+ @timeout = options.fetch(:timeout_seconds, 2)
9
10
  end
10
11
 
11
12
  def available?
@@ -15,6 +16,8 @@ module LitmusPaper
15
16
  available = servers.select { |s| s['status'] == "UP" }
16
17
 
17
18
  available.size > 0
19
+ rescue Timeout::Error
20
+ false
18
21
  end
19
22
 
20
23
  def to_s
@@ -34,9 +37,11 @@ module LitmusPaper
34
37
  end
35
38
 
36
39
  def _fetch_stats
37
- UNIXSocket.open(@domain_socket) do |socket|
38
- socket.send "show stat\n", 0
39
- socket.read
40
+ Timeout.timeout(@timeout) do
41
+ UNIXSocket.open(@domain_socket) do |socket|
42
+ socket.send "show stat\n", 0
43
+ socket.read
44
+ end
40
45
  end
41
46
  end
42
47
  end
@@ -6,6 +6,7 @@ module LitmusPaper
6
6
  @expected_content = Regexp.new(options.fetch(:content, '.*'))
7
7
  @method = options.fetch(:method, 'GET')
8
8
  @ca_file = options[:ca_file]
9
+ @timeout = options.fetch(:timeout_seconds, 5)
9
10
  end
10
11
 
11
12
  def available?
@@ -28,6 +29,8 @@ module LitmusPaper
28
29
  request.set_form_data({})
29
30
 
30
31
  connection = Net::HTTP.new(uri.host, uri.port)
32
+ connection.open_timeout = @timeout
33
+ connection.read_timeout = @timeout
31
34
  if uri.scheme == "https"
32
35
  connection.use_ssl = true
33
36
  connection.verify_mode = OpenSSL::SSL::VERIFY_PEER
@@ -1,12 +1,13 @@
1
1
  module LitmusPaper
2
2
  module Dependency
3
3
  class TCP
4
- def initialize(ip, port)
4
+ def initialize(ip, port, options = {})
5
5
  @ip, @port = ip, port
6
+ @timeout = options.fetch(:timeout_seconds, 5)
6
7
  end
7
8
 
8
9
  def available?
9
- Timeout.timeout(5) do
10
+ Timeout.timeout(@timeout) do
10
11
  socket = TCPSocket.new(@ip, @port)
11
12
  socket.close
12
13
  end
@@ -6,10 +6,6 @@ module LitmusPaper
6
6
  @checks = checks
7
7
  end
8
8
 
9
- def success?
10
- health > 0
11
- end
12
-
13
9
  def current_health
14
10
  forced_health = _determine_forced_health
15
11
  return forced_health unless forced_health.nil?
@@ -1,3 +1,3 @@
1
1
  module LitmusPaper
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
data/lib/litmus_paper.rb CHANGED
@@ -32,6 +32,16 @@ module LitmusPaper
32
32
 
33
33
  self.logger = Logger.new
34
34
 
35
+ def self.check_service(service_name)
36
+ Facter.flush
37
+
38
+ if service = @services[service_name]
39
+ service.current_health
40
+ else
41
+ nil
42
+ end
43
+ end
44
+
35
45
  def self.configure(filename)
36
46
  @config_file = filename
37
47
 
data/litmus_paper.gemspec CHANGED
@@ -1,5 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/litmus_paper/version', __FILE__)
2
+ $LOAD_PATH.unshift(File.expand_path('../lib', __FILE__))
3
+ require "litmus_paper/version"
3
4
 
4
5
  Gem::Specification.new do |gem|
5
6
  gem.authors = ["Braintreeps"]
@@ -234,6 +234,22 @@ describe LitmusPaper::App do
234
234
  last_response.status.should == 200
235
235
  last_response.body.should match(/Up for testing/)
236
236
  end
237
+
238
+ it "resets the Facter cache" do
239
+ test_service = LitmusPaper::Service.new('test', [AlwaysAvailableDependency.new], [ConstantMetric.new(100)])
240
+ LitmusPaper.services['test'] = test_service
241
+
242
+ get "/test/status"
243
+ last_response.should be_ok
244
+
245
+ facter_uptime = Facter.value("uptime_seconds")
246
+ sleep 1
247
+
248
+ get "/test/status"
249
+ last_response.should be_ok
250
+
251
+ Facter.value("uptime_seconds").should > facter_uptime
252
+ end
237
253
  end
238
254
 
239
255
  describe "server errors" do
@@ -14,13 +14,27 @@ describe LitmusPaper::Dependency::HaproxyBackends do
14
14
  haproxy.should be_available
15
15
  end
16
16
 
17
- it "returns 0 if no nodes are available" do
17
+ it "returns false if no nodes are available" do
18
18
  pending "Broken on TravisCI 1.9.x; works locally" if ENV["TRAVIS_RUBY_VERSION"] =~ /\A1.9/
19
19
  haproxy = LitmusPaper::Dependency::HaproxyBackends.new("/tmp/stub-haproxy-stats", "orange_cluster")
20
20
  haproxy.should_not be_available
21
21
  end
22
22
  end
23
23
 
24
+ describe "timeouts" do
25
+ before(:each) do
26
+ FileUtils.rm_rf("/tmp/stub-haproxy-stats")
27
+ system "spec/support/haproxy_test_socket /tmp/stub-haproxy-stats 3 &"
28
+ sleep 1
29
+ end
30
+
31
+ it "returns false after a configurable number of seconds" do
32
+ pending "Broken on TravisCI 1.9.x; works locally" if ENV["TRAVIS_RUBY_VERSION"] =~ /\A1.9/
33
+ haproxy = LitmusPaper::Dependency::HaproxyBackends.new("/tmp/stub-haproxy-stats", "yellow_cluster", :timeout_seconds => 1)
34
+ haproxy.should_not be_available
35
+ end
36
+ end
37
+
24
38
  describe "to_s" do
25
39
  it "includes the socket file and the cluster" do
26
40
  haproxy = LitmusPaper::Dependency::HaproxyBackends.new("/tmp/stub-haproxy-stats", "orange_cluster")
@@ -75,6 +75,11 @@ describe LitmusPaper::Dependency::HTTP do
75
75
  check = LitmusPaper::Dependency::HTTP.new('http://127.0.0.1:7777')
76
76
  check.should_not be_available
77
77
  end
78
+
79
+ it "is false when the request times out" do
80
+ check = LitmusPaper::Dependency::HTTP.new("#{@url}/sleep/2", :timeout_seconds => 1)
81
+ check.should_not be_available
82
+ end
78
83
  end
79
84
 
80
85
  describe "to_s" do
@@ -2,9 +2,15 @@
2
2
 
3
3
  require 'socket'
4
4
 
5
+ socket_file, sleep_time = ARGV
6
+ sleep_time ||= 0.1
7
+ sleep_time = sleep_time.to_f
8
+
5
9
  UNIXServer.open(ARGV[0]) do |server|
6
10
  socket = server.accept
7
- socket.puts <<-DATA
11
+ sleep sleep_time
12
+ begin
13
+ socket.puts <<-DATA
8
14
  # pxname,svname,qcur,qmax,scur,smax,slim,stot,bin,bout,dreq,dresp,ereq,econ,eresp,wretr,wredis,status,weight,act,bck,chkfail,chkdown,lastchg,downtime,qlimit,pid,iid,sid,throttle,lbtot,tracked,type,rate,rate_lim,rate_max,check_status,check_code,check_duration,hrsp_1xx,hrsp_2xx,hrsp_3xx,hrsp_4xx,hrsp_5xx,hrsp_other,hanafail,req_rate,req_rate_max,req_tot,cli_abrt,srv_abrt,
9
15
  stats,FRONTEND,,,0,0,2000,0,0,0,0,0,0,,,,,OPEN,,,,,,,,,1,1,0,,,,0,0,0,0,,,,0,0,0,0,0,0,,0,0,0,,,
10
16
  stats_backend,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,UP,0,0,0,,0,35,0,,1,2,0,,0,,1,0,,0,,,,0,0,0,0,0,0,,,,,0,0,
@@ -18,5 +24,8 @@ orange_cluster,orange1,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,0,35,0,,1,6,1,,0,
18
24
  orange_cluster,orange2,0,0,0,0,,0,0,0,,0,,0,0,0,0,DOWN,1,1,0,0,0,35,0,,1,6,1,,0,,2,0,,0,L4OK,,5,,,,,,,0,,,,0,0,
19
25
  orange_cluster,BACKEND,0,0,0,0,0,0,0,0,0,0,,0,0,0,0,DOWN,1,1,0,,0,35,0,,1,6,0,,0,,1,0,,0,,,,,,,,,,,,,,0,0,
20
26
  DATA
21
- socket.close
27
+ socket.close
28
+ rescue Errno::EINVAL
29
+ # client closed connection because of timeout
30
+ end
22
31
  end
@@ -19,6 +19,12 @@ class HttpTestServer < Sinatra::Base
19
19
  end
20
20
  end
21
21
 
22
+ get "/sleep/:seconds" do
23
+ sleep params[:seconds].to_f
24
+ $stderr.puts "sleeping #{params[:seconds]}"
25
+ text 200, "Woke up after #{params.inspect} seconds"
26
+ end
27
+
22
28
  def text(response_code, body, headers ={})
23
29
  [response_code, { "Content-Type" => "text/plain" }.merge(headers), body]
24
30
  end
metadata CHANGED
@@ -1,102 +1,146 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: litmus_paper
3
- version: !ruby/object:Gem::Version
4
- version: 0.3.2
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ hash: 21
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 3
9
+ - 3
10
+ version: 0.3.3
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Braintreeps
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2012-06-22 00:00:00.000000000 Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
17
+
18
+ date: 2012-06-26 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
15
22
  name: sinatra
16
- requirement: &70248649019060 !ruby/object:Gem::Requirement
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
17
25
  none: false
18
- requirements:
26
+ requirements:
19
27
  - - ~>
20
- - !ruby/object:Gem::Version
28
+ - !ruby/object:Gem::Version
29
+ hash: 31
30
+ segments:
31
+ - 1
32
+ - 3
33
+ - 2
21
34
  version: 1.3.2
22
35
  type: :runtime
23
- prerelease: false
24
- version_requirements: *70248649019060
25
- - !ruby/object:Gem::Dependency
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
26
38
  name: facter
27
- requirement: &70248649000380 !ruby/object:Gem::Requirement
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
28
41
  none: false
29
- requirements:
42
+ requirements:
30
43
  - - ~>
31
- - !ruby/object:Gem::Version
44
+ - !ruby/object:Gem::Version
45
+ hash: 1
46
+ segments:
47
+ - 1
48
+ - 6
49
+ - 7
32
50
  version: 1.6.7
33
51
  type: :runtime
34
- prerelease: false
35
- version_requirements: *70248649000380
36
- - !ruby/object:Gem::Dependency
52
+ version_requirements: *id002
53
+ - !ruby/object:Gem::Dependency
37
54
  name: SyslogLogger
38
- requirement: &70248648925460 !ruby/object:Gem::Requirement
55
+ prerelease: false
56
+ requirement: &id003 !ruby/object:Gem::Requirement
39
57
  none: false
40
- requirements:
58
+ requirements:
41
59
  - - ~>
42
- - !ruby/object:Gem::Version
60
+ - !ruby/object:Gem::Version
61
+ hash: 5
62
+ segments:
63
+ - 1
64
+ - 4
65
+ - 1
43
66
  version: 1.4.1
44
67
  type: :runtime
45
- prerelease: false
46
- version_requirements: *70248648925460
47
- - !ruby/object:Gem::Dependency
68
+ version_requirements: *id003
69
+ - !ruby/object:Gem::Dependency
48
70
  name: rspec
49
- requirement: &70248644644480 !ruby/object:Gem::Requirement
71
+ prerelease: false
72
+ requirement: &id004 !ruby/object:Gem::Requirement
50
73
  none: false
51
- requirements:
74
+ requirements:
52
75
  - - ~>
53
- - !ruby/object:Gem::Version
76
+ - !ruby/object:Gem::Version
77
+ hash: 43
78
+ segments:
79
+ - 2
80
+ - 9
81
+ - 0
54
82
  version: 2.9.0
55
83
  type: :development
56
- prerelease: false
57
- version_requirements: *70248644644480
58
- - !ruby/object:Gem::Dependency
84
+ version_requirements: *id004
85
+ - !ruby/object:Gem::Dependency
59
86
  name: rack-test
60
- requirement: &70248644537640 !ruby/object:Gem::Requirement
87
+ prerelease: false
88
+ requirement: &id005 !ruby/object:Gem::Requirement
61
89
  none: false
62
- requirements:
90
+ requirements:
63
91
  - - ~>
64
- - !ruby/object:Gem::Version
92
+ - !ruby/object:Gem::Version
93
+ hash: 5
94
+ segments:
95
+ - 0
96
+ - 6
97
+ - 1
65
98
  version: 0.6.1
66
99
  type: :development
67
- prerelease: false
68
- version_requirements: *70248644537640
69
- - !ruby/object:Gem::Dependency
100
+ version_requirements: *id005
101
+ - !ruby/object:Gem::Dependency
70
102
  name: rake
71
- requirement: &70248644543240 !ruby/object:Gem::Requirement
103
+ prerelease: false
104
+ requirement: &id006 !ruby/object:Gem::Requirement
72
105
  none: false
73
- requirements:
106
+ requirements:
74
107
  - - ~>
75
- - !ruby/object:Gem::Version
108
+ - !ruby/object:Gem::Version
109
+ hash: 11
110
+ segments:
111
+ - 0
112
+ - 9
113
+ - 2
114
+ - 2
76
115
  version: 0.9.2.2
77
116
  type: :development
78
- prerelease: false
79
- version_requirements: *70248644543240
80
- - !ruby/object:Gem::Dependency
117
+ version_requirements: *id006
118
+ - !ruby/object:Gem::Dependency
81
119
  name: rake_commit
82
- requirement: &70248644542440 !ruby/object:Gem::Requirement
120
+ prerelease: false
121
+ requirement: &id007 !ruby/object:Gem::Requirement
83
122
  none: false
84
- requirements:
123
+ requirements:
85
124
  - - ~>
86
- - !ruby/object:Gem::Version
87
- version: '0.13'
125
+ - !ruby/object:Gem::Version
126
+ hash: 17
127
+ segments:
128
+ - 0
129
+ - 13
130
+ version: "0.13"
88
131
  type: :development
89
- prerelease: false
90
- version_requirements: *70248644542440
132
+ version_requirements: *id007
91
133
  description: Backend health tester for HA Services
92
- email:
134
+ email:
93
135
  - code@getbraintree.com
94
- executables:
136
+ executables:
95
137
  - litmus
96
138
  - litmusctl
97
139
  extensions: []
140
+
98
141
  extra_rdoc_files: []
99
- files:
142
+
143
+ files:
100
144
  - .gitignore
101
145
  - .rake_commit
102
146
  - .rvmrc
@@ -155,31 +199,41 @@ files:
155
199
  - spec/support/stub_facter.rb
156
200
  - spec/support/test.config
157
201
  - spec/support/test.d.config
202
+ has_rdoc: true
158
203
  homepage: https://github.com/braintree/litmus_paper
159
204
  licenses: []
205
+
160
206
  post_install_message:
161
207
  rdoc_options: []
162
- require_paths:
208
+
209
+ require_paths:
163
210
  - lib
164
- required_ruby_version: !ruby/object:Gem::Requirement
211
+ required_ruby_version: !ruby/object:Gem::Requirement
165
212
  none: false
166
- requirements:
167
- - - ! '>='
168
- - !ruby/object:Gem::Version
169
- version: '0'
170
- required_rubygems_version: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ hash: 3
217
+ segments:
218
+ - 0
219
+ version: "0"
220
+ required_rubygems_version: !ruby/object:Gem::Requirement
171
221
  none: false
172
- requirements:
173
- - - ! '>='
174
- - !ruby/object:Gem::Version
175
- version: '0'
222
+ requirements:
223
+ - - ">="
224
+ - !ruby/object:Gem::Version
225
+ hash: 3
226
+ segments:
227
+ - 0
228
+ version: "0"
176
229
  requirements: []
230
+
177
231
  rubyforge_project:
178
- rubygems_version: 1.8.10
232
+ rubygems_version: 1.3.7
179
233
  signing_key:
180
234
  specification_version: 3
181
235
  summary: Backend health tester for HA Services, partner project of big_brother
182
- test_files:
236
+ test_files:
183
237
  - spec/litmus_paper/app_spec.rb
184
238
  - spec/litmus_paper/cli/admin_spec.rb
185
239
  - spec/litmus_paper/cli/server_spec.rb