outpost 0.1.0 → 0.2.0

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.
Files changed (41) hide show
  1. data/.gitignore +1 -0
  2. data/CHANGELOG.rdoc +16 -0
  3. data/Gemfile +9 -3
  4. data/Gemfile.lock +39 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.markdown +40 -8
  7. data/Rakefile +14 -0
  8. data/TODO.md +7 -0
  9. data/lib/outpost.rb +1 -1
  10. data/lib/outpost/application.rb +143 -0
  11. data/lib/outpost/expectations/response_body.rb +23 -9
  12. data/lib/outpost/expectations/response_code.rb +5 -0
  13. data/lib/outpost/expectations/response_time.rb +10 -1
  14. data/lib/outpost/notifiers.rb +2 -0
  15. data/lib/outpost/notifiers/campfire.rb +50 -0
  16. data/lib/outpost/notifiers/email.rb +59 -0
  17. data/lib/outpost/report.rb +7 -1
  18. data/lib/outpost/scout.rb +82 -0
  19. data/lib/outpost/scout_config.rb +10 -4
  20. data/lib/outpost/scouts/http.rb +28 -7
  21. data/lib/outpost/scouts/ping.rb +26 -6
  22. data/lib/outpost/version.rb +4 -1
  23. data/outpost.gemspec +0 -2
  24. data/test/integration/{basic_dsl_test.rb → basic_application_test.rb} +5 -5
  25. data/test/integration/more_complex_test.rb +20 -8
  26. data/test/integration/notifiers_test.rb +51 -0
  27. data/test/outpost/dsl_test.rb +74 -3
  28. data/test/outpost/expectations/response_body_test.rb +13 -15
  29. data/test/outpost/expectations/response_code_test.rb +5 -7
  30. data/test/outpost/expectations/response_time_test.rb +9 -11
  31. data/test/outpost/notifiers/campfire_test.rb +72 -0
  32. data/test/outpost/notifiers/email_test.rb +90 -0
  33. data/test/outpost/scout_test.rb +5 -6
  34. data/test/outpost/scouts/http_test.rb +51 -0
  35. data/test/outpost/scouts/ping_test.rb +41 -0
  36. data/test/support/nothing_raised.rb +10 -0
  37. data/test/support/server.rb +0 -1
  38. data/test/support/stubs.rb +11 -0
  39. data/test/test_helper.rb +8 -6
  40. metadata +32 -22
  41. data/lib/outpost/dsl.rb +0 -54
data/outpost.gemspec CHANGED
@@ -16,6 +16,4 @@ Gem::Specification.new do |s|
16
16
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
17
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
18
  s.require_paths = ["lib"]
19
-
20
- s.add_dependency("net-ping", "~> 1.3.7")
21
19
  end
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  require 'outpost/scouts/http'
4
4
 
5
- describe "basic DSL integration test" do
5
+ describe "basic application integration test" do
6
6
  before(:each) do
7
7
  @server = Server.new
8
8
  @server.boot(TestApp)
@@ -12,28 +12,28 @@ describe "basic DSL integration test" do
12
12
  end
13
13
  end
14
14
 
15
- class ExampleSuccess < Outpost::DSL
15
+ class ExampleSuccess < Outpost::Application
16
16
  using Outpost::Scouts::Http => 'master http server' do
17
17
  options :host => 'localhost', :port => 9595
18
18
  report :up, :response_code => 200
19
19
  end
20
20
  end
21
21
 
22
- class ExampleFailure < Outpost::DSL
22
+ class ExampleFailure < Outpost::Application
23
23
  using Outpost::Scouts::Http => 'master http server' do
24
24
  options :host => 'localhost', :port => 9595, :path => '/fail'
25
25
  report :up, :response_code => 200
26
26
  end
27
27
  end
28
28
 
29
- class ExampleBodyFailure < Outpost::DSL
29
+ class ExampleBodyFailure < Outpost::Application
30
30
  using Outpost::Scouts::Http => 'master http server' do
31
31
  options :host => 'localhost', :port => 9595, :path => '/fail'
32
32
  report :down, :response_body => {:equals => 'Omg fail'}
33
33
  end
34
34
  end
35
35
 
36
- class ExampleBodySuccess < Outpost::DSL
36
+ class ExampleBodySuccess < Outpost::Application
37
37
  using Outpost::Scouts::Http => 'master http server' do
38
38
  options :host => 'localhost', :port => 9595, :path => '/'
39
39
  report :up, :response_body => {:match => /Up/}
