ruby-prof 0.18.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +500 -0
  3. data/LICENSE +25 -0
  4. data/README.rdoc +487 -0
  5. data/Rakefile +113 -0
  6. data/bin/ruby-prof +345 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/examples/flat.txt +50 -0
  9. data/examples/graph.dot +84 -0
  10. data/examples/graph.html +823 -0
  11. data/examples/graph.txt +139 -0
  12. data/examples/multi.flat.txt +23 -0
  13. data/examples/multi.graph.html +760 -0
  14. data/examples/multi.grind.dat +114 -0
  15. data/examples/multi.stack.html +547 -0
  16. data/examples/stack.html +547 -0
  17. data/ext/ruby_prof/extconf.rb +68 -0
  18. data/ext/ruby_prof/rp_call_info.c +425 -0
  19. data/ext/ruby_prof/rp_call_info.h +53 -0
  20. data/ext/ruby_prof/rp_measure.c +40 -0
  21. data/ext/ruby_prof/rp_measure.h +45 -0
  22. data/ext/ruby_prof/rp_measure_allocations.c +76 -0
  23. data/ext/ruby_prof/rp_measure_cpu_time.c +136 -0
  24. data/ext/ruby_prof/rp_measure_gc_runs.c +73 -0
  25. data/ext/ruby_prof/rp_measure_gc_time.c +60 -0
  26. data/ext/ruby_prof/rp_measure_memory.c +77 -0
  27. data/ext/ruby_prof/rp_measure_process_time.c +71 -0
  28. data/ext/ruby_prof/rp_measure_wall_time.c +45 -0
  29. data/ext/ruby_prof/rp_method.c +630 -0
  30. data/ext/ruby_prof/rp_method.h +75 -0
  31. data/ext/ruby_prof/rp_stack.c +173 -0
  32. data/ext/ruby_prof/rp_stack.h +63 -0
  33. data/ext/ruby_prof/rp_thread.c +277 -0
  34. data/ext/ruby_prof/rp_thread.h +27 -0
  35. data/ext/ruby_prof/ruby_prof.c +794 -0
  36. data/ext/ruby_prof/ruby_prof.h +60 -0
  37. data/ext/ruby_prof/vc/ruby_prof.sln +31 -0
  38. data/ext/ruby_prof/vc/ruby_prof.vcxproj +141 -0
  39. data/lib/2.6.3/ruby_prof.so +0 -0
  40. data/lib/ruby-prof.rb +68 -0
  41. data/lib/ruby-prof/aggregate_call_info.rb +76 -0
  42. data/lib/ruby-prof/assets/call_stack_printer.css.html +117 -0
  43. data/lib/ruby-prof/assets/call_stack_printer.js.html +385 -0
  44. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  45. data/lib/ruby-prof/call_info.rb +115 -0
  46. data/lib/ruby-prof/call_info_visitor.rb +40 -0
  47. data/lib/ruby-prof/compatibility.rb +179 -0
  48. data/lib/ruby-prof/method_info.rb +121 -0
  49. data/lib/ruby-prof/printers/abstract_printer.rb +104 -0
  50. data/lib/ruby-prof/printers/call_info_printer.rb +41 -0
  51. data/lib/ruby-prof/printers/call_stack_printer.rb +265 -0
  52. data/lib/ruby-prof/printers/call_tree_printer.rb +143 -0
  53. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  54. data/lib/ruby-prof/printers/flat_printer.rb +70 -0
  55. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +83 -0
  56. data/lib/ruby-prof/printers/graph_html_printer.rb +249 -0
  57. data/lib/ruby-prof/printers/graph_printer.rb +116 -0
  58. data/lib/ruby-prof/printers/multi_printer.rb +84 -0
  59. data/lib/ruby-prof/profile.rb +26 -0
  60. data/lib/ruby-prof/profile/exclude_common_methods.rb +207 -0
  61. data/lib/ruby-prof/profile/legacy_method_elimination.rb +50 -0
  62. data/lib/ruby-prof/rack.rb +174 -0
  63. data/lib/ruby-prof/task.rb +147 -0
  64. data/lib/ruby-prof/thread.rb +35 -0
  65. data/lib/ruby-prof/version.rb +3 -0
  66. data/lib/unprof.rb +10 -0
  67. data/ruby-prof.gemspec +58 -0
  68. data/test/abstract_printer_test.rb +53 -0
  69. data/test/aggregate_test.rb +136 -0
  70. data/test/basic_test.rb +128 -0
  71. data/test/block_test.rb +74 -0
  72. data/test/call_info_test.rb +78 -0
  73. data/test/call_info_visitor_test.rb +31 -0
  74. data/test/duplicate_names_test.rb +32 -0
  75. data/test/dynamic_method_test.rb +55 -0
  76. data/test/enumerable_test.rb +21 -0
  77. data/test/exceptions_test.rb +24 -0
  78. data/test/exclude_methods_test.rb +146 -0
  79. data/test/exclude_threads_test.rb +53 -0
  80. data/test/fiber_test.rb +79 -0
  81. data/test/issue137_test.rb +63 -0
  82. data/test/line_number_test.rb +80 -0
  83. data/test/measure_allocations_test.rb +26 -0
  84. data/test/measure_cpu_time_test.rb +212 -0
  85. data/test/measure_gc_runs_test.rb +32 -0
  86. data/test/measure_gc_time_test.rb +36 -0
  87. data/test/measure_memory_test.rb +33 -0
  88. data/test/measure_process_time_test.rb +61 -0
  89. data/test/measure_wall_time_test.rb +255 -0
  90. data/test/method_elimination_test.rb +84 -0
  91. data/test/module_test.rb +45 -0
  92. data/test/multi_printer_test.rb +104 -0
  93. data/test/no_method_class_test.rb +15 -0
  94. data/test/pause_resume_test.rb +166 -0
  95. data/test/prime.rb +54 -0
  96. data/test/printers_test.rb +275 -0
  97. data/test/printing_recursive_graph_test.rb +127 -0
  98. data/test/rack_test.rb +157 -0
  99. data/test/recursive_test.rb +215 -0
  100. data/test/singleton_test.rb +38 -0
  101. data/test/stack_printer_test.rb +77 -0
  102. data/test/stack_test.rb +138 -0
  103. data/test/start_stop_test.rb +112 -0
  104. data/test/test_helper.rb +267 -0
  105. data/test/thread_test.rb +187 -0
  106. data/test/unique_call_path_test.rb +202 -0
  107. data/test/yarv_test.rb +55 -0
  108. metadata +199 -0
