inquisitor 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (C) 2011, brain-geek
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the "Software"), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
20
+
21
+ Images by @genn_org
@@ -0,0 +1,54 @@
1
+ Inquisitor
2
+ ===============
3
+
4
+ [![Build Status](https://secure.travis-ci.org/brain-geek/inquisitor.png)](http://travis-ci.org/brain-geek/inquisitor)
5
+ [![Dependencies Status](https://gemnasium.com/brain-geek/inquisitor.png)](https://gemnasium.com/brain-geek/inquisitor)
6
+
7
+ This project is aimed on creation ruby-powered monitoring solution with simple web interface.
8
+
9
+ Usage
10
+ -----
11
+ ###Standalone install:
12
+ #####Running check:
13
+
14
+ monitor -d sqlite3://`pwd`/sqlite_database.db
15
+
16
+ #####Running web server:
17
+
18
+ monitor_web -d sqlite3://`pwd`/sqlite_database.db
19
+
20
+ ###Mounting to rails app:
21
+ #####Add to gemfile:
22
+
23
+ gem 'data_mapper'
24
+ gem 'dm-redis-adapter'
25
+ gem 'inquisitor', :git => 'git://github.com/brain-geek/inquisitor.git'
26
+
27
+ #####Create initializer:
28
+
29
+ require 'inquisitor/web'
30
+ Inquisitor.settings.set :db_path => {:adapter => "redis"}
31
+
32
+ #####Add to routes:
33
+
34
+ mount Inquisitor::Web.new, :at => "/inquisitor"
35
+
36
+ ###Development web server
37
+ shotgun config.dev.ru
38
+
39
+ Features
40
+ -----
41
+ #####Databases supported
42
+ It should work with all databases supported by datamapper. Tested with postgresql, mysql, redis and sqlite. Format for db_path can be found [in datamapper doc](http://datamapper.org/getting-started.html) - "Specify your database connection".
43
+
44
+ #####Cli options:
45
+ You can read availible options from lib/inquisitor/cli.rb . Same options are supported by standalone install
46
+
47
+ #####Supported types of monitoring:
48
+ [outpost gem](https://github.com/vinibaggio/outpost) is used as backend for monitoring. For now, http:// and ping:// checks are supported.
49
+
50
+ Copyright
51
+ ---------
52
+
53
+ Copyright (c) 2011 @brain-geek. See LICENSE for details.
54
+
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'inquisitor', 'cli')
4
+
5
+ Inquisitor.check_all
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'inquisitor', 'cli')
3
+
4
+ Inquisitor::Web.bind = '0.0.0.0'
5
+
6
+ Inquisitor::Web.run!
@@ -0,0 +1,35 @@
1
+ require 'outpost'
2
+ require 'outpost/scouts'
3
+ require 'outpost/notifiers/email'
4
+
5
+ require 'data_mapper'
6
+ require File.join(File.dirname(__FILE__), 'inquisitor', 'extensions.rb')
7
+ require File.join(File.dirname(__FILE__), 'inquisitor', 'node.rb')
8
+ require File.join(File.dirname(__FILE__), 'inquisitor', 'contact.rb')
9
+ require File.join(File.dirname(__FILE__), 'inquisitor', 'settings.rb')
10
+ DataMapper.finalize
11
+
12
+ module Inquisitor
13
+ class << self
14
+ def create_outpost(name = '')
15
+ outpost = Outpost::Application.new
16
+ outpost.name = name
17
+
18
+ Inquisitor::Contact.all.each do |contact|
19
+ outpost.add_notifier Outpost::Notifiers::Email, {
20
+ :from => Inquisitor.settings.mail_from,
21
+ :to => contact.email,
22
+ :subject => Inquisitor.settings.mail_subject
23
+ }
24
+ end
25
+
26
+ outpost
27
+ end
28
+
29
+ def settings
30
+ @settings ||= Settings.new
31
+ end
32
+
33
+ delegate :check_all, :to => Node
34
+ end
35
+ end
@@ -0,0 +1,22 @@
1
+ begin
2
+ require 'slop'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ require 'slop'
6
+ end
7
+
8
+ require File.join(File.dirname(__FILE__), '..', 'inquisitor')
9
+ require File.join(File.dirname(__FILE__), 'web')
10
+
11
+ opts = Slop.parse do
12
+ on :d, :db_path, 'DB path', :optional => false
13
+ on :mail_from, 'Send mail from email', :optional => true
14
+ on :mail_subject, 'Mail subject', :optional => true
15
+ on :check_period, :as => :integer, :optional => true
16
+ end
17
+
18
+ opts = opts.to_hash.delete_if{|key, value| value.nil? }
19
+
20
+ raise 'DB connection is not set' unless opts.has_key?(:db_path)
21
+
22
+ Inquisitor.settings.set opts
@@ -0,0 +1,7 @@
1
+ module Inquisitor
2
+ class Contact
3
+ include DataMapper::Resource
4
+ property :id, Serial
5
+ property :email, String, :format => :email_address, :index => :unique, :required => true
6
+ end
7
+ end
@@ -0,0 +1,54 @@
1
+ #Module.delegate by active_support
2
+ class Module
3
+ # File activesupport/lib/active_support/core_ext/module/delegation.rb, line 106
4
+ def delegate(*methods)
5
+ options = methods.pop
6
+ unless options.is_a?(Hash) && to = options[:to]
7
+ raise ArgumentError, "Delegation needs a target. Supply an options hash with a :to key as the last argument (e.g. delegate :hello, :to => :greeter)."
8
+ end
9
+
10
+ if options[:prefix] == true && options[:to].to_s =~ /^[^a-z_]/
11
+ raise ArgumentError, "Can only automatically set the delegation prefix when delegating to a method."
12
+ end
13
+
14
+ prefix = options[:prefix] && "#{options[:prefix] == true ? to : options[:prefix]}_" || ''
15
+
16
+ file, line = caller.first.split(':', 2)
17
+ line = line.to_i
18
+
19
+ methods.each do |method|
20
+ on_nil =
21
+ if options[:allow_nil]
22
+ 'return'
23
+ else
24
+ %Q(raise "#{self}##{prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}")
25
+ end
26
+
27
+ module_eval(" def #{prefix}#{method}(*args, &block) # def customer_name(*args, &block)
28
+ #{to}.__send__(#{method.inspect}, *args, &block) # client.__send__(:name, *args, &block)
29
+ rescue NoMethodError # rescue NoMethodError
30
+ if #{to}.nil? # if client.nil?
31
+ #{on_nil} # return # depends on :allow_nil
32
+ else # else
33
+ raise # raise
34
+ end # end
35
+ end # end
36
+ ", file, line - 1)
37
+ end
38
+ end
39
+ end
40
+
41
+ module ActiveSupport
42
+ module Delegation #:nodoc:
43
+ def self.perform(object, target, method, method_name, allow_nil, to, args, block)
44
+ target.__send__(method, *args, &block)
45
+ rescue NoMethodError
46
+ if target.nil?
47
+ return nil if allow_nil
48
+ raise "#{object.class}##{method_name} delegated to #{to}.#{method}, but #{to} is nil: #{object.inspect}"
49
+ else
50
+ raise
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,61 @@
1
+ require 'uri'
2
+
3
+ module Inquisitor
4
+ class Node
5
+ include DataMapper::Resource
6
+ property :id, Serial
7
+ property :url, String, :index => :unique
8
+ property :name, String, :index => true
9
+
10
+ validates_presence_of :url
11
+ validates_with_method :url, :method => :check_protocol
12
+
13
+ delegate :run, :notify, :to => :outpost
14
+ alias :check :run
15
+
16
+ def check_and_notify
17
+ notify unless run == :up
18
+ end
19
+
20
+ def self.check_all
21
+ all.each &:check_and_notify
22
+ end
23
+
24
+ def last_log
25
+ outpost.messages.join('<br />')
26
+ end
27
+
28
+ def check_protocol
29
+ outpost
30
+ true
31
+ rescue URI::InvalidURIError
32
+ false
33
+ end
34
+
35
+ protected
36
+ def outpost
37
+ @outpost ||= begin
38
+ outpost = Inquisitor.create_outpost(self.name)
39
+ uri = URI.parse(url)
40
+
41
+ case uri.scheme
42
+ when 'http'
43
+ outpost.add_scout Outpost::Scouts::Http => '' do
44
+ options :host => uri.host, :port => uri.port, :path => uri.path.empty? ? '/' : uri.path
45
+ report :up, :response_code => 200...400
46
+ report :down, :response_code => 400..600
47
+ end
48
+ when 'ping'
49
+ outpost.add_scout Outpost::Scouts::Ping => '' do
50
+ options :host => uri.host
51
+ report :up, :response_time => {:less_than => 1000}
52
+ end
53
+ else
54
+ raise URI::InvalidURIError
55
+ end
56
+
57
+ outpost
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,31 @@
1
+ $(window).load(function(){
2
+ // status loading
3
+ $('td.status-load').each(function(index, element){
4
+ $.get($(this).attr('rel'), '', function(req)
5
+ {
6
+ $('.element-' + req['id'] + ' .status-load img').attr('src', $('body').attr('root_path') + req.status + '.png')
7
+ $('.element-' + req['id'] + ' .status-load').attr('detailed', req.log)
8
+ });
9
+ });
10
+
11
+ // submit on enter
12
+ $('form.form-stacked input').keypress(function(e)
13
+ {
14
+ if(e.which == 13)
15
+ {
16
+ $(this).closest('form').submit();
17
+ e.preventDefault();
18
+ return false;
19
+ }
20
+ });
21
+
22
+
23
+ // magic with show-hide
24
+ $('.show_detailed').click(function(){
25
+ $(this).closest('form').find('.hidden').toggle();
26
+ return false;
27
+ });
28
+
29
+
30
+
31
+ });
@@ -0,0 +1,38 @@
1
+ html, body
2
+ {
3
+ background-color: #EEE;
4
+ }
5
+
6
+ .content
7
+ {
8
+ background-color: white;
9
+ padding: 20px;
10
+ margin: 0 -20px;
11
+ }
12
+
13
+ td.status-load
14
+ {
15
+ width: 40px;
16
+ }
17
+
18
+ #nodes table
19
+ {
20
+ margin-bottom: 0px;
21
+ }
22
+
23
+ #nodes fieldset .hidden
24
+ {
25
+ display:none;
26
+ }
27
+
28
+ #nodes fieldset button
29
+ {
30
+ margin-top: 10px;
31
+ }
32
+
33
+ a.show_detailed {
34
+ border-bottom: 1px dotted #00438A;
35
+ margin-bottom: 10px;
36
+ text-decoration: none;
37
+ font-size: 10px;
38
+ }
@@ -0,0 +1,40 @@
1
+ %h2 Check nodes
2
+ #nodes
3
+ %table
4
+ - @nodes.each do |node|
5
+ %tr{ :class => "element-#{node.id}"}
6
+ %td.status-load{:rel => url_for("node/status/#{node.id}")}
7
+ %img{:src => url_for('loading.gif'), :height => 36, :width => 32}
8
+ %td= node.url
9
+ %td{:width => '100%'}= node.name
10
+ %td
11
+ %a.btn.danger{:href => url_for("/node/delete/#{node.id}")} Delete
12
+
13
+ %form.form-stacked.actions{:action => url_for("/node/new"), :method => "post", :id => 'add_node'}
14
+ %fieldset
15
+ .clearfix
16
+ %label{:for => "node[name]"}Url
17
+ %input{:type => "text", :name => "node[url]", :id => "add-url-field"}
18
+ .clearfix
19
+ %a.show_detailed{:href => '#'} Options
20
+ .clearfix.hidden
21
+ %label{:for => "node[name]"}Title
22
+ %input{:type => "text", :name => "node[name]", :id => "add-name-field"}
23
+ .clearfix
24
+ %input.btn.primary{:type => "submit", :value => "Add node"}
25
+
26
+ %h2 Notify me by
27
+ #contacts
28
+ .list
29
+ %table
30
+ - @contacts.each do |contact|
31
+ %tr{ :class => "element-#{contact.id}"}
32
+ %td= contact.email
33
+
34
+ %form.form-stacked.actions{:action => url_for("/contact/new"), :method => "post", :id => 'add_contact'}
35
+ %fieldset
36
+ .clearfix
37
+ %label{:for => "contact[email]"}Email
38
+ %input{:type => "text", :name => "contact[email]", :id => "add-email-field"}
39
+ .clearfix
40
+ %input.btn{:type => "submit", :value => "Add contact"}
@@ -0,0 +1,15 @@
1
+ !!! 5
2
+ %html
3
+ %head
4
+ %title Index page
5
+ %meta{:content => "text/html;charset=utf-8", "http-equiv" => "Content-Type"}
6
+ = stylesheet 'http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css', url_for('/style.css')
7
+ %script{:src => 'http://code.jquery.com/jquery-1.7.1.min.js'}
8
+ %script{:src => url_for('/script.js')}
9
+ :javascript
10
+ $(function(){$('body').attr('root_path', '#{url_for("/")}')});
11
+
12
+ %body
13
+ .container
14
+ .content
15
+ = yield
@@ -0,0 +1,24 @@
1
+ module Inquisitor
2
+ class Settings
3
+ attr_accessor :mail_from, :mail_subject, :check_period
4
+
5
+ def initialize
6
+ self.mail_from = 'changeme.in@Inquisitor.settings'
7
+ self.mail_subject = 'Subject for Inquisitor notify letter'
8
+ self.check_period = 30
9
+ end
10
+
11
+ def db_path=(path)
12
+ DataMapper.setup(:default, path)
13
+ DataMapper.auto_upgrade!
14
+ end
15
+
16
+ def set(params)
17
+ params.each do |key, value|
18
+ if respond_to?("#{key}=")
19
+ send("#{key}=", value)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,6 @@
1
+ module Inquisitor
2
+ PATCH = 1
3
+ MINOR = 1
4
+ MAJOR = 0
5
+ VERSION = "#{MAJOR}.#{MINOR}.#{PATCH}".freeze
6
+ end
@@ -0,0 +1,55 @@
1
+ require 'sinatra/base'
2
+ require 'sinatra/link_header'
3
+ require 'sinatra/json'
4
+ require 'sinatra/url_for'
5
+ require 'haml'
6
+
7
+ module Inquisitor
8
+ class Web < Sinatra::Base
9
+ helpers Sinatra::LinkHeader
10
+ helpers Sinatra::JSON
11
+ helpers Sinatra::UrlForHelper
12
+
13
+ dir = File.dirname(File.expand_path(__FILE__))
14
+
15
+ set :views, "#{dir}/server/views"
16
+
17
+ if respond_to? :public_folder
18
+ set :public_folder, "#{dir}/server/public"
19
+ else
20
+ set :public, "#{dir}/server/public"
21
+ end
22
+
23
+ set :static, true
24
+ set :run, false
25
+
26
+ get '/' do
27
+ @nodes = Inquisitor::Node.all
28
+ @contacts = Inquisitor::Contact.all
29
+ haml :index, :format => :html5
30
+ end
31
+
32
+ get '/node/status/:id' do
33
+ n = Inquisitor::Node.get(params[:id].to_i)
34
+ json :status => n.check, :log => n.last_log, :id => n.id
35
+ end
36
+
37
+ get '/node/delete/:id' do
38
+ n = Inquisitor::Node.get(params[:id].to_i)
39
+ n.destroy unless n.nil?
40
+ redirect url_for('/')
41
+ end
42
+
43
+ post '/node/new' do
44
+ Inquisitor::Node.create params["node"]
45
+
46
+ redirect url_for('/')
47
+ end
48
+
49
+ post '/contact/new' do
50
+ Inquisitor::Contact.create params["contact"]
51
+
52
+ redirect url_for('/')
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,14 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ describe Inquisitor::Contact do
4
+ describe "validation" do
5
+ it "saves with valid email" do
6
+ c = Inquisitor::Contact.make_unsaved :email => "valid#{Time.now.to_i}@gmail.com"
7
+ c.save.should be_true
8
+ end
9
+ it "does not save with invalid email" do
10
+ c = Inquisitor::Contact.make_unsaved :email => '#{Time.now.to_i}invalidfghdfhdgdgmail.com'
11
+ c.save.should be_false
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,80 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ describe Inquisitor::Node do
4
+ describe 'http checking' do
5
+ it "should check if it tells that http site is ok" do
6
+ n = Inquisitor::Node.make :url => 'http://ya.ru'
7
+
8
+ n.check.should == :up
9
+ end
10
+
11
+ it "should tell that page with redirect is ok, not down" do
12
+ n = Inquisitor::Node.make :url => 'http://google.com/'
13
+
14
+ n.check.should == :up
15
+ end
16
+
17
+ it "should fail if hostname not found" do
18
+ n = Inquisitor::Node.make :url => 'http://akjfsjjgsdf.google.com'
19
+
20
+ n.check.should == :down
21
+ end
22
+
23
+ it "should fail if page not found" do
24
+ n = Inquisitor::Node.make :url => 'http://www.google.com/404.html'
25
+
26
+ n.check.should == :down
27
+ end
28
+ end
29
+
30
+ describe 'ping checking' do
31
+ it "should pass if host is reachable" do
32
+ n = Inquisitor::Node.make :url => 'ping://127.0.0.1'
33
+ n.check.should == :up
34
+ end
35
+ it "should not pass if host is not reachable" do
36
+ n = Inquisitor::Node.make :url => 'ping://sdfsadfasdfasdf.asdfasdfasdf.asdfasdf'
37
+ n.check.should == :down
38
+ end
39
+ end
40
+
41
+ describe 'validation' do
42
+ it "should fail if unknown protocol of url is passed" do
43
+ n = Inquisitor::Node.make_unsaved :url => 'https://github.com'
44
+ n.save.should be_false
45
+ end
46
+ end
47
+
48
+ describe "work with outpost" do
49
+ it "should return logs from outpost" do
50
+ n = Inquisitor::Node.make
51
+ o = Object.new
52
+ o.should_receive(:messages).and_return([])
53
+ n.should_receive(:outpost).and_return(o)
54
+
55
+ n.last_log
56
+ end
57
+ end
58
+
59
+ it "should run all checks at once" do
60
+ nodes = []
61
+
62
+ 5.times do
63
+ node = Inquisitor::Node.make
64
+ node.should_receive(:run).and_return(:down)
65
+ node.should_receive(:notify)
66
+ nodes.push node
67
+ end
68
+
69
+ 5.times do
70
+ node = Inquisitor::Node.make
71
+ node.should_receive(:run).and_return(:up)
72
+ node.should_not_receive(:notify)
73
+ nodes.push node
74
+ end
75
+
76
+ Inquisitor::Node.should_receive(:all).and_return(nodes)
77
+
78
+ Inquisitor.check_all
79
+ end
80
+ end
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_integration_helper.rb')
2
+
3
+ describe 'Outpost factory' do
4
+ before do
5
+ @contact = Inquisitor::Contact.make
6
+ end
7
+
8
+ it "should add email notifiers" do
9
+ outpost = Inquisitor.create_outpost 'title'
10
+
11
+ outpost.name.should == 'title'
12
+
13
+ outpost.notifiers.first[0].should == Outpost::Notifiers::Email
14
+ outpost.notifiers.first[1][:to].should == @contact.email
15
+ end
16
+
17
+ it "should send emails" do
18
+ Mail.defaults do
19
+ delivery_method :test
20
+ end
21
+
22
+ Mail::TestMailer.deliveries.should == []
23
+ Inquisitor::Node.make(:url => 'ping://non-existant.domain').check_and_notify
24
+ Mail::TestMailer.deliveries.count.should == 1
25
+ end
26
+ end
@@ -0,0 +1,41 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper.rb')
2
+
3
+ describe 'App settings' do
4
+ before :each do
5
+ Inquisitor.instance_variable_set '@settings', nil
6
+ end
7
+
8
+ it "should have default values" do
9
+ Inquisitor.settings.mail_from.should == 'changeme.in@Inquisitor.settings'
10
+ Inquisitor.settings.mail_subject.should == 'Subject for Inquisitor notify letter'
11
+
12
+ Inquisitor.settings.check_period.should == 30
13
+ end
14
+
15
+ it "should send email from emails we set and with defined title" do
16
+ Inquisitor::Contact.make
17
+
18
+ subj = 'Notify set in test env'
19
+ mail = 'test-receiver@gmail.com'
20
+
21
+ Inquisitor.settings.mail_from = mail
22
+ Inquisitor.settings.mail_subject = subj
23
+ outpost = Inquisitor.create_outpost
24
+
25
+ outpost.notifiers.first[1][:from].should == mail
26
+ outpost.notifiers.first[1][:subject].should == subj
27
+ end
28
+
29
+ it "should set db settings" do
30
+ DataMapper.should_receive(:setup).with :default, :path
31
+ DataMapper.should_receive(:auto_upgrade!)
32
+
33
+ Inquisitor.settings.db_path = :path
34
+ end
35
+
36
+ it "should do mass asignments" do
37
+ Inquisitor.settings.set :mail_from => 'me@gmail.com', :check_period => 900
38
+ Inquisitor.settings.mail_from.should == 'me@gmail.com'
39
+ Inquisitor.settings.check_period.should == 900
40
+ end
41
+ end
@@ -0,0 +1,118 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_integration_helper.rb')
2
+ require 'json'
3
+
4
+ describe "Basic frontend test" do
5
+ def app
6
+ @app ||= Inquisitor::Web
7
+ end
8
+
9
+ it "should respond to / and list all" do
10
+ nodes = []
11
+ 5.times { nodes.push Inquisitor::Node.make }
12
+ Inquisitor::Node.should_receive(:all).and_return(nodes)
13
+
14
+ contacts = []
15
+ 3.times { contacts.push Inquisitor::Contact.make }
16
+ Inquisitor::Contact.should_receive(:all).and_return(contacts)
17
+
18
+ get '/'
19
+
20
+ last_response.should be_ok
21
+
22
+ nodes.each do |n|
23
+ within "#nodes .element-#{n.id}" do |scope|
24
+ scope.should contain n.name
25
+ scope.should contain n.url
26
+ scope.should have_selector("td[rel='node/status/#{n.id}']")
27
+ end
28
+ end
29
+
30
+ contacts.each do |n|
31
+ within "#contacts .element-#{n.id}" do |scope|
32
+ scope.should contain n.email
33
+ end
34
+ end
35
+ end
36
+
37
+ it "should delete node from interface" do
38
+ 5.times { Inquisitor::Node.make }
39
+ node = Inquisitor::Node.make
40
+ 5.times { Inquisitor::Node.make }
41
+
42
+ get '/'
43
+
44
+ Inquisitor::Node.first(node.attributes).should_not be_nil
45
+
46
+ within "#nodes .element-#{node.id}" do |scope|
47
+ scope.click_link "Delete"
48
+ end
49
+
50
+ Inquisitor::Node.first(node.attributes).should be_nil
51
+ end
52
+
53
+ it "should respond with service status" do
54
+ n = Inquisitor::Node.make
55
+ n.should_receive(:check).and_return(:up)
56
+ n.should_receive(:last_log).and_return('best log in the world')
57
+
58
+ Inquisitor::Node.should_receive(:get).with(n.id).and_return(n)
59
+
60
+ get "/node/status/#{n.id}"
61
+
62
+ resp = JSON.parse(response.body)
63
+ resp['status'].should == 'up'
64
+ resp['log'].should == 'best log in the world'
65
+ end
66
+
67
+ it "should create node" do
68
+ node = Inquisitor::Node.make_unsaved.attributes
69
+ visit '/'
70
+ Inquisitor::Node.first(node).should be_nil
71
+
72
+ fill_in "add-name-field", :with => node[:name]
73
+ fill_in "add-url-field", :with => node[:url]
74
+ click_button "Add node"
75
+
76
+ Inquisitor::Node.first(node).should_not be_nil
77
+ end
78
+
79
+ it "should create new contact" do
80
+ contact = Inquisitor::Contact.make_unsaved.attributes
81
+ visit '/'
82
+ Inquisitor::Contact.first(contact).should be_nil
83
+
84
+ fill_in "add-email-field", :with => contact[:email]
85
+ click_button "Add contact"
86
+
87
+ Inquisitor::Contact.first(contact).should_not be_nil
88
+ end
89
+
90
+ it "should delete node" do
91
+ test_delete(Inquisitor::Node)
92
+ end
93
+
94
+ it "should create node" do
95
+ test_new(Inquisitor::Node)
96
+ end
97
+
98
+ it "should create contact" do
99
+ test_new(Inquisitor::Contact)
100
+ end
101
+
102
+ private
103
+ def test_new(cls)
104
+ attrs = cls.make_unsaved.attributes
105
+ name = cls.to_s.split('::').last.downcase
106
+ cls.first(attrs).should be_nil
107
+ post "/#{name}/new", name => attrs
108
+ cls.first(attrs).should_not be_nil
109
+ end
110
+
111
+ def test_delete(cls)
112
+ attrs = cls.make.attributes
113
+ cls.first(attrs).should_not be_nil
114
+ name = cls.to_s.split('::').last.downcase
115
+ get "/#{name}/delete/#{attrs[:id]}"
116
+ cls.first(attrs).should be_nil
117
+ end
118
+ end
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'rack/test'
3
+ require 'rspec'
4
+ require 'webrat'
5
+ require 'ffaker'
6
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'inquisitor.rb')
7
+
8
+ RSpec.configure do |config|
9
+ config.before(:all) { Sham.reset(:before_all) }
10
+ config.before(:each) { Sham.reset(:before_each) }
11
+ end
12
+
13
+ if ENV['DB'] == 'sqlite'
14
+ Inquisitor.settings.db_path = "sqlite3://#{Dir.pwd}/test.db"
15
+ puts "Using sqlite"
16
+ elsif ENV['DB'] == 'redis'
17
+ Inquisitor.settings.db_path ={:adapter => "redis"}
18
+ puts "Using redis"
19
+ elsif ENV['DB'] == 'mysql'
20
+ `mysql -e 'create database test;'`
21
+ Inquisitor.settings.db_path ="mysql://@localhost/test"
22
+ puts "Using mysql"
23
+ elsif ENV['DB'] == 'pg'
24
+ `psql -c 'create database test;' -U postgres`
25
+ Inquisitor.settings.db_path ="postgres://postgres@localhost/test"
26
+ puts "Using pg"
27
+ else
28
+ Inquisitor.settings.db_path = 'sqlite3::memory:'
29
+ puts 'Using sqlite(by default)'
30
+ end
31
+
32
+ require File.join(File.dirname(__FILE__), 'support/blueprints.rb')
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__), 'spec_helper.rb')
2
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'inquisitor', 'web.rb')
3
+
4
+ RSpec.configure do |config|
5
+ config.include Rack::Test::Methods
6
+ config.include Webrat::Methods
7
+ config.include Webrat::Matchers
8
+ config.before{ Inquisitor::Node.all.destroy }
9
+ end
10
+
11
+ Webrat.configure do |config|
12
+ config.mode= :rack
13
+ end
14
+
15
+ Inquisitor::Web.set :environment, :test
@@ -0,0 +1,11 @@
1
+ require 'machinist/data_mapper'
2
+ require 'sham'
3
+
4
+ Inquisitor::Node.blueprint do
5
+ url { 'http://' + Faker::Lorem.words(2).join('-').downcase + '.com' }
6
+ name { Faker::Name.name }
7
+ end
8
+
9
+ Inquisitor::Contact.blueprint do
10
+ email { Faker::Internet.email }
11
+ end
metadata ADDED
@@ -0,0 +1,224 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: inquisitor
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Rozumiy Alexander
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-01-12 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ hash: 3
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ requirement: *id001
31
+ prerelease: false
32
+ type: :runtime
33
+ name: data_mapper
34
+ - !ruby/object:Gem::Dependency
35
+ version_requirements: &id002 !ruby/object:Gem::Requirement
36
+ none: false
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ hash: 3
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ requirement: *id002
45
+ prerelease: false
46
+ type: :runtime
47
+ name: outpost
48
+ - !ruby/object:Gem::Dependency
49
+ version_requirements: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ hash: 3
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ requirement: *id003
59
+ prerelease: false
60
+ type: :runtime
61
+ name: net-ping
62
+ - !ruby/object:Gem::Dependency
63
+ version_requirements: &id004 !ruby/object:Gem::Requirement
64
+ none: false
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ hash: 3
69
+ segments:
70
+ - 0
71
+ version: "0"
72
+ requirement: *id004
73
+ prerelease: false
74
+ type: :runtime
75
+ name: mail
76
+ - !ruby/object:Gem::Dependency
77
+ version_requirements: &id005 !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ requirement: *id005
87
+ prerelease: false
88
+ type: :runtime
89
+ name: sinatra
90
+ - !ruby/object:Gem::Dependency
91
+ version_requirements: &id006 !ruby/object:Gem::Requirement
92
+ none: false
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ hash: 3
97
+ segments:
98
+ - 0
99
+ version: "0"
100
+ requirement: *id006
101
+ prerelease: false
102
+ type: :runtime
103
+ name: sinatra-contrib
104
+ - !ruby/object:Gem::Dependency
105
+ version_requirements: &id007 !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ requirement: *id007
115
+ prerelease: false
116
+ type: :runtime
117
+ name: haml
118
+ - !ruby/object:Gem::Dependency
119
+ version_requirements: &id008 !ruby/object:Gem::Requirement
120
+ none: false
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ hash: 3
125
+ segments:
126
+ - 0
127
+ version: "0"
128
+ requirement: *id008
129
+ prerelease: false
130
+ type: :runtime
131
+ name: emk-sinatra-url-for
132
+ - !ruby/object:Gem::Dependency
133
+ version_requirements: &id009 !ruby/object:Gem::Requirement
134
+ none: false
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ hash: 3
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ requirement: *id009
143
+ prerelease: false
144
+ type: :runtime
145
+ name: slop
146
+ description: Monitoring daemon with simple web UI.
147
+ email: brain-geek@yandex.ua
148
+ executables:
149
+ - monitor
150
+ - monitor_web
151
+ extensions: []
152
+
153
+ extra_rdoc_files: []
154
+
155
+ files:
156
+ - lib/inquisitor/extensions.rb
157
+ - lib/inquisitor/cli.rb
158
+ - lib/inquisitor/contact.rb
159
+ - lib/inquisitor/node.rb
160
+ - lib/inquisitor/settings.rb
161
+ - lib/inquisitor/web.rb
162
+ - lib/inquisitor/version.rb
163
+ - lib/inquisitor/server/public/down.png
164
+ - lib/inquisitor/server/public/loading.gif
165
+ - lib/inquisitor/server/public/script.js
166
+ - lib/inquisitor/server/public/style.css
167
+ - lib/inquisitor/server/public/up.png
168
+ - lib/inquisitor/server/views/layout.haml
169
+ - lib/inquisitor/server/views/index.haml
170
+ - lib/inquisitor.rb
171
+ - bin/monitor
172
+ - bin/monitor_web
173
+ - README.md
174
+ - LICENSE
175
+ - spec/inquisitor/node_spec.rb
176
+ - spec/inquisitor/web_spec.rb
177
+ - spec/inquisitor/contact_spec.rb
178
+ - spec/inquisitor/outpost_factory_spec.rb
179
+ - spec/inquisitor/settings_spec.rb
180
+ - spec/support/blueprints.rb
181
+ - spec/spec_helper.rb
182
+ - spec/spec_integration_helper.rb
183
+ homepage: https://github.com/brain-geek/inquisitor
184
+ licenses: []
185
+
186
+ post_install_message:
187
+ rdoc_options: []
188
+
189
+ require_paths:
190
+ - lib
191
+ required_ruby_version: !ruby/object:Gem::Requirement
192
+ none: false
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ hash: 3
197
+ segments:
198
+ - 0
199
+ version: "0"
200
+ required_rubygems_version: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ">="
204
+ - !ruby/object:Gem::Version
205
+ hash: 3
206
+ segments:
207
+ - 0
208
+ version: "0"
209
+ requirements: []
210
+
211
+ rubyforge_project:
212
+ rubygems_version: 1.8.11
213
+ signing_key:
214
+ specification_version: 3
215
+ summary: Monitoring daemon with simple web UI.
216
+ test_files:
217
+ - spec/inquisitor/node_spec.rb
218
+ - spec/inquisitor/web_spec.rb
219
+ - spec/inquisitor/contact_spec.rb
220
+ - spec/inquisitor/outpost_factory_spec.rb
221
+ - spec/inquisitor/settings_spec.rb
222
+ - spec/support/blueprints.rb
223
+ - spec/spec_helper.rb
224
+ - spec/spec_integration_helper.rb