@@ -2,8 +2,17 @@ require 'test_helper'
2
2
 
3
3
  require 'outpost/scouts'
4
4
 
5
- describe "using more complex DSL integration test" do
6
- class ExamplePingAndHttp < Outpost::DSL
5
+ describe "using more complex application 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 ExamplePingAndHttp < Outpost::Application
7
16
  using Outpost::Scouts::Http => 'master http server' do
8
17
  options :host => 'localhost', :port => 9595, :path => '/'
9
18
  report :up, :response_body => {:match => /Up/}
@@ -15,7 +24,7 @@ describe "using more complex DSL integration test" do
15
24
  end
16
25
  end
17
26
 
18
- class ExampleOneFailingOnePassing < Outpost::DSL
27
+ class ExampleOneFailingOnePassing < Outpost::Application
19
28
  using Outpost::Scouts::Http => 'master http server' do
20
29
  options :host => 'localhost', :port => 9595, :path => '/'
21
30
  report :up, :response_body => {:match => /Up/}
@@ -27,7 +36,7 @@ describe "using more complex DSL integration test" do
27
36
  end
28
37
  end
29
38
 
30
- class ExampleAllFailing < Outpost::DSL
39
+ class ExampleAllFailing < Outpost::Application
31
40
  using Outpost::Scouts::Http => 'master http server' do
32
41
  options :host => 'localhost', :port => 9595, :path => '/fail'
33
42
  report :up, :response_body => {:match => /Up/}
@@ -55,10 +64,13 @@ describe "using more complex DSL integration test" do
55
64
  outpost = ExampleAllFailing.new
56
65
  outpost.run
57
66
 
58
- assert_equal "Outpost::Scouts::Http: 'master http server' is reporting down.",
59
- outpost.messages.first
67
+ assert outpost.messages.include?(
68
+ "Outpost::Scouts::Http: 'master http server' is reporting down."
69
+ )
70
+
71
+ assert outpost.messages.include?(
72
+ "Outpost::Scouts::Ping: 'load balancer' is reporting down."
73
+ )
60
74
 
61
- assert_equal "Outpost::Scouts::Ping: 'load balancer' is reporting down.",
62
- outpost.messages.last
63
75
  end
64
76
  end
@@ -0,0 +1,51 @@
1
+ require 'test_helper'
2
+
3
+ require 'outpost/scouts'
4
+ require 'outpost/notifiers'
5
+
6
+ describe "using notifiers" do
7
+ class ExampleMailNotifier < Outpost::Application
8
+ notify Outpost::Notifiers::Email, {
9
+ :from => 'outpost@example.com',
10
+ :to => 'sleep_deprived_admin@example.com',
11
+ :subject => 'System 1 status'
12
+ }
13
+
14
+ using Outpost::Scouts::Ping => 'load balancer' do
15
+ options :host => 'localhost'
16
+ report :down, :response_time => {:more_than => 0}
17
+ end
18
+ end
19
+
20
+ before(:each) do
21
+ Mail.defaults do
22
+ delivery_method :test
23
+ end
24
+
25
+ @outpost = ExampleMailNotifier.new
26
+ @outpost.run
27
+ end
28
+
29
+ after(:each) do
30
+ Mail::TestMailer.deliveries = []
31
+ end
32
+
33
+ it "should send email when asked to notify" do
34
+ @outpost.notify
35
+
36
+ refute_empty Mail::TestMailer.deliveries
37
+ end
38
+
39
+ it "should set email headers accordingly" do
40
+ @outpost.notify
41
+ message = Mail::TestMailer.deliveries.first
42
+
43
+ assert_equal 'outpost@example.com', message.from.first.to_s
44
+ assert_equal 'sleep_deprived_admin@example.com', message.to.first.to_s
45
+ assert_equal 'System 1 status', message.subject.to_s
46
+ end
47
+
48
+ it "should not send email when not asked to notify" do
49
+ assert_empty Mail::TestMailer.deliveries
50
+ end
51
+ end
@@ -1,14 +1,30 @@
1
1
  require 'test_helper'
2
2
 
3
- describe Outpost::DSL do
3
+ describe Outpost::Application do
4
4
  class ScoutMock
5
5
  class << self
6
6
  attr_accessor :status
7
7
  end
8
- def run; self.class.status; end
8
+ def initialize(*args); end
9
+ def run ; self.class.status ; end
9
10
  end
10
11
 