@@ -0,0 +1,275 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'stringio'
6
+ require 'fileutils'
7
+
8
+ # -- Tests ----
9
+ class PrintersTest < TestCase
10
+ def setup
11
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
12
+ RubyProf::measure_mode = RubyProf::WALL_TIME
13
+ @result = RubyProf.profile do
14
+ run_primes(1000, 5000)
15
+ end
16
+ end
17
+
18
+ def test_printers
19
+ assert_nothing_raised do
20
+ output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new('')
21
+
22
+ printer = RubyProf::CallInfoPrinter.new(@result)
23
+ printer.print(output)
24
+
25
+ printer = RubyProf::CallTreePrinter.new(@result)
26
+ printer.print()
27
+
28
+ printer = RubyProf::FlatPrinter.new(@result)
29
+ printer.print(output)
30
+
31
+ printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
32
+ printer.print(output)
33
+
34
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
35
+ printer.print(output)
36
+
37
+ printer = RubyProf::GraphPrinter.new(@result)
38
+ printer.print(output)
39
+ end
40
+ end
41
+
42
+ def test_print_to_files
43
+ assert_nothing_raised do
44
+ output_dir = 'examples2'
45
+
46
+ if ENV['SAVE_NEW_PRINTER_EXAMPLES']
47
+ output_dir = 'examples'
48
+ end
49
+ FileUtils.mkdir_p output_dir
50
+
51
+ printer = RubyProf::DotPrinter.new(@result)
52
+ File.open("#{output_dir}/graph.dot", "w") {|f| printer.print(f)}
53
+
54
+ printer = RubyProf::CallStackPrinter.new(@result)
55
+ File.open("#{output_dir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
56
+
57
+ printer = RubyProf::MultiPrinter.new(@result)
58
+ printer.print(:path => "#{output_dir}", :profile => "multi", :application => "primes")
59
+ for file in ['graph.dot', 'multi.flat.txt', 'multi.graph.html', "multi.callgrind.out.#{$$}", 'multi.stack.html', 'stack.html']
60
+ existant_file = output_dir + '/' + file
61
+ assert File.size(existant_file) > 0
62
+ end
63
+ end
64
+ end
65
+
66
+ def test_refuses_io_objects
67
+ p = RubyProf::MultiPrinter.new(@result)
68
+ begin
69
+ p.print(STDOUT)
70
+ flunk "should have raised an ArgumentError"
71
+ rescue ArgumentError => e
72
+ assert_match(/IO/, e.to_s)
73
+ end
74
+ end
75
+
76
+ def test_refuses_non_hashes
77
+ p = RubyProf::MultiPrinter.new (@result)
78
+ begin
79
+ p.print([])
80
+ flunk "should have raised an ArgumentError"
81
+ rescue ArgumentError => e
82
+ assert_match(/hash/, e.to_s)
83
+ end
84
+ end
85
+
86
+ def test_flat_string
87
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
88
+ refute_match(/prime.rb/, output)
89
+ end
90
+
91
+ def helper_test_flat_string(klass)
92
+ output = ''
93
+
94
+ printer = klass.new(@result)
95
+ printer.print(output)
96
+
97
+ assert_match(/Thread ID: -?\d+/i, output)
98
+ assert_match(/Fiber ID: -?\d+/i, output)
99
+ assert_match(/Total: \d+\.\d+/i, output)
100
+ assert_match(/Object#run_primes/i, output)
101
+ output
102
+ end
103
+
104
+ def test_flat_string_with_numbers
105
+ output = helper_test_flat_string RubyProf::FlatPrinterWithLineNumbers
106
+ assert_match(/prime.rb/, output)
107
+ refute_match(/ruby_runtime:0/, output)
108
+ assert_match(/called from/, output)
109
+
110
+ # should combine common parents
111
+ # 1.9 inlines it's Fixnum#- so we don't see as many
112
+ assert_equal(2, output.scan(/Object#is_prime/).length)
113
+ refute_match(/\.\/test\/prime.rb/, output) # don't use relative paths
114
+ end
115
+
116
+ def test_graph_html_string
117
+ output = ''
118
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
119
+ printer.print(output)
120
+
121
+ assert_match(/DTD HTML 4\.01/i, output)
122
+ assert_match( %r{<th>Total Time</th>}i, output)
123
+ assert_match(/Object#run_primes/i, output)
124
+ end
125
+
126
+ def test_graph_string
127
+ output = ''
128
+ printer = RubyProf::GraphPrinter.new(@result)
129
+ printer.print(output)
130
+
131
+ assert_match(/Thread ID: -?\d+/i, output)
132
+ assert_match(/Fiber ID: -?\d+/i, output)
133
+ assert_match(/Total Time: \d+\.\d+/i, output)
134
+ assert_match(/Object#run_primes/i, output)
135
+ end
136
+
137
+ def test_call_tree_string
138
+ printer = RubyProf::CallTreePrinter.new(@result)
139
+ printer.print(:profile => "lolcat", :path => RubyProf.tmpdir)
140
+ main_output_file_name = File.join(RubyProf.tmpdir, "lolcat.callgrind.out.#{$$}")
141
+ assert(File.exist?(main_output_file_name))
142
+ output = File.read(main_output_file_name)
143
+ assert_match(/fn=Object::find_primes/i, output)
144
+ assert_match(/events: wall_time/i, output)
145
+ refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
146
+ end
147
+
148
+ def do_nothing
149
+ start = Time.now
150
+ while(Time.now == start)
151
+ end
152
+ end
153
+
154
+ def test_all_with_small_percentiles
155
+ result = RubyProf.profile do
156
+ sleep 2
157
+ do_nothing
158
+ end
159
+
160
+ # RubyProf::CallTreePrinter doesn't "do" a min_percent
161
+ # RubyProf::FlatPrinter only outputs if self time > percent...
162
+ # RubyProf::FlatPrinterWithLineNumbers same
163
+ for klass in [ RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
164
+ printer = klass.new(result)
165
+ out = ''
166
+ printer.print(out, :min_percent => 0.00000001)
167
+ assert_match(/do_nothing/, out)
168
+ end
169
+
170
+ end
171
+
172
+ def test_flat_result_sorting_by_self_time_is_default
173
+ printer = RubyProf::FlatPrinter.new(@result)
174
+
175
+ printer.print(output = '')
176
+ self_times = flat_output_nth_column_values(output, 3)
177
+
178
+ assert_sorted self_times
179
+ end
180
+
181
+ def test_flat_result_sorting
182
+ printer = RubyProf::FlatPrinter.new(@result)
183
+
184
+ sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
185
+
186
+ sort_method_with_column_number.each_pair do |sort_method, n|
187
+ printer.print(output = '', :sort_method => sort_method)
188
+ times = flat_output_nth_column_values(output, n)
189
+ assert_sorted times
190
+ end
191
+ end
192
+
193
+ def test_flat_result_with_line_numbers_sorting_by_self_time_is_default
194
+ printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
195
+
196
+ printer.print(output = '')
197
+ self_times = flat_output_nth_column_values(output, 3)
198
+
199
+ assert_sorted self_times
200
+ end
201
+
202
+ def test_flat_with_line_numbers_result_sorting
203
+ printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
204
+
205
+ sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
206
+
207
+ sort_method_with_column_number.each_pair do |sort_method, n|
208
+ printer.print(output = '', :sort_method => sort_method)
209
+ times = flat_output_nth_column_values(output, n)
210
+ assert_sorted times
211
+ end
212
+ end
213
+
214
+ def test_graph_result_sorting_by_total_time_is_default
215
+ printer = RubyProf::GraphPrinter.new(@result)
216
+ printer.print(output = '')
217
+ total_times = graph_output_nth_column_values(output, 3)
218
+
219
+ assert_sorted total_times
220
+ end
221
+
222
+ def test_graph_results_sorting
223
+ printer = RubyProf::GraphPrinter.new(@result)
224
+
225
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
226
+
227
+ sort_method_with_column_number.each_pair do |sort_method, n|
228
+ printer.print(output = '', :sort_method => sort_method)
229
+ times = graph_output_nth_column_values(output, n)
230
+ assert_sorted times
231
+ end
232
+ end
233
+
234
+ def test_graph_html_result_sorting_by_total_time_is_default
235
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
236
+ printer.print(output = '')
237
+ total_times = graph_html_output_nth_column_values(output, 3)
238
+
239
+ assert_sorted total_times
240
+ end
241
+
242
+ def test_graph_html_result_sorting
243
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
244
+
245
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
246
+
247
+ sort_method_with_column_number.each_pair do |sort_method, n|
248
+ printer.print(output = '', :sort_method => sort_method)
249
+ times = graph_html_output_nth_column_values(output, n)
250
+ assert_sorted times
251
+ end
252
+ end
253
+
254
+ private
255
+ def flat_output_nth_column_values(output, n)
256
+ only_method_calls = output.split("\n").select { |line| line =~ /^ +\d+/ }
257
+ only_method_calls.collect { |line| line.split(/ +/)[n] }
258
+ end
259
+
260
+ def graph_output_nth_column_values(output, n)
261
+ only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
262
+ only_root_calls.collect { |line| line.split(/ +/)[n] }
263
+ end
264
+
265
+ def graph_html_output_nth_column_values(output, n)
266
+ only_root_calls = output.split('<tr class="method">')
267
+ only_root_calls.delete_at(0)
268
+ only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
269
+ end
270
+
271
+ def assert_sorted array
272
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
273
+ assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
274
+ end
275
+ end
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'stringio'
6
+ require 'fileutils'
7
+
8
+ # --- code to be tested ---
9
+ module PRGT
10
+ extend self
11
+
12
+ def f(n)
13
+ n.times { sleep 0.1 }
14
+ end
15
+
16
+ def g(n)
17
+ n.times { sleep 0.2 }
18
+ end
19
+
20
+ def run
21
+ 2.times { f(2); g(4) }
22
+ end
23
+ end
24
+
25
+ # --- expected test output ---
26
+ =begin
27
+ Measure Mode: wall_time
28
+ Thread ID: 70238775664960
29
+ Fiber ID: 70238784046840
30
+ Total Time: 2.040249824523926
31
+ Sort by: total_time
32
+
33
+ %total %self total self wait child calls Name
34
+ --------------------------------------------------------------------------------
35
+ 100.00% 0.00% 2.040 0.000 0.000 2.040 1 PrintingRecursiveGraphTest#setup
36
+ 2.040 0.000 0.000 2.040 1/1 PRGT#run
37
+ --------------------------------------------------------------------------------
38
+ 2.040 0.000 0.000 2.040 1/1 PrintingRecursiveGraphTest#setup
39
+ 100.00% 0.00% 2.040 0.000 0.000 2.040 1 PRGT#run
40
+ 2.040 0.000 0.000 2.040 1/5 Integer#times
41
+ --------------------------------------------------------------------------------
42
+ 0.409 0.000 0.000 0.409 2/5 Prgt#f
43
+ 1.631 0.000 0.000 1.631 2/5 PRGT#g
44
+ 2.040 0.000 0.000 2.040 1/5 PRGT#run
45
+ 100.00% 0.00% 2.040 0.000 0.000 2.040 5 *Integer#times
46
+ 2.040 2.040 0.000 0.000 12/12 Kernel#sleep
47
+ 1.631 0.000 0.000 1.631 2/2 PRGT#g
48
+ 0.409 0.000 0.000 0.409 2/2 PRGT#f
49
+ --------------------------------------------------------------------------------
50
+ 2.040 2.040 0.000 0.000 12/12 Integer#times
51
+ 99.99% 99.99% 2.040 2.040 0.000 0.000 12 Kernel#sleep
52
+ --------------------------------------------------------------------------------
53
+ 1.631 0.000 0.000 1.631 2/2 Integer#times
54
+ 79.94% 0.00% 1.631 0.000 0.000 1.631 2 PRGT#g
55
+ 1.631 0.000 0.000 1.631 2/5 Integer#times
56
+ --------------------------------------------------------------------------------
57
+ 0.409 0.000 0.000 0.409 2/2 Integer#times
58
+ 20.05% 0.00% 0.409 0.000 0.000 0.409 2 PRGT#f
59
+ 0.409 0.000 0.000 0.409 2/5 Integer#times
60
+
61
+ * indicates recursively called methods
62
+ =end
63
+
64
+ class PrintingRecursiveGraphTest < TestCase
65
+ include PrinterTestHelper
66
+
67
+ def setup
68
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
69
+ RubyProf::measure_mode = RubyProf::WALL_TIME
70
+ @result = RubyProf.profile do
71
+ PRGT.run
72
+ end
73
+ end
74
+
75
+ def test_printing_rescursive_graph
76
+ printer = RubyProf::GraphPrinter.new(@result)
77
+
78
+ buffer = ''
79
+ printer.print(StringIO.new(buffer))
80
+
81
+ puts buffer if ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1"
82
+
83
+ parsed_output = MetricsArray.parse(buffer)
84
+
85
+ assert( integer_times = parsed_output.metrics_for("*Integer#times") )
86
+
87
+ actual_parents = integer_times.parents.map(&:name)
88
+ expected_parents = %w(PRGT#f PRGT#g PRGT#run)
89
+ assert_equal expected_parents, actual_parents
90
+
91
+ actual_children = integer_times.children.map(&:name)
92
+ expected_children = %w(Kernel#sleep PRGT#g PRGT#f)
93
+ assert_equal expected_children, actual_children
94
+
95
+ assert( fp = integer_times.parent("PRGT#f") )
96
+ assert_in_delta(fp.total, fp.child, 0.01)
97
+ assert_equal("2/5", fp.calls)
98
+
99
+ assert( gp = integer_times.parent("PRGT#g") )
100
+ assert_in_delta(gp.total, gp.child, 0.01)
101
+ assert_equal("2/5", gp.calls)
102
+
103
+ assert( rp = integer_times.parent("PRGT#run") )
104
+ assert_in_delta(rp.total, rp.child, 0.01)
105
+ assert_equal("1/5", rp.calls)
106
+
107
+ assert_in_delta(4*fp.total, gp.total, 0.05)
108
+ assert_in_delta(fp.total + gp.total, rp.total, 0.05)
109
+ assert_in_delta(integer_times.metrics.total, rp.total, 0.05)
110
+
111
+ assert( fc = integer_times.child("PRGT#f") )
112
+ assert_in_delta(fc.total, fc.child, 0.01)
113
+ assert_equal("2/2", fc.calls)
114
+
115
+ assert( gc = integer_times.child("PRGT#g") )
116
+ assert_in_delta(gc.total, gc.child, 0.01)
117
+ assert_equal("2/2", gc.calls)
118
+
119
+ assert( ks = integer_times.child("Kernel#sleep") )
120
+ assert_in_delta(ks.total, ks.self_t, 0.01)
121
+ assert_equal("12/12", ks.calls)
122
+
123
+ assert_in_delta(4*fc.total, gc.total, 0.05)
124
+ assert_in_delta(fp.total + gc.total, ks.total, 0.05)
125
+ assert_in_delta(integer_times.metrics.total, ks.total, 0.05)
126
+ end
127
+ end
data/test/rack_test.rb ADDED
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class FakeRackApp
7
+ def call(env)
8
+ end
9
+ end
10
+
11
+ module Rack
12
+ class Request
13
+ def initialize(env)
14
+ if env == :fake_env
15
+ @env = {}
16
+ else
17
+ @env = env
18
+ end
19
+ end
20
+
21
+ def path
22
+ @env[:path] || '/path/to/resource.json'
23
+ end
24
+ end
25
+ end
26
+
27
+ module Rack
28
+ class RubyProf
29
+ attr_reader :_profiler
30
+
31
+ def public_delete_profiler!
32
+ delete_profiler!
33
+ end
34
+ end
35
+ end
36
+
37
+ class RackTest < TestCase
38
+ def test_create_print_path
39
+ path = Dir.mktmpdir
40
+ Dir.delete(path)
41
+
42
+ Rack::RubyProf.new(FakeRackApp.new, :path => path)
43
+
44
+ assert(Dir.exist?(path))
45
+ end
46
+
47
+ def test_create_profile_reports
48
+ path = Dir.mktmpdir
49
+
50
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path)
51
+
52
+ adapter.call(:fake_env)
53
+
54
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
55
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
56
+ assert(File.exist?(file_path))
57
+ end
58
+ end
59
+
60
+ def test_skip_paths
61
+ path = Dir.mktmpdir
62
+
63
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :skip_paths => [%r{\.json$}])
64
+
65
+ adapter.call(:fake_env)
66
+
67
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
68
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
69
+ assert(!File.exist?(file_path))
70
+ end
71
+ end
72
+
73
+ def test_only_paths
74
+ path = Dir.mktmpdir
75
+
76
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :only_paths => [%r{\.json$}])
77
+
78
+ adapter.call({path: '/path/to/resource.json'})
79
+
80
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
81
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
82
+ assert(File.exist?(file_path))
83
+ end
84
+
85
+ adapter.call({path: '/path/to/resource.html'})
86
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
87
+ file_path = ::File.join(path, "path-to-resource.html-#{base_name}")
88
+ assert(!File.exist?(file_path))
89
+ end
90
+ end
91
+
92
+ def test_allows_lazy_filename_setting
93
+ path = Dir.mktmpdir
94
+
95
+ printer = {::RubyProf::FlatPrinter => lambda { 'dynamic.txt' }}
96
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :printers => printer)
97
+
98
+ adapter.call(:fake_env)
99
+
100
+ file_path = ::File.join(path, 'path-to-resource.json-dynamic.txt')
101
+ assert(File.exist?(file_path))
102
+ end
103
+
104
+ def test_works_for_multiple_requests
105
+ path = Dir.mktmpdir
106
+
107
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :max_requests => 2)
108
+
109
+ # make a 1st request, and check that this didn't create any files
110
+ adapter.call(:fake_env)
111
+ assert(Dir["#{path}/*"].empty?)
112
+
113
+ # now a second request should create all the expected files
114
+ adapter.call(:fake_env)
115
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
116
+ file_path = ::File.join(path, "multi-requests-2-#{base_name}")
117
+ assert(File.exist?(file_path))
118
+ end
119
+
120
+ # let's clean up
121
+ FileUtils.rm_rf(Dir["#{path}/*"])
122
+
123
+ # and do the same again for the next 2 requests
124
+ adapter.call(:fake_env)
125
+ assert(Dir["#{path}/*"].empty?)
126
+
127
+ adapter.call(:fake_env)
128
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
129
+ file_path = ::File.join(path, "multi-requests-2-#{base_name}")
130
+ assert(File.exist?(file_path))
131
+ end
132
+ end
133
+
134
+ def test_tries_to_print_results_if_shut_down_before_max_requests_reached
135
+ path = Dir.mktmpdir
136
+
137
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :max_requests => 100)
138
+
139
+ # make a 1st request, and check that this didn't create any files
140
+ adapter.call(:fake_env)
141
+ assert(Dir["#{path}/*"].empty?)
142
+
143
+ adapter.public_delete_profiler!
144
+
145
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
146
+ file_path = ::File.join(path, "multi-requests-1-#{base_name}")
147
+ assert(File.exist?(file_path))
148
+ end
149
+ end
150
+
151
+ def test_it_uses_separate_profilers_if_not_aggregating_multiple_requests
152
+ adapter1 = Rack::RubyProf.new(FakeRackApp.new)
153
+ adapter2 = Rack::RubyProf.new(FakeRackApp.new)
154
+
155
+ assert(adapter1.object_id != adapter2.object_id)
156
+ end
157
+ end