gentooboontoo-rack-bug 0.3.0.edge
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/.gitignore +3 -0
- data/History.txt +46 -0
- data/MIT-LICENSE.txt +19 -0
- data/README.md +120 -0
- data/Rakefile +23 -0
- data/Thorfile +113 -0
- data/lib/rack/bug/autoloading.rb +25 -0
- data/lib/rack/bug/filtered_backtrace.rb +38 -0
- data/lib/rack/bug/options.rb +89 -0
- data/lib/rack/bug/panel.rb +50 -0
- data/lib/rack/bug/panel_app.rb +33 -0
- data/lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb +18 -0
- data/lib/rack/bug/panels/active_record_panel.rb +45 -0
- data/lib/rack/bug/panels/cache_panel/dalli_extension.rb +16 -0
- data/lib/rack/bug/panels/cache_panel/memcache_extension.rb +129 -0
- data/lib/rack/bug/panels/cache_panel/panel_app.rb +48 -0
- data/lib/rack/bug/panels/cache_panel/stats.rb +97 -0
- data/lib/rack/bug/panels/cache_panel.rb +51 -0
- data/lib/rack/bug/panels/log_panel/logger_extension.rb +24 -0
- data/lib/rack/bug/panels/log_panel.rb +56 -0
- data/lib/rack/bug/panels/memory_panel.rb +27 -0
- data/lib/rack/bug/panels/mongo_panel/mongo_extension.rb +27 -0
- data/lib/rack/bug/panels/mongo_panel/stats.rb +48 -0
- data/lib/rack/bug/panels/mongo_panel.rb +44 -0
- data/lib/rack/bug/panels/rails_info_panel.rb +23 -0
- data/lib/rack/bug/panels/redis_panel/redis_extension.rb +28 -0
- data/lib/rack/bug/panels/redis_panel/stats.rb +52 -0
- data/lib/rack/bug/panels/redis_panel.rb +44 -0
- data/lib/rack/bug/panels/request_variables_panel.rb +52 -0
- data/lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb +25 -0
- data/lib/rack/bug/panels/sphinx_panel/stats.rb +96 -0
- data/lib/rack/bug/panels/sphinx_panel.rb +44 -0
- data/lib/rack/bug/panels/sql_panel/panel_app.rb +37 -0
- data/lib/rack/bug/panels/sql_panel/query.rb +63 -0
- data/lib/rack/bug/panels/sql_panel/sql_extension.rb +11 -0
- data/lib/rack/bug/panels/sql_panel.rb +55 -0
- data/lib/rack/bug/panels/templates_panel/actionview_extension.rb +12 -0
- data/lib/rack/bug/panels/templates_panel/rendering.rb +67 -0
- data/lib/rack/bug/panels/templates_panel/trace.rb +34 -0
- data/lib/rack/bug/panels/templates_panel.rb +47 -0
- data/lib/rack/bug/panels/timer_panel.rb +40 -0
- data/lib/rack/bug/params_signature.rb +63 -0
- data/lib/rack/bug/public/__rack_bug__/bookmarklet.html +10 -0
- data/lib/rack/bug/public/__rack_bug__/bookmarklet.js +217 -0
- data/lib/rack/bug/public/__rack_bug__/bug.css +220 -0
- data/lib/rack/bug/public/__rack_bug__/bug.js +84 -0
- data/lib/rack/bug/public/__rack_bug__/jquery-1.3.2.js +4376 -0
- data/lib/rack/bug/public/__rack_bug__/jquery.tablesorter.min.js +1 -0
- data/lib/rack/bug/public/__rack_bug__/spinner.gif +0 -0
- data/lib/rack/bug/rack_static_bug_avoider.rb +16 -0
- data/lib/rack/bug/redirect_interceptor.rb +27 -0
- data/lib/rack/bug/render.rb +67 -0
- data/lib/rack/bug/toolbar.rb +64 -0
- data/lib/rack/bug/views/error.html.erb +16 -0
- data/lib/rack/bug/views/panels/active_record.html.erb +17 -0
- data/lib/rack/bug/views/panels/cache.html.erb +93 -0
- data/lib/rack/bug/views/panels/execute_sql.html.erb +38 -0
- data/lib/rack/bug/views/panels/explain_sql.html.erb +38 -0
- data/lib/rack/bug/views/panels/log.html.erb +21 -0
- data/lib/rack/bug/views/panels/mongo.html.erb +32 -0
- data/lib/rack/bug/views/panels/profile_sql.html.erb +38 -0
- data/lib/rack/bug/views/panels/rails_info.html.erb +19 -0
- data/lib/rack/bug/views/panels/redis.html.erb +46 -0
- data/lib/rack/bug/views/panels/request_variables.html.erb +29 -0
- data/lib/rack/bug/views/panels/sphinx.html.erb +32 -0
- data/lib/rack/bug/views/panels/sql.html.erb +41 -0
- data/lib/rack/bug/views/panels/templates.html.erb +7 -0
- data/lib/rack/bug/views/panels/timer.html.erb +19 -0
- data/lib/rack/bug/views/panels/view_cache.html.erb +19 -0
- data/lib/rack/bug/views/redirect.html.erb +16 -0
- data/lib/rack/bug/views/toolbar.html.erb +42 -0
- data/lib/rack/bug.rb +82 -0
- data/rack-bug.gemspec +155 -0
- data/spec/custom_matchers.rb +21 -0
- data/spec/fixtures/config.ru +8 -0
- data/spec/fixtures/dummy_panel.rb +2 -0
- data/spec/fixtures/sample_app.rb +46 -0
- data/spec/rack/bug/panels/active_record_panel_spec.rb +30 -0
- data/spec/rack/bug/panels/cache_panel_spec.rb +167 -0
- data/spec/rack/bug/panels/log_panel_spec.rb +43 -0
- data/spec/rack/bug/panels/memory_panel_spec.rb +22 -0
- data/spec/rack/bug/panels/mongo_panel_spec.rb +51 -0
- data/spec/rack/bug/panels/rails_info_panel_spec.rb +40 -0
- data/spec/rack/bug/panels/redis_panel_spec.rb +69 -0
- data/spec/rack/bug/panels/sql_panel_spec.rb +146 -0
- data/spec/rack/bug/panels/templates_panel_spec.rb +71 -0
- data/spec/rack/bug/panels/timer_panel_spec.rb +38 -0
- data/spec/rack/bug_spec.rb +137 -0
- data/spec/rcov.opts +1 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +44 -0
- metadata +245 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
<h3>SQL Queries</h3>
|
2
|
+
<table class="sortable">
|
3
|
+
<thead>
|
4
|
+
<tr>
|
5
|
+
<th class="time">Time (ms)</th>
|
6
|
+
<th class="query">Query</th>
|
7
|
+
<th class="backtrace"></th>
|
8
|
+
<th class="actions"></th>
|
9
|
+
</tr>
|
10
|
+
</thead>
|
11
|
+
<tbody>
|
12
|
+
<% i = 1 %>
|
13
|
+
<% queries.each do |query| %>
|
14
|
+
<tr>
|
15
|
+
<td><%= query.human_time %></td>
|
16
|
+
<td class="syntax">
|
17
|
+
<%= query.sql %>
|
18
|
+
<div class='opts'>
|
19
|
+
<% if query.has_backtrace? %>
|
20
|
+
<a href="#" class="reveal_backtrace">Show Backtrace</a>
|
21
|
+
<% end %>
|
22
|
+
<% if query.inspectable? && query.has_backtrace? %>
|
23
|
+
|
|
24
|
+
<% end %>
|
25
|
+
<% if query.inspectable? %>
|
26
|
+
<a href="/__rack_bug__/execute_sql?<%= signed_params("query" => query.sql, "time" => query.time) %>" class="remote_call">SELECT</a> |
|
27
|
+
<a href="/__rack_bug__/explain_sql?<%= signed_params("query" => query.sql, "time" => query.time) %>" class="remote_call">EXPLAIN</a> |
|
28
|
+
<a href="/__rack_bug__/profile_sql?<%= signed_params("query" => query.sql, "time" => query.time) %>" class="remote_call">Profile</a>
|
29
|
+
<% end %>
|
30
|
+
</div>
|
31
|
+
<ul style="display:none" class='backtrace'>
|
32
|
+
<% query.filtered_backtrace.each do |line| %>
|
33
|
+
<li><%=h line %></li>
|
34
|
+
<% end %>
|
35
|
+
</ul>
|
36
|
+
</td>
|
37
|
+
</tr>
|
38
|
+
<% i += 1 %>
|
39
|
+
<% end %>
|
40
|
+
</tbody>
|
41
|
+
</table>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<h3>Resource Usage</h3>
|
2
|
+
<table class="sortable">
|
3
|
+
<thead>
|
4
|
+
<tr>
|
5
|
+
<th>Key</th>
|
6
|
+
<th>Value</th>
|
7
|
+
</tr>
|
8
|
+
</thead>
|
9
|
+
<tbody>
|
10
|
+
<% i = 1 %>
|
11
|
+
<% measurements.each do |key, val| %>
|
12
|
+
<tr>
|
13
|
+
<td><%=h key %></td>
|
14
|
+
<td><%=h val %></td>
|
15
|
+
</tr>
|
16
|
+
<% i += 1 %>
|
17
|
+
<% end %>
|
18
|
+
</tbody>
|
19
|
+
</table>
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<a class="back" href="">« Back</a>
|
2
|
+
|
3
|
+
<h3>Cache Read</h3>
|
4
|
+
|
5
|
+
<dl>
|
6
|
+
<dt>Key</dt>
|
7
|
+
<dd><pre><%=h key %></pre></dd>
|
8
|
+
|
9
|
+
<dt>Time</dt>
|
10
|
+
<dd><%=h "%.2f" % (0.0 * 1_000) %>ms</dd>
|
11
|
+
</dl>
|
12
|
+
|
13
|
+
<p>
|
14
|
+
<% if value.is_a?(String )%>
|
15
|
+
<%=h value %>
|
16
|
+
<% else %>
|
17
|
+
<%=h value.inspect %>
|
18
|
+
<% end %>
|
19
|
+
</p>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
</head>
|
4
|
+
<body>
|
5
|
+
<h1>Redirect</h1>
|
6
|
+
|
7
|
+
<p>Location: <a href="<%= redirect_to %>"><%= redirect_to %></a></p>
|
8
|
+
|
9
|
+
<p class="notice">
|
10
|
+
Rack::Bug has intercepted a redirect to the above URL for debug viewing
|
11
|
+
purposes. You can click the above link to continue with the redirect as
|
12
|
+
normal. If you'd like to disable this feature, set the Rack::Bug
|
13
|
+
<code>internal_redirects</code> option to <code>false</code>.
|
14
|
+
</p>
|
15
|
+
</body>
|
16
|
+
</html>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<script type="text/javascript" charset="utf-8">
|
2
|
+
if (typeof jQuery == 'undefined') {
|
3
|
+
var jquery_url = '/__rack_bug__/jquery-1.3.2.js';
|
4
|
+
document.write(unescape('%3Cscript src="' + jquery_url + '" type="text/javascript"%3E%3C/script%3E'));
|
5
|
+
}
|
6
|
+
</script>
|
7
|
+
<script type="text/javascript" src="/__rack_bug__/jquery.tablesorter.min.js"></script>
|
8
|
+
<script type="text/javascript" src="/__rack_bug__/bug.js"></script>
|
9
|
+
<style type="text/css" media="screen">
|
10
|
+
@import url(/__rack_bug__/bug.css);
|
11
|
+
</style>
|
12
|
+
|
13
|
+
<div id="rack_bug" class="rb_top">
|
14
|
+
<div id="rack_bug_toolbar">
|
15
|
+
<ul class="panels">
|
16
|
+
<li id="rb_debug_button">Rack::Bug</li>
|
17
|
+
|
18
|
+
<% panels.each do |panel| %>
|
19
|
+
<li>
|
20
|
+
<% if panel.has_content? %>
|
21
|
+
<a href="#" class="<%= panel.name %>">
|
22
|
+
<%= panel.heading %>
|
23
|
+
</a>
|
24
|
+
<% else %>
|
25
|
+
<%= panel.heading %>
|
26
|
+
<% end %>
|
27
|
+
</li>
|
28
|
+
<% end %>
|
29
|
+
</ul>
|
30
|
+
</div>
|
31
|
+
|
32
|
+
<% panels.each do |panel| %>
|
33
|
+
<% if panel.has_content? %>
|
34
|
+
<div class="panel_content" id="<%= panel.name %>">
|
35
|
+
<a href="" class="rack_bug_close">Close</a>
|
36
|
+
<%= panel.content %>
|
37
|
+
</div>
|
38
|
+
<% end %>
|
39
|
+
<% end %>
|
40
|
+
|
41
|
+
<div id="rack_bug_debug_window" class="panel_content"></div>
|
42
|
+
</div>
|
data/lib/rack/bug.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require "ipaddr"
|
2
|
+
require "digest"
|
3
|
+
require "rack"
|
4
|
+
require "digest/sha1"
|
5
|
+
require "rack/bug/autoloading"
|
6
|
+
|
7
|
+
class Rack::Bug
|
8
|
+
include Options
|
9
|
+
|
10
|
+
VERSION = "0.3.0"
|
11
|
+
|
12
|
+
class SecurityError < StandardError
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.enable
|
16
|
+
Thread.current["rack-bug.enabled"] = true
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.disable
|
20
|
+
Thread.current["rack-bug.enabled"] = false
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.enabled?
|
24
|
+
Thread.current["rack-bug.enabled"] == true
|
25
|
+
end
|
26
|
+
|
27
|
+
def initialize(app, options = {}, &block)
|
28
|
+
@app = asset_server(app)
|
29
|
+
initialize_options options
|
30
|
+
instance_eval(&block) if block_given?
|
31
|
+
|
32
|
+
@toolbar = Toolbar.new(RedirectInterceptor.new(@app))
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
def call(env)
|
37
|
+
env.replace @default_options.merge(env)
|
38
|
+
@env = env
|
39
|
+
@original_request = Rack::Request.new(@env)
|
40
|
+
|
41
|
+
if toolbar_requested? && ip_authorized? && password_authorized? && toolbar_xhr?
|
42
|
+
@toolbar.call(env)
|
43
|
+
else
|
44
|
+
@app.call(env)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def toolbar_xhr?
|
51
|
+
!@original_request.xhr? || @original_request.path =~ /^\/__rack_bug__/
|
52
|
+
end
|
53
|
+
|
54
|
+
def asset_server(app)
|
55
|
+
RackStaticBugAvoider.new(app, Rack::Static.new(app, :urls => ["/__rack_bug__"], :root => public_path))
|
56
|
+
end
|
57
|
+
|
58
|
+
def public_path
|
59
|
+
::File.expand_path(::File.dirname(__FILE__) + "/bug/public")
|
60
|
+
end
|
61
|
+
|
62
|
+
def toolbar_requested?
|
63
|
+
@original_request.cookies["rack_bug_enabled"]
|
64
|
+
end
|
65
|
+
|
66
|
+
def ip_authorized?
|
67
|
+
return true unless options["rack-bug.ip_masks"]
|
68
|
+
|
69
|
+
options["rack-bug.ip_masks"].any? do |ip_mask|
|
70
|
+
ip_mask.include?(IPAddr.new(@original_request.ip))
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def password_authorized?
|
75
|
+
return true unless options["rack-bug.password"]
|
76
|
+
|
77
|
+
expected_sha = Digest::SHA1.hexdigest ["rack_bug", options["rack-bug.password"]].join(":")
|
78
|
+
actual_sha = @original_request.cookies["rack_bug_password"]
|
79
|
+
|
80
|
+
actual_sha == expected_sha
|
81
|
+
end
|
82
|
+
end
|
data/rack-bug.gemspec
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{gentooboontoo-rack-bug}
|
5
|
+
s.version = "0.3.0.edge"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Bryan Helmkamp"]
|
9
|
+
s.date = %q{2012-02-15}
|
10
|
+
s.email = %q{bryan@brynary.com}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"README.md",
|
13
|
+
"MIT-LICENSE.txt"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".gitignore",
|
17
|
+
"History.txt",
|
18
|
+
"MIT-LICENSE.txt",
|
19
|
+
"README.md",
|
20
|
+
"Rakefile",
|
21
|
+
"Thorfile",
|
22
|
+
"lib/rack/bug.rb",
|
23
|
+
"lib/rack/bug/autoloading.rb",
|
24
|
+
"lib/rack/bug/filtered_backtrace.rb",
|
25
|
+
"lib/rack/bug/options.rb",
|
26
|
+
"lib/rack/bug/panel.rb",
|
27
|
+
"lib/rack/bug/panel_app.rb",
|
28
|
+
"lib/rack/bug/panels/active_record_panel.rb",
|
29
|
+
"lib/rack/bug/panels/active_record_panel/activerecord_extensions.rb",
|
30
|
+
"lib/rack/bug/panels/cache_panel.rb",
|
31
|
+
"lib/rack/bug/panels/cache_panel/dalli_extension.rb",
|
32
|
+
"lib/rack/bug/panels/cache_panel/memcache_extension.rb",
|
33
|
+
"lib/rack/bug/panels/cache_panel/panel_app.rb",
|
34
|
+
"lib/rack/bug/panels/cache_panel/stats.rb",
|
35
|
+
"lib/rack/bug/panels/log_panel.rb",
|
36
|
+
"lib/rack/bug/panels/log_panel/logger_extension.rb",
|
37
|
+
"lib/rack/bug/panels/memory_panel.rb",
|
38
|
+
"lib/rack/bug/panels/mongo_panel.rb",
|
39
|
+
"lib/rack/bug/panels/mongo_panel/mongo_extension.rb",
|
40
|
+
"lib/rack/bug/panels/mongo_panel/stats.rb",
|
41
|
+
"lib/rack/bug/panels/rails_info_panel.rb",
|
42
|
+
"lib/rack/bug/panels/redis_panel.rb",
|
43
|
+
"lib/rack/bug/panels/redis_panel/redis_extension.rb",
|
44
|
+
"lib/rack/bug/panels/redis_panel/stats.rb",
|
45
|
+
"lib/rack/bug/panels/request_variables_panel.rb",
|
46
|
+
"lib/rack/bug/panels/sphinx_panel.rb",
|
47
|
+
"lib/rack/bug/panels/sphinx_panel/sphinx_extension.rb",
|
48
|
+
"lib/rack/bug/panels/sphinx_panel/stats.rb",
|
49
|
+
"lib/rack/bug/panels/sql_panel.rb",
|
50
|
+
"lib/rack/bug/panels/sql_panel/panel_app.rb",
|
51
|
+
"lib/rack/bug/panels/sql_panel/query.rb",
|
52
|
+
"lib/rack/bug/panels/sql_panel/sql_extension.rb",
|
53
|
+
"lib/rack/bug/panels/templates_panel.rb",
|
54
|
+
"lib/rack/bug/panels/templates_panel/actionview_extension.rb",
|
55
|
+
"lib/rack/bug/panels/templates_panel/rendering.rb",
|
56
|
+
"lib/rack/bug/panels/templates_panel/trace.rb",
|
57
|
+
"lib/rack/bug/panels/timer_panel.rb",
|
58
|
+
"lib/rack/bug/params_signature.rb",
|
59
|
+
"lib/rack/bug/public/__rack_bug__/bookmarklet.html",
|
60
|
+
"lib/rack/bug/public/__rack_bug__/bookmarklet.js",
|
61
|
+
"lib/rack/bug/public/__rack_bug__/bug.css",
|
62
|
+
"lib/rack/bug/public/__rack_bug__/bug.js",
|
63
|
+
"lib/rack/bug/public/__rack_bug__/jquery-1.3.2.js",
|
64
|
+
"lib/rack/bug/public/__rack_bug__/jquery.tablesorter.min.js",
|
65
|
+
"lib/rack/bug/public/__rack_bug__/spinner.gif",
|
66
|
+
"lib/rack/bug/rack_static_bug_avoider.rb",
|
67
|
+
"lib/rack/bug/redirect_interceptor.rb",
|
68
|
+
"lib/rack/bug/render.rb",
|
69
|
+
"lib/rack/bug/toolbar.rb",
|
70
|
+
"lib/rack/bug/views/error.html.erb",
|
71
|
+
"lib/rack/bug/views/panels/active_record.html.erb",
|
72
|
+
"lib/rack/bug/views/panels/cache.html.erb",
|
73
|
+
"lib/rack/bug/views/panels/execute_sql.html.erb",
|
74
|
+
"lib/rack/bug/views/panels/explain_sql.html.erb",
|
75
|
+
"lib/rack/bug/views/panels/log.html.erb",
|
76
|
+
"lib/rack/bug/views/panels/mongo.html.erb",
|
77
|
+
"lib/rack/bug/views/panels/profile_sql.html.erb",
|
78
|
+
"lib/rack/bug/views/panels/rails_info.html.erb",
|
79
|
+
"lib/rack/bug/views/panels/redis.html.erb",
|
80
|
+
"lib/rack/bug/views/panels/request_variables.html.erb",
|
81
|
+
"lib/rack/bug/views/panels/sphinx.html.erb",
|
82
|
+
"lib/rack/bug/views/panels/sql.html.erb",
|
83
|
+
"lib/rack/bug/views/panels/templates.html.erb",
|
84
|
+
"lib/rack/bug/views/panels/timer.html.erb",
|
85
|
+
"lib/rack/bug/views/panels/view_cache.html.erb",
|
86
|
+
"lib/rack/bug/views/redirect.html.erb",
|
87
|
+
"lib/rack/bug/views/toolbar.html.erb",
|
88
|
+
"rack-bug.gemspec",
|
89
|
+
"spec/custom_matchers.rb",
|
90
|
+
"spec/fixtures/config.ru",
|
91
|
+
"spec/fixtures/dummy_panel.rb",
|
92
|
+
"spec/fixtures/sample_app.rb",
|
93
|
+
"spec/rack/bug/panels/active_record_panel_spec.rb",
|
94
|
+
"spec/rack/bug/panels/cache_panel_spec.rb",
|
95
|
+
"spec/rack/bug/panels/log_panel_spec.rb",
|
96
|
+
"spec/rack/bug/panels/memory_panel_spec.rb",
|
97
|
+
"spec/rack/bug/panels/mongo_panel_spec.rb",
|
98
|
+
"spec/rack/bug/panels/rails_info_panel_spec.rb",
|
99
|
+
"spec/rack/bug/panels/redis_panel_spec.rb",
|
100
|
+
"spec/rack/bug/panels/sql_panel_spec.rb",
|
101
|
+
"spec/rack/bug/panels/templates_panel_spec.rb",
|
102
|
+
"spec/rack/bug/panels/timer_panel_spec.rb",
|
103
|
+
"spec/rack/bug_spec.rb",
|
104
|
+
"spec/rcov.opts",
|
105
|
+
"spec/spec.opts",
|
106
|
+
"spec/spec_helper.rb"
|
107
|
+
]
|
108
|
+
s.homepage = %q{http://github.com/brynary/rack-bug}
|
109
|
+
s.require_paths = ["lib"]
|
110
|
+
s.rubyforge_project = %q{rack-bug}
|
111
|
+
s.rubygems_version = %q{1.3.7}
|
112
|
+
s.summary = %q{Debugging toolbar for Rack applications implemented as middleware}
|
113
|
+
s.test_files = [
|
114
|
+
"spec/custom_matchers.rb",
|
115
|
+
"spec/fixtures/dummy_panel.rb",
|
116
|
+
"spec/fixtures/sample_app.rb",
|
117
|
+
"spec/rack/bug/panels/active_record_panel_spec.rb",
|
118
|
+
"spec/rack/bug/panels/cache_panel_spec.rb",
|
119
|
+
"spec/rack/bug/panels/log_panel_spec.rb",
|
120
|
+
"spec/rack/bug/panels/memory_panel_spec.rb",
|
121
|
+
"spec/rack/bug/panels/mongo_panel_spec.rb",
|
122
|
+
"spec/rack/bug/panels/rails_info_panel_spec.rb",
|
123
|
+
"spec/rack/bug/panels/redis_panel_spec.rb",
|
124
|
+
"spec/rack/bug/panels/sql_panel_spec.rb",
|
125
|
+
"spec/rack/bug/panels/templates_panel_spec.rb",
|
126
|
+
"spec/rack/bug/panels/timer_panel_spec.rb",
|
127
|
+
"spec/rack/bug_spec.rb",
|
128
|
+
"spec/spec_helper.rb"
|
129
|
+
]
|
130
|
+
|
131
|
+
if s.respond_to? :specification_version then
|
132
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
133
|
+
s.specification_version = 3
|
134
|
+
|
135
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
136
|
+
s.add_runtime_dependency(%q<rack>, [">= 1.0"])
|
137
|
+
s.add_development_dependency(%q<webrat>, [">= 0"])
|
138
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
139
|
+
s.add_development_dependency(%q<sinatra>, [">= 0"])
|
140
|
+
s.add_development_dependency(%q<git>, [">= 0"])
|
141
|
+
else
|
142
|
+
s.add_dependency(%q<rack>, [">= 1.0"])
|
143
|
+
s.add_dependency(%q<webrat>, [">= 0"])
|
144
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
145
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
146
|
+
s.add_dependency(%q<git>, [">= 0"])
|
147
|
+
end
|
148
|
+
else
|
149
|
+
s.add_dependency(%q<rack>, [">= 1.0"])
|
150
|
+
s.add_dependency(%q<webrat>, [">= 0"])
|
151
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
152
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
153
|
+
s.add_dependency(%q<git>, [">= 0"])
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CustomMatchers
|
2
|
+
def have_row(container, key, value = nil)
|
3
|
+
simple_matcher("contain row") do |response|
|
4
|
+
if value
|
5
|
+
response.should have_selector("#{container} tr", :content => key) do |row|
|
6
|
+
row.should contain(value)
|
7
|
+
end
|
8
|
+
else
|
9
|
+
response.should have_selector("#{container} tr", :content => key)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def have_heading(text)
|
15
|
+
simple_matcher("have heading") do |response|
|
16
|
+
response.should have_selector("#rack_bug_toolbar li") do |heading|
|
17
|
+
heading.should contain(text)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../../lib'
|
2
|
+
require "rack/bug"
|
3
|
+
|
4
|
+
require "sinatra/base"
|
5
|
+
require 'logger'
|
6
|
+
|
7
|
+
RAILS_ENV = "development" unless defined?(RAILS_ENV)
|
8
|
+
log_to = RAILS_ENV == "test" ? StringIO.new : STDOUT
|
9
|
+
LOGGER = Logger.new(log_to)
|
10
|
+
|
11
|
+
class SampleApp < Sinatra::Base
|
12
|
+
use Rack::Bug#, :intercept_redirects => true, :password => 'secret'
|
13
|
+
set :environment, 'test'
|
14
|
+
|
15
|
+
configure :test do
|
16
|
+
set :raise_errors, true
|
17
|
+
end
|
18
|
+
|
19
|
+
get "/redirect" do
|
20
|
+
redirect "/"
|
21
|
+
end
|
22
|
+
|
23
|
+
get "/error" do
|
24
|
+
raise "Error!"
|
25
|
+
end
|
26
|
+
|
27
|
+
get "/" do
|
28
|
+
if params[:content_type]
|
29
|
+
headers["Content-Type"] = params[:content_type]
|
30
|
+
end
|
31
|
+
LOGGER.error "I am a log message"
|
32
|
+
<<-HTML
|
33
|
+
<html>
|
34
|
+
<head>
|
35
|
+
</head>
|
36
|
+
<body>
|
37
|
+
<p>Hello</p>
|
38
|
+
<p><a href="__rack_bug__/bookmarklet.html">Page with bookmarklet for enabling Rack::Bug</a></p>
|
39
|
+
<p><a href="/redirect">Page with a redirect - turn on intercept_redirects to see Rack::Bug catch it</a></p>
|
40
|
+
<p><a href="/error">Page with an error to check rack-bug not rescuing errors</a></p>
|
41
|
+
</body>
|
42
|
+
</html>
|
43
|
+
HTML
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
class Rack::Bug
|
4
|
+
describe ActiveRecordPanel do
|
5
|
+
before do
|
6
|
+
ActiveRecordPanel.reset
|
7
|
+
rack_env "rack-bug.panel_classes", [ActiveRecordPanel]
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "heading" do
|
11
|
+
it "displays the total number of instantiated AR objects" do
|
12
|
+
ActiveRecordPanel.record("User")
|
13
|
+
ActiveRecordPanel.record("Group")
|
14
|
+
response = get_via_rack "/"
|
15
|
+
response.should have_heading("2 AR Objects")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "content" do
|
20
|
+
it "displays the count of instantiated objects for each class" do
|
21
|
+
ActiveRecordPanel.record("User")
|
22
|
+
ActiveRecordPanel.record("User")
|
23
|
+
ActiveRecordPanel.record("Group")
|
24
|
+
response = get_via_rack "/"
|
25
|
+
response.should have_row("#active_record", "User", "2")
|
26
|
+
response.should have_row("#active_record", "Group", "1")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../../spec_helper')
|
2
|
+
|
3
|
+
class Rack::Bug
|
4
|
+
describe CachePanel do
|
5
|
+
before do
|
6
|
+
CachePanel.reset
|
7
|
+
rack_env "rack-bug.panel_classes", [CachePanel]
|
8
|
+
unless defined?(Rails)
|
9
|
+
@added_rails = true
|
10
|
+
Object.const_set :Rails, Module.new
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
after do
|
15
|
+
Object.send :remove_const, :Rails if @added_rails
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "heading" do
|
19
|
+
it "displays the total memcache time" do
|
20
|
+
response = get_via_rack "/"
|
21
|
+
response.should have_heading("Cache: 0.00ms")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "content" do
|
26
|
+
describe "usage table" do
|
27
|
+
it "displays the total number of memcache calls" do
|
28
|
+
CachePanel.record(:get, "user:1") { }
|
29
|
+
response = get_via_rack "/"
|
30
|
+
|
31
|
+
# This causes a bus error:
|
32
|
+
# response.should have_selector("th:content('Total Calls') + td", :content => "1")
|
33
|
+
|
34
|
+
response.should have_row("#cache_usage", "Total Calls", "1")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "displays the total memcache time" do
|
38
|
+
response = get_via_rack "/"
|
39
|
+
response.should have_row("#cache_usage", "Total Time", "0.00ms")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "dispays the number of memcache hits" do
|
43
|
+
CachePanel.record(:get, "user:1") { }
|
44
|
+
response = get_via_rack "/"
|
45
|
+
response.should have_row("#cache_usage", "Hits", "0")
|
46
|
+
end
|
47
|
+
|
48
|
+
it "displays the number of memcache misses" do
|
49
|
+
CachePanel.record(:get, "user:1") { }
|
50
|
+
response = get_via_rack "/"
|
51
|
+
response.should have_row("#cache_usage", "Misses", "1")
|
52
|
+
end
|
53
|
+
|
54
|
+
it "displays the number of memcache gets" do
|
55
|
+
CachePanel.record(:get, "user:1") { }
|
56
|
+
response = get_via_rack "/"
|
57
|
+
response.should have_row("#cache_usage", "gets", "1")
|
58
|
+
end
|
59
|
+
|
60
|
+
it "displays the number of memcache sets" do
|
61
|
+
CachePanel.record(:set, "user:1") { }
|
62
|
+
response = get_via_rack "/"
|
63
|
+
response.should have_row("#cache_usage", "sets", "1")
|
64
|
+
end
|
65
|
+
|
66
|
+
it "displays the number of memcache deletes" do
|
67
|
+
CachePanel.record(:delete, "user:1") { }
|
68
|
+
response = get_via_rack "/"
|
69
|
+
response.should have_row("#cache_usage", "deletes", "1")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "displays the number of memcache get_multis" do
|
73
|
+
CachePanel.record(:get_multi, "user:1", "user:2") { }
|
74
|
+
response = get_via_rack "/"
|
75
|
+
response.should have_row("#cache_usage", "get_multis", "1")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "breakdown" do
|
80
|
+
it "displays each memcache operation" do
|
81
|
+
CachePanel.record(:get, "user:1") { }
|
82
|
+
response = get_via_rack "/"
|
83
|
+
response.should have_row("#cache_breakdown", "get")
|
84
|
+
end
|
85
|
+
|
86
|
+
it "displays the time for each memcache call" do
|
87
|
+
CachePanel.record(:get, "user:1") { }
|
88
|
+
response = get_via_rack "/"
|
89
|
+
response.should have_row("#cache_breakdown", "user:1", TIME_MS_REGEXP)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "displays the keys for each memcache call" do
|
93
|
+
CachePanel.record(:get, "user:1") { }
|
94
|
+
response = get_via_rack "/"
|
95
|
+
response.should have_row("#cache_breakdown", "user:1", "get")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "expire_all" do
|
101
|
+
before do
|
102
|
+
rack_env "rack-bug.secret_key", 'abc'
|
103
|
+
end
|
104
|
+
|
105
|
+
it "expires the cache keys" do
|
106
|
+
Rails.stub!(:cache => mock("cache"))
|
107
|
+
Rails.cache.should_receive(:delete).with("user:1")
|
108
|
+
Rails.cache.should_receive(:delete).with("user:2")
|
109
|
+
Rails.cache.should_receive(:delete).with("user:3")
|
110
|
+
Rails.cache.should_receive(:delete).with("user:4")
|
111
|
+
|
112
|
+
get_via_rack "/__rack_bug__/delete_cache_list",
|
113
|
+
:keys_1 => "user:1", :keys_2 => "user:2", :keys_3 => "user:3", :keys_4 => "user:4",
|
114
|
+
:hash => "c367b76e0199c308862a3afd8fba32b8715e7976"
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns OK" do
|
118
|
+
Rails.stub!(:cache => mock("cache", :delete => nil))
|
119
|
+
response = get_via_rack "/__rack_bug__/delete_cache_list",
|
120
|
+
:keys_1 => "user:1", :keys_2 => "user:2", :keys_3 => "user:3", :keys_4 => "user:4",
|
121
|
+
:hash => "c367b76e0199c308862a3afd8fba32b8715e7976"
|
122
|
+
response.should contain("OK")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "expire" do
|
127
|
+
before do
|
128
|
+
rack_env "rack-bug.secret_key", 'abc'
|
129
|
+
end
|
130
|
+
|
131
|
+
it "expires the cache key" do
|
132
|
+
Rails.stub!(:cache => mock("cache"))
|
133
|
+
Rails.cache.should_receive(:delete).with("user:1")
|
134
|
+
get_via_rack "/__rack_bug__/delete_cache", :key => "user:1",
|
135
|
+
:hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
|
136
|
+
end
|
137
|
+
|
138
|
+
it "returns OK" do
|
139
|
+
Rails.stub!(:cache => mock("cache", :delete => nil))
|
140
|
+
response = get_via_rack "/__rack_bug__/delete_cache", :key => "user:1",
|
141
|
+
:hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
|
142
|
+
response.should contain("OK")
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "view_cache" do
|
147
|
+
before do
|
148
|
+
rack_env "rack-bug.secret_key", 'abc'
|
149
|
+
end
|
150
|
+
|
151
|
+
it "renders the cache key" do
|
152
|
+
Rails.stub!(:cache => mock("cache", :read => "cache body"))
|
153
|
+
response = get_via_rack "/__rack_bug__/view_cache", :key => "user:1",
|
154
|
+
:hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
|
155
|
+
response.should contain("cache body")
|
156
|
+
end
|
157
|
+
|
158
|
+
it "renders non-String cache values properly" do
|
159
|
+
Rails.stub!(:cache => mock("cache", :read => [1, 2]))
|
160
|
+
response = get_via_rack "/__rack_bug__/view_cache", :key => "user:1",
|
161
|
+
:hash => "f87215442d312d8e42cf51e6b66fc3eb3d59ac74"
|
162
|
+
response.should contain("[1, 2]")
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|