11
- class ExampleOne < Outpost::DSL
12
+ class NotifierMock
13
+ class << self
14
+ attr_accessor :last_messages
15
+ end
16
+ attr_accessor :options
17
+
18
+ def initialize(options); @options = options; end
19
+
20
+ def notify(outpost)
21
+ self.class.last_messages = outpost.messages
22
+ end
23
+ end
24
+
25
+ class ExampleOne < Outpost::Application
26
+ notify NotifierMock, :email => 'mail@example.com'
27
+
12
28
  using ScoutMock => 'master http server' do
13
29
  options :host => 'localhost'
14
30
  report :up, :response_code => 200
@@ -30,6 +46,46 @@ describe Outpost::DSL do
30
46
  assert_equal({{:response_code => 200} => :up}, config.reports)
31
47
  end
32
48
 
49
+ it "should create notifiers configuration" do
50
+ notifiers = ExampleOne.notifiers
51
+ assert_equal({NotifierMock => {:email => 'mail@example.com'}}, notifiers)
52
+ end
53
+
54
+ describe "#run" do
55
+ it "should return up when scouts return up" do
56
+ ScoutMock.status = :up
57
+ assert_equal :up, ExampleOne.new.run
58
+ end
59
+
60
+ it "should return up when scouts return down" do
61
+ ScoutMock.status = :down
62
+ assert_equal :down, ExampleOne.new.run
63
+ end
64
+ end
65
+
66
+ describe "#notify" do
67
+ after(:each) do
68
+ NotifierMock.last_messages = nil
69
+ end
70
+
71
+ it "should run the notifications if there are reports to deliver" do
72
+ ScoutMock.status = :up
73
+
74
+ outpost = ExampleOne.new
75
+ outpost.run
76
+ outpost.notify
77
+
78
+ assert_equal "ScoutMock: 'master http server' is reporting up.",
79
+ NotifierMock.last_messages.first
80
+ end
81
+
82
+ it "should not run the notifications if there are no reports" do
83
+ ExampleOne.new.notify
84
+
85
+ refute NotifierMock.last_messages
86
+ end
87
+ end
88
+
33
89
  describe "#up?" do
34
90
  before(:each) do
35
91
  @outpost = ExampleOne.new
@@ -70,6 +126,21 @@ describe Outpost::DSL do
70
126
  end
71
127
  end
72
128
 
129
+ describe "#name" do
130
+ it "should be set as the class is informed" do
131
+ ExampleTwo = Class.new(ExampleOne)
132
+ ExampleTwo.class_eval do
133
+ name 'Example outpost'
134
+ end
135
+
136
+ assert_equal 'Example outpost', ExampleTwo.new.name
137
+ end
138
+
139
+ it "should be the class' name if it is not set" do
140
+ assert_equal 'ExampleOne', ExampleOne.new.name
141
+ end
142
+ end
143
+
73
144
  describe "#messages" do
74
145
  before(:each) do
75
146
  @outpost = ExampleOne.new
@@ -16,58 +16,58 @@ describe Outpost::Expectations::ResponseBody do
16
16
 
17
17
  describe ".evaluate_response_body with match" do
18
18
  it "should return true when it matches" do
19
- assert SubjectBody.evaluate_response_body(scout_mock, :match => /ll/)
19
+ assert SubjectBody.evaluate_response_body(scout_stub, :match => /ll/)
20
20
  end
21
21
 
22
22
  it "should return false when it doesn't" do
23
- refute SubjectBody.evaluate_response_body(scout_mock, :match => /omg/)
23
+ refute SubjectBody.evaluate_response_body(scout_stub, :match => /omg/)
24
24
  end
25
25
  end
26
26
 
27
27
  describe ".evaluate_response_body with not_match" do
28
28
  it "should return true when it matches" do
29
- assert SubjectBody.evaluate_response_body(scout_mock, :not_match => /omg/)
29
+ assert SubjectBody.evaluate_response_body(scout_stub, :not_match => /omg/)
30
30
  end
31
31
 
32
32
  it "should return false when it doesn't" do
33
- refute SubjectBody.evaluate_response_body(scout_mock, :not_match => /Hello/)
33
+ refute SubjectBody.evaluate_response_body(scout_stub, :not_match => /Hello/)
34
34
  end
35
35
  end
36
36
 
37
37
  describe ".evaluate_response_body with equals" do
38
38
  it "should return true when it matches" do
