pinglish 0.0.0 → 0.0.1
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/Gemfile.lock +3 -0
- data/README.md +0 -3
- data/lib/pinglish.rb +3 -8
- data/pinglish.gemspec +2 -1
- data/script/tests +1 -1
- data/test/check_test.rb +23 -0
- data/test/helper.rb +2 -0
- data/test/pinglish_test.rb +173 -3
- metadata +22 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -22,9 +22,6 @@ conforms to the spec below.
|
|
22
22
|
0. The response __must__ return an `HTTP 503 SERVICE UNAVAILABLE`
|
23
23
|
status code if any health checks fail.
|
24
24
|
|
25
|
-
0. The response __must__ return an `HTTP 418 I'M A TEAPOT` status code
|
26
|
-
if the request asks for any content-type but `application/json`.
|
27
|
-
|
28
25
|
0. The response __must__ be of Content-Type `application/json;
|
29
26
|
charset=UTF-8`.
|
30
27
|
|
data/lib/pinglish.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "json"
|
2
2
|
require "timeout"
|
3
|
+
require "rack/request"
|
3
4
|
|
4
5
|
# This Rack middleware provides a "/_ping" endpoint for configurable
|
5
6
|
# system health checks. It's intended to be consumed by machines.
|
@@ -17,11 +18,6 @@ class Pinglish
|
|
17
18
|
|
18
19
|
MAX_TOTAL_TIME = 29
|
19
20
|
|
20
|
-
# This triple is returned if the request media type isn't
|
21
|
-
# "application/json".
|
22
|
-
|
23
|
-
TEAPOT = [418, HEADERS, ['{"teapot":"true"}']]
|
24
|
-
|
25
21
|
# Represents a check, which is a behavior block with a name and
|
26
22
|
# timeout in seconds.
|
27
23
|
|
@@ -64,7 +60,6 @@ class Pinglish
|
|
64
60
|
request = Rack::Request.new env
|
65
61
|
|
66
62
|
return @app.call env unless request.path == @path
|
67
|
-
return TEAPOT unless request.media_type == "application/json"
|
68
63
|
|
69
64
|
timeout MAX_TOTAL_TIME do
|
70
65
|
results = {}
|
@@ -135,11 +130,11 @@ class Pinglish
|
|
135
130
|
end
|
136
131
|
|
137
132
|
# Does `value` represent a check failure? This default
|
138
|
-
# implementation returns `true` for any value that is an Exception.
|
133
|
+
# implementation returns `true` for any value that is an Exception or false.
|
139
134
|
# Subclasses can override this method for different behavior.
|
140
135
|
|
141
136
|
def failure?(value)
|
142
|
-
value.is_a?
|
137
|
+
value.is_a?(Exception) || value == false
|
143
138
|
end
|
144
139
|
|
145
140
|
# Raise Pinglish::TooLong after `seconds` has elapsed. This default
|
data/pinglish.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |gem|
|
4
4
|
gem.name = "pinglish"
|
5
|
-
gem.version = "0.0.
|
5
|
+
gem.version = "0.0.1"
|
6
6
|
gem.authors = ["John Barnette", "Will Farrington"]
|
7
7
|
gem.email = ["jbarnette@github.com", "wfarr@github.com"]
|
8
8
|
gem.description = "A simple Rack middleware for checking app health."
|
@@ -15,4 +15,5 @@ Gem::Specification.new do |gem|
|
|
15
15
|
|
16
16
|
gem.add_dependency "rack"
|
17
17
|
gem.add_development_dependency "minitest", "~> 4.5"
|
18
|
+
gem.add_development_dependency "rack-test", "~> 0.6"
|
18
19
|
end
|
data/script/tests
CHANGED
data/test/check_test.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class PinglishCheckTest < MiniTest::Unit::TestCase
|
4
|
+
def test_initialize
|
5
|
+
check = Pinglish::Check.new(:db)
|
6
|
+
assert_equal :db, check.name
|
7
|
+
end
|
8
|
+
|
9
|
+
def test_initialize_default_timeout
|
10
|
+
check = Pinglish::Check.new(:db)
|
11
|
+
assert_equal 1, check.timeout
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_initialize_override_timeout
|
15
|
+
check = Pinglish::Check.new(:db, :timeout => 2)
|
16
|
+
assert_equal 2, check.timeout
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_call
|
20
|
+
check = Pinglish::Check.new(:db) { :result_of_block }
|
21
|
+
assert_equal :result_of_block, check.call
|
22
|
+
end
|
23
|
+
end
|
data/test/helper.rb
ADDED
data/test/pinglish_test.rb
CHANGED
@@ -1,7 +1,177 @@
|
|
1
|
-
require "
|
1
|
+
require "helper"
|
2
|
+
require "rack/test"
|
2
3
|
|
3
4
|
class PinglishTest < MiniTest::Unit::TestCase
|
4
|
-
|
5
|
-
|
5
|
+
FakeApp = lambda { |env| [404, {}, []] }
|
6
|
+
|
7
|
+
def build_app(*args, &block)
|
8
|
+
Rack::Builder.new do |builder|
|
9
|
+
builder.use Pinglish, *args, &block
|
10
|
+
builder.run FakeApp
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_with_defaults
|
15
|
+
app = build_app
|
16
|
+
|
17
|
+
session = Rack::Test::Session.new(app)
|
18
|
+
session.get '/_ping'
|
19
|
+
assert_equal 200, session.last_response.status
|
20
|
+
assert_equal 'application/json; charset=UTF-8',
|
21
|
+
session.last_response.content_type
|
22
|
+
|
23
|
+
json = JSON.load(session.last_response.body)
|
24
|
+
assert json.key?('now')
|
25
|
+
assert_equal 'ok', json['status']
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_with_good_check
|
29
|
+
app = build_app do |ping|
|
30
|
+
ping.check(:db) { :up_and_at_em }
|
31
|
+
ping.check(:queue) { :pushin_and_poppin }
|
32
|
+
end
|
33
|
+
|
34
|
+
session = Rack::Test::Session.new(app)
|
35
|
+
session.get '/_ping'
|
36
|
+
|
37
|
+
assert_equal 'application/json; charset=UTF-8',
|
38
|
+
session.last_response.content_type
|
39
|
+
|
40
|
+
json = JSON.load(session.last_response.body)
|
41
|
+
assert json.key?('now')
|
42
|
+
assert_equal 'ok', json['status']
|
43
|
+
assert_equal 'up_and_at_em', json['db']
|
44
|
+
assert_equal 'pushin_and_poppin', json['queue']
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_with_unnamed_check
|
48
|
+
app = build_app do |ping|
|
49
|
+
ping.check { :yohoho }
|
50
|
+
end
|
51
|
+
|
52
|
+
session = Rack::Test::Session.new(app)
|
53
|
+
session.get '/_ping'
|
54
|
+
|
55
|
+
assert_equal 'application/json; charset=UTF-8',
|
56
|
+
session.last_response.content_type
|
57
|
+
|
58
|
+
json = JSON.load(session.last_response.body)
|
59
|
+
assert json.key?('now')
|
60
|
+
assert_equal 'ok', json['status']
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_with_check_that_raises
|
64
|
+
app = build_app do |ping|
|
65
|
+
ping.check(:db) { :ok }
|
66
|
+
ping.check(:raise) { raise 'nooooope' }
|
67
|
+
end
|
68
|
+
|
69
|
+
session = Rack::Test::Session.new(app)
|
70
|
+
session.get '/_ping'
|
71
|
+
|
72
|
+
assert_equal 503, session.last_response.status
|
73
|
+
assert_equal 'application/json; charset=UTF-8',
|
74
|
+
session.last_response.content_type
|
75
|
+
|
76
|
+
json = JSON.load(session.last_response.body)
|
77
|
+
assert json.key?('now')
|
78
|
+
assert_equal 'fail', json['status']
|
79
|
+
end
|
80
|
+
|
81
|
+
def test_with_check_that_returns_false
|
82
|
+
app = build_app do |ping|
|
83
|
+
ping.check(:db) { :ok }
|
84
|
+
ping.check(:fail) { false }
|
85
|
+
end
|
86
|
+
|
87
|
+
session = Rack::Test::Session.new(app)
|
88
|
+
session.get '/_ping'
|
89
|
+
|
90
|
+
assert_equal 503, session.last_response.status
|
91
|
+
assert_equal 'application/json; charset=UTF-8',
|
92
|
+
session.last_response.content_type
|
93
|
+
|
94
|
+
json = JSON.load(session.last_response.body)
|
95
|
+
assert json.key?('now')
|
96
|
+
assert_equal 'fail', json['status']
|
97
|
+
assert_equal ['fail'], json['failures']
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_with_check_that_times_out
|
101
|
+
app = build_app do |ping|
|
102
|
+
ping.check(:db) { :ok }
|
103
|
+
ping.check(:long, :timeout => 0.001) { sleep 0.003 }
|
104
|
+
end
|
105
|
+
|
106
|
+
session = Rack::Test::Session.new(app)
|
107
|
+
session.get '/_ping'
|
108
|
+
|
109
|
+
assert_equal 503, session.last_response.status
|
110
|
+
assert_equal 'application/json; charset=UTF-8',
|
111
|
+
session.last_response.content_type
|
112
|
+
|
113
|
+
json = JSON.load(session.last_response.body)
|
114
|
+
assert json.key?('now')
|
115
|
+
assert_equal 'fail', json['status']
|
116
|
+
assert_equal ['long'], json['timeouts']
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_with_custom_path
|
120
|
+
app = build_app("/_piiiiing")
|
121
|
+
|
122
|
+
session = Rack::Test::Session.new(app)
|
123
|
+
session.get '/_piiiiing'
|
124
|
+
assert_equal 200, session.last_response.status
|
125
|
+
assert_equal 'application/json; charset=UTF-8',
|
126
|
+
session.last_response.content_type
|
127
|
+
|
128
|
+
json = JSON.load(session.last_response.body)
|
129
|
+
assert json.key?('now')
|
130
|
+
assert_equal 'ok', json['status']
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_check_without_name
|
134
|
+
pinglish = Pinglish.new(FakeApp)
|
135
|
+
check = pinglish.check { :ok }
|
136
|
+
assert_instance_of Pinglish::Check, check
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_check_with_name
|
140
|
+
pinglish = Pinglish.new(FakeApp)
|
141
|
+
check = pinglish.check(:db) { :ok }
|
142
|
+
assert_instance_of Pinglish::Check, check
|
143
|
+
assert_equal :db, check.name
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_failure_boolean
|
147
|
+
pinglish = Pinglish.new(FakeApp)
|
148
|
+
|
149
|
+
assert pinglish.failure?(Exception.new),
|
150
|
+
"Expected failure with exception to be true"
|
151
|
+
|
152
|
+
assert pinglish.failure?(false),
|
153
|
+
"Expected failure with false to be true"
|
154
|
+
|
155
|
+
assert !pinglish.failure?(true),
|
156
|
+
"Expected failure with true value to be false"
|
157
|
+
|
158
|
+
assert !pinglish.failure?(:ok),
|
159
|
+
"Expected failure with non-false and non-exception to be false"
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_timeout
|
163
|
+
pinglish = Pinglish.new(FakeApp)
|
164
|
+
begin
|
165
|
+
pinglish.timeout(0.001) { sleep 0.003 }
|
166
|
+
assert false, "Timeout did not happen, but should have."
|
167
|
+
rescue Pinglish::TooLong => e
|
168
|
+
# all good
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_timeout_boolean
|
173
|
+
pinglish = Pinglish.new(FakeApp)
|
174
|
+
assert_equal true, pinglish.timeout?(Pinglish::TooLong.new)
|
175
|
+
assert_equal false, pinglish.timeout?(Exception.new)
|
6
176
|
end
|
7
177
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pinglish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-02-26 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rack
|
@@ -44,6 +44,22 @@ dependencies:
|
|
44
44
|
- - ~>
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '4.5'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rack-test
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.6'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0.6'
|
47
63
|
description: A simple Rack middleware for checking app health.
|
48
64
|
email:
|
49
65
|
- jbarnette@github.com
|
@@ -62,6 +78,8 @@ files:
|
|
62
78
|
- script/bootstrap
|
63
79
|
- script/release
|
64
80
|
- script/tests
|
81
|
+
- test/check_test.rb
|
82
|
+
- test/helper.rb
|
65
83
|
- test/pinglish_test.rb
|
66
84
|
homepage: https://github.com/jbarnette/pinglish
|
67
85
|
licenses: []
|
@@ -88,4 +106,6 @@ signing_key:
|
|
88
106
|
specification_version: 3
|
89
107
|
summary: /_ping your way to freedom.
|
90
108
|
test_files:
|
109
|
+
- test/check_test.rb
|
110
|
+
- test/helper.rb
|
91
111
|
- test/pinglish_test.rb
|