nugget 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ ### Nugget
2
+
3
+ Nugget is a service for performing http and tcp integration tests. It uses [turd](https://github.com/joewilliams/turd/) under the covers to verify urls are responding properly. Kinda like pingdom, better in some ways, worse in others.
4
+
5
+ #### Usage
6
+
7
+ The examples directory includes an example config file. The config file is a json description of tests you want to run.
8
+
9
+ The following starts nugget up in daemon mode. In this mode nugget just loops performing tests and writing the results in json to `/tmp/nugget_results.json`.
10
+
11
+ $ nugget -c examples/config.json -d
12
+
13
+ Running nugget once is also possible.
14
+
15
+ $ nugget -c examples/config.json
16
+
17
+ Nugget also includes a very basic web service daemon that simply reads the current results file.
18
+
19
+ $ nugget -w
20
+
21
+ Additionally, nugget includes support for sending results of the tests to [backstop](https://github.com/obfuscurity/backstop).
22
+
23
+ ![](https://dl.dropboxusercontent.com/s/1xhl7fnuw0y0934/2014-01-13%20at%207.47%20PM.png)
24
+
25
+ #### License
26
+
27
+ nugget is open source software available under the MIT License
data/bin/nugget ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'nugget'))
4
+
5
+ Nugget.main
@@ -0,0 +1,54 @@
1
+ module Nugget
2
+ class Backstop
3
+
4
+ def self.send_metrics(name, result, response)
5
+ send_test_result(name, result)
6
+ send_test_timings(name, response)
7
+ end
8
+
9
+ def self.send_test_result(name, result)
10
+
11
+ if result == "FAIL"
12
+ backstop_requst("#{name}.result", 1)
13
+ end
14
+
15
+ end
16
+
17
+ def self.send_test_timings(name, response)
18
+
19
+ response.each do |key, value|
20
+ if key.to_s.include?("_time")
21
+ backstop_requst("#{name}.#{key}", value)
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ def self.backstop_requst(metric, value)
28
+
29
+ Nugget::Log.debug("Sending the following to backstop: #{metric}: #{value}")
30
+
31
+ body = [{
32
+ metric: metric,
33
+ value: value,
34
+ measure_time: Time.now.to_i
35
+ }].to_json
36
+
37
+ request = Typhoeus::Request.new(
38
+ Nugget::Config.backstop_url,
39
+ method: :post,
40
+ body: body,
41
+ headers: { 'Content-Type' => 'application/json' }
42
+ )
43
+
44
+ response = request.run
45
+
46
+ if response.options[:response_code] > 299
47
+ # hack a bad response error in here
48
+ Nugget::Log.error("Error publishing #{metric} to backstop, got #{response.options[:response_code]}")
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+ end
data/lib/nugget/cli.rb ADDED
@@ -0,0 +1,69 @@
1
+ module Nugget
2
+ class CLI
3
+ include Mixlib::CLI
4
+
5
+ option :log_level,
6
+ :short => "-l LEVEL",
7
+ :long => "--log_level LEVEL",
8
+ :description => "Set the log level (debug, info, warn, error, fatal)",
9
+ :default => :info,
10
+ :proc => Proc.new { |l| l.to_sym }
11
+
12
+ option :interval,
13
+ :short => "-i SECONDS",
14
+ :long => "--interval SECONDS",
15
+ :default => 30,
16
+ :description => "How long Nugget waits between testing runs when in daemon mode."
17
+
18
+ option :config,
19
+ :short => "-c PATH",
20
+ :long => "--config PATH",
21
+ :description => "Path of the json config."
22
+
23
+ option :daemon,
24
+ :short => "-d",
25
+ :long => "--daemon",
26
+ :boolean => true,
27
+ :default => false,
28
+ :description => "Run as a daemon. If not specified nugget just runs once."
29
+
30
+ option :web,
31
+ :short => "-w",
32
+ :long => "--web",
33
+ :boolean => true,
34
+ :description => "Run the web service."
35
+
36
+ option :ip,
37
+ :short => "-z IP",
38
+ :long => "--ip IP",
39
+ :default => "0.0.0.0",
40
+ :description => "IP for the web service."
41
+
42
+ option :port,
43
+ :short => "-p PORT",
44
+ :long => "--port PORT",
45
+ :default => 3000,
46
+ :description => "Port for the web service."
47
+
48
+ option :backstop_url,
49
+ :short => "-b URL",
50
+ :long => "--backstop URL",
51
+ :description => "URL for backstop metrics thing."
52
+
53
+ option :resultsfile,
54
+ :short => "-r FILE",
55
+ :long => "--results FILE",
56
+ :default => "/tmp/nugget_results.json",
57
+ :description => "Path to where results file is written/read."
58
+
59
+ option :help,
60
+ :short => "-h",
61
+ :long => "--help",
62
+ :description => "Show this message",
63
+ :on => :tail,
64
+ :boolean => true,
65
+ :show_options => true,
66
+ :exit => 0
67
+
68
+ end
69
+ end
@@ -0,0 +1,10 @@
1
+ module Nugget
2
+ class Config
3
+ extend Mixlib::Config
4
+
5
+ configure do |c|
6
+
7
+ end
8
+
9
+ end
10
+ end
data/lib/nugget/log.rb ADDED
@@ -0,0 +1,6 @@
1
+ module Nugget
2
+ class Log
3
+ extend Mixlib::Log
4
+
5
+ end
6
+ end
@@ -0,0 +1,96 @@
1
+ module Nugget
2
+ class Service
3
+
4
+ def self.run_daemon()
5
+ Nugget::Log.info("Starting up Nugget in daemon mode ...")
6
+
7
+ loop do
8
+ run()
9
+
10
+ # chill
11
+ sleep(Nugget::Config.interval.to_i)
12
+ end
13
+ end
14
+
15
+ def self.run_once()
16
+ Nugget::Log.info("Starting up Nugget in run-once mode ...")
17
+ run()
18
+ end
19
+
20
+ def self.run()
21
+ config_file = File.new(Nugget::Config.config, 'r')
22
+ parser = Yajl::Parser.new(:symbolize_keys => true)
23
+ config = parser.parse(config_file)
24
+
25
+ results = Hash.new
26
+
27
+ config.each do |test, definition|
28
+ result = nil
29
+ response = nil
30
+
31
+ begin
32
+ request_definition = config_converter(definition)
33
+ response_definition = definition[:response]
34
+
35
+ response = Turd.run(request_definition, response_definition)
36
+ result = "PASS"
37
+ rescue Exception => e
38
+ Nugget::Log.error("#{definition[:type]} test #{test} failed!")
39
+ Nugget::Log.error(e)
40
+
41
+ result = "FAIL"
42
+ response = e.response
43
+ end
44
+
45
+ Nugget::Log.info("Test #{test} complete with status #{result}")
46
+
47
+ results.store(test, {
48
+ :config => definition,
49
+ :result => result,
50
+ :response => response,
51
+ :timestamp => Time.now.to_i
52
+ })
53
+
54
+ if Nugget::Config.backstop_url
55
+ Nugget::Backstop.send_metrics(test, result, response)
56
+ end
57
+ end
58
+
59
+ if Nugget::Config.daemon
60
+ Nugget::Service.write_results(results)
61
+ end
62
+ end
63
+
64
+ def self.config_converter(definition)
65
+ options = definition[:request]
66
+
67
+ if options[:method]
68
+ sym_method = options[:method].to_sym
69
+ options.store(:method, sym_method)
70
+ end
71
+
72
+ if options[:url]
73
+ url = options[:url]
74
+ options.delete(:url)
75
+ end
76
+
77
+ {
78
+ :url => url,
79
+ :type => definition[:type],
80
+ :options => options
81
+ }
82
+ end
83
+
84
+ def self.write_results(results)
85
+ begin
86
+ file = File.open(Nugget::Config.resultsfile, "w")
87
+ file.puts(results.to_json)
88
+ file.close
89
+ rescue Exception => e
90
+ Nugget::Log.error("Something went wrong with writing out the results file!")
91
+ Nugget::Log.error(e)
92
+ end
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,3 @@
1
+ module Nugget
2
+ VERSION = "0.0.2"
3
+ end
data/lib/nugget/web.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Nugget
2
+ class Web
3
+
4
+ def self.run()
5
+ app = Rack::URLMap.new('/' => Nugget::Web.new)
6
+ Thin::Server.start(Nugget::Config.ip, Nugget::Config.port, app)
7
+ end
8
+
9
+ def call(env)
10
+ time_diff = Time.now.to_i - File.mtime(Nugget::Config.resultsfile).to_i
11
+
12
+ if time_diff < 3600
13
+ body = [File.read(Nugget::Config.resultsfile)]
14
+ [200, { 'Content-Type' => 'text/plain' }, body]
15
+ else
16
+ [500, { 'Content-Type' => 'text/plain' }, ["nugget results file is stale (#{time_diff} seconds), something is wrong"]]
17
+ end
18
+ end
19
+
20
+ end
21
+ end
data/lib/nugget.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'rubygems'
2
+
3
+ require 'turd'
4
+ require 'mixlib/cli'
5
+ require 'mixlib/config'
6
+ require 'mixlib/log'
7
+ require 'yajl/json_gem'
8
+ require 'thin'
9
+
10
+ __DIR__ = File.dirname(__FILE__)
11
+
12
+ $LOAD_PATH.unshift __DIR__ unless
13
+ $LOAD_PATH.include?(__DIR__) ||
14
+ $LOAD_PATH.include?(File.expand_path(__DIR__))
15
+
16
+ require 'nugget/config'
17
+ require 'nugget/log'
18
+ require 'nugget/cli'
19
+ require 'nugget/service'
20
+ require 'nugget/web'
21
+ require 'nugget/backstop'
22
+ require 'nugget/version'
23
+
24
+ module Nugget
25
+ class << self
26
+
27
+ def main
28
+ cli = Nugget::CLI.new
29
+ cli.parse_options
30
+ Nugget::Config.merge!(cli.config)
31
+
32
+ Nugget::Log.level(Nugget::Config.log_level)
33
+
34
+ if Nugget::Config.web
35
+ Nugget::Web.run()
36
+ else
37
+ if Nugget::Config.config
38
+ if Nugget::Config.daemon
39
+ Nugget::Service.run_daemon()
40
+ else
41
+ Nugget::Service.run_once()
42
+ end
43
+ else
44
+ Nugget::Log.error("No config supplied! Use \"-c FILE\".")
45
+ end
46
+ end
47
+ end
48
+
49
+ end
50
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nugget
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - joe williams
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mixlib-config
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: mixlib-log
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: mixlib-cli
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: turd
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: yajl-ruby
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: thin
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description:
111
+ email: joe@joetify.com
112
+ executables:
113
+ - nugget
114
+ extensions: []
115
+ extra_rdoc_files:
116
+ - README.md
117
+ files:
118
+ - bin/nugget
119
+ - lib/nugget/backstop.rb
120
+ - lib/nugget/cli.rb
121
+ - lib/nugget/config.rb
122
+ - lib/nugget/log.rb
123
+ - lib/nugget/service.rb
124
+ - lib/nugget/version.rb
125
+ - lib/nugget/web.rb
126
+ - lib/nugget.rb
127
+ - README.md
128
+ homepage: http://github.com/joewilliams/nugget
129
+ licenses: []
130
+ post_install_message:
131
+ rdoc_options: []
132
+ require_paths:
133
+ - lib
134
+ required_ruby_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ! '>='
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 1.8.23
149
+ signing_key:
150
+ specification_version: 3
151
+ summary: a http and tcp testing service
152
+ test_files: []