39
- assert SubjectBody.evaluate_response_body(scout_mock, :equals => "Hello!")
39
+ assert SubjectBody.evaluate_response_body(scout_stub, :equals => "Hello!")
40
40
  end
41
41
 
42
42
  it "should return false when it doesn't" do
43
- refute SubjectBody.evaluate_response_body(scout_mock, :equals => "Hell")
43
+ refute SubjectBody.evaluate_response_body(scout_stub, :equals => "Hell")
44
44
  end
45
45
  end
46
46
 
47
47
  describe ".evaluate_response_body with differs" do
48
48
  it "should return true when it matches" do
49
- assert SubjectBody.evaluate_response_body(scout_mock, :differs => "Hell")
49
+ assert SubjectBody.evaluate_response_body(scout_stub, :differs => "Hell")
50
50
  end
51
51
 
52
52
  it "should return false when it doesn't" do
53
- refute SubjectBody.evaluate_response_body(scout_mock, :differs => "Hello!")
53
+ refute SubjectBody.evaluate_response_body(scout_stub, :differs => "Hello!")
54
54
  end
55
55
  end
56
56
 
57
57
  describe ".evaluate_response_body with multiple rules" do
58
58
  it "should return true when all rules matches" do
59
59
  rules = {:differs => 'omg', :match => /ll/}
60
- assert SubjectBody.evaluate_response_body(scout_mock, rules)
60
+ assert SubjectBody.evaluate_response_body(scout_stub, rules)
61
61
  end
62
62
 
63
63
  it "should return false when there are no matches" do
64
64
  rules = {:equals => 'omg', :not_match => /ll/}
65
- refute SubjectBody.evaluate_response_body(scout_mock, rules)
65
+ refute SubjectBody.evaluate_response_body(scout_stub, rules)
66
66
  end
67
67
 
68
68
  it "should return false when at least one rule doesn't match" do
69
69
  rules = {:equals => 'Hello!', :match => /Hell/, :differs => 'Hello!'}
70
- refute SubjectBody.evaluate_response_body(scout_mock, rules)
70
+ refute SubjectBody.evaluate_response_body(scout_stub, rules)
71
71
  end
72
72
  end
73
73
 
@@ -81,9 +81,7 @@ describe Outpost::Expectations::ResponseBody do
81
81
  end
82
82
 
83
83
  private
84
- def scout_mock
85
- @scout_mock ||= OpenStruct.new.tap do |scout_mock|
86
- scout_mock.response_body = 'Hello!'
87
- end
84
+ def scout_stub
85
+ build_stub(:response_body => 'Hello!')
88
86
  end
89
87
  end
@@ -16,15 +16,15 @@ describe Outpost::Expectations::ResponseCode do
16
16
  end
17
17
 
18
18
  it "should return true when response codes match" do
19
- assert SubjectCode.evaluate_response_code(scout_mock, 200)
19
+ assert SubjectCode.evaluate_response_code(scout_stub, 200)
20
20
  end
21
21
 
22
22
  it "should return false when response codes doesn't match" do
23
- refute SubjectCode.evaluate_response_code(scout_mock, 404)
23
+ refute SubjectCode.evaluate_response_code(scout_stub, 404)
24
24
  end
25
25
 
26
26
  it "should convert types accordinly" do
27
- assert SubjectCode.evaluate_response_code(scout_mock, "200")
27
+ assert SubjectCode.evaluate_response_code(scout_stub, "200")
28
28
  end
29
29
 
30
30
  it "should set expectation correctly" do
@@ -37,9 +37,7 @@ describe Outpost::Expectations::ResponseCode do
37
37
  end
38
38
 
39
39
  private
40
- def scout_mock
41
- @scout_mock ||= OpenStruct.new.tap do |scout_mock|
42
- scout_mock.response_code = 200
43
- end
40
+ def scout_stub
41
+ build_stub(:response_code => 200)
44
42
  end
45
43
  end
@@ -16,38 +16,38 @@ describe Outpost::Expectations::ResponseTime do
16
16
 
17
17
  describe ".evaluate_response_time with less_than" do
18
18
  it "should return true when it matches" do
19
- assert SubjectTime.evaluate_response_time(scout_mock, :less_than => 5000)
19
+ assert SubjectTime.evaluate_response_time(scout_stub, :less_than => 5000)
20
20
  end
21
21
 
22
22
  it "should return false when it doesn't" do
23
- refute SubjectTime.evaluate_response_time(scout_mock, :less_than => 1)
23
+ refute SubjectTime.evaluate_response_time(scout_stub, :less_than => 1)
24
24
  end
