rack-perftools_profiler 0.4.1 → 0.5.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/README.rdoc +14 -3
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/lib/rack/perftools_profiler/action.rb +14 -10
- data/lib/rack/perftools_profiler/profile_data_action.rb +1 -1
- data/lib/rack/perftools_profiler/profile_once.rb +3 -1
- data/lib/rack/perftools_profiler/profiler.rb +23 -12
- data/lib/rack/perftools_profiler/profiler_middleware.rb +6 -3
- data/lib/rack/perftools_profiler/return_password_error.rb +14 -0
- data/lib/rack/perftools_profiler.rb +1 -0
- data/rack-perftools_profiler-0.4.1.gem +0 -0
- data/rack-perftools_profiler.gemspec +31 -38
- data/test/multiple_request_profiling_test.rb +18 -3
- data/test/single_request_profiling_test.rb +34 -5
- metadata +31 -15
- data/.gitignore +0 -6
data/README.rdoc
CHANGED
|
@@ -54,11 +54,12 @@ For Rack::Builder, call 'use' inside the Builder constructor block
|
|
|
54
54
|
|
|
55
55
|
== Options
|
|
56
56
|
|
|
57
|
-
* :default_printer - can be set to 'text', 'gif', or 'pdf'. Default is
|
|
57
|
+
* :default_printer - can be set to 'text', 'gif', or 'pdf'. Default is 'text'.
|
|
58
58
|
* :mode - can be set to 'cputime', 'methods', 'objects', 'walltime'. Default is :cputime. See the 'Profiling Modes' section below.
|
|
59
|
-
* :frequency - in :cputime mode, the number of times per second the app will be sampled. Default is 100 (times/sec)
|
|
60
|
-
* :bundler - run the profiler binary using 'bundle' if set to true. Default is false
|
|
59
|
+
* :frequency - in :cputime mode, the number of times per second the app will be sampled. Default is 100 (times/sec).
|
|
60
|
+
* :bundler - run the profiler binary using 'bundle' if set to true. Default is false.
|
|
61
61
|
* :gemfile_dir - directory with Gemfile. Default is the current directory.
|
|
62
|
+
* :password - password-protect profiling.
|
|
62
63
|
|
|
63
64
|
== Usage
|
|
64
65
|
|
|
@@ -139,6 +140,16 @@ When profiling using multiple requests, add the option when visiting \_\_start\_
|
|
|
139
140
|
|
|
140
141
|
If the 'mode' option is omitted, the middleware will default to the mode specified at configuration.
|
|
141
142
|
|
|
143
|
+
== Profiling in production
|
|
144
|
+
|
|
145
|
+
It is recommended that you always profile your application in the 'production' environment (using `rails server -e production` or an equivalent), since there can be important differences between 'development' and 'production' that may affect performance.
|
|
146
|
+
|
|
147
|
+
However, it is recommended that you profile your application on a development or staging machine rather than on a production machine. This is because profiling with multiple requests *will not* work if your app is running in multiple Ruby server processes.
|
|
148
|
+
|
|
149
|
+
Profiling a single request will work if there are multiple server processes. If your staging machine is publicly accessible, you can password-protect single-request profiling by using the `:password` option and then using the `profile` GET parameter to provide the password:
|
|
150
|
+
|
|
151
|
+
curl http://localhost:3000/foobar?profile=PASSWORD
|
|
152
|
+
|
|
142
153
|
== Changing behavior with environment variables
|
|
143
154
|
|
|
144
155
|
The mode and frequency settings are enabled by setting environment variables. Some of these environment variables must be set before 'perftools' is required. If you only require 'rack/perftools_profiler', it will do the right thing (require 'perftools' after setting the environment variables).
|
data/Rakefile
CHANGED
|
@@ -10,7 +10,7 @@ begin
|
|
|
10
10
|
gem.email = 'ben@bbrinck.com'
|
|
11
11
|
gem.homepage = 'http://github.com/bhb/rack-perftools_profiler'
|
|
12
12
|
gem.authors = ['Ben Brinckerhoff']
|
|
13
|
-
gem.add_dependency 'perftools.rb', '~> 0.5'
|
|
13
|
+
gem.add_dependency 'perftools.rb', '~> 0.5.6'
|
|
14
14
|
gem.add_dependency 'rack', '~> 1.0'
|
|
15
15
|
gem.add_dependency('open4', '~> 1.0')
|
|
16
16
|
gem.add_development_dependency 'rack', '~> 1.1'
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.5.0
|
|
@@ -17,18 +17,22 @@ module Rack::PerftoolsProfiler
|
|
|
17
17
|
def self.for_env(env, profiler, middleware)
|
|
18
18
|
request = Rack::Request.new(env)
|
|
19
19
|
klass =
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
StartProfiling
|
|
23
|
-
when %r{/__stop__$}
|
|
24
|
-
StopProfiling
|
|
25
|
-
when %r{/__data__$}
|
|
26
|
-
ReturnData
|
|
20
|
+
if !profiler.password_valid?(request.GET['profile'])
|
|
21
|
+
ReturnPasswordError
|
|
27
22
|
else
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
case request.path_info
|
|
24
|
+
when %r{/__start__$}
|
|
25
|
+
StartProfiling
|
|
26
|
+
when %r{/__stop__$}
|
|
27
|
+
StopProfiling
|
|
28
|
+
when %r{/__data__$}
|
|
29
|
+
ReturnData
|
|
30
30
|
else
|
|
31
|
-
|
|
31
|
+
if ProfileOnce.has_special_param?(request)
|
|
32
|
+
ProfileOnce
|
|
33
|
+
else
|
|
34
|
+
CallAppDirectly
|
|
35
|
+
end
|
|
32
36
|
end
|
|
33
37
|
end
|
|
34
38
|
klass.new(env, profiler, middleware)
|
|
@@ -9,7 +9,7 @@ module Rack::PerftoolsProfiler
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def self.check_printer(printer, env=nil)
|
|
12
|
-
if printer != nil && !ProfilerMiddleware::PRINTERS.member?(printer.to_sym)
|
|
12
|
+
if printer != nil && printer != '' && !ProfilerMiddleware::PRINTERS.member?(printer.to_sym)
|
|
13
13
|
message = "Invalid printer type: #{printer}. Valid printer values are #{ProfilerMiddleware::PRINTERS.join(", ")}"
|
|
14
14
|
raise ProfilerArgumentError, message
|
|
15
15
|
end
|
|
@@ -34,7 +34,9 @@ module Rack::PerftoolsProfiler
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def delete_custom_params(env)
|
|
37
|
-
|
|
37
|
+
# I used to clone the env, but it broke any apps that used Warden
|
|
38
|
+
# ex) new_env = env.clone
|
|
39
|
+
new_env = env
|
|
38
40
|
|
|
39
41
|
get_params = Rack::Request.new(new_env).GET
|
|
40
42
|
get_params.delete('profile')
|
|
@@ -32,8 +32,9 @@ module Rack::PerftoolsProfiler
|
|
|
32
32
|
@printer = (options.delete(:default_printer) { DEFAULT_PRINTER }).to_sym
|
|
33
33
|
@frequency = (options.delete(:frequency) { UNSET_FREQUENCY }).to_s
|
|
34
34
|
@mode = (options.delete(:mode) { DEFAULT_MODE }).to_sym
|
|
35
|
-
@bundler =
|
|
36
|
-
@gemfile_dir =
|
|
35
|
+
@bundler = options.delete(:bundler) { false }
|
|
36
|
+
@gemfile_dir = options.delete(:gemfile_dir) { DEFAULT_GEMFILE_DIR }
|
|
37
|
+
@password = options.delete(:password) { nil }
|
|
37
38
|
@mode_for_request = nil
|
|
38
39
|
ProfileDataAction.check_printer(@printer)
|
|
39
40
|
ensure_mode_is_valid(@mode)
|
|
@@ -53,6 +54,10 @@ module Rack::PerftoolsProfiler
|
|
|
53
54
|
def self.clear_data
|
|
54
55
|
::File.delete(PROFILING_DATA_FILE) if ::File.exists?(PROFILING_DATA_FILE)
|
|
55
56
|
end
|
|
57
|
+
|
|
58
|
+
def password_valid?(password)
|
|
59
|
+
@password.nil? || password == @password
|
|
60
|
+
end
|
|
56
61
|
|
|
57
62
|
def start(mode = nil)
|
|
58
63
|
ensure_mode_is_changeable(mode) if mode
|
|
@@ -84,17 +89,23 @@ module Rack::PerftoolsProfiler
|
|
|
84
89
|
printer = (options.fetch('printer') {@printer}).to_sym
|
|
85
90
|
ignore = options.fetch('ignore') { nil }
|
|
86
91
|
focus = options.fetch('focus') { nil }
|
|
92
|
+
nodecount = options.fetch('nodecount') { nil }
|
|
93
|
+
nodefraction = options.fetch('nodefraction') { nil }
|
|
87
94
|
if ::File.exists?(PROFILING_DATA_FILE)
|
|
88
|
-
args = "--#{printer}"
|
|
89
|
-
args
|
|
90
|
-
args
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
args = ["--#{printer}"]
|
|
96
|
+
args << "--ignore=#{ignore}" if ignore
|
|
97
|
+
args << "--focus=#{focus}" if focus
|
|
98
|
+
args << "--nodecount=#{nodecount}" if nodecount
|
|
99
|
+
args << "--nodefraction=#{nodefraction}" if nodefraction
|
|
100
|
+
args << PROFILING_DATA_FILE
|
|
101
|
+
cmd = ["pprof.rb"] + args
|
|
102
|
+
cmd = ["bundle", "exec"] + cmd if @bundler
|
|
103
|
+
|
|
104
|
+
stdout, stderr, status = Dir.chdir(@gemfile_dir) { run(*cmd) }
|
|
94
105
|
if status!=0
|
|
95
|
-
raise ProfilingError.new("Running the command '#{cmd}' exited with status #{status}", stderr)
|
|
106
|
+
raise ProfilingError.new("Running the command '#{cmd.join(" ")}' exited with status #{status}", stderr)
|
|
96
107
|
elsif stdout.length == 0 && stderr.length > 0
|
|
97
|
-
raise ProfilingError.new("Running the command '#{cmd}' failed to generate a file", stderr)
|
|
108
|
+
raise ProfilingError.new("Running the command '#{cmd.join(" ")}' failed to generate a file", stderr)
|
|
98
109
|
else
|
|
99
110
|
[printer, stdout]
|
|
100
111
|
end
|
|
@@ -105,10 +116,10 @@ module Rack::PerftoolsProfiler
|
|
|
105
116
|
|
|
106
117
|
private
|
|
107
118
|
|
|
108
|
-
def run(command)
|
|
119
|
+
def run(*command)
|
|
109
120
|
out = err = ""
|
|
110
121
|
pid = nil
|
|
111
|
-
status = Open4.popen4(command) do |pid, stdin, stdout, stderr|
|
|
122
|
+
status = Open4.popen4(*command) do |pid, stdin, stdout, stderr|
|
|
112
123
|
stdin.close
|
|
113
124
|
pid = pid
|
|
114
125
|
out = stdout.read
|
|
@@ -9,7 +9,8 @@ module Rack::PerftoolsProfiler
|
|
|
9
9
|
:text => 'text/plain',
|
|
10
10
|
:gif => 'image/gif',
|
|
11
11
|
:pdf => 'application/pdf',
|
|
12
|
-
:callgrind => 'text/plain'
|
|
12
|
+
:callgrind => 'text/plain',
|
|
13
|
+
:raw => 'application/octet-stream'
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
PRINTERS = PRINTER_CONTENT_TYPE.keys
|
|
@@ -20,7 +21,9 @@ module Rack::PerftoolsProfiler
|
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
def call(env)
|
|
23
|
-
|
|
24
|
+
# I used to clone the env, but it broke any apps that used Warden
|
|
25
|
+
# ex) @env = env.clone
|
|
26
|
+
@env = env
|
|
24
27
|
action = Action.for_env(@env, @profiler, self)
|
|
25
28
|
action.act
|
|
26
29
|
action.response
|
|
@@ -58,7 +61,7 @@ module Rack::PerftoolsProfiler
|
|
|
58
61
|
'Content-Type' => PRINTER_CONTENT_TYPE[printer],
|
|
59
62
|
'Content-Length' => content_length(body)
|
|
60
63
|
}
|
|
61
|
-
if printer==:
|
|
64
|
+
if printer ==:raw
|
|
62
65
|
filetype = printer
|
|
63
66
|
filename='profile_data'
|
|
64
67
|
headers['Content-Disposition'] = %(attachment; filename="#{filename}.#{filetype}")
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Rack::PerftoolsProfiler
|
|
2
|
+
|
|
3
|
+
class ReturnPasswordError < Action
|
|
4
|
+
include Rack::PerftoolsProfiler::Utils
|
|
5
|
+
|
|
6
|
+
def response
|
|
7
|
+
[401,
|
|
8
|
+
{'Content-Type' => 'text/plain'},
|
|
9
|
+
["Profiling is password-protected. Password is incorrect.\nProvide a password using the 'profile' GET param:\nhttp://domain.com/foobar?profile=PASSWORD"]]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -12,6 +12,7 @@ require 'rack/perftools_profiler/profile_data_action'
|
|
|
12
12
|
require 'rack/perftools_profiler/profile_once'
|
|
13
13
|
require 'rack/perftools_profiler/return_data'
|
|
14
14
|
require 'rack/perftools_profiler/call_app_directly'
|
|
15
|
+
require 'rack/perftools_profiler/return_password_error'
|
|
15
16
|
|
|
16
17
|
module Rack::PerftoolsProfiler
|
|
17
18
|
|
|
Binary file
|
|
@@ -1,70 +1,63 @@
|
|
|
1
1
|
# Generated by jeweler
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
|
4
4
|
# -*- encoding: utf-8 -*-
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |s|
|
|
7
7
|
s.name = %q{rack-perftools_profiler}
|
|
8
|
-
s.version = "0.
|
|
8
|
+
s.version = "0.5.0"
|
|
9
9
|
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
11
|
s.authors = ["Ben Brinckerhoff"]
|
|
12
|
-
s.date = %q{2011-
|
|
12
|
+
s.date = %q{2011-07-25}
|
|
13
13
|
s.description = %q{Middleware for profiling Rack-compatible apps using perftools.rb}
|
|
14
14
|
s.email = %q{ben@bbrinck.com}
|
|
15
15
|
s.extra_rdoc_files = [
|
|
16
16
|
"LICENSE",
|
|
17
|
-
|
|
17
|
+
"README.rdoc"
|
|
18
18
|
]
|
|
19
19
|
s.files = [
|
|
20
20
|
".document",
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"README.rdoc",
|
|
23
|
+
"Rakefile",
|
|
24
|
+
"VERSION",
|
|
25
|
+
"lib/rack/perftools_profiler.rb",
|
|
26
|
+
"lib/rack/perftools_profiler/action.rb",
|
|
27
|
+
"lib/rack/perftools_profiler/call_app_directly.rb",
|
|
28
|
+
"lib/rack/perftools_profiler/profile_data_action.rb",
|
|
29
|
+
"lib/rack/perftools_profiler/profile_once.rb",
|
|
30
|
+
"lib/rack/perftools_profiler/profiler.rb",
|
|
31
|
+
"lib/rack/perftools_profiler/profiler_middleware.rb",
|
|
32
|
+
"lib/rack/perftools_profiler/return_data.rb",
|
|
33
|
+
"lib/rack/perftools_profiler/return_password_error.rb",
|
|
34
|
+
"lib/rack/perftools_profiler/start_profiling.rb",
|
|
35
|
+
"lib/rack/perftools_profiler/stop_profiling.rb",
|
|
36
|
+
"lib/rack/perftools_profiler/utils.rb",
|
|
37
|
+
"rack-perftools_profiler-0.4.1.gem",
|
|
38
|
+
"rack-perftools_profiler.gemspec",
|
|
39
|
+
"test/multiple_request_profiling_test.rb",
|
|
40
|
+
"test/rack-perftools-profiler_test.rb",
|
|
41
|
+
"test/single_request_profiling_test.rb",
|
|
42
|
+
"test/test_helper.rb"
|
|
42
43
|
]
|
|
43
44
|
s.homepage = %q{http://github.com/bhb/rack-perftools_profiler}
|
|
44
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
|
45
45
|
s.require_paths = ["lib"]
|
|
46
|
-
s.rubygems_version = %q{1.
|
|
46
|
+
s.rubygems_version = %q{1.6.2}
|
|
47
47
|
s.summary = %q{Middleware for profiling Rack-compatible apps using perftools.rb}
|
|
48
|
-
s.test_files = [
|
|
49
|
-
"test/multiple_request_profiling_test.rb",
|
|
50
|
-
"test/rack-perftools-profiler_test.rb",
|
|
51
|
-
"test/single_request_profiling_test.rb",
|
|
52
|
-
"test/test_helper.rb"
|
|
53
|
-
]
|
|
54
48
|
|
|
55
49
|
if s.respond_to? :specification_version then
|
|
56
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
57
50
|
s.specification_version = 3
|
|
58
51
|
|
|
59
|
-
if Gem::Version.new(Gem::
|
|
60
|
-
s.add_runtime_dependency(%q<perftools.rb>, ["~> 0.5"])
|
|
52
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
53
|
+
s.add_runtime_dependency(%q<perftools.rb>, ["~> 0.5.6"])
|
|
61
54
|
s.add_runtime_dependency(%q<rack>, ["~> 1.0"])
|
|
62
55
|
s.add_runtime_dependency(%q<open4>, ["~> 1.0"])
|
|
63
56
|
s.add_development_dependency(%q<rack>, ["~> 1.1"])
|
|
64
57
|
s.add_development_dependency(%q<shoulda>, ["~> 2.10"])
|
|
65
58
|
s.add_development_dependency(%q<mocha>, ["~> 0.9"])
|
|
66
59
|
else
|
|
67
|
-
s.add_dependency(%q<perftools.rb>, ["~> 0.5"])
|
|
60
|
+
s.add_dependency(%q<perftools.rb>, ["~> 0.5.6"])
|
|
68
61
|
s.add_dependency(%q<rack>, ["~> 1.0"])
|
|
69
62
|
s.add_dependency(%q<open4>, ["~> 1.0"])
|
|
70
63
|
s.add_dependency(%q<rack>, ["~> 1.1"])
|
|
@@ -72,7 +65,7 @@ Gem::Specification.new do |s|
|
|
|
72
65
|
s.add_dependency(%q<mocha>, ["~> 0.9"])
|
|
73
66
|
end
|
|
74
67
|
else
|
|
75
|
-
s.add_dependency(%q<perftools.rb>, ["~> 0.5"])
|
|
68
|
+
s.add_dependency(%q<perftools.rb>, ["~> 0.5.6"])
|
|
76
69
|
s.add_dependency(%q<rack>, ["~> 1.0"])
|
|
77
70
|
s.add_dependency(%q<open4>, ["~> 1.0"])
|
|
78
71
|
s.add_dependency(%q<rack>, ["~> 1.1"])
|
|
@@ -158,7 +158,7 @@ class MultipleRequestProfilingTest < Test::Unit::TestCase
|
|
|
158
158
|
should "call pprof.rb using 'bundle' command if bundler is set" do
|
|
159
159
|
status = stub_everything(:exitstatus => 0)
|
|
160
160
|
profiled_app = Rack::PerftoolsProfiler.new(@app, :bundler => true)
|
|
161
|
-
Open4.expects(:popen4).with(
|
|
161
|
+
Open4.expects(:popen4).with('bundle', 'exec', 'pprof.rb', '--text', regexp_matches(/rack_perftools_profiler\.prof$/)).returns(status)
|
|
162
162
|
profile(profiled_app)
|
|
163
163
|
end
|
|
164
164
|
|
|
@@ -176,6 +176,17 @@ class MultipleRequestProfilingTest < Test::Unit::TestCase
|
|
|
176
176
|
|
|
177
177
|
end
|
|
178
178
|
|
|
179
|
+
context "when the nodefraction parameter is specified" do
|
|
180
|
+
should "call pprof.rb with nodefraction" do
|
|
181
|
+
status = stub_everything(:exitstatus => 0)
|
|
182
|
+
profiled_app = Rack::PerftoolsProfiler.new(@app)
|
|
183
|
+
custom_env = Rack::MockRequest.env_for('/method1', :params => 'profile=true&nodefraction=160')
|
|
184
|
+
Open4.expects(:popen4).with('pprof.rb', '--text', '--nodefraction=160', regexp_matches(/rack_perftools_profiler\.prof$/)).returns(status)
|
|
185
|
+
profiled_app.call(custom_env)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
|
|
179
190
|
context "when overriding profiling mode" do
|
|
180
191
|
|
|
181
192
|
should "default to configured mode if mode is empty string" do
|
|
@@ -300,7 +311,9 @@ class MultipleRequestProfilingTest < Test::Unit::TestCase
|
|
|
300
311
|
profiled_app = Rack::PerftoolsProfiler.new(app, :default_printer => 'text')
|
|
301
312
|
profiled_app.call(@start_env)
|
|
302
313
|
profiled_app.call(env)
|
|
303
|
-
|
|
314
|
+
# I used to clone the environment to avoid conflicts, but this seems to break
|
|
315
|
+
# Devise/Warden.
|
|
316
|
+
# assert_equal env, old_env
|
|
304
317
|
end
|
|
305
318
|
|
|
306
319
|
should 'pass on non-profiling params in environment' do
|
|
@@ -314,7 +327,9 @@ class MultipleRequestProfilingTest < Test::Unit::TestCase
|
|
|
314
327
|
profiled_app = Rack::PerftoolsProfiler.new(app, :default_printer => 'text')
|
|
315
328
|
profiled_app.call(@start_env)
|
|
316
329
|
profiled_app.call(env)
|
|
317
|
-
|
|
330
|
+
# I used to clone the environment to avoid conflicts, but this seems to break
|
|
331
|
+
# Devise/Warden.
|
|
332
|
+
# assert_equal env, old_env
|
|
318
333
|
end
|
|
319
334
|
|
|
320
335
|
should 'not alter regular calls' do
|
|
@@ -105,7 +105,7 @@ class SingleRequestProfilingTest < Test::Unit::TestCase
|
|
|
105
105
|
should "call pprof.rb using 'bundle' command if bundler is set" do
|
|
106
106
|
status = stub_everything(:exitstatus => 0)
|
|
107
107
|
profiled_app = Rack::PerftoolsProfiler.new(@app, :bundler => true)
|
|
108
|
-
Open4.expects(:popen4).with(
|
|
108
|
+
Open4.expects(:popen4).with('bundle', 'exec', 'pprof.rb', '--text', regexp_matches(/rack_perftools_profiler\.prof$/)).returns(status)
|
|
109
109
|
profiled_app.call(@profiled_request_env)
|
|
110
110
|
end
|
|
111
111
|
|
|
@@ -123,6 +123,16 @@ class SingleRequestProfilingTest < Test::Unit::TestCase
|
|
|
123
123
|
|
|
124
124
|
end
|
|
125
125
|
|
|
126
|
+
context "when the nodecount parameter is specified" do
|
|
127
|
+
should "call pprof.rb with nodecount" do
|
|
128
|
+
status = stub_everything(:exitstatus => 0)
|
|
129
|
+
profiled_app = Rack::PerftoolsProfiler.new(@app)
|
|
130
|
+
custom_env = Rack::MockRequest.env_for('/method1', :params => 'profile=true&nodecount=160')
|
|
131
|
+
Open4.expects(:popen4).with('pprof.rb', '--text', '--nodecount=160', regexp_matches(/rack_perftools_profiler\.prof$/)).returns(status)
|
|
132
|
+
profiled_app.call(custom_env)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
126
136
|
context "when overriding profiling mode" do
|
|
127
137
|
|
|
128
138
|
should "default to configured mode if mode is empty string" do
|
|
@@ -248,11 +258,11 @@ class SingleRequestProfilingTest < Test::Unit::TestCase
|
|
|
248
258
|
|
|
249
259
|
end
|
|
250
260
|
|
|
251
|
-
context 'when using the
|
|
261
|
+
context 'when using the raw printer' do
|
|
252
262
|
|
|
253
263
|
should 'have default filename' do
|
|
254
|
-
_, headers, _ = Rack::PerftoolsProfiler.new(@app, :default_printer => '
|
|
255
|
-
assert_equal %q{attachment; filename="profile_data.
|
|
264
|
+
_, headers, _ = Rack::PerftoolsProfiler.new(@app, :default_printer => 'raw').call(@profiled_request_env)
|
|
265
|
+
assert_equal %q{attachment; filename="profile_data.raw"}, headers['Content-Disposition']
|
|
256
266
|
end
|
|
257
267
|
|
|
258
268
|
end
|
|
@@ -272,7 +282,9 @@ class SingleRequestProfilingTest < Test::Unit::TestCase
|
|
|
272
282
|
app = @app.clone
|
|
273
283
|
app.expects(:call).with(expected_env)
|
|
274
284
|
Rack::PerftoolsProfiler.new(app, :default_printer => 'gif').call(env)
|
|
275
|
-
|
|
285
|
+
# I used to clone the environment to avoid conflicts, but this seems to break
|
|
286
|
+
# Devise/Warden.
|
|
287
|
+
# assert_equal env, old_env
|
|
276
288
|
end
|
|
277
289
|
|
|
278
290
|
context "when request is not GET" do
|
|
@@ -312,4 +324,21 @@ class SingleRequestProfilingTest < Test::Unit::TestCase
|
|
|
312
324
|
|
|
313
325
|
end
|
|
314
326
|
|
|
327
|
+
context "when a profile password is required" do
|
|
328
|
+
should "error if password does not match" do
|
|
329
|
+
app = @app.clone
|
|
330
|
+
env = Rack::MockRequest.env_for('/', :params => {'profile' => 'true'})
|
|
331
|
+
status, headers, body = Rack::PerftoolsProfiler.new(app, :default_printer => 'pdf', :password => 'secret_password').call(env)
|
|
332
|
+
assert_equal 401, status
|
|
333
|
+
assert_equal 'text/plain', headers['Content-Type']
|
|
334
|
+
assert_match /Profiling is password-protected\. Password is incorrect\./, RackResponseBody.new(body).to_s
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
should "profile if the parameter matches" do
|
|
338
|
+
env = Rack::MockRequest.env_for('/', :params => 'profile=secret_password&printer=gif')
|
|
339
|
+
_, headers, _ = Rack::PerftoolsProfiler.new(@app, :default_printer => 'pdf', :password => 'secret_password').call(env)
|
|
340
|
+
assert_equal 'image/gif', headers['Content-Type']
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
315
344
|
end
|
metadata
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rack-perftools_profiler
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
4
|
+
hash: 11
|
|
5
|
+
prerelease:
|
|
5
6
|
segments:
|
|
6
7
|
- 0
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
version: 0.
|
|
8
|
+
- 5
|
|
9
|
+
- 0
|
|
10
|
+
version: 0.5.0
|
|
10
11
|
platform: ruby
|
|
11
12
|
authors:
|
|
12
13
|
- Ben Brinckerhoff
|
|
@@ -14,29 +15,34 @@ autorequire:
|
|
|
14
15
|
bindir: bin
|
|
15
16
|
cert_chain: []
|
|
16
17
|
|
|
17
|
-
date: 2011-
|
|
18
|
+
date: 2011-07-25 00:00:00 -06:00
|
|
18
19
|
default_executable:
|
|
19
20
|
dependencies:
|
|
20
21
|
- !ruby/object:Gem::Dependency
|
|
21
22
|
name: perftools.rb
|
|
22
23
|
prerelease: false
|
|
23
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
24
26
|
requirements:
|
|
25
27
|
- - ~>
|
|
26
28
|
- !ruby/object:Gem::Version
|
|
29
|
+
hash: 7
|
|
27
30
|
segments:
|
|
28
31
|
- 0
|
|
29
32
|
- 5
|
|
30
|
-
|
|
33
|
+
- 6
|
|
34
|
+
version: 0.5.6
|
|
31
35
|
type: :runtime
|
|
32
36
|
version_requirements: *id001
|
|
33
37
|
- !ruby/object:Gem::Dependency
|
|
34
38
|
name: rack
|
|
35
39
|
prerelease: false
|
|
36
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
|
41
|
+
none: false
|
|
37
42
|
requirements:
|
|
38
43
|
- - ~>
|
|
39
44
|
- !ruby/object:Gem::Version
|
|
45
|
+
hash: 15
|
|
40
46
|
segments:
|
|
41
47
|
- 1
|
|
42
48
|
- 0
|
|
@@ -47,9 +53,11 @@ dependencies:
|
|
|
47
53
|
name: open4
|
|
48
54
|
prerelease: false
|
|
49
55
|
requirement: &id003 !ruby/object:Gem::Requirement
|
|
56
|
+
none: false
|
|
50
57
|
requirements:
|
|
51
58
|
- - ~>
|
|
52
59
|
- !ruby/object:Gem::Version
|
|
60
|
+
hash: 15
|
|
53
61
|
segments:
|
|
54
62
|
- 1
|
|
55
63
|
- 0
|
|
@@ -60,9 +68,11 @@ dependencies:
|
|
|
60
68
|
name: rack
|
|
61
69
|
prerelease: false
|
|
62
70
|
requirement: &id004 !ruby/object:Gem::Requirement
|
|
71
|
+
none: false
|
|
63
72
|
requirements:
|
|
64
73
|
- - ~>
|
|
65
74
|
- !ruby/object:Gem::Version
|
|
75
|
+
hash: 13
|
|
66
76
|
segments:
|
|
67
77
|
- 1
|
|
68
78
|
- 1
|
|
@@ -73,9 +83,11 @@ dependencies:
|
|
|
73
83
|
name: shoulda
|
|
74
84
|
prerelease: false
|
|
75
85
|
requirement: &id005 !ruby/object:Gem::Requirement
|
|
86
|
+
none: false
|
|
76
87
|
requirements:
|
|
77
88
|
- - ~>
|
|
78
89
|
- !ruby/object:Gem::Version
|
|
90
|
+
hash: 23
|
|
79
91
|
segments:
|
|
80
92
|
- 2
|
|
81
93
|
- 10
|
|
@@ -86,9 +98,11 @@ dependencies:
|
|
|
86
98
|
name: mocha
|
|
87
99
|
prerelease: false
|
|
88
100
|
requirement: &id006 !ruby/object:Gem::Requirement
|
|
101
|
+
none: false
|
|
89
102
|
requirements:
|
|
90
103
|
- - ~>
|
|
91
104
|
- !ruby/object:Gem::Version
|
|
105
|
+
hash: 25
|
|
92
106
|
segments:
|
|
93
107
|
- 0
|
|
94
108
|
- 9
|
|
@@ -106,7 +120,6 @@ extra_rdoc_files:
|
|
|
106
120
|
- README.rdoc
|
|
107
121
|
files:
|
|
108
122
|
- .document
|
|
109
|
-
- .gitignore
|
|
110
123
|
- LICENSE
|
|
111
124
|
- README.rdoc
|
|
112
125
|
- Rakefile
|
|
@@ -119,9 +132,11 @@ files:
|
|
|
119
132
|
- lib/rack/perftools_profiler/profiler.rb
|
|
120
133
|
- lib/rack/perftools_profiler/profiler_middleware.rb
|
|
121
134
|
- lib/rack/perftools_profiler/return_data.rb
|
|
135
|
+
- lib/rack/perftools_profiler/return_password_error.rb
|
|
122
136
|
- lib/rack/perftools_profiler/start_profiling.rb
|
|
123
137
|
- lib/rack/perftools_profiler/stop_profiling.rb
|
|
124
138
|
- lib/rack/perftools_profiler/utils.rb
|
|
139
|
+
- rack-perftools_profiler-0.4.1.gem
|
|
125
140
|
- rack-perftools_profiler.gemspec
|
|
126
141
|
- test/multiple_request_profiling_test.rb
|
|
127
142
|
- test/rack-perftools-profiler_test.rb
|
|
@@ -132,33 +147,34 @@ homepage: http://github.com/bhb/rack-perftools_profiler
|
|
|
132
147
|
licenses: []
|
|
133
148
|
|
|
134
149
|
post_install_message:
|
|
135
|
-
rdoc_options:
|
|
136
|
-
|
|
150
|
+
rdoc_options: []
|
|
151
|
+
|
|
137
152
|
require_paths:
|
|
138
153
|
- lib
|
|
139
154
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
|
+
none: false
|
|
140
156
|
requirements:
|
|
141
157
|
- - ">="
|
|
142
158
|
- !ruby/object:Gem::Version
|
|
159
|
+
hash: 3
|
|
143
160
|
segments:
|
|
144
161
|
- 0
|
|
145
162
|
version: "0"
|
|
146
163
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
164
|
+
none: false
|
|
147
165
|
requirements:
|
|
148
166
|
- - ">="
|
|
149
167
|
- !ruby/object:Gem::Version
|
|
168
|
+
hash: 3
|
|
150
169
|
segments:
|
|
151
170
|
- 0
|
|
152
171
|
version: "0"
|
|
153
172
|
requirements: []
|
|
154
173
|
|
|
155
174
|
rubyforge_project:
|
|
156
|
-
rubygems_version: 1.
|
|
175
|
+
rubygems_version: 1.6.2
|
|
157
176
|
signing_key:
|
|
158
177
|
specification_version: 3
|
|
159
178
|
summary: Middleware for profiling Rack-compatible apps using perftools.rb
|
|
160
|
-
test_files:
|
|
161
|
-
|
|
162
|
-
- test/rack-perftools-profiler_test.rb
|
|
163
|
-
- test/single_request_profiling_test.rb
|
|
164
|
-
- test/test_helper.rb
|
|
179
|
+
test_files: []
|
|
180
|
+
|