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.
- data/lib/litmus_paper/app.rb +2 -3
- data/lib/litmus_paper/dependency/haproxy_backends.rb +9 -4
- data/lib/litmus_paper/dependency/http.rb +3 -0
- data/lib/litmus_paper/dependency/tcp.rb +3 -2
- data/lib/litmus_paper/service.rb +0 -4
- data/lib/litmus_paper/version.rb +1 -1
- data/lib/litmus_paper.rb +10 -0
- data/litmus_paper.gemspec +2 -1
- data/spec/litmus_paper/app_spec.rb +16 -0
- data/spec/litmus_paper/dependency/haproxy_backends_spec.rb +15 -1
- data/spec/litmus_paper/dependency/http_spec.rb +5 -0
- data/spec/support/haproxy_test_socket +11 -2
- data/spec/support/http_test_server.rb +6 -0
- metadata +120 -66
data/lib/litmus_paper/app.rb
CHANGED
@@ -28,11 +28,10 @@ module LitmusPaper
|
|
28
28
|
end
|
29
29
|
|
30
30
|
get "/:service/status" do
|
31
|
-
|
32
|
-
if
|
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
|
-
|
38
|
-
|
39
|
-
|
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(
|
10
|
+
Timeout.timeout(@timeout) do
|
10
11
|
socket = TCPSocket.new(@ip, @port)
|
11
12
|
socket.close
|
12
13
|
end
|
data/lib/litmus_paper/service.rb
CHANGED
data/lib/litmus_paper/version.rb
CHANGED
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
@@ -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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
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
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
26
38
|
name: facter
|
27
|
-
|
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
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
52
|
+
version_requirements: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
37
54
|
name: SyslogLogger
|
38
|
-
|
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
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
68
|
+
version_requirements: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
48
70
|
name: rspec
|
49
|
-
|
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
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
84
|
+
version_requirements: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
59
86
|
name: rack-test
|
60
|
-
|
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
|
-
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Dependency
|
100
|
+
version_requirements: *id005
|
101
|
+
- !ruby/object:Gem::Dependency
|
70
102
|
name: rake
|
71
|
-
|
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
|
-
|
79
|
-
|
80
|
-
- !ruby/object:Gem::Dependency
|
117
|
+
version_requirements: *id006
|
118
|
+
- !ruby/object:Gem::Dependency
|
81
119
|
name: rake_commit
|
82
|
-
|
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
|
-
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
hash: 17
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
- 13
|
130
|
+
version: "0.13"
|
88
131
|
type: :development
|
89
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
170
|
-
|
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
|
-
|
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.
|
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
|