abstract_analyzer 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ test/*.log
2
+ lib/*.log
3
+ lib/middlewares/*.log
4
+ lib/middlewares/*.db
5
+ *.db
6
+ *.log
data/README.rdoc ADDED
@@ -0,0 +1,63 @@
1
+ =Abstract Analyzer
2
+
3
+ This is a Rack based analyzer. The idea is to use different methods and libraries to track requests on Rack app and report those back in some simple views.
4
+
5
+ I'm starting with a Fiveruns Dash analyzer that reports to a MongoDB instance. Reporting actually be it's own small Rack app and for the time being, will mostly text based.
6
+
7
+ ==Requirements
8
+
9
+ I hope to trim this down, but for now...
10
+
11
+ gems:
12
+ * mongodb-mongo
13
+ * fiveruns-dash-ruby
14
+ * usher
15
+ * ruport
16
+
17
+ In addition for the tests to pass, you need mongod running on localhost:27017
18
+
19
+ ==Implementation
20
+
21
+ You can use the DashAnalyzer with any rack app you'd like. Check the tests for an example.
22
+
23
+ ===Rails
24
+
25
+ If Rails is your bag, I've included a middleware implementation of the DashAnalyzer. Implementing is pretty easy.
26
+
27
+ First, this thing isn't a gem yet, so just load the whole thing into lib or somewhere else Rails will see it.
28
+
29
+ Secound, in RAILS_ROOT/config/initializers/middlewares.rb
30
+
31
+ require 'abstract_analyzer/abstract_analyzer'
32
+
33
+ # Setup the Analyzer DB
34
+ abstract_analyzer_db = Mongo::Connection.new('localhost', 27017).db('aa-rails-dash-analyzer-db')
35
+ AbstractAnalyzer.const_set("DB", abstract_analyzer_db)
36
+
37
+ # Setup the Analyzer LOGGER
38
+ abstract_logger = Logger.new("#{RAILS_ROOT}/log/abstract_analyzer_logger.log")
39
+ AbstractAnalyzer.const_set("LOGGER", abstract_logger)
40
+
41
+ # Use the Analyzer and View middlewares
42
+ ActionController::Dispatcher.middleware.use AbstractAnalyzer::Middleware::Rails::Dash::Analyzer
43
+ ActionController::Dispatcher.middleware.use AbstractAnalyzer::Middleware::Rails::Dash::View
44
+
45
+ Third, make sure you actually have a mongo db running on localhost:27017 or change the connection accordingly ;)
46
+
47
+ ==Todo
48
+
49
+ * Basic html views
50
+ * Implementing reports for Non-time based metrics
51
+ * Non-Rails middlewares?
52
+ * Non-Dash implementations?
53
+
54
+ ==Props
55
+
56
+ * Carl Lerche and Yehuda Katz for their Extending Rails training at the Lone Star Ruby Conference that planted this seed
57
+ * The company formally known as Fiveruns for open sourcing their reporter gems
58
+ * Adam Keys for explaining how the Dash gems work
59
+ * The guys a SqueeJee for saying MongoDB enough times to make me try it in something
60
+
61
+ ==License
62
+
63
+ See LICENSE
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "abstract_analyzer"
8
+ gem.summary = %Q{A rack based app analyzer}
9
+ gem.email = "markmcspadden@gmail.com"
10
+ gem.homepage = "http://github.com/garlandgroup/abstract-analyzer"
11
+ gem.authors = ["Mark McSpadden"]
12
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
13
+ end
14
+
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
18
+ end
19
+
20
+ require 'rake/rdoctask'
21
+ Rake::RDocTask.new do |rdoc|
22
+ rdoc.rdoc_dir = 'rdoc'
23
+ rdoc.title = 'abstract_analyzer'
24
+ rdoc.options << '--line-numbers' << '--inline-source'
25
+ rdoc.rdoc_files.include('README*')
26
+ rdoc.rdoc_files.include('lib/**/*.rb')
27
+ end
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :patch: 0
3
+ :major: 0
4
+ :minor: 0
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) << '/view'
2
+ require File.dirname(__FILE__) << '/dash_analyzer'
3
+ require File.dirname(__FILE__) << '/middleware'
4
+
5
+ module AbstractAnalyzer
6
+
7
+ # CONSTANTS DB, LOGGER, STORE are currently being set and expected
8
+
9
+ # STORE = "mongoDB"
10
+ # DB = Mongo::Connection.new('localhost', 27017).db('abstract-analyzer-db')
11
+ # LOGGER = Logger.new(File.dirname(__FILE__) << "/abstract_analyzer_logger.log")
12
+
13
+ end
14
+
15
+
16
+
@@ -0,0 +1,24 @@
1
+ require 'yaml'
2
+
3
+ require 'logger'
4
+
5
+ require 'rubygems' # I know I know...
6
+
7
+
8
+ gem 'fiveruns-dash-ruby' # Put its path first
9
+ require 'fiveruns/dash'
10
+
11
+ require 'mongo'
12
+
13
+ require File.dirname(__FILE__) << '/dash_analyzer/dash_extensions'
14
+ require File.dirname(__FILE__) << '/dash_analyzer/base'
15
+ require File.dirname(__FILE__) << '/dash_analyzer/view'
16
+
17
+ module DashAnalyzer
18
+
19
+ end
20
+
21
+
22
+
23
+
24
+
@@ -0,0 +1,55 @@
1
+ module DashAnalyzer
2
+ # Hooks up dash to your db
3
+ # Implement in as a middleware like so:
4
+ #
5
+ # class MyApp < DashAnalyzer::Base
6
+ # Fiveruns::Dash.register_recipe :testpack, :url => 'http://example.org' do |recipe|
7
+ # Fiveruns::Dash.logger.info 'REGISTERING ACTIONPACK RECIPE'
8
+ # recipe.time :response_time, :method => 'DashAnalyzer::Base#call', :mark => true
9
+ # recipe.time :another_response_time, :method => 'DashAnalyzer::Base#call', :mark => true
10
+ # end
11
+ #
12
+ # def initialize(*)
13
+ # @recipes = [{:name => :testpack, :url => 'http://example.org'}]
14
+ # super
15
+ # end
16
+ # end
17
+ #
18
+ class Base
19
+ attr_accessor :db, :logger
20
+
21
+ def initialize(app, dash_interval=60)
22
+ @db = AbstractAnalyzer.const_get("DB")
23
+ @logger = AbstractAnalyzer.const_get("LOGGER")
24
+
25
+ startup_dash(dash_interval)
26
+
27
+ @app = app
28
+ end
29
+
30
+ def call(env)
31
+ @app.call(env)
32
+ end
33
+
34
+ def startup_dash(interval = 60)
35
+ return if Fiveruns::Dash.session.reporter.started?
36
+
37
+ Fiveruns::Dash.session.reset
38
+
39
+ Fiveruns::Dash.logger = @logger
40
+
41
+ ENV['DASH_UPDATE'] = "mongo://db"
42
+
43
+ Fiveruns::Dash.configure do |config|
44
+ config.db = db
45
+
46
+ @recipes.each do |r|
47
+ config.add_recipe r[:name], r[:url]
48
+ end
49
+ end
50
+
51
+ Fiveruns::Dash.session.interval = interval
52
+ Fiveruns::Dash.session.start
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,88 @@
1
+ # Setup db to receive rollups
2
+ class Fiveruns::Dash::Configuration
3
+ attr_accessor :db
4
+ end
5
+
6
+ # Allow the Fiveruns::Dash::Session interval to be set
7
+ module FiverunsDashSessionExtensions
8
+ def interval=(value)
9
+ reporter.interval = value
10
+ end
11
+ end
12
+ Fiveruns::Dash::Session.__send__ :include, FiverunsDashSessionExtensions
13
+
14
+
15
+ # Allow direct access to the Fiveruns::Dash::Payload data hash
16
+ module FiverunsDashPayloadExtensions
17
+ attr_reader :data
18
+ end
19
+ Fiveruns::Dash::Payload.__send__ :include, FiverunsDashPayloadExtensions
20
+
21
+ # Setup a store_mongo method on Fiveruns::Dash::Store
22
+ # NOTE: I think there is a better way to do this
23
+ module Fiveruns::Dash::Store::Mongo
24
+ def store_mongo(*uris)
25
+ Fiveruns::Dash.logger.info "Attempting to send #{payload.class}"
26
+
27
+ if payload.is_a? Fiveruns::Dash::DataPayload
28
+ data = payload.data
29
+
30
+ data.each do |d|
31
+ recipe_name = d[:recipe_name]
32
+ name = d[:name]
33
+ storage_name = "#{recipe_name}-#{name}"
34
+ d[:created_at] = Time.now
35
+
36
+ # TODO: Use upsert to handle cluser wide implementations
37
+ Fiveruns::Dash.session.configuration.db.collection(storage_name).insert(d)
38
+ Fiveruns::Dash.logger.info "Sent #{payload.class} to #{Fiveruns::Dash.session.configuration.db}"
39
+ end
40
+ else
41
+ raise "Payload of type #{payload.class} Not Currently Supported"
42
+ end
43
+ rescue
44
+ Fiveruns::Dash.logger.warn "Could not send #{payload.class}: #{$!}"
45
+ end
46
+ end
47
+
48
+ # Allow Fiveruns::Dash::Update to recognize mongo style urls
49
+ # Yes I think I totally just made up mongo style urls
50
+ # They look like 'mongo://ANYTHING_GOES_HERE_FOR_NOW'
51
+
52
+ # Also, I think I like the duck punching better than this send/include/send/alias_method mess
53
+ # Open to rewrites
54
+ module FiverunsDashUpdateExtensions
55
+ include Fiveruns::Dash::Store::Mongo
56
+
57
+ private
58
+ def storage_method_for_with_mongo(scheme)
59
+ if scheme =~ /^mongo/
60
+ :mongo
61
+ else
62
+ storage_method_for_without_mongo(scheme)
63
+ end
64
+ end
65
+ end
66
+ Fiveruns::Dash::Update.__send__ :include, FiverunsDashUpdateExtensions
67
+ Fiveruns::Dash::Update.__send__ :alias_method, :storage_method_for_without_mongo, :storage_method_for
68
+ Fiveruns::Dash::Update.__send__ :alias_method, :storage_method_for, :storage_method_for_with_mongo
69
+
70
+ # Duck punched version
71
+ # module Fiveruns::Dash
72
+ # class Update
73
+ # include Store::Mongo
74
+ #
75
+ # private
76
+ #
77
+ # def storage_method_for_with_mongo(scheme)
78
+ # if scheme =~ /^mongo/
79
+ # :mongo
80
+ # else
81
+ # storage_method_for_without_mongo(scheme)
82
+ # end
83
+ # end
84
+ # # alias_method_chain :storage_method_for, :mongo
85
+ # alias_method :storage_method_for_without_mongo, :storage_method_for
86
+ # alias_method :storage_method_for, :storage_method_for_with_mongo
87
+ # end
88
+ # end
@@ -0,0 +1,89 @@
1
+ require 'ruport'
2
+
3
+ module DashAnalyzer
4
+ class TimeView < AbstractAnalyzer::View
5
+
6
+ def initialize(*)
7
+ super
8
+ setup_show
9
+ end
10
+
11
+ # Create some kind of index view
12
+ get "/analytics" do
13
+ # Only look at time metrics for now
14
+ collection_names = db.collection_names.select{ |n| n.match(/time/)}
15
+
16
+ table = Table(:column_names => ["Metric", "Total Number of Calls", "Total Time (s)", "Avg Time per Call (s)"])
17
+
18
+ collection_names.each do |name|
19
+ coll = db.collection(name)
20
+
21
+ total_values = 0
22
+ total_invocations = 0
23
+
24
+ coll.find().each do |row|
25
+ values = row["values"]
26
+
27
+ # Why is this an array
28
+ if values && !values.empty?
29
+ v = values.first
30
+ value = v["value"]
31
+ invocations = v["invocations"]
32
+
33
+ total_values += value.to_f
34
+ total_invocations += invocations.to_i
35
+ end
36
+ end
37
+
38
+ table << [name.to_s.titlecase, total_invocations.to_i, total_values.to_f, total_values.to_f/total_invocations.to_f]
39
+ end
40
+
41
+ trail = "There are more details at:\n#{collection_names.collect{ |n| " * /analytics/show/#{n}"}.join("\n")}"
42
+
43
+ [table.to_s, trail].join("\n")
44
+ end
45
+
46
+ # Use the collection names to create views
47
+ def setup_show
48
+ db.collection_names.each do |name|
49
+ self.class.class_eval do
50
+ get "/analytics/show/#{name}" do
51
+ coll = db.collection(name)
52
+
53
+ lead = "Listing #{coll.count} #{name.to_s.titlecase} Rollups in the Last Hour"
54
+
55
+ table = Table(:column_names => ["Time", "Metric Name", "Number of Calls", "Total Time"])
56
+
57
+ total_invocations = 0
58
+ total_values = 0.0
59
+
60
+ # TODO: Reverse this collection
61
+ coll.find({:created_at => {:$gte => Time.now.advance(:hours => -1)}}, {:sort => {:created_at => Mongo::DESCENDING}}).each do |row|
62
+ values = row["values"]
63
+
64
+ # Why is this an array
65
+ if values && !values.empty?
66
+ value = values.first["value"]
67
+ invocations = values.first["invocations"]
68
+
69
+ total_values = value.to_f
70
+ total_invocations += invocations.to_i
71
+ end
72
+
73
+ table << [row["created_at"], row["description"], invocations.to_i, value.to_f]
74
+ end
75
+
76
+ results = []
77
+ results << "Total Calls: #{total_invocations}"
78
+ results << "Total Time: #{total_values} seconds"
79
+ results << "Avg Time per Call: #{total_values/total_invocations.to_f} seconds"
80
+ results = results.join("\n")
81
+
82
+ [lead, results, table.to_s].join("\n")
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ end
89
+ end
data/lib/middleware.rb ADDED
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) << '/middleware/rails'
2
+
3
+ module AbstractAnalzyer
4
+ module Middleware
5
+
6
+ end
7
+ end
@@ -0,0 +1,41 @@
1
+ # TODO: Figure out what to do with these.
2
+ # They already be loaded if it's actually in a Rails project
3
+ # But if it's not, we'd hate to load all this mess.
4
+
5
+ RAILS_ROOT = File.dirname(__FILE__) unless defined?(RAILS_ROOT)
6
+ RAILS_DEFAULT_LOGGER = Logger.new(File.dirname(__FILE__) << "/middleware_rails_dash.log") unless defined?(RAILS_DEFAULT_LOGGER)
7
+ gem 'rails'
8
+ gem 'activesupport'
9
+ gem 'activerecord'
10
+ gem 'actionpack'
11
+ require 'action_controller'
12
+ require 'action_controller/base'
13
+
14
+
15
+
16
+ require File.dirname(__FILE__) << '/rails/dash'
17
+
18
+ module AbstractAnalyzer
19
+ module Middleware
20
+ # Implementation
21
+ # In RAILS_ROOT/config/initializers/middlewares.rb
22
+ #
23
+ # require 'abstract_analyzer/abstract_analyzer'
24
+ #
25
+ # # Setup the Analyzer DB
26
+ # abstract_analyzer_db = Mongo::Connection.new('localhost', 27017).db('aa-rails-dash-analyzer-db')
27
+ # AbstractAnalyzer.const_set("DB", abstract_analyzer_db)
28
+ #
29
+ # # Setup the Analyzer LOGGER
30
+ # abstract_logger = Logger.new("#{RAILS_ROOT}/log/abstract_analyzer_logger.log")
31
+ # AbstractAnalyzer.const_set("LOGGER", abstract_logger)
32
+ #
33
+ # # Use the Analyzer and View middlewares
34
+ # ActionController::Dispatcher.middleware.use AbstractAnalyzer::Middleware::Rails::Dash::Analyzer
35
+ # ActionController::Dispatcher.middleware.use AbstractAnalyzer::Middleware::Rails::Dash::View
36
+ #
37
+ # NOTE: The require piece will be replace by an environment.rb config.gem call at some point
38
+ module Rails
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,35 @@
1
+ require 'fiveruns-dash-rails'
2
+
3
+ module AbstractAnalyzer
4
+ module Middleware
5
+ module Rails
6
+ module Dash
7
+ # This is where we grab the analytics
8
+ class Analyzer < DashAnalyzer::Base
9
+ # Fiveruns::Dash.register_recipe :actionpack, :url => 'http://example.org' do |recipe|
10
+ # Fiveruns::Dash.logger.info 'REGISTERING ACTIONPACK RECIPE'
11
+ #
12
+ # recipe.time :response_time, :method => 'AbstractController::Base#process_action', :mark => true
13
+ # end
14
+
15
+ def initialize(*)
16
+ # Fiveruns::Dash::Rails.load_recipes
17
+
18
+ #@recipes = [{:name => :actionpack, :url => 'http://example.org'}]
19
+ @recipes = [{:name => :ruby, :url => 'http://dash.fiveruns.com'},
20
+ {:name => :rails, :url => 'http://dash.fiveruns.com'}]
21
+ super
22
+ end
23
+ end
24
+
25
+ # This is where we view them
26
+ class View < DashAnalyzer::TimeView
27
+ def initialize(*)
28
+ super
29
+ #self.collection = 'actionpack-response_time'
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/view.rb ADDED
@@ -0,0 +1,75 @@
1
+ require 'usher'
2
+
3
+ module AbstractAnalyzer
4
+ class View
5
+ def db
6
+ AbstractAnalyzer.const_get("DB")
7
+ end
8
+
9
+ attr_accessor :collection
10
+ def initialize(app, collection = nil)
11
+ @collection = collection.to_s
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ method_name = "[#{env["REQUEST_METHOD"].to_s.downcase}] #{env["PATH_INFO"]}"
17
+
18
+ # This has got to be not good for performance
19
+ # Consider using the PATH_INFO var instead
20
+ if self.respond_to?(method_name)
21
+ content = self.__send__(method_name)
22
+ [200, {"Content-Type" => "text/plain"}, content]
23
+ else
24
+ @app.call(env)
25
+ end
26
+ end
27
+
28
+ class << self
29
+ # From Railsnatra
30
+ # Set @_routes on child classes
31
+ def inherited(klass)
32
+ klass.class_eval { @_routes = [] }
33
+ end
34
+
35
+ def to_app
36
+ routes, controller = @_routes, self
37
+
38
+ # From Railsnatra ;)
39
+ # We're using Usher as a router for this project. To
40
+ # simplify things, we just used the rack interface to
41
+ # router and it's DSL.
42
+ app = Usher::Interface.for(:rack) do
43
+ routes.each do |route|
44
+ conditions = {:request_method => route[:method]}
45
+ add(route[:uri], :conditions => conditions.merge(route[:options])).
46
+ to(controller.action(route[:action]))
47
+ end
48
+ end
49
+
50
+ app
51
+ end
52
+
53
+ def get(uri, options = {}, &block)
54
+ route(:get, uri, options, &block)
55
+ end
56
+
57
+ private
58
+ # From Railsnatra
59
+ def route(http_method, uri, options, &block)
60
+ # Since we need unique actions for each possible GET,
61
+ # POST, etc... URLs, we add the method in the action
62
+ # name. ActionController::Metal has the ability to
63
+ # route an action with any name format.
64
+ action_name = "[#{http_method}] #{uri}"
65
+ # We save the route options in the global @_routes
66
+ # variable so that we can build the routes when the
67
+ # app is generated.
68
+ @_routes << {:method => http_method.to_s.upcase, :uri => uri,
69
+ :action => action_name, :options => options}
70
+ # Now, we finally create the action method.
71
+ define_method(action_name, &block)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,133 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ class BaseTest < Test::Unit::TestCase
4
+ include Rack::Test::Methods
5
+
6
+ class MyApp < DashAnalyzer::Base
7
+
8
+ Fiveruns::Dash.register_recipe :testpack, :url => 'http://example.org' do |recipe|
9
+ Fiveruns::Dash.logger.info 'REGISTERING ACTIONPACK RECIPE'
10
+ recipe.time :response_time, :method => 'DashAnalyzer::Base#call', :mark => true
11
+ recipe.time :another_response_time, :method => 'DashAnalyzer::Base#call', :mark => true
12
+ end
13
+
14
+ def initialize(*)
15
+ @recipes = [{:name => :testpack, :url => 'http://example.org'}]
16
+ super
17
+ end
18
+ end
19
+
20
+ def app
21
+ MyApp.new(FooApp.new, 1)
22
+ end
23
+
24
+ # MAKE SURE MONGO IS RUNNING ON localhost:27017
25
+ def test_mongodb
26
+ get "/foo"
27
+
28
+ assert_not_nil app.db
29
+ end
30
+
31
+ def test_success
32
+ get "/foo"
33
+
34
+ assert last_response.ok?
35
+ end
36
+
37
+ # Should I really be testing Dash internals? I think not.
38
+ def x_test_session_data_store
39
+ 5.times do
40
+ get "/foo"
41
+ end
42
+
43
+ # Not really sure what this is all about, but I got it to work
44
+ data = Fiveruns::Dash.session.data
45
+
46
+ assert_equal 5, data.first[:values].first[:invocations]
47
+
48
+ 7.times do
49
+ get "/foo"
50
+ end
51
+
52
+ # OK. Accessing the session data clears it out.
53
+ data2 = Fiveruns::Dash.session.data
54
+ assert_equal 7, data2.first[:values].first[:invocations]
55
+ end
56
+
57
+ def test_mongo_data_store
58
+ coll = app.db.collection('testpack-response_time')
59
+ coll.clear
60
+
61
+ 5.times do
62
+ get "/foo"
63
+ end
64
+
65
+ sleep Fiveruns::Dash.session.reporter.interval
66
+
67
+ total_invocations = 0
68
+
69
+ coll.find().each do |row|
70
+ values = row[:values]
71
+ if values
72
+ invocations = values[:invocations]
73
+ total_invocations += invocations
74
+ end
75
+ end
76
+
77
+ assert 5, total_invocations
78
+ end
79
+
80
+ def test_mongo_data_store_with_multiple_metrics
81
+ coll1 = app.db.collection('testpack-response_time')
82
+ coll1.clear
83
+
84
+ coll2 = app.db.collection('testpack-another_response_time')
85
+ coll2.clear
86
+
87
+ 10.times do
88
+ get "/foo"
89
+ end
90
+
91
+ sleep Fiveruns::Dash.session.reporter.interval
92
+
93
+ #coll.find().each { |row| puts row.class; puts row.inspect; puts "-------" }
94
+
95
+ total_coll1_invocations = 0
96
+
97
+ coll1.find().each do |row|
98
+ values = row[:values]
99
+ if values
100
+ invocations = values[:invocations]
101
+ total_coll1_invocations += invocations
102
+ end
103
+ end
104
+
105
+ total_coll2_invocations = 0
106
+
107
+ coll2.find().each do |row|
108
+ values = row[:values]
109
+ if values
110
+ invocations = values[:invocations]
111
+ total_coll2_invocations += invocations
112
+ end
113
+ end
114
+
115
+ assert 5, total_coll1_invocations
116
+ assert 5, total_coll2_invocations
117
+ end
118
+
119
+ # Just trying to ensure Dash is sending info when requests aren't being made
120
+ def test_frequency_of_mongo_data_inserts
121
+ coll = app.db.collection('testpack-response_time')
122
+ coll.clear
123
+
124
+ 5.times do
125
+ get "/foo"
126
+ end
127
+
128
+ sleep Fiveruns::Dash.session.reporter.interval*20
129
+
130
+ assert 20 <= coll.count
131
+ end
132
+
133
+ end
@@ -0,0 +1,7 @@
1
+ # These really need to be run through the ol testers
2
+
3
+ # require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
4
+ #
5
+ # class DashExtensionsTest < Test::Unit::TestCase
6
+ #
7
+ # end
@@ -0,0 +1,27 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
2
+
3
+ class ViewTest < Test::Unit::TestCase
4
+ include Rack::Test::Methods
5
+
6
+ class MyApp < DashAnalyzer::TimeView
7
+ end
8
+
9
+ def app
10
+ MyApp.new(FooApp.new, 'testpack-response_time')
11
+ end
12
+
13
+ def test_index
14
+ get "/analytics"
15
+
16
+ assert last_response.ok?
17
+
18
+ puts last_response.body
19
+ end
20
+
21
+ def test_show
22
+ get "/analytics/show/testpack-response_time"
23
+
24
+ assert last_response.ok?
25
+ end
26
+
27
+ end
@@ -0,0 +1,7 @@
1
+ # What goes here?
2
+ #
3
+ # require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
4
+ #
5
+ # class RailsTest < Test::Unit::TestCase
6
+ #
7
+ # end
@@ -0,0 +1,7 @@
1
+ # What goes here?
2
+
3
+ # require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
4
+ #
5
+ # class DashTest < Test::Unit::TestCase
6
+ #
7
+ # end
@@ -0,0 +1,7 @@
1
+ # What goes here?
2
+
3
+ # require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
4
+ #
5
+ # class DashAnalyzerTest < Test::Unit::TestCase
6
+ #
7
+ # end
@@ -0,0 +1,7 @@
1
+ # What goes here?
2
+
3
+ # require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
4
+ #
5
+ # class MiddlewareTest < Test::Unit::TestCase
6
+ #
7
+ # end
@@ -0,0 +1,23 @@
1
+ require "rubygems" # I know...I know...don't do this
2
+
3
+ require "test/unit"
4
+ require "autotest"
5
+
6
+ require "rack/test"
7
+
8
+ require File.dirname(__FILE__) << "/../lib/abstract_analyzer"
9
+
10
+ # Create a test mongo db
11
+ test_mongo_db = Mongo::Connection.new('localhost', 27017).db('test-dash-analyzer-db')
12
+ AbstractAnalyzer.const_set("DB", test_mongo_db)
13
+
14
+ # Create a test log
15
+ test_logger = Logger.new(File.dirname(__FILE__) << "/abstract_analyzer_logger.log")
16
+ AbstractAnalyzer.const_set("LOGGER", test_logger)
17
+
18
+ # Create a test rack app
19
+ class FooApp
20
+ def call(env)
21
+ [200, {"Content-Type" => "text/plain"}, ["Hello world!"]]
22
+ end
23
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: abstract_analyzer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark McSpadden
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-10-28 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: markmcspadden@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ files:
25
+ - .gitignore
26
+ - README.rdoc
27
+ - Rakefile
28
+ - VERSION.yml
29
+ - lib/abstract_analyzer.rb
30
+ - lib/dash_analyzer.rb
31
+ - lib/dash_analyzer/base.rb
32
+ - lib/dash_analyzer/dash_extensions.rb
33
+ - lib/dash_analyzer/view.rb
34
+ - lib/middleware.rb
35
+ - lib/middleware/rails.rb
36
+ - lib/middleware/rails/dash.rb
37
+ - lib/view.rb
38
+ - test/lib/dash_analyzer/test_base.rb
39
+ - test/lib/dash_analyzer/test_dash_extensions.rb
40
+ - test/lib/dash_analyzer/test_view.rb
41
+ - test/lib/middleware/rails.rb
42
+ - test/lib/middleware/rails/dash.rb
43
+ - test/lib/test_dash_analyzer.rb
44
+ - test/lib/test_middleware.rb
45
+ - test/test_helper.rb
46
+ has_rdoc: true
47
+ homepage: http://github.com/garlandgroup/abstract-analyzer
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: A rack based app analyzer
74
+ test_files:
75
+ - test/lib/dash_analyzer/test_base.rb
76
+ - test/lib/dash_analyzer/test_dash_extensions.rb
77
+ - test/lib/dash_analyzer/test_view.rb
78
+ - test/lib/middleware/rails/dash.rb
79
+ - test/lib/middleware/rails.rb
80
+ - test/lib/test_dash_analyzer.rb
81
+ - test/lib/test_middleware.rb
82
+ - test/test_helper.rb