25
25
  end
26
26
 
27
27
  describe ".evaluate_response_time with more_than" do
28
28
  it "should return true when it matches" do
29
- assert SubjectTime.evaluate_response_time(scout_mock, :more_than => 1)
29
+ assert SubjectTime.evaluate_response_time(scout_stub, :more_than => 1)
30
30
  end
31
31
 
32
32
  it "should return false when it doesn't" do
33
- refute SubjectTime.evaluate_response_time(scout_mock, :more_than => 5000)
33
+ refute SubjectTime.evaluate_response_time(scout_stub, :more_than => 5000)
34
34
  end
35
35
  end
36
36
 
37
37
  describe ".evaluate_response_time with multiple rules" do
38
38
  it "should return true when all rules matches" do
39
39
  rules = {:more_than => 200, :less_than => 5000}
40
- assert SubjectTime.evaluate_response_time(scout_mock, rules)
40
+ assert SubjectTime.evaluate_response_time(scout_stub, rules)
41
41
  end
42
42
 
43
43
  it "should return false when there are no matches" do
44
44
  rules = {:more_than => 700, :less_than => 200}
45
- refute SubjectTime.evaluate_response_time(scout_mock, rules)
45
+ refute SubjectTime.evaluate_response_time(scout_stub, rules)
46
46
  end
47
47
 
48
48
  it "should return false when at least one rule doesn't match" do
49
49
  rules = {:more_than => 100, :less_than => 200}
50
- refute SubjectTime.evaluate_response_time(scout_mock, rules)
50
+ refute SubjectTime.evaluate_response_time(scout_stub, rules)
51
51
  end
52
52
  end
53
53
 
@@ -61,10 +61,8 @@ describe Outpost::Expectations::ResponseTime do
61
61
  end
62
62
 
63
63
  private
64
- def scout_mock
65
- @scout_mock ||= OpenStruct.new.tap do |scout_mock|
66
- scout_mock.response_time = 300
67
- end
64
+ def scout_stub
65
+ build_stub(:response_time => 300)
68
66
  end
69
67
  end
70
68
 
@@ -0,0 +1,72 @@
1
+ require 'test_helper'
2
+
3
+ describe Outpost::Notifiers::Campfire do
4
+ class CampfireMock
5
+ class << self
6
+ attr_accessor :mock
7
+ end
8
+ def initialize(*args); end
9
+ def find_room_by_name(room); self.class.mock; end
10
+ end
11
+
12
+ describe "#initialize" do
13
+ it "should raise argument error if token is missing" do
14
+ params = {:subdomain => '123', :room => '123'}
15
+
16
+ assert_raises ArgumentError do
17
+ campfire = Outpost::Notifiers::Campfire.new(params)
18
+ end
19
+ end
20
+
21
+ it "should raise argument error if subdomain is missing" do
22
+ params = {:token => '123', :room => '123'}
23
+
24
+ assert_raises ArgumentError do
25
+ campfire = Outpost::Notifiers::Campfire.new(params)
26
+ end
27
+ end
28
+
29
+ it "should raise argument error if room is missing" do
30
+ params = {:token => '123', :subdomain => '123'}
31
+
32
+ assert_raises ArgumentError do
33
+ campfire = Outpost::Notifiers::Campfire.new(params)
34
+ end
35
+ end
36
+
37
+ it "should raise argument error if no attributes were supplied" do
38
+ assert_raises ArgumentError do
39
+ campfire = Outpost::Notifiers::Campfire.new
40
+ end
41
+ end
42
+ end
43
+
44
+ describe "#notify" do
45
+ it "should build the message" do
46
+ campfire_room_mock = MiniTest::Mock.new
47
+ campfire_room_mock.expect :speak, nil, ["System is up: 1,2"]
48
+
49
+ CampfireMock.mock = campfire_room_mock
50
+
51
+ params = {
52
+ :token => '123',
53
+ :subdomain => '123',
54
+ :room => '123',
55
+ :campfire_notifier => CampfireMock
56
+ }
57
+
58
+ campfire = Outpost::Notifiers::Campfire.new(params)
59
+ campfire.notify(outpost_stub)
60
+
61
+ campfire_room_mock.verify
62
+ end
63
+ end
64
+
65
+ def outpost_stub
66
+ build_stub(
67
+ :name => 'test outpost',
68
+ :last_status => :up,
69
+ :messages => ['1', '2']
70
+ )
71
+ end
72
+ end