ruby-prof 0.18.0-x64-mingw32

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.
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