outpost 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +10 -0
- data/Gemfile.lock +39 -0
- data/README.markdown +159 -0
- data/Rakefile +12 -0
- data/lib/outpost.rb +8 -0
- data/lib/outpost/dsl.rb +54 -0
- data/lib/outpost/expectations.rb +3 -0
- data/lib/outpost/expectations/response_body.rb +22 -0
- data/lib/outpost/expectations/response_code.rb +13 -0
- data/lib/outpost/expectations/response_time.rb +20 -0
- data/lib/outpost/report.rb +28 -0
- data/lib/outpost/scout.rb +56 -0
- data/lib/outpost/scout_config.rb +31 -0
- data/lib/outpost/scouts.rb +2 -0
- data/lib/outpost/scouts/http.rb +28 -0
- data/lib/outpost/scouts/ping.rb +23 -0
- data/lib/outpost/version.rb +3 -0
- data/outpost.gemspec +21 -0
- data/test/integration/basic_dsl_test.rb +58 -0
- data/test/integration/more_complex_test.rb +64 -0
- data/test/outpost/dsl_test.rb +86 -0
- data/test/outpost/expectations/response_body_test.rb +89 -0
- data/test/outpost/expectations/response_code_test.rb +45 -0
- data/test/outpost/expectations/response_time_test.rb +70 -0
- data/test/outpost/report_test.rb +19 -0
- data/test/outpost/scout_config_test.rb +29 -0
- data/test/outpost/scout_test.rb +91 -0
- data/test/support/server.rb +24 -0
- data/test/support/test_app.rb +11 -0
- data/test/test_helper.rb +21 -0
- metadata +118 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
archive-tar-minitar (0.5.2)
|
5
|
+
columnize (0.3.2)
|
6
|
+
daemons (1.1.0)
|
7
|
+
eventmachine (0.12.10)
|
8
|
+
linecache19 (0.5.11)
|
9
|
+
ruby_core_source (>= 0.1.4)
|
10
|
+
net-ping (1.3.7)
|
11
|
+
rack (1.2.1)
|
12
|
+
ruby-debug-base19 (0.11.24)
|
13
|
+
columnize (>= 0.3.1)
|
14
|
+
linecache19 (>= 0.5.11)
|
15
|
+
ruby_core_source (>= 0.1.4)
|
16
|
+
ruby-debug19 (0.11.6)
|
17
|
+
columnize (>= 0.3.1)
|
18
|
+
linecache19 (>= 0.5.11)
|
19
|
+
ruby-debug-base19 (>= 0.11.19)
|
20
|
+
ruby_core_source (0.1.4)
|
21
|
+
archive-tar-minitar (>= 0.5.2)
|
22
|
+
sinatra (1.1.2)
|
23
|
+
rack (~> 1.1)
|
24
|
+
tilt (~> 1.2)
|
25
|
+
thin (1.2.7)
|
26
|
+
daemons (>= 1.0.9)
|
27
|
+
eventmachine (>= 0.12.6)
|
28
|
+
rack (>= 1.0.0)
|
29
|
+
tilt (1.2.2)
|
30
|
+
|
31
|
+
PLATFORMS
|
32
|
+
ruby
|
33
|
+
|
34
|
+
DEPENDENCIES
|
35
|
+
net-ping
|
36
|
+
rack
|
37
|
+
ruby-debug19
|
38
|
+
sinatra
|
39
|
+
thin
|
data/README.markdown
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
# Outpost
|
2
|
+
|
3
|
+
Outpost is under development and is a project for the RMU: Ruby Mendicant
|
4
|
+
University.
|
5
|
+
|
6
|
+
## Features
|
7
|
+
|
8
|
+
Outpost is a tool to monitor the state of your service (not server). What does it mean?
|
9
|
+
|
10
|
+
It means:
|
11
|
+
|
12
|
+
* it can monitor the state of a server, such as MySQL;
|
13
|
+
* it can monitor some business rule to see if everything is running accordingly (such as cron jobs)
|
14
|
+
* it can monitor several servers
|
15
|
+
* it can monitor whatever you can code with Ruby
|
16
|
+
|
17
|
+
It will connect to the related machines (it won't have any proxies/agents running on the servers to
|
18
|
+
report data) and collect the data. The idea is to be completely uncoupled with the systems.
|
19
|
+
It should report a status per declared system.
|
20
|
+
|
21
|
+
The idea is to make a reliable framework for the Ruby developer to create his own monitoring rules.
|
22
|
+
So, summing it all up, Nagios in Ruby, much cooler!
|
23
|
+
|
24
|
+
## Installing
|
25
|
+
|
26
|
+
gem install outpost
|
27
|
+
|
28
|
+
## Starting
|
29
|
+
|
30
|
+
To create your Outposts, you must require 'outpost'. You also need to include
|
31
|
+
'outpost/scouts' if you want to use the supplied scouts. Example:
|
32
|
+
|
33
|
+
require 'outpost'
|
34
|
+
require 'outpost/scouts'
|
35
|
+
|
36
|
+
class Bla < Outpost::DSL
|
37
|
+
using Outpost::Scouts::Http => "web page" do
|
38
|
+
options :host => 'localhost', :port => 3000
|
39
|
+
report :up, :response_code => 200
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
a = Bla.new
|
44
|
+
a.run
|
45
|
+
p a.messages # => ["Outpost::Scouts::Http: 'web page' is reporting up."]
|
46
|
+
|
47
|
+
|
48
|
+
## How it works
|
49
|
+
|
50
|
+
Consider the following example:
|
51
|
+
|
52
|
+
require 'outpost'
|
53
|
+
require 'outpost/scouts'
|
54
|
+
|
55
|
+
class HttpOutpostExample < Outpost::DSL
|
56
|
+
using Outpost::Scouts::Http => "web page" do
|
57
|
+
options :host => 'localhost', :port => 3000
|
58
|
+
report :up, :response_code => 200
|
59
|
+
report :down, :response_body => {:match => /Ops/}
|
60
|
+
end
|
61
|
+
end
|
62
|
+
outpost = HttpOutpostExample.new
|
63
|
+
outpost.run # => :down
|
64
|
+
|
65
|
+
In this simple example, an Outpost was created to monitor a web server running
|
66
|
+
on localhost at port 3000. Every time #run is called, the outpost will
|
67
|
+
run associated rules (in this example, check if the HTTP response code is 200
|
68
|
+
and report "up" if it does and also check if the response body matches /Ops/,
|
69
|
+
reporting "down" in that case).
|
70
|
+
|
71
|
+
## Outpost
|
72
|
+
|
73
|
+
Outpost is the description of the system and provides a DSL to do it.
|
74
|
+
Check "How it works" section for an example, or check the [integration tests](https://github.com/vinibaggio/outpost/blob/master/test/integration/basic_dsl_test.rb)
|
75
|
+
for more.
|
76
|
+
|
77
|
+
## Scout
|
78
|
+
|
79
|
+
Scout are pure Ruby classes that will test your server. For instance, check the
|
80
|
+
Outpost::Scouts::Http example below:
|
81
|
+
|
82
|
+
module Outpost
|
83
|
+
module Scouts
|
84
|
+
class Http < Outpost::Scout
|
85
|
+
extend Outpost::Expectations::ResponseCode
|
86
|
+
extend Outpost::Expectations::ResponseBody
|
87
|
+
|
88
|
+
attr_reader :response_code, :response_body
|
89
|
+
|
90
|
+
def setup(options)
|
91
|
+
@host = options[:host]
|
92
|
+
@port = options[:port] || 80
|
93
|
+
@path = options[:path] || '/'
|
94
|
+
end
|
95
|
+
|
96
|
+
def execute
|
97
|
+
response = Net::HTTP.get_response(@host, @path, @port)
|
98
|
+
@response_code = response.code.to_i
|
99
|
+
@response_body = response.body
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
It must implement the #setup and #execute methods. The magic lies in the #execute
|
106
|
+
method, where you can implement any kind of logic to test whether your system is up
|
107
|
+
or not. You may also include expectations in order to process the output of your system.
|
108
|
+
For more information about expectations, check the section below.
|
109
|
+
|
110
|
+
## Expectations
|
111
|
+
|
112
|
+
Consider the following code snippet, taken from previous examples:
|
113
|
+
|
114
|
+
report :up, :response_code => 200
|
115
|
+
report :down, :response_body => {:match => /Ops/}
|
116
|
+
|
117
|
+
In the example above, :response\_code and :response\_body are expectations, responsible
|
118
|
+
to get Scout's output and evaluate it, in order to determine a status.
|
119
|
+
|
120
|
+
They must be registered into each Scout that wish to support different types
|
121
|
+
of expectations. You can supply a block or an object that respond to #call
|
122
|
+
and return true if any of the rules match. It will receive an instance
|
123
|
+
of the scout (so you can query current system state) as the first parameter
|
124
|
+
and the state defined in the #report method as the second.
|
125
|
+
|
126
|
+
So you can easily create your own expectation. Let's recreate the :response\_code in
|
127
|
+
Outpost::Scouts::Http:
|
128
|
+
|
129
|
+
module Outpost
|
130
|
+
module Scouts
|
131
|
+
class Http < Outpost::Scout
|
132
|
+
expect(:response_code) { |scout,code| scout.response_code == code }
|
133
|
+
|
134
|
+
attr_reader :response_code
|
135
|
+
|
136
|
+
def setup(options)
|
137
|
+
@host = options[:host]
|
138
|
+
@port = options[:port] || 80
|
139
|
+
@path = options[:path] || '/'
|
140
|
+
end
|
141
|
+
|
142
|
+
def execute
|
143
|
+
response = Net::HTTP.get_response(@host, @path, @port)
|
144
|
+
@response_code = response.code.to_i
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
You can also check the supplied expectations in the source of the project to have
|
151
|
+
an idea on how to implement more complex rules.
|
152
|
+
|
153
|
+
## TODO
|
154
|
+
|
155
|
+
There's a lot to be done yet. For example, SSH support, :warning status, etc.
|
156
|
+
|
157
|
+
## License
|
158
|
+
|
159
|
+
MIT.
|
data/Rakefile
ADDED
data/lib/outpost.rb
ADDED
data/lib/outpost/dsl.rb
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
module Outpost
|
2
|
+
class DSL
|
3
|
+
class << self
|
4
|
+
attr_reader :scouts
|
5
|
+
|
6
|
+
def using(scouts, &block)
|
7
|
+
@scouts ||= Hash.new { |h, k| h[k] = {} }
|
8
|
+
|
9
|
+
config = ScoutConfig.new
|
10
|
+
config.instance_eval(&block)
|
11
|
+
|
12
|
+
scouts.each do |scout, description|
|
13
|
+
@scouts[scout][:description] = description
|
14
|
+
@scouts[scout][:config] = config
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :last_status, :reports
|
20
|
+
|
21
|
+
def run
|
22
|
+
@reports = self.class.scouts.map do |scout, options|
|
23
|
+
run_scout(scout, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
statuses = @reports.map { |r| r.status }
|
27
|
+
|
28
|
+
@last_status = Report.summarize(statuses)
|
29
|
+
end
|
30
|
+
|
31
|
+
def up?
|
32
|
+
@last_status == :up
|
33
|
+
end
|
34
|
+
|
35
|
+
def down?
|
36
|
+
@last_status == :down
|
37
|
+
end
|
38
|
+
|
39
|
+
def messages
|
40
|
+
reports.map { |r| r.to_s }
|
41
|
+
end
|
42
|
+
|
43
|
+
def run_scout(scout, options)
|
44
|
+
scout_instance = scout.new(options[:description], options[:config])
|
45
|
+
|
46
|
+
params = {
|
47
|
+
:name => scout.name,
|
48
|
+
:description => options[:description],
|
49
|
+
:status => scout_instance.run
|
50
|
+
}
|
51
|
+
Report.new(params)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Outpost
|
2
|
+
module Expectations
|
3
|
+
module ResponseBody
|
4
|
+
RESPONSE_BODY_MAPPING = {
|
5
|
+
:match => "=~",
|
6
|
+
:not_match => "!~",
|
7
|
+
:equals => "==",
|
8
|
+
:differs => "!="
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
def self.extended(base)
|
12
|
+
base.expect :response_body, base.method(:evaluate_response_body)
|
13
|
+
end
|
14
|
+
|
15
|
+
def evaluate_response_body(scout, rules)
|
16
|
+
rules.all? do |rule,comparison|
|
17
|
+
scout.response_body.send(RESPONSE_BODY_MAPPING[rule], comparison)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Outpost
|
2
|
+
module Expectations
|
3
|
+
module ResponseCode
|
4
|
+
def self.extended(base)
|
5
|
+
base.expect :response_code, base.method(:evaluate_response_code)
|
6
|
+
end
|
7
|
+
|
8
|
+
def evaluate_response_code(scout, response_code)
|
9
|
+
scout.response_code == response_code.to_i
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Outpost
|
2
|
+
module Expectations
|
3
|
+
module ResponseTime
|
4
|
+
RESPONSE_TIME_MAPPING = {
|
5
|
+
:less_than => "<",
|
6
|
+
:more_than => ">",
|
7
|
+
}.freeze
|
8
|
+
|
9
|
+
def self.extended(base)
|
10
|
+
base.expect :response_time, base.method(:evaluate_response_time)
|
11
|
+
end
|
12
|
+
|
13
|
+
def evaluate_response_time(scout, rules)
|
14
|
+
rules.all? do |rule,comparison|
|
15
|
+
scout.response_time.send(RESPONSE_TIME_MAPPING[rule], comparison)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Outpost
|
2
|
+
class Report
|
3
|
+
# summarizes the list of statuses in a single status only.
|
4
|
+
# The logic is rather simple - it will return the lowest status
|
5
|
+
# present in the list.
|
6
|
+
#
|
7
|
+
# Examples:
|
8
|
+
#
|
9
|
+
# if passed [:up, :up, :up], will result on :up
|
10
|
+
# if passed [:up, :down, :up], will result on :down
|
11
|
+
def self.summarize(status_list)
|
12
|
+
return :down if status_list.empty? || status_list.include?(:down)
|
13
|
+
return :up
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :name, :description, :status
|
17
|
+
|
18
|
+
def initialize(params)
|
19
|
+
@name = params[:name]
|
20
|
+
@description = params[:description]
|
21
|
+
@status = params[:status]
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"#{name}: '#{description}' is reporting #{status}."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Outpost
|
2
|
+
class Scout
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def expectations
|
6
|
+
@expectations ? @expectations.dup : []
|
7
|
+
end
|
8
|
+
|
9
|
+
def expect(expectation, callable=nil, &callable_block)
|
10
|
+
callable ||= callable_block
|
11
|
+
|
12
|
+
if callable.respond_to?(:call)
|
13
|
+
@expectations ||= {}
|
14
|
+
@expectations[expectation] = callable
|
15
|
+
else
|
16
|
+
raise ArgumentError, 'Object must respond to method #call to be a valid expectation.'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(description, config)
|
22
|
+
@description = description
|
23
|
+
@config = config
|
24
|
+
|
25
|
+
setup(config.options)
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
statuses = []
|
30
|
+
execute
|
31
|
+
@config.reports.each do |response_pair, status|
|
32
|
+
response_pair.each do |expectation, value|
|
33
|
+
if self.class.expectations[expectation].nil?
|
34
|
+
message = "expectation '#{expectation}' wasn't implemented by #{self.class.name}"
|
35
|
+
raise NotImplementedError, message
|
36
|
+
end
|
37
|
+
|
38
|
+
if self.class.expectations[expectation].call(self, value)
|
39
|
+
statuses << status
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Report.summarize(statuses)
|
45
|
+
end
|
46
|
+
|
47
|
+
def setup(*args)
|
48
|
+
raise NotImplementedError, 'You must implement the setup method for Scout to work correctly.'
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute(*args)
|
52
|
+
raise NotImplementedError, 'You must implement the execute method for Scout to work correctly.'
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Outpost
|
2
|
+
class ScoutConfig
|
3
|
+
attr_reader :options, :reports
|
4
|
+
|
5
|
+
# Reads/writes any options. It will passed
|
6
|
+
# down to the scout.
|
7
|
+
def options(args=nil)
|
8
|
+
if args.nil?
|
9
|
+
@options
|
10
|
+
else
|
11
|
+
@options = args
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Reads reporting as:
|
16
|
+
# report :up, :response_code => 200
|
17
|
+
#
|
18
|
+
# It reads much better in the DSL, but doesn't make
|
19
|
+
# much sense in terms of code, so it is changed to
|
20
|
+
# an inverted approach, so:
|
21
|
+
# status = 200
|
22
|
+
# params = {:response_code => 200}
|
23
|
+
#
|
24
|
+
# gets stored as:
|
25
|
+
# {:response_code => 200} = up
|
26
|
+
def report(status, params)
|
27
|
+
@reports ||= {}
|
28
|
+
@reports[params] = status
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'outpost'
|
3
|
+
|
4
|
+
require 'outpost/expectations'
|
5
|
+
|
6
|
+
module Outpost
|
7
|
+
module Scouts
|
8
|
+
class Http < Outpost::Scout
|
9
|
+
extend Outpost::Expectations::ResponseCode
|
10
|
+
extend Outpost::Expectations::ResponseBody
|
11
|
+
|
12
|
+
attr_reader :response_code, :response_body
|
13
|
+
|
14
|
+
def setup(options)
|
15
|
+
@host = options[:host]
|
16
|
+
@port = options[:port] || 80
|
17
|
+
@path = options[:path] || '/'
|
18
|
+
end
|
19
|
+
|
20
|
+
def execute
|
21
|
+
# FIXME Apply Dependency Injection Principle here
|
22
|
+
response = Net::HTTP.get_response(@host, @path, @port)
|
23
|
+
@response_code = response.code.to_i
|
24
|
+
@response_body = response.body
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'net/ping/external'
|
2
|
+
|
3
|
+
module Outpost
|
4
|
+
module Scouts
|
5
|
+
class Ping < Outpost::Scout
|
6
|
+
extend Outpost::Expectations::ResponseTime
|
7
|
+
attr_reader :response_time
|
8
|
+
|
9
|
+
def setup(options)
|
10
|
+
@host = options[:host]
|
11
|
+
end
|
12
|
+
|
13
|
+
def execute
|
14
|
+
# FIXME Apply Dependency Injection Principle here
|
15
|
+
pinger = Net::Ping::External.new
|
16
|
+
if pinger.ping(@host)
|
17
|
+
# Miliseconds
|
18
|
+
@response_time = pinger.duration * 100
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/outpost.gemspec
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "outpost/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "outpost"
|
6
|
+
s.version = Outpost::VERSION.dup
|
7
|
+
s.description = "Simple service monitoring with a clean DSL for configuration."
|
8
|
+
s.summary = "Simple service monitoring with a clean DSL for configuration."
|
9
|
+
s.author = "Vinicius Baggio Fuentes"
|
10
|
+
s.email = "vinibaggio@gmail.com"
|
11
|
+
s.homepage = "http://www.github.com/vinibaggio/outpost"
|
12
|
+
|
13
|
+
s.rubyforge_project = "outpost"
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency("net-ping", "~> 1.3.7")
|
21
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'outpost/scouts/http'
|
4
|
+
|
5
|
+
describe "basic DSL integration test" do
|
6
|
+
before(:each) do
|
7
|
+
@server = Server.new
|
8
|
+
@server.boot(TestApp)
|
9
|
+
|
10
|
+
while !@server.responsive?
|
11
|
+
sleep 0.1
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class ExampleSuccess < Outpost::DSL
|
16
|
+
using Outpost::Scouts::Http => 'master http server' do
|
17
|
+
options :host => 'localhost', :port => 9595
|
18
|
+
report :up, :response_code => 200
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class ExampleFailure < Outpost::DSL
|
23
|
+
using Outpost::Scouts::Http => 'master http server' do
|
24
|
+
options :host => 'localhost', :port => 9595, :path => '/fail'
|
25
|
+
report :up, :response_code => 200
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
class ExampleBodyFailure < Outpost::DSL
|
30
|
+
using Outpost::Scouts::Http => 'master http server' do
|
31
|
+
options :host => 'localhost', :port => 9595, :path => '/fail'
|
32
|
+
report :down, :response_body => {:equals => 'Omg fail'}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class ExampleBodySuccess < Outpost::DSL
|
37
|
+
using Outpost::Scouts::Http => 'master http server' do
|
38
|
+
options :host => 'localhost', :port => 9595, :path => '/'
|
39
|
+
report :up, :response_body => {:match => /Up/}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should report up when everything's ok" do
|
44
|
+
assert_equal :up, ExampleSuccess.new.run
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should report failure when something's wrong" do
|
48
|
+
assert_equal :down, ExampleFailure.new.run
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should report success when body is okay" do
|
52
|
+
assert_equal :up, ExampleBodySuccess.new.run
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should report failure when body is wrong" do
|
56
|
+
assert_equal :down, ExampleBodyFailure.new.run
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'outpost/scouts'
|
4
|
+
|
5
|
+
describe "using more complex DSL integration test" do
|
6
|
+
class ExamplePingAndHttp < Outpost::DSL
|
7
|
+
using Outpost::Scouts::Http => 'master http server' do
|
8
|
+
options :host => 'localhost', :port => 9595, :path => '/'
|
9
|
+
report :up, :response_body => {:match => /Up/}
|
10
|
+
end
|
11
|
+
|
12
|
+
using Outpost::Scouts::Ping => 'load balancer' do
|
13
|
+
options :host => 'localhost'
|
14
|
+
report :up, :response_time => {:less_than => 500}
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class ExampleOneFailingOnePassing < Outpost::DSL
|
19
|
+
using Outpost::Scouts::Http => 'master http server' do
|
20
|
+
options :host => 'localhost', :port => 9595, :path => '/'
|
21
|
+
report :up, :response_body => {:match => /Up/}
|
22
|
+
end
|
23
|
+
|
24
|
+
using Outpost::Scouts::Ping => 'load balancer' do
|
25
|
+
options :host => 'localhost'
|
26
|
+
report :up, :response_time => {:less_than => 0}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class ExampleAllFailing < Outpost::DSL
|
31
|
+
using Outpost::Scouts::Http => 'master http server' do
|
32
|
+
options :host => 'localhost', :port => 9595, :path => '/fail'
|
33
|
+
report :up, :response_body => {:match => /Up/}
|
34
|
+
end
|
35
|
+
|
36
|
+
using Outpost::Scouts::Ping => 'load balancer' do
|
37
|
+
options :host => 'localhost'
|
38
|
+
report :up, :response_time => {:less_than => -1}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should report up when everything's ok" do
|
43
|
+
assert_equal :up, ExamplePingAndHttp.new.run
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should report down when at least one scout reports down" do
|
47
|
+
assert_equal :down, ExampleOneFailingOnePassing.new.run
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should report down when all are down" do
|
51
|
+
assert_equal :down, ExampleAllFailing.new.run
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should build error message" do
|
55
|
+
outpost = ExampleAllFailing.new
|
56
|
+
outpost.run
|
57
|
+
|
58
|
+
assert_equal "Outpost::Scouts::Http: 'master http server' is reporting down.",
|
59
|
+
outpost.messages.first
|
60
|
+
|
61
|
+
assert_equal "Outpost::Scouts::Ping: 'load balancer' is reporting down.",
|
62
|
+
outpost.messages.last
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Outpost::DSL do
|
4
|
+
class ScoutMock
|
5
|
+
class << self
|
6
|
+
attr_accessor :status
|
7
|
+
end
|
8
|
+
def run; self.class.status; end
|
9
|
+
end
|
10
|
+
|
11
|
+
class ExampleOne < Outpost::DSL
|
12
|
+
using ScoutMock => 'master http server' do
|
13
|
+
options :host => 'localhost'
|
14
|
+
report :up, :response_code => 200
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
before(:each) do
|
19
|
+
@scouts = ExampleOne.scouts
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should create correct scout description" do
|
23
|
+
assert_equal(ScoutMock, @scouts.keys.first)
|
24
|
+
assert_equal('master http server', @scouts[ScoutMock][:description])
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should create correct scout config" do
|
28
|
+
config = @scouts[ScoutMock][:config]
|
29
|
+
assert_equal({:host => 'localhost'}, config.options)
|
30
|
+
assert_equal({{:response_code => 200} => :up}, config.reports)
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#up?" do
|
34
|
+
before(:each) do
|
35
|
+
@outpost = ExampleOne.new
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return true when last status is up" do
|
39
|
+
ScoutMock.status = :up
|
40
|
+
@outpost.run
|
41
|
+
|
42
|
+
assert @outpost.up?
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should return false when last status isn't up" do
|
46
|
+
ScoutMock.status = :down
|
47
|
+
@outpost.run
|
48
|
+
|
49
|
+
refute @outpost.up?
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#down?" do
|
54
|
+
before(:each) do
|
55
|
+
@outpost = ExampleOne.new
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should return true when last status is down" do
|
59
|
+
ScoutMock.status = :down
|
60
|
+
@outpost.run
|
61
|
+
|
62
|
+
assert @outpost.down?
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should return false when last status isn't down" do
|
66
|
+
ScoutMock.status = :up
|
67
|
+
@outpost.run
|
68
|
+
|
69
|
+
refute @outpost.down?
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#messages" do
|
74
|
+
before(:each) do
|
75
|
+
@outpost = ExampleOne.new
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should return true when last status is up" do
|
79
|
+
ScoutMock.status = :up
|
80
|
+
@outpost.run
|
81
|
+
|
82
|
+
assert_equal "ScoutMock: 'master http server' is reporting up.",
|
83
|
+
@outpost.messages.first
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Outpost::Expectations::ResponseBody do
|
4
|
+
class SubjectBody
|
5
|
+
class << self
|
6
|
+
attr_reader :expectation, :evaluation_method
|
7
|
+
|
8
|
+
def expect(expectation, evaluation_method)
|
9
|
+
@expectation = expectation
|
10
|
+
@evaluation_method = evaluation_method
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
extend Outpost::Expectations::ResponseBody
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".evaluate_response_body with match" do
|
18
|
+
it "should return true when it matches" do
|
19
|
+
assert SubjectBody.evaluate_response_body(scout_mock, :match => /ll/)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return false when it doesn't" do
|
23
|
+
refute SubjectBody.evaluate_response_body(scout_mock, :match => /omg/)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe ".evaluate_response_body with not_match" do
|
28
|
+
it "should return true when it matches" do
|
29
|
+
assert SubjectBody.evaluate_response_body(scout_mock, :not_match => /omg/)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return false when it doesn't" do
|
33
|
+
refute SubjectBody.evaluate_response_body(scout_mock, :not_match => /Hello/)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe ".evaluate_response_body with equals" do
|
38
|
+
it "should return true when it matches" do
|
39
|
+
assert SubjectBody.evaluate_response_body(scout_mock, :equals => "Hello!")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should return false when it doesn't" do
|
43
|
+
refute SubjectBody.evaluate_response_body(scout_mock, :equals => "Hell")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe ".evaluate_response_body with differs" do
|
48
|
+
it "should return true when it matches" do
|
49
|
+
assert SubjectBody.evaluate_response_body(scout_mock, :differs => "Hell")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should return false when it doesn't" do
|
53
|
+
refute SubjectBody.evaluate_response_body(scout_mock, :differs => "Hello!")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe ".evaluate_response_body with multiple rules" do
|
58
|
+
it "should return true when all rules matches" do
|
59
|
+
rules = {:differs => 'omg', :match => /ll/}
|
60
|
+
assert SubjectBody.evaluate_response_body(scout_mock, rules)
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return false when there are no matches" do
|
64
|
+
rules = {:equals => 'omg', :not_match => /ll/}
|
65
|
+
refute SubjectBody.evaluate_response_body(scout_mock, rules)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should return false when at least one rule doesn't match" do
|
69
|
+
rules = {:equals => 'Hello!', :match => /Hell/, :differs => 'Hello!'}
|
70
|
+
refute SubjectBody.evaluate_response_body(scout_mock, rules)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should set expectation correctly" do
|
75
|
+
assert_equal :response_body, SubjectBody.expectation
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should set evaluation method correctly" do
|
79
|
+
assert_equal SubjectBody.method(:evaluate_response_body), \
|
80
|
+
SubjectBody.evaluation_method
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
def scout_mock
|
85
|
+
@scout_mock ||= OpenStruct.new.tap do |scout_mock|
|
86
|
+
scout_mock.response_body = 'Hello!'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe Outpost::Expectations::ResponseCode do
|
5
|
+
class SubjectCode
|
6
|
+
class << self
|
7
|
+
attr_reader :expectation, :evaluation_method
|
8
|
+
|
9
|
+
def expect(expectation, evaluation_method)
|
10
|
+
@expectation = expectation
|
11
|
+
@evaluation_method = evaluation_method
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
extend Outpost::Expectations::ResponseCode
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should return true when response codes match" do
|
19
|
+
assert SubjectCode.evaluate_response_code(scout_mock, 200)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return false when response codes doesn't match" do
|
23
|
+
refute SubjectCode.evaluate_response_code(scout_mock, 404)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should convert types accordinly" do
|
27
|
+
assert SubjectCode.evaluate_response_code(scout_mock, "200")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should set expectation correctly" do
|
31
|
+
assert_equal :response_code, SubjectCode.expectation
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should set evaluation method correctly" do
|
35
|
+
assert_equal SubjectCode.method(:evaluate_response_code),
|
36
|
+
SubjectCode.evaluation_method
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
def scout_mock
|
41
|
+
@scout_mock ||= OpenStruct.new.tap do |scout_mock|
|
42
|
+
scout_mock.response_code = 200
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Outpost::Expectations::ResponseTime do
|
4
|
+
class SubjectTime
|
5
|
+
class << self
|
6
|
+
attr_reader :expectation, :evaluation_method
|
7
|
+
|
8
|
+
def expect(expectation, evaluation_method)
|
9
|
+
@expectation = expectation
|
10
|
+
@evaluation_method = evaluation_method
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
extend Outpost::Expectations::ResponseTime
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ".evaluate_response_time with less_than" do
|
18
|
+
it "should return true when it matches" do
|
19
|
+
assert SubjectTime.evaluate_response_time(scout_mock, :less_than => 5000)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return false when it doesn't" do
|
23
|
+
refute SubjectTime.evaluate_response_time(scout_mock, :less_than => 1)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe ".evaluate_response_time with more_than" do
|
28
|
+
it "should return true when it matches" do
|
29
|
+
assert SubjectTime.evaluate_response_time(scout_mock, :more_than => 1)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should return false when it doesn't" do
|
33
|
+
refute SubjectTime.evaluate_response_time(scout_mock, :more_than => 5000)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe ".evaluate_response_time with multiple rules" do
|
38
|
+
it "should return true when all rules matches" do
|
39
|
+
rules = {:more_than => 200, :less_than => 5000}
|
40
|
+
assert SubjectTime.evaluate_response_time(scout_mock, rules)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should return false when there are no matches" do
|
44
|
+
rules = {:more_than => 700, :less_than => 200}
|
45
|
+
refute SubjectTime.evaluate_response_time(scout_mock, rules)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should return false when at least one rule doesn't match" do
|
49
|
+
rules = {:more_than => 100, :less_than => 200}
|
50
|
+
refute SubjectTime.evaluate_response_time(scout_mock, rules)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should set expectation correctly" do
|
55
|
+
assert_equal :response_time, SubjectTime.expectation
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should set evaluation method correctly" do
|
59
|
+
assert_equal SubjectTime.method(:evaluate_response_time),
|
60
|
+
SubjectTime.evaluation_method
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
def scout_mock
|
65
|
+
@scout_mock ||= OpenStruct.new.tap do |scout_mock|
|
66
|
+
scout_mock.response_time = 300
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Outpost::Report do
|
4
|
+
it "should report up when all are up" do
|
5
|
+
assert_equal :up, Outpost::Report.summarize([:up, :up, :up, :up])
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should report down when mixed statuses" do
|
9
|
+
assert_equal :down, Outpost::Report.summarize([:up, :down, :up, :up])
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should report down when all are down" do
|
13
|
+
assert_equal :down, Outpost::Report.summarize([:down, :down, :down])
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should report down when there are no statuses" do
|
17
|
+
assert_equal :down, Outpost::Report.summarize([])
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
describe Outpost::ScoutConfig do
|
4
|
+
before(:each) do
|
5
|
+
@config = Outpost::ScoutConfig.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should assign options accordingly" do
|
9
|
+
@config.options :host => 'localhost'
|
10
|
+
|
11
|
+
assert_equal({:host => 'localhost'}, @config.options)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should assign reports accordingly" do
|
15
|
+
@config.report :up, :response_code => 200
|
16
|
+
|
17
|
+
assert_equal({{:response_code => 200} => :up}, @config.reports)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should assign multiple reports" do
|
21
|
+
@config.report :up, :response_code => 200
|
22
|
+
@config.report :down, :response_code => 404
|
23
|
+
|
24
|
+
assert_equal({
|
25
|
+
{:response_code => 200} => :up,
|
26
|
+
{:response_code => 404} => :down,
|
27
|
+
}, @config.reports)
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'ostruct'
|
3
|
+
|
4
|
+
describe Outpost::Scout do
|
5
|
+
NoisyError = Class.new(StandardError)
|
6
|
+
|
7
|
+
class ScoutExample < Outpost::Scout
|
8
|
+
attr_accessor :response
|
9
|
+
expect :response, lambda {|scout, status| scout.response == status }
|
10
|
+
|
11
|
+
def setup(*args); end
|
12
|
+
def execute(*args); end
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should report up when status match" do
|
16
|
+
scout = ScoutExample.new("a scout", config_mock)
|
17
|
+
scout.response = true
|
18
|
+
assert_equal :up, scout.run
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should report up when status match" do
|
22
|
+
scout = ScoutExample.new("a scout", config_mock)
|
23
|
+
scout.response = false
|
24
|
+
assert_equal :down, scout.run
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should not register an invalid expectation" do
|
28
|
+
assert_raises ArgumentError do
|
29
|
+
add_expectation(:invalid_expectation, nil)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should register a expectation using a lambda" do
|
34
|
+
add_expectation(:valid_expectation, lambda{|b| b})
|
35
|
+
|
36
|
+
refute_nil ScoutExample.expectations[:valid_expectation]
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should register a expectation using pure blocks for flexibility" do
|
40
|
+
ScoutExample.expect(:valid_expectation) { |b| b }
|
41
|
+
|
42
|
+
refute_nil ScoutExample.expectations[:valid_expectation]
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should not be able to have its expectations modified" do
|
46
|
+
ScoutExample.expectations[:another_expectation] = {}
|
47
|
+
assert_nil ScoutExample.expectations[:another_expectation]
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not call expectation when there are no rules for that" do
|
51
|
+
add_expectation(:noisy, proc {|s,r| raise NoisyError})
|
52
|
+
assert_nothing_raised do
|
53
|
+
scout = ScoutExample.new("a scout", config_mock)
|
54
|
+
scout.run
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should call expectation when there are rules for that" do
|
59
|
+
add_expectation(:noisy, proc {|s,r| raise NoisyError})
|
60
|
+
config = config_mock
|
61
|
+
config.reports[{:noisy => nil}] = :down
|
62
|
+
|
63
|
+
assert_raises NoisyError do
|
64
|
+
scout = ScoutExample.new("a scout", config)
|
65
|
+
scout.run
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should complain when an unregistered expectation is called" do
|
70
|
+
config = config_mock
|
71
|
+
config.reports[{:unregistered => nil}] = :up
|
72
|
+
|
73
|
+
assert_raises NotImplementedError do
|
74
|
+
scout = ScoutExample.new("a scout", config)
|
75
|
+
scout.run
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
def config_mock
|
81
|
+
OpenStruct.new.tap do |config|
|
82
|
+
config.reports = {}
|
83
|
+
config.reports[{:response => true}] = :up
|
84
|
+
config.reports[{:response => false}] = :down
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_expectation(expectation, callable)
|
89
|
+
ScoutExample.expect expectation, callable
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rack/handler/thin'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
class Server
|
5
|
+
# Got it from Capybara, but simplified it a bit.
|
6
|
+
# lib/capybara/server.rb
|
7
|
+
def responsive?
|
8
|
+
res = Net::HTTP.start('localhost', 9595) { |http| http.get('/') }
|
9
|
+
|
10
|
+
res.is_a?(Net::HTTPSuccess) or res.is_a?(Net::HTTPRedirection)
|
11
|
+
rescue Errno::ECONNREFUSED, Errno::EBADF
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
|
15
|
+
def boot(app)
|
16
|
+
if not responsive?
|
17
|
+
Thread.new do
|
18
|
+
Thin::Logging.silent = true
|
19
|
+
Rack::Handler::Thin.run(app, :Port => 9595)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
Bundler.setup(:default, :test)
|
3
|
+
|
4
|
+
require 'ruby-debug'
|
5
|
+
require 'minitest/spec'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
|
8
|
+
# Integration test helpers
|
9
|
+
require 'support/test_app'
|
10
|
+
require 'support/server'
|
11
|
+
|
12
|
+
require 'outpost'
|
13
|
+
require 'outpost/expectations'
|
14
|
+
|
15
|
+
# Inspired by assert_raises from minitest
|
16
|
+
def assert_nothing_raised(&block)
|
17
|
+
block.call
|
18
|
+
rescue Exception => e
|
19
|
+
flunk "No exception expected, but #{mu_pp(e.class)} was raised."
|
20
|
+
end
|
21
|
+
|
metadata
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: outpost
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Vinicius Baggio Fuentes
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-02-01 00:00:00 -02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: net-ping
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ~>
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 1
|
30
|
+
- 3
|
31
|
+
- 7
|
32
|
+
version: 1.3.7
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description: Simple service monitoring with a clean DSL for configuration.
|
36
|
+
email: vinibaggio@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- Gemfile
|
45
|
+
- Gemfile.lock
|
46
|
+
- README.markdown
|
47
|
+
- Rakefile
|
48
|
+
- lib/outpost.rb
|
49
|
+
- lib/outpost/dsl.rb
|
50
|
+
- lib/outpost/expectations.rb
|
51
|
+
- lib/outpost/expectations/response_body.rb
|
52
|
+
- lib/outpost/expectations/response_code.rb
|
53
|
+
- lib/outpost/expectations/response_time.rb
|
54
|
+
- lib/outpost/report.rb
|
55
|
+
- lib/outpost/scout.rb
|
56
|
+
- lib/outpost/scout_config.rb
|
57
|
+
- lib/outpost/scouts.rb
|
58
|
+
- lib/outpost/scouts/http.rb
|
59
|
+
- lib/outpost/scouts/ping.rb
|
60
|
+
- lib/outpost/version.rb
|
61
|
+
- outpost.gemspec
|
62
|
+
- test/integration/basic_dsl_test.rb
|
63
|
+
- test/integration/more_complex_test.rb
|
64
|
+
- test/outpost/dsl_test.rb
|
65
|
+
- test/outpost/expectations/response_body_test.rb
|
66
|
+
- test/outpost/expectations/response_code_test.rb
|
67
|
+
- test/outpost/expectations/response_time_test.rb
|
68
|
+
- test/outpost/report_test.rb
|
69
|
+
- test/outpost/scout_config_test.rb
|
70
|
+
- test/outpost/scout_test.rb
|
71
|
+
- test/support/server.rb
|
72
|
+
- test/support/test_app.rb
|
73
|
+
- test/test_helper.rb
|
74
|
+
has_rdoc: true
|
75
|
+
homepage: http://www.github.com/vinibaggio/outpost
|
76
|
+
licenses: []
|
77
|
+
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
segments:
|
89
|
+
- 0
|
90
|
+
version: "0"
|
91
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
version: "0"
|
99
|
+
requirements: []
|
100
|
+
|
101
|
+
rubyforge_project: outpost
|
102
|
+
rubygems_version: 1.3.7
|
103
|
+
signing_key:
|
104
|
+
specification_version: 3
|
105
|
+
summary: Simple service monitoring with a clean DSL for configuration.
|
106
|
+
test_files:
|
107
|
+
- test/integration/basic_dsl_test.rb
|
108
|
+
- test/integration/more_complex_test.rb
|
109
|
+
- test/outpost/dsl_test.rb
|
110
|
+
- test/outpost/expectations/response_body_test.rb
|
111
|
+
- test/outpost/expectations/response_code_test.rb
|
112
|
+
- test/outpost/expectations/response_time_test.rb
|
113
|
+
- test/outpost/report_test.rb
|
114
|
+
- test/outpost/scout_config_test.rb
|
115
|
+
- test/outpost/scout_test.rb
|
116
|
+
- test/support/server.rb
|
117
|
+
- test/support/test_app.rb
|
118
|
+
- test/test_helper.rb
|