litmus_paper 0.3.2 → 0.3.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.
@@ -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