nimble_nodes 0.1.9 → 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.
- data/Rakefile +5 -2
- data/VERSION +1 -1
- data/lib/nimble_nodes/app.rb +51 -0
- data/lib/nimble_nodes/dynos.rb +52 -3
- data/lib/nimble_nodes/middleware.rb +1 -1
- data/lib/nimble_nodes/rails/filter.rb +17 -0
- data/lib/nimble_nodes/report.rb +16 -14
- data/lib/nimble_nodes/server.rb +53 -8
- data/lib/nimble_nodes/settings.rb +51 -0
- data/lib/nimble_nodes/workers.rb +35 -0
- data/lib/nimble_nodes.rb +17 -19
- data/nimble_nodes.gemspec +25 -7
- data/test/helper.rb +4 -3
- data/test/unit/test_app.rb +102 -0
- data/test/unit/test_dynos.rb +97 -0
- data/test/unit/test_nimble_nodes.rb +80 -0
- data/test/unit/test_settings.rb +93 -0
- metadata +46 -7
- data/lib/nimble_nodes/filter.rb +0 -15
- data/test/test_nimble_nodes.rb +0 -7
data/Rakefile
CHANGED
@@ -5,12 +5,15 @@ begin
|
|
5
5
|
require 'jeweler'
|
6
6
|
Jeweler::Tasks.new do |gem|
|
7
7
|
gem.name = "nimble_nodes"
|
8
|
-
gem.summary = "
|
9
|
-
gem.description = "
|
8
|
+
gem.summary = "coming soon"
|
9
|
+
gem.description = "coming soon"
|
10
10
|
gem.email = "jordan@digitalignition.com"
|
11
11
|
gem.homepage = "http://github.com/glasner/nimble_nodes"
|
12
12
|
gem.authors = ["Jordan Glasner"]
|
13
13
|
gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
|
14
|
+
gem.add_development_dependency "mocha"
|
15
|
+
gem.add_development_dependency "fakeweb"
|
16
|
+
gem.add_dependency "json"
|
14
17
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
15
18
|
end
|
16
19
|
Jeweler::GemcutterTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.0
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module NimbleNodes
|
2
|
+
|
3
|
+
module App
|
4
|
+
|
5
|
+
#= Rails
|
6
|
+
|
7
|
+
def self.rails?
|
8
|
+
defined?(RAILS_GEM_VERSION) ? true : false
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.rails_version
|
12
|
+
RAILS_GEM_VERSION.slice(0..2).to_f
|
13
|
+
end
|
14
|
+
|
15
|
+
#== Check Rails version
|
16
|
+
# returns true if gem is loaded in a pre 2.3 version of rails
|
17
|
+
def self.use_rails_filter?
|
18
|
+
NimbleNodes::App.rails? and NimbleNodes::App.rails_version < 2.3
|
19
|
+
end
|
20
|
+
|
21
|
+
# set through Heroku API when app is created
|
22
|
+
def self.name
|
23
|
+
ENV['NIMBLE_NODES_APP_NAME']
|
24
|
+
end
|
25
|
+
|
26
|
+
# set through Heroku API when app is created at server
|
27
|
+
def self.token
|
28
|
+
ENV['NIMBLE_NODES_APP_TOKEN']
|
29
|
+
end
|
30
|
+
|
31
|
+
# returns true if app has been setup at server correctly
|
32
|
+
def self.token?
|
33
|
+
not NimbleNodes::App.token.nil?
|
34
|
+
end
|
35
|
+
|
36
|
+
# path at server for calling app resource and subresources
|
37
|
+
def self.path(subpath='/')
|
38
|
+
name = NimbleNodes::App.name
|
39
|
+
return nil if name.nil?
|
40
|
+
'/' + name + subpath
|
41
|
+
end
|
42
|
+
|
43
|
+
# returns path to platform specific report implementation
|
44
|
+
def self.reporter
|
45
|
+
path = NimbleNodes::App.use_rails_filter? ? '/rails/filter' : '/middleware'
|
46
|
+
NimbleNodes.lib_path(path)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
data/lib/nimble_nodes/dynos.rb
CHANGED
@@ -2,16 +2,65 @@ module NimbleNodes
|
|
2
2
|
|
3
3
|
module Dynos
|
4
4
|
|
5
|
+
#= Settings
|
6
|
+
|
7
|
+
# shortcut for accessing NimbleNodes.settings[:dynos_pool][key]
|
8
|
+
def self.[](key)
|
9
|
+
NimbleNodes::Dynos.settings[key]
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.settings
|
13
|
+
hash = NimbleNodes::Settings['dynos_pool']
|
14
|
+
hash.nil? ? {} : hash
|
15
|
+
end
|
16
|
+
|
5
17
|
def self.size
|
6
|
-
|
18
|
+
NimbleNodes::Dynos['size']
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.min
|
22
|
+
NimbleNodes::Dynos['min']
|
7
23
|
end
|
8
24
|
|
9
25
|
def self.max
|
10
|
-
|
26
|
+
NimbleNodes::Dynos['max']
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.request_queue
|
30
|
+
hash = NimbleNodes::Dynos.settings['request_queue']
|
31
|
+
hash.nil? ? {} : hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.min_request_queue
|
35
|
+
NimbleNodes::Dynos.request_queue['min']
|
11
36
|
end
|
12
37
|
|
13
38
|
def self.max_request_queue
|
14
|
-
|
39
|
+
NimbleNodes::Dynos.request_queue['max']
|
40
|
+
end
|
41
|
+
|
42
|
+
#= Status Inspector
|
43
|
+
|
44
|
+
def self.paused?
|
45
|
+
not NimbleNodes::Dynos['paused_at'].nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
#= Monitoring
|
49
|
+
|
50
|
+
def self.monitor?
|
51
|
+
NimbleNodes.active? and !NimbleNodes::Dynos.paused?
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
# pass over the hash containing Rack env variables
|
56
|
+
# a Report will be created and posted if neccessary
|
57
|
+
def self.monitor(env)
|
58
|
+
begin
|
59
|
+
report = NimbleNodes::Report.new(env)
|
60
|
+
report.post if report.post?
|
61
|
+
rescue
|
62
|
+
# rescues any possible errors to ensure app performace isn't affected
|
63
|
+
end
|
15
64
|
end
|
16
65
|
|
17
66
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module NimbleNodes
|
2
|
+
module Rails
|
3
|
+
module Filter
|
4
|
+
|
5
|
+
# Use as a before_filter
|
6
|
+
def monitor_heroku_app
|
7
|
+
NimbleNodes::Dynos.monitor(request.env) if NimbleNodes::Dynos.monitor?
|
8
|
+
end
|
9
|
+
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
ActionController::Base.send(:include, NimbleNodes::Rails::Filter)
|
data/lib/nimble_nodes/report.rb
CHANGED
@@ -2,11 +2,6 @@ module NimbleNodes
|
|
2
2
|
|
3
3
|
class Report
|
4
4
|
|
5
|
-
|
6
|
-
def self.path
|
7
|
-
"/#{ENV['NN_APP_NAME']}/dynos/reports.json"
|
8
|
-
end
|
9
|
-
|
10
5
|
def initialize(env)
|
11
6
|
@dynos_in_use = env['HTTP_X_HEROKU_DYNOS_IN_USE'].to_i
|
12
7
|
@request_queue_depth = env['HTTP_X_HEROKU_QUEUE_DEPTH'].to_i
|
@@ -16,29 +11,36 @@ module NimbleNodes
|
|
16
11
|
params = {
|
17
12
|
:dynos_in_use => @dynos_in_use,
|
18
13
|
:request_queue_size => @request_queue_depth }
|
19
|
-
NimbleNodes::Server.post(
|
14
|
+
NimbleNodes::Server.post('/dynos/reports.json', params)
|
20
15
|
end
|
21
16
|
|
17
|
+
# returns true if report needs to be posted to server
|
22
18
|
def post?
|
23
|
-
return false unless NimbleNodes.installed?
|
24
19
|
return true
|
25
|
-
|
26
|
-
dynos_maxed_out? or queue_depth_too_long? or unused_dynos?
|
20
|
+
dynos_maxed_out? or queue_depth_too_long? or queue_depth_too_short? or idle_dynos?
|
27
21
|
end
|
28
22
|
|
23
|
+
# returns true if app is using all available dynos
|
29
24
|
def dynos_maxed_out?
|
30
25
|
return false if @dynos_in_use.nil?
|
31
|
-
@dynos_in_use >= Dynos.max
|
26
|
+
@dynos_in_use >= NimbleNodes::Dynos.max
|
32
27
|
end
|
33
|
-
|
28
|
+
|
29
|
+
# returns true if queue depth is over max
|
34
30
|
def queue_depth_too_long?
|
35
31
|
return false if @request_queue_depth.nil?
|
36
|
-
@request_queue_depth > Dynos.max_request_queue
|
32
|
+
@request_queue_depth > NimbleNodes::Dynos.max_request_queue
|
33
|
+
end
|
34
|
+
|
35
|
+
def queue_depth_too_short?
|
36
|
+
return false if @request_queue_depth.nil?
|
37
|
+
@request_queue_depth < NimbleNodes::Dynos.min_request_queue
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
+
# returns true if app isn't using all of it's dynos
|
41
|
+
def idle_dynos?
|
40
42
|
return false if @dynos_in_use.nil?
|
41
|
-
@dynos_in_use < Dynos.size
|
43
|
+
@dynos_in_use < NimbleNodes::Dynos.size
|
42
44
|
end
|
43
45
|
|
44
46
|
end
|
data/lib/nimble_nodes/server.rb
CHANGED
@@ -4,18 +4,63 @@ module NimbleNodes
|
|
4
4
|
|
5
5
|
class Server
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
#= HTTP Requests
|
8
|
+
# GETs and POSTs both add App.token to request automatically
|
9
|
+
|
10
|
+
def self.get(path)
|
11
|
+
begin
|
12
|
+
path = NimbleNodes::App.path(path)
|
13
|
+
uri = uri_with_token(path)
|
14
|
+
path = uri.route_from(NimbleNodes::Server.url[0..-2]).to_s
|
15
|
+
request = Net::HTTP::Get.new(path)
|
16
|
+
return Net::HTTP.start(uri.host, uri.port) {|http| http.request(request)}.body
|
17
|
+
rescue
|
18
|
+
return nil
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def self.post(path,params)
|
24
|
+
begin
|
25
|
+
path = NimbleNodes::App.path(path)
|
26
|
+
uri = uri(path)
|
27
|
+
request = Net::HTTP::Post.new(uri.path)
|
28
|
+
request.set_form_data({:token => NimbleNodes::App.token, :json => params.to_json, :created_at => Time.now })
|
29
|
+
return Net::HTTP.start(uri.host, uri.port) {|http| http.request(request)}
|
30
|
+
rescue
|
31
|
+
return nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
#= Domain & URLs
|
37
|
+
|
38
|
+
# set ENV variable in development to override production domain
|
39
|
+
def self.domain
|
40
|
+
ENV['NIMBLE_NODES_DOMAIN'].nil? ? 'nimblenodes.com' : ENV['NIMBLE_NODES_DOMAIN']
|
12
41
|
end
|
13
42
|
|
14
|
-
|
15
|
-
|
16
|
-
|
43
|
+
# returns string for url to given path at server
|
44
|
+
def self.url(path='/')
|
45
|
+
'http://' + domain + path
|
17
46
|
end
|
18
47
|
|
48
|
+
# returns parsed URI for given path at server
|
49
|
+
def self.uri(path)
|
50
|
+
URI.parse(url(path))
|
51
|
+
end
|
52
|
+
|
53
|
+
# returns parsed URI with App.token in query
|
54
|
+
def self.uri_with_token(path)
|
55
|
+
uri = uri(path)
|
56
|
+
query = (uri.query || '').split('&')
|
57
|
+
query.push("token=#{NimbleNodes::App.token}")
|
58
|
+
uri.query = query.join('&')
|
59
|
+
uri
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
19
64
|
end
|
20
65
|
|
21
66
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module NimbleNodes
|
2
|
+
|
3
|
+
class Settings
|
4
|
+
|
5
|
+
#= Setting accessor
|
6
|
+
#= allows NimbleNodes::Settings to be treated as a hash
|
7
|
+
# shortcut for accessing NimbleNodes.settings cache
|
8
|
+
def self.[](key)
|
9
|
+
cache[key]
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
#= Cache
|
15
|
+
# settings are fetched once from server and cached in global constant
|
16
|
+
|
17
|
+
# returns hash of settings from cache or fetched from nimblenodes.com
|
18
|
+
def self.cache
|
19
|
+
return CACHE if cache? and fresh_cache?
|
20
|
+
const_set('CACHE',NimbleNodes::Settings.fetch_from_server)
|
21
|
+
end
|
22
|
+
|
23
|
+
#== Fetch from server
|
24
|
+
|
25
|
+
# returns hash from parsed server response
|
26
|
+
def self.fetch_from_server
|
27
|
+
response = NimbleNodes::Server.get("/settings.json")
|
28
|
+
return {} if response.nil?
|
29
|
+
JSON[response].merge('fetched_at' => Time.now)
|
30
|
+
end
|
31
|
+
|
32
|
+
#== Cache Inspectors
|
33
|
+
|
34
|
+
# returns true if local settings have been set
|
35
|
+
def self.cache?
|
36
|
+
defined?(NimbleNodes::Settings::CACHE) and !NimbleNodes::Settings::CACHE.nil? and !NimbleNodes::Settings::CACHE.empty?
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.fresh_cache?
|
40
|
+
fetched_at = CACHE['fetched_at']
|
41
|
+
return false if fetched_at.nil?
|
42
|
+
age = Time.now.to_i - fetched_at.to_i
|
43
|
+
five_minutes = 300
|
44
|
+
age > five_minutes
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module NimbleNodes
|
2
|
+
|
3
|
+
module Workers
|
4
|
+
|
5
|
+
def self.active?
|
6
|
+
ENV.has_key?('NN_WORKERS_POOL_ACTIVE')
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.size
|
10
|
+
ENV['NN_WORKERS_POOL_SIZE']
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.min
|
14
|
+
ENV['NN_WORKERS_POOL_MIN']
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.max
|
18
|
+
ENV['NN_WORKERS_POOL_MAX']
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.min
|
22
|
+
ENV['NN_WORKERS_POOL_MIN']
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.min_job_queue
|
26
|
+
ENV['NN_WORKERS_JOB_QUEUE_MIN']
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.max_job_queue
|
30
|
+
ENV['NN_WORKERS_JOB_QUEUE_MAX']
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/lib/nimble_nodes.rb
CHANGED
@@ -1,36 +1,34 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
1
3
|
module NimbleNodes
|
2
4
|
|
3
|
-
|
4
|
-
def self.files
|
5
|
-
files = %w(dynos report server)
|
6
|
-
files.push NimbleNodes.legacy? ? 'filter' : 'middleware'
|
7
|
-
files
|
8
|
-
end
|
9
|
-
|
5
|
+
#= Check Rails version
|
10
6
|
# returns true if gem is loaded in a pre 2.3 version of rails
|
11
7
|
def self.legacy?
|
12
8
|
defined?(RAILS_GEM_VERSION) and RAILS_GEM_VERSION.slice(0..2).to_f < 2.3
|
13
|
-
end
|
9
|
+
end
|
14
10
|
|
15
|
-
#=
|
16
|
-
|
17
|
-
|
18
|
-
def self.monitor(env)
|
19
|
-
report = NimbleNodes::Report.new(env)
|
20
|
-
report.post if report.post?
|
11
|
+
#= App status inspectors
|
12
|
+
def self.active?
|
13
|
+
NimbleNodes::App.token? and !NimbleNodes.paused?
|
21
14
|
end
|
22
15
|
|
23
|
-
def self.
|
24
|
-
not
|
16
|
+
def self.paused?
|
17
|
+
not NimbleNodes::Settings[:paused_at].nil?
|
25
18
|
end
|
26
19
|
|
27
|
-
|
28
|
-
|
20
|
+
|
21
|
+
|
22
|
+
def self.lib_path(path='')
|
23
|
+
File.dirname(__FILE__) + '/nimble_nodes' + path
|
29
24
|
end
|
30
25
|
|
31
26
|
end
|
32
27
|
|
33
|
-
|
28
|
+
files = %w(app settings dynos workers report server)
|
29
|
+
files.each { |file| require NimbleNodes.lib_path('/' + file) }
|
30
|
+
|
31
|
+
require NimbleNodes::App.reporter
|
34
32
|
|
35
33
|
|
36
34
|
|
data/nimble_nodes.gemspec
CHANGED
@@ -5,12 +5,12 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{nimble_nodes}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.2.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jordan Glasner"]
|
12
|
-
s.date = %q{2010-
|
13
|
-
s.description = %q{
|
12
|
+
s.date = %q{2010-04-04}
|
13
|
+
s.description = %q{coming soon}
|
14
14
|
s.email = %q{jordan@digitalignition.com}
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE",
|
@@ -24,23 +24,32 @@ Gem::Specification.new do |s|
|
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
26
|
"lib/nimble_nodes.rb",
|
27
|
+
"lib/nimble_nodes/app.rb",
|
27
28
|
"lib/nimble_nodes/dynos.rb",
|
28
|
-
"lib/nimble_nodes/filter.rb",
|
29
29
|
"lib/nimble_nodes/middleware.rb",
|
30
|
+
"lib/nimble_nodes/rails/filter.rb",
|
30
31
|
"lib/nimble_nodes/report.rb",
|
31
32
|
"lib/nimble_nodes/server.rb",
|
33
|
+
"lib/nimble_nodes/settings.rb",
|
34
|
+
"lib/nimble_nodes/workers.rb",
|
32
35
|
"nimble_nodes.gemspec",
|
33
36
|
"test/helper.rb",
|
34
|
-
"test/
|
37
|
+
"test/unit/test_app.rb",
|
38
|
+
"test/unit/test_dynos.rb",
|
39
|
+
"test/unit/test_nimble_nodes.rb",
|
40
|
+
"test/unit/test_settings.rb"
|
35
41
|
]
|
36
42
|
s.homepage = %q{http://github.com/glasner/nimble_nodes}
|
37
43
|
s.rdoc_options = ["--charset=UTF-8"]
|
38
44
|
s.require_paths = ["lib"]
|
39
45
|
s.rubygems_version = %q{1.3.5}
|
40
|
-
s.summary = %q{
|
46
|
+
s.summary = %q{coming soon}
|
41
47
|
s.test_files = [
|
42
48
|
"test/helper.rb",
|
43
|
-
"test/
|
49
|
+
"test/unit/test_app.rb",
|
50
|
+
"test/unit/test_dynos.rb",
|
51
|
+
"test/unit/test_nimble_nodes.rb",
|
52
|
+
"test/unit/test_settings.rb"
|
44
53
|
]
|
45
54
|
|
46
55
|
if s.respond_to? :specification_version then
|
@@ -49,11 +58,20 @@ Gem::Specification.new do |s|
|
|
49
58
|
|
50
59
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
51
60
|
s.add_development_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
61
|
+
s.add_development_dependency(%q<mocha>, [">= 0"])
|
62
|
+
s.add_development_dependency(%q<fakeweb>, [">= 0"])
|
63
|
+
s.add_runtime_dependency(%q<json>, [">= 0"])
|
52
64
|
else
|
53
65
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
66
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
67
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
68
|
+
s.add_dependency(%q<json>, [">= 0"])
|
54
69
|
end
|
55
70
|
else
|
56
71
|
s.add_dependency(%q<thoughtbot-shoulda>, [">= 0"])
|
72
|
+
s.add_dependency(%q<mocha>, [">= 0"])
|
73
|
+
s.add_dependency(%q<fakeweb>, [">= 0"])
|
74
|
+
s.add_dependency(%q<json>, [">= 0"])
|
57
75
|
end
|
58
76
|
end
|
59
77
|
|
data/test/helper.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'test/unit'
|
3
|
+
|
3
4
|
require 'shoulda'
|
5
|
+
require 'mocha'
|
6
|
+
require 'fakeweb'
|
4
7
|
|
5
|
-
|
6
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
7
|
-
require 'nimble_nodes'
|
8
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../lib/nimble_nodes'
|
8
9
|
|
9
10
|
class Test::Unit::TestCase
|
10
11
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../helper'
|
2
|
+
|
3
|
+
class TestApp < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "An App" do
|
6
|
+
|
7
|
+
setup { @module = NimbleNodes::App }
|
8
|
+
|
9
|
+
context "on Rails" do
|
10
|
+
|
11
|
+
setup { @module.stubs(:rails?).returns(true) }
|
12
|
+
|
13
|
+
context "2.3 or later" do
|
14
|
+
setup { @module.stubs(:rails_version).returns(2.3) }
|
15
|
+
|
16
|
+
should "not use rails before_filter" do
|
17
|
+
assert(!@module.use_rails_filter?)
|
18
|
+
end
|
19
|
+
|
20
|
+
should "return NimbleNodes::Middleware as reporter" do
|
21
|
+
assert_equal 'middleware', @module.reporter.split('/').last
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
context "prior to 2.3" do
|
27
|
+
setup { NimbleNodes::App.stubs(:rails_version).returns(2.2) }
|
28
|
+
|
29
|
+
should "use rails before_filter" do
|
30
|
+
assert(@module.use_rails_filter?)
|
31
|
+
end
|
32
|
+
|
33
|
+
should "return NimbleNodes::Filter as reporter" do
|
34
|
+
assert_equal 'filter', @module.reporter.split('/').last
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "off Rails" do
|
43
|
+
|
44
|
+
should "return false for rails?" do
|
45
|
+
# we're not in Rails so this works
|
46
|
+
assert_equal false, @module.rails?
|
47
|
+
end
|
48
|
+
|
49
|
+
should "return NimbleNodes::Middleware as reporter" do
|
50
|
+
assert_equal 'middleware', @module.reporter.split('/').last
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
context "installed at NimbleNodes" do
|
57
|
+
|
58
|
+
setup {
|
59
|
+
ENV['NIMBLE_NODES_APP_NAME'] = 'nimble-nodes-test'
|
60
|
+
ENV['NIMBLE_NODES_APP_TOKEN'] = 'test'
|
61
|
+
}
|
62
|
+
|
63
|
+
should "return name from ENV" do
|
64
|
+
assert_equal ENV['NIMBLE_NODES_APP_NAME'], @module.name
|
65
|
+
end
|
66
|
+
|
67
|
+
should "return token from ENV" do
|
68
|
+
assert_equal ENV['NIMBLE_NODES_APP_TOKEN'], @module.token
|
69
|
+
end
|
70
|
+
|
71
|
+
should "return true for token?" do
|
72
|
+
assert @module.token?
|
73
|
+
end
|
74
|
+
|
75
|
+
should "return relative path at NN server" do
|
76
|
+
assert_equal '/nimble-nodes-test/', @module.path
|
77
|
+
end
|
78
|
+
|
79
|
+
should "return relative path to app resource for given path" do
|
80
|
+
assert_equal '/nimble-nodes-test/dynos', @module.path('/dynos')
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
|
86
|
+
context "not installed at NimbleNodes" do
|
87
|
+
|
88
|
+
setup {
|
89
|
+
ENV['NIMBLE_NODES_APP_NAME'] = nil
|
90
|
+
ENV['NIMBLE_NODES_APP_TOKEN'] = nil
|
91
|
+
}
|
92
|
+
|
93
|
+
should "return false for token?" do
|
94
|
+
assert_equal false, @module.token?
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../helper'
|
2
|
+
|
3
|
+
class Test::Unit::TestCase
|
4
|
+
|
5
|
+
def self.should_not_raise_anything_when_monitored
|
6
|
+
should "not raise any exceptions when sent :monitored?" do
|
7
|
+
assert_nothing_raised { @module.monitor? }
|
8
|
+
NimbleNodes::Server.stubs(:post).returns(nil)
|
9
|
+
assert_nothing_raised { @module.monitor({}) }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.should_not_be_monitored
|
14
|
+
should "not be monitored" do
|
15
|
+
assert_equal false, @module.monitor?
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
class TestDynos < Test::Unit::TestCase
|
24
|
+
|
25
|
+
context "Dynos" do
|
26
|
+
|
27
|
+
setup {
|
28
|
+
@module = NimbleNodes::Dynos
|
29
|
+
}
|
30
|
+
|
31
|
+
context "App setup at NimbleNodes" do
|
32
|
+
|
33
|
+
setup {
|
34
|
+
NimbleNodes::App.stubs({
|
35
|
+
:name => 'nimble-nodes-test',
|
36
|
+
:token => 'token'
|
37
|
+
})
|
38
|
+
@module.stubs(:settings).returns({
|
39
|
+
'paused_at' => nil,
|
40
|
+
'min' => 1,
|
41
|
+
'max' => 2
|
42
|
+
})
|
43
|
+
}
|
44
|
+
|
45
|
+
context "and App not paused" do
|
46
|
+
setup { NimbleNodes.stubs(:paused?).returns(false) }
|
47
|
+
|
48
|
+
should "be monitored" do
|
49
|
+
assert @module.monitor?
|
50
|
+
end
|
51
|
+
|
52
|
+
should_not_raise_anything_when_monitored
|
53
|
+
|
54
|
+
context "and Dynos paused" do
|
55
|
+
setup {
|
56
|
+
@module.stubs(:settings).returns({
|
57
|
+
'paused_at' => Time.now,
|
58
|
+
'min' => 1,
|
59
|
+
'max' => 2
|
60
|
+
})
|
61
|
+
}
|
62
|
+
|
63
|
+
should "be paused" do
|
64
|
+
assert @module.paused?
|
65
|
+
end
|
66
|
+
|
67
|
+
should_not_be_monitored
|
68
|
+
should_not_raise_anything_when_monitored
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
context "and App paused" do
|
76
|
+
setup { NimbleNodes.stubs(:paused?).returns(true) }
|
77
|
+
should_not_be_monitored
|
78
|
+
should_not_raise_anything_when_monitored
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
context "App *not* setup at NimbleNodes.com" do
|
86
|
+
|
87
|
+
should_not_be_monitored
|
88
|
+
|
89
|
+
should_not_raise_anything_when_monitored
|
90
|
+
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../helper'
|
2
|
+
|
3
|
+
class TestNimbleNodes < Test::Unit::TestCase
|
4
|
+
|
5
|
+
|
6
|
+
context "NimbleNodes module" do
|
7
|
+
setup { @module = NimbleNodes }
|
8
|
+
|
9
|
+
context "in a Rails app" do
|
10
|
+
|
11
|
+
setup { NimbleNodes::App.stubs(:rails?).returns(true) }
|
12
|
+
|
13
|
+
context "pre 2.3" do
|
14
|
+
setup { NimbleNodes::App.stubs(:rails_version).returns(2.2) }
|
15
|
+
|
16
|
+
should "use NimbleNodes::Filter as reporter" do
|
17
|
+
assert_equal 'filter', @module.reporter.split('/').last
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
context "2.3 or later" do
|
23
|
+
setup { NimbleNodes::App.stubs(:rails_version).returns(2.3) }
|
24
|
+
|
25
|
+
should "use NimbleNodes::Middleware as reporter" do
|
26
|
+
assert_equal 'middleware', @module.reporter.split('/').last
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
context "in a non-Rails app" do
|
34
|
+
setup { NimbleNodes::App.stubs(:rails?).returns(false) }
|
35
|
+
|
36
|
+
should "use NimbleNodes::Middleware" do
|
37
|
+
assert_equal 'middleware8', @module.reporter.split('/').last
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "App installed at NimbleNodes" do
|
43
|
+
|
44
|
+
setup {
|
45
|
+
NimbleNodes::App.stubs({
|
46
|
+
:name => 'nimble-nodes-test',
|
47
|
+
:token => 'token'
|
48
|
+
})
|
49
|
+
}
|
50
|
+
|
51
|
+
context "not paused" do
|
52
|
+
|
53
|
+
setup {
|
54
|
+
@module.stubs(:paused?).returns(false)
|
55
|
+
}
|
56
|
+
|
57
|
+
should "be active" do
|
58
|
+
assert @module.active?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "paused" do
|
63
|
+
|
64
|
+
setup {
|
65
|
+
@module.stubs(:paused?).returns(true)
|
66
|
+
}
|
67
|
+
|
68
|
+
should "be not active" do
|
69
|
+
assert(!@module.active?)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../helper'
|
2
|
+
|
3
|
+
class Test::Unit::TestCase
|
4
|
+
|
5
|
+
def self.should_not_raise_any_errors_when_fetching_from_server
|
6
|
+
should "not raise any errors when fetching from server" do
|
7
|
+
assert_nothing_raised { @module.fetch_from_server }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.should_not_raise_any_errors_on_unknown_keys
|
12
|
+
should "not raise errors on any unknown keys" do
|
13
|
+
assert_nothing_raised { @module.cache['bogus-key'] }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
class TestSettings < Test::Unit::TestCase
|
21
|
+
|
22
|
+
context "Settings" do
|
23
|
+
|
24
|
+
setup {
|
25
|
+
@module = NimbleNodes::Settings
|
26
|
+
@module.send(:remove_const,'CACHE') if defined?(@module::CACHE)
|
27
|
+
}
|
28
|
+
|
29
|
+
context "App is installed at NimbleNodes.com" do
|
30
|
+
setup do
|
31
|
+
NimbleNodes::App.stubs({
|
32
|
+
:name => "nimble-nodes-test",
|
33
|
+
:token => 'test'
|
34
|
+
})
|
35
|
+
end
|
36
|
+
|
37
|
+
context "server responds with JSON" do
|
38
|
+
|
39
|
+
setup {
|
40
|
+
@json = '{"paused_at":null,"dynos_pool":{"size":1,"paused_at":null,"max":1,"request_queue":{"max":5,"min":0},"min":1}}'
|
41
|
+
@parsed = JSON[@json]
|
42
|
+
NimbleNodes::Server.expects(:get).returns(@json)
|
43
|
+
}
|
44
|
+
|
45
|
+
should "only fetch from server once" do
|
46
|
+
@module.expects(:fetch_from_server).once
|
47
|
+
@module['paused_at']
|
48
|
+
@module['dynos_pool']
|
49
|
+
end
|
50
|
+
|
51
|
+
should "save parsed parsed response in cache" do
|
52
|
+
cached = @module.cache
|
53
|
+
cached.delete('fetched_at')
|
54
|
+
assert_equal @parsed, cached
|
55
|
+
end
|
56
|
+
|
57
|
+
should "add fetched_at to server response" do
|
58
|
+
assert_not_nil @module['fetched_at']
|
59
|
+
end
|
60
|
+
|
61
|
+
should_not_raise_any_errors_on_unknown_keys
|
62
|
+
|
63
|
+
should_not_raise_any_errors_when_fetching_from_server
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
context "server responds with error" do
|
68
|
+
setup { NimbleNodes::Server.expects(:get).once.returns(nil) }
|
69
|
+
should_not_raise_any_errors_on_unknown_keys
|
70
|
+
should_not_raise_any_errors_when_fetching_from_server
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
context "App is *not* installed at NimbleNodes.com" do
|
76
|
+
|
77
|
+
setup {
|
78
|
+
NimbleNodes::App.stubs({
|
79
|
+
:name => nil,
|
80
|
+
:token => nil
|
81
|
+
})
|
82
|
+
NimbleNodes::Server.expects(:get).returns(nil)
|
83
|
+
}
|
84
|
+
|
85
|
+
should_not_raise_any_errors_on_unknown_keys
|
86
|
+
should_not_raise_any_errors_when_fetching_from_server
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nimble_nodes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jordan Glasner
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-04-04 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,7 +22,37 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: "0"
|
24
24
|
version:
|
25
|
-
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: mocha
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: fakeweb
|
37
|
+
type: :development
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: json
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
description: coming soon
|
26
56
|
email: jordan@digitalignition.com
|
27
57
|
executables: []
|
28
58
|
|
@@ -39,14 +69,20 @@ files:
|
|
39
69
|
- Rakefile
|
40
70
|
- VERSION
|
41
71
|
- lib/nimble_nodes.rb
|
72
|
+
- lib/nimble_nodes/app.rb
|
42
73
|
- lib/nimble_nodes/dynos.rb
|
43
|
-
- lib/nimble_nodes/filter.rb
|
44
74
|
- lib/nimble_nodes/middleware.rb
|
75
|
+
- lib/nimble_nodes/rails/filter.rb
|
45
76
|
- lib/nimble_nodes/report.rb
|
46
77
|
- lib/nimble_nodes/server.rb
|
78
|
+
- lib/nimble_nodes/settings.rb
|
79
|
+
- lib/nimble_nodes/workers.rb
|
47
80
|
- nimble_nodes.gemspec
|
48
81
|
- test/helper.rb
|
49
|
-
- test/
|
82
|
+
- test/unit/test_app.rb
|
83
|
+
- test/unit/test_dynos.rb
|
84
|
+
- test/unit/test_nimble_nodes.rb
|
85
|
+
- test/unit/test_settings.rb
|
50
86
|
has_rdoc: true
|
51
87
|
homepage: http://github.com/glasner/nimble_nodes
|
52
88
|
licenses: []
|
@@ -74,7 +110,10 @@ rubyforge_project:
|
|
74
110
|
rubygems_version: 1.3.5
|
75
111
|
signing_key:
|
76
112
|
specification_version: 3
|
77
|
-
summary:
|
113
|
+
summary: coming soon
|
78
114
|
test_files:
|
79
115
|
- test/helper.rb
|
80
|
-
- test/
|
116
|
+
- test/unit/test_app.rb
|
117
|
+
- test/unit/test_dynos.rb
|
118
|
+
- test/unit/test_nimble_nodes.rb
|
119
|
+
- test/unit/test_settings.rb
|
data/lib/nimble_nodes/filter.rb
DELETED
data/test/test_nimble_nodes.rb
DELETED