outpost 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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