ruby-prof 0.16.2 → 1.1.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.
Files changed (203) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +532 -467
  3. data/LICENSE +24 -24
  4. data/README.rdoc +5 -454
  5. data/Rakefile +110 -113
  6. data/bin/ruby-prof +380 -340
  7. data/bin/ruby-prof-check-trace +45 -45
  8. data/ext/ruby_prof/extconf.rb +36 -64
  9. data/ext/ruby_prof/rp_allocation.c +279 -0
  10. data/ext/ruby_prof/rp_allocation.h +31 -0
  11. data/ext/ruby_prof/rp_call_info.c +271 -407
  12. data/ext/ruby_prof/rp_call_info.h +35 -48
  13. data/ext/ruby_prof/rp_measure_allocations.c +52 -76
  14. data/ext/ruby_prof/rp_measure_memory.c +42 -77
  15. data/ext/ruby_prof/rp_measure_process_time.c +67 -71
  16. data/ext/ruby_prof/rp_measure_wall_time.c +62 -45
  17. data/ext/ruby_prof/rp_measurement.c +230 -0
  18. data/ext/ruby_prof/rp_measurement.h +50 -0
  19. data/ext/ruby_prof/rp_method.c +630 -411
  20. data/ext/ruby_prof/rp_method.h +70 -52
  21. data/ext/ruby_prof/rp_profile.c +895 -0
  22. data/ext/ruby_prof/rp_profile.h +37 -0
  23. data/ext/ruby_prof/rp_stack.c +196 -128
  24. data/ext/ruby_prof/rp_stack.h +56 -51
  25. data/ext/ruby_prof/rp_thread.c +337 -273
  26. data/ext/ruby_prof/rp_thread.h +36 -27
  27. data/ext/ruby_prof/ruby_prof.c +48 -671
  28. data/ext/ruby_prof/ruby_prof.h +17 -56
  29. data/ext/ruby_prof/vc/ruby_prof.sln +20 -21
  30. data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +38 -5
  31. data/lib/ruby-prof.rb +52 -58
  32. data/lib/ruby-prof/assets/call_stack_printer.html.erb +713 -0
  33. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  34. data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
  35. data/lib/ruby-prof/call_info.rb +57 -126
  36. data/lib/ruby-prof/call_info_visitor.rb +38 -40
  37. data/lib/ruby-prof/compatibility.rb +109 -178
  38. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  39. data/lib/ruby-prof/measurement.rb +14 -0
  40. data/lib/ruby-prof/method_info.rb +90 -129
  41. data/lib/ruby-prof/printers/abstract_printer.rb +127 -85
  42. data/lib/ruby-prof/printers/call_info_printer.rb +51 -41
  43. data/lib/ruby-prof/printers/call_stack_printer.rb +182 -260
  44. data/lib/ruby-prof/printers/call_tree_printer.rb +151 -130
  45. data/lib/ruby-prof/printers/dot_printer.rb +132 -132
  46. data/lib/ruby-prof/printers/flat_printer.rb +52 -70
  47. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -244
  48. data/lib/ruby-prof/printers/graph_printer.rb +114 -116
  49. data/lib/ruby-prof/printers/multi_printer.rb +127 -58
  50. data/lib/ruby-prof/profile.rb +33 -55
  51. data/lib/ruby-prof/rack.rb +171 -95
  52. data/lib/ruby-prof/task.rb +147 -147
  53. data/lib/ruby-prof/thread.rb +35 -41
  54. data/lib/ruby-prof/version.rb +3 -3
  55. data/lib/unprof.rb +10 -10
  56. data/ruby-prof.gemspec +58 -57
  57. data/test/abstract_printer_test.rb +26 -0
  58. data/test/alias_test.rb +129 -0
  59. data/test/basic_test.rb +129 -128
  60. data/test/call_info_visitor_test.rb +31 -31
  61. data/test/duplicate_names_test.rb +32 -32
  62. data/test/dynamic_method_test.rb +53 -55
  63. data/test/enumerable_test.rb +21 -21
  64. data/test/exceptions_test.rb +24 -16
  65. data/test/exclude_methods_test.rb +146 -0
  66. data/test/exclude_threads_test.rb +53 -53
  67. data/test/fiber_test.rb +73 -79
  68. data/test/gc_test.rb +96 -0
  69. data/test/line_number_test.rb +161 -71
  70. data/test/marshal_test.rb +119 -0
  71. data/test/measure_allocations.rb +30 -0
  72. data/test/measure_allocations_test.rb +385 -26
  73. data/test/measure_allocations_trace_test.rb +385 -0
  74. data/test/measure_memory_trace_test.rb +756 -0
  75. data/test/measure_process_time_test.rb +849 -63
  76. data/test/measure_times.rb +54 -0
  77. data/test/measure_wall_time_test.rb +459 -255
  78. data/test/multi_printer_test.rb +71 -83
  79. data/test/no_method_class_test.rb +15 -15
  80. data/test/parser_timings.rb +24 -0
  81. data/test/pause_resume_test.rb +166 -166
  82. data/test/prime.rb +56 -54
  83. data/test/printer_call_stack_test.rb +28 -0
  84. data/test/printer_call_tree_test.rb +31 -0
  85. data/test/printer_flat_test.rb +68 -0
  86. data/test/printer_graph_html_test.rb +60 -0
  87. data/test/printer_graph_test.rb +41 -0
  88. data/test/printers_test.rb +141 -255
  89. data/test/printing_recursive_graph_test.rb +81 -127
  90. data/test/rack_test.rb +157 -93
  91. data/test/recursive_test.rb +210 -215
  92. data/test/singleton_test.rb +38 -38
  93. data/test/stack_printer_test.rb +64 -78
  94. data/test/start_stop_test.rb +109 -112
  95. data/test/test_helper.rb +24 -264
  96. data/test/thread_test.rb +144 -187
  97. data/test/unique_call_path_test.rb +190 -202
  98. data/test/yarv_test.rb +56 -55
  99. metadata +34 -114
  100. data/doc/LICENSE.html +0 -114
  101. data/doc/README_rdoc.html +0 -603
  102. data/doc/Rack.html +0 -95
  103. data/doc/Rack/RubyProf.html +0 -226
  104. data/doc/RubyProf.html +0 -962
  105. data/doc/RubyProf/AbstractPrinter.html +0 -546
  106. data/doc/RubyProf/AggregateCallInfo.html +0 -551
  107. data/doc/RubyProf/CallInfo.html +0 -639
  108. data/doc/RubyProf/CallInfoPrinter.html +0 -120
  109. data/doc/RubyProf/CallInfoVisitor.html +0 -198
  110. data/doc/RubyProf/CallStackPrinter.html +0 -1121
  111. data/doc/RubyProf/CallTreePrinter.html +0 -641
  112. data/doc/RubyProf/Cmd.html +0 -631
  113. data/doc/RubyProf/DotPrinter.html +0 -257
  114. data/doc/RubyProf/FlatPrinter.html +0 -163
  115. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -208
  116. data/doc/RubyProf/GraphHtmlPrinter.html +0 -552
  117. data/doc/RubyProf/GraphPrinter.html +0 -139
  118. data/doc/RubyProf/MethodInfo.html +0 -745
  119. data/doc/RubyProf/MultiPrinter.html +0 -360
  120. data/doc/RubyProf/Profile.html +0 -763
  121. data/doc/RubyProf/ProfileTask.html +0 -490
  122. data/doc/RubyProf/Thread.html +0 -310
  123. data/doc/created.rid +0 -31
  124. data/doc/css/fonts.css +0 -167
  125. data/doc/css/rdoc.css +0 -590
  126. data/doc/examples/flat_txt.html +0 -138
  127. data/doc/examples/graph_html.html +0 -909
  128. data/doc/examples/graph_txt.html +0 -247
  129. data/doc/fonts/Lato-Light.ttf +0 -0
  130. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  131. data/doc/fonts/Lato-Regular.ttf +0 -0
  132. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  133. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  134. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  135. data/doc/images/add.png +0 -0
  136. data/doc/images/arrow_up.png +0 -0
  137. data/doc/images/brick.png +0 -0
  138. data/doc/images/brick_link.png +0 -0
  139. data/doc/images/bug.png +0 -0
  140. data/doc/images/bullet_black.png +0 -0
  141. data/doc/images/bullet_toggle_minus.png +0 -0
  142. data/doc/images/bullet_toggle_plus.png +0 -0
  143. data/doc/images/date.png +0 -0
  144. data/doc/images/delete.png +0 -0
  145. data/doc/images/find.png +0 -0
  146. data/doc/images/loadingAnimation.gif +0 -0
  147. data/doc/images/macFFBgHack.png +0 -0
  148. data/doc/images/package.png +0 -0
  149. data/doc/images/page_green.png +0 -0
  150. data/doc/images/page_white_text.png +0 -0
  151. data/doc/images/page_white_width.png +0 -0
  152. data/doc/images/plugin.png +0 -0
  153. data/doc/images/ruby.png +0 -0
  154. data/doc/images/tag_blue.png +0 -0
  155. data/doc/images/tag_green.png +0 -0
  156. data/doc/images/transparent.png +0 -0
  157. data/doc/images/wrench.png +0 -0
  158. data/doc/images/wrench_orange.png +0 -0
  159. data/doc/images/zoom.png +0 -0
  160. data/doc/index.html +0 -626
  161. data/doc/js/darkfish.js +0 -161
  162. data/doc/js/jquery.js +0 -4
  163. data/doc/js/navigation.js +0 -142
  164. data/doc/js/navigation.js.gz +0 -0
  165. data/doc/js/search.js +0 -109
  166. data/doc/js/search_index.js +0 -1
  167. data/doc/js/search_index.js.gz +0 -0
  168. data/doc/js/searcher.js +0 -228
  169. data/doc/js/searcher.js.gz +0 -0
  170. data/doc/table_of_contents.html +0 -942
  171. data/examples/cachegrind.out.1 +0 -114
  172. data/examples/cachegrind.out.1.32313213 +0 -114
  173. data/examples/flat.txt +0 -50
  174. data/examples/graph.dot +0 -84
  175. data/examples/graph.html +0 -823
  176. data/examples/graph.txt +0 -139
  177. data/examples/multi.flat.txt +0 -23
  178. data/examples/multi.graph.html +0 -760
  179. data/examples/multi.grind.dat +0 -114
  180. data/examples/multi.stack.html +0 -547
  181. data/examples/stack.html +0 -547
  182. data/ext/ruby_prof/rp_measure.c +0 -40
  183. data/ext/ruby_prof/rp_measure.h +0 -45
  184. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
  185. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
  186. data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
  187. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +0 -108
  188. data/ext/ruby_prof/vc/ruby_prof_19.vcxproj +0 -110
  189. data/lib/ruby-prof/aggregate_call_info.rb +0 -76
  190. data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
  191. data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
  192. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -64
  193. data/test/aggregate_test.rb +0 -136
  194. data/test/block_test.rb +0 -74
  195. data/test/call_info_test.rb +0 -78
  196. data/test/issue137_test.rb +0 -63
  197. data/test/measure_cpu_time_test.rb +0 -213
  198. data/test/measure_gc_runs_test.rb +0 -32
  199. data/test/measure_gc_time_test.rb +0 -36
  200. data/test/measure_memory_test.rb +0 -33
  201. data/test/method_elimination_test.rb +0 -84
  202. data/test/module_test.rb +0 -45
  203. data/test/stack_test.rb +0 -138
@@ -1,54 +1,56 @@
1
- # A silly little test program that finds prime numbers. It
2
- # is intentionally badly designed to show off the use
3
- # of ruby-prof.
4
- #
5
- # Source from http://people.cs.uchicago.edu/~bomb154/154/maclabs/profilers-lab/
6
-
7
- def make_random_array(length, maxnum)
8
- result = Array.new(length)
9
- result.each_index do |i|
10
- result[i] = rand(maxnum)
11
- end
12
-
13
- result
14
- end
15
-
16
- def is_prime(x)
17
- y = 2
18
- y.upto(x-1) do |i|
19
- return false if (x % i) == 0
20
- end
21
- true
22
- end
23
-
24
- def find_primes(arr)
25
- result = arr.select do |value|
26
- is_prime(value)
27
- end
28
- result
29
- end
30
-
31
- def find_largest(primes)
32
- largest = primes.first
33
-
34
- # Intentionally use upto for example purposes
35
- # (upto is also called from is_prime)
36
- 0.upto(primes.length-1) do |i|
37
- prime = primes[i]
38
- if prime > largest
39
- largest = prime
40
- end
41
- end
42
- largest
43
- end
44
-
45
- def run_primes(length=10, maxnum=1000)
46
- # Create random numbers
47
- random_array = make_random_array(length, maxnum)
48
-
49
- # Find the primes
50
- primes = find_primes(random_array)
51
-
52
- # Find the largest primes
53
- find_largest(primes)
54
- end
1
+ # A silly little test program that finds prime numbers. It
2
+ # is intentionally badly designed to show off the use
3
+ # of ruby-prof.
4
+ #
5
+ # Source from http://people.cs.uchicago.edu/~bomb154/154/maclabs/profilers-lab/
6
+
7
+ require File.expand_path('../test_helper', __FILE__)
8
+
9
+ def make_random_array(length, maxnum)
10
+ result = Array.new(length)
11
+ result.each_index do |i|
12
+ result[i] = rand(maxnum)
13
+ end
14
+
15
+ result
16
+ end
17
+
18
+ def is_prime(x)
19
+ y = 2
20
+ y.upto(x-1) do |i|
21
+ return false if (x % i) == 0
22
+ end
23
+ true
24
+ end
25
+
26
+ def find_primes(arr)
27
+ result = arr.select do |value|
28
+ is_prime(value)
29
+ end
30
+ result
31
+ end
32
+
33
+ def find_largest(primes)
34
+ largest = primes.first
35
+
36
+ # Intentionally use upto for example purposes
37
+ # (upto is also called from is_prime)
38
+ 0.upto(primes.length-1) do |i|
39
+ prime = primes[i]
40
+ if prime > largest
41
+ largest = prime
42
+ end
43
+ end
44
+ largest
45
+ end
46
+
47
+ def run_primes(length=10, maxnum=1000)
48
+ # Create random numbers
49
+ random_array = make_random_array(length, maxnum)
50
+
51
+ # Find the primes
52
+ primes = find_primes(random_array)
53
+
54
+ # Find the largest primes
55
+ find_largest(primes)
56
+ end
@@ -0,0 +1,28 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterCallStackTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def test_graph_html_string
21
+ output = ''
22
+ printer = RubyProf::CallStackPrinter.new(@result)
23
+ printer.print(output)
24
+
25
+ assert_match(/<!DOCTYPE html>/i, output)
26
+ assert_match(/Object#run_primes/i, output)
27
+ end
28
+ end
@@ -0,0 +1,31 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterCallTreeTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def test_call_tree_string
21
+ printer = RubyProf::CallTreePrinter.new(@result)
22
+
23
+ printer.print(:profile => "lolcat", :path => Dir.tmpdir)
24
+ main_output_file_name = File.join(Dir.tmpdir, "lolcat.callgrind.out.#{$$}")
25
+ assert(File.exist?(main_output_file_name))
26
+ output = File.read(main_output_file_name)
27
+ assert_match(/fn=Object::find_primes/i, output)
28
+ assert_match(/events: wall_time/i, output)
29
+ refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
30
+ end
31
+ end
@@ -0,0 +1,68 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterFlatTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def flat_output_nth_column_values(output, n)
21
+ only_method_calls = output.split("\n").select { |line| line =~ /^ +\d+/ }
22
+ only_method_calls.collect { |line| line.split(/ +/)[n] }
23
+ end
24
+
25
+ def assert_sorted array
26
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
27
+ assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
28
+ end
29
+
30
+ def test_flat_string
31
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
32
+ assert_match(/prime.rb/, output)
33
+ end
34
+
35
+ def helper_test_flat_string(klass)
36
+ output = ''
37
+
38
+ printer = klass.new(@result)
39
+ printer.print(output)
40
+
41
+ assert_match(/Thread ID: -?\d+/i, output)
42
+ assert_match(/Fiber ID: -?\d+/i, output)
43
+ assert_match(/Total: \d+\.\d+/i, output)
44
+ assert_match(/Object#run_primes/i, output)
45
+ output
46
+ end
47
+
48
+ def test_flat_result_sorting_by_self_time_is_default
49
+ printer = RubyProf::FlatPrinter.new(@result)
50
+
51
+ printer.print(output = '')
52
+ self_times = flat_output_nth_column_values(output, 3)
53
+
54
+ assert_sorted self_times
55
+ end
56
+
57
+ def test_flat_result_sorting
58
+ printer = RubyProf::FlatPrinter.new(@result)
59
+
60
+ sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
61
+
62
+ sort_method_with_column_number.each_pair do |sort_method, n|
63
+ printer.print(output = '', :sort_method => sort_method)
64
+ times = flat_output_nth_column_values(output, n)
65
+ assert_sorted times
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,60 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterGraphHtmlTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def graph_html_output_nth_column_values(output, n)
21
+ only_root_calls = output.split('<tr class="method">')
22
+ only_root_calls.delete_at(0)
23
+ only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
24
+ end
25
+
26
+ def assert_sorted array
27
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
28
+ assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
29
+ end
30
+
31
+ def test_graph_html_string
32
+ output = ''
33
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
34
+ printer.print(output)
35
+
36
+ assert_match(/<!DOCTYPE html>/i, output)
37
+ assert_match( %r{<th>Total</th>}i, output)
38
+ assert_match(/Object#run_primes/i, output)
39
+ end
40
+
41
+ def test_graph_html_result_sorting_by_total_time_is_default
42
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
43
+ printer.print(output = '')
44
+ total_times = graph_html_output_nth_column_values(output, 3)
45
+
46
+ assert_sorted total_times
47
+ end
48
+
49
+ def test_graph_html_result_sorting
50
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
51
+
52
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
53
+
54
+ sort_method_with_column_number.each_pair do |sort_method, n|
55
+ printer.print(output = '', :sort_method => sort_method)
56
+ times = graph_html_output_nth_column_values(output, n)
57
+ assert_sorted times
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,41 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterGraphTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def graph_output_nth_column_values(output, n)
21
+ only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
22
+ only_root_calls.collect { |line| line.split(/ +/)[n] }
23
+ end
24
+
25
+ def assert_sorted array
26
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
27
+ assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
28
+ end
29
+
30
+ def test_graph_results_sorting
31
+ printer = RubyProf::GraphPrinter.new(@result)
32
+
33
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
34
+
35
+ sort_method_with_column_number.each_pair do |sort_method, n|
36
+ printer.print(output = '', :sort_method => sort_method)
37
+ times = graph_output_nth_column_values(output, n)
38
+ assert_sorted times
39
+ end
40
+ end
41
+ end
@@ -1,255 +1,141 @@
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_flat_string
67
- output = helper_test_flat_string(RubyProf::FlatPrinter)
68
- refute_match(/prime.rb/, output)
69
- end
70
-
71
- def helper_test_flat_string(klass)
72
- output = ''
73
-
74
- printer = klass.new(@result)
75
- printer.print(output)
76
-
77
- assert_match(/Thread ID: -?\d+/i, output)
78
- assert_match(/Fiber ID: -?\d+/i, output)
79
- assert_match(/Total: \d+\.\d+/i, output)
80
- assert_match(/Object#run_primes/i, output)
81
- output
82
- end
83
-
84
- def test_flat_string_with_numbers
85
- output = helper_test_flat_string RubyProf::FlatPrinterWithLineNumbers
86
- assert_match(/prime.rb/, output)
87
- refute_match(/ruby_runtime:0/, output)
88
- assert_match(/called from/, output)
89
-
90
- # should combine common parents
91
- # 1.9 inlines it's Fixnum#- so we don't see as many
92
- assert_equal(2, output.scan(/Object#is_prime/).length)
93
- refute_match(/\.\/test\/prime.rb/, output) # don't use relative paths
94
- end
95
-
96
- def test_graph_html_string
97
- output = ''
98
- printer = RubyProf::GraphHtmlPrinter.new(@result)
99
- printer.print(output)
100
-
101
- assert_match(/DTD HTML 4\.01/i, output)
102
- assert_match( %r{<th>Total Time</th>}i, output)
103
- assert_match(/Object#run_primes/i, output)
104
- end
105
-
106
- def test_graph_string
107
- output = ''
108
- printer = RubyProf::GraphPrinter.new(@result)
109
- printer.print(output)
110
-
111
- assert_match(/Thread ID: -?\d+/i, output)
112
- assert_match(/Fiber ID: -?\d+/i, output)
113
- assert_match(/Total Time: \d+\.\d+/i, output)
114
- assert_match(/Object#run_primes/i, output)
115
- end
116
-
117
- def test_call_tree_string
118
- printer = RubyProf::CallTreePrinter.new(@result)
119
- printer.print(:profile => "lolcat", :path => RubyProf.tmpdir)
120
- main_output_file_name = File.join(RubyProf.tmpdir, "lolcat.callgrind.out.#{$$}")
121
- assert(File.exist?(main_output_file_name))
122
- output = File.read(main_output_file_name)
123
- assert_match(/fn=Object#find_primes/i, output)
124
- assert_match(/events: wall_time/i, output)
125
- refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
126
- end
127
-
128
- def do_nothing
129
- start = Time.now
130
- while(Time.now == start)
131
- end
132
- end
133
-
134
- def test_all_with_small_percentiles
135
- result = RubyProf.profile do
136
- sleep 2
137
- do_nothing
138
- end
139
-
140
- # RubyProf::CallTreePrinter doesn't "do" a min_percent
141
- # RubyProf::FlatPrinter only outputs if self time > percent...
142
- # RubyProf::FlatPrinterWithLineNumbers same
143
- for klass in [ RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
144
- printer = klass.new(result)
145
- out = ''
146
- printer.print(out, :min_percent => 0.00000001)
147
- assert_match(/do_nothing/, out)
148
- end
149
-
150
- end
151
-
152
- def test_flat_result_sorting_by_self_time_is_default
153
- printer = RubyProf::FlatPrinter.new(@result)
154
-
155
- printer.print(output = '')
156
- self_times = flat_output_nth_column_values(output, 3)
157
-
158
- assert_sorted self_times
159
- end
160
-
161
- def test_flat_result_sorting
162
- printer = RubyProf::FlatPrinter.new(@result)
163
-
164
- sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
165
-
166
- sort_method_with_column_number.each_pair do |sort_method, n|
167
- printer.print(output = '', :sort_method => sort_method)
168
- times = flat_output_nth_column_values(output, n)
169
- assert_sorted times
170
- end
171
- end
172
-
173
- def test_flat_result_with_line_numbers_sorting_by_self_time_is_default
174
- printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
175
-
176
- printer.print(output = '')
177
- self_times = flat_output_nth_column_values(output, 3)
178
-
179
- assert_sorted self_times
180
- end
181
-
182
- def test_flat_with_line_numbers_result_sorting
183
- printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
184
-
185
- sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
186
-
187
- sort_method_with_column_number.each_pair do |sort_method, n|
188
- printer.print(output = '', :sort_method => sort_method)
189
- times = flat_output_nth_column_values(output, n)
190
- assert_sorted times
191
- end
192
- end
193
-
194
- def test_graph_result_sorting_by_total_time_is_default
195
- printer = RubyProf::GraphPrinter.new(@result)
196
- printer.print(output = '')
197
- total_times = graph_output_nth_column_values(output, 3)
198
-
199
- assert_sorted total_times
200
- end
201
-
202
- def test_graph_results_sorting
203
- printer = RubyProf::GraphPrinter.new(@result)
204
-
205
- sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
206
-
207
- sort_method_with_column_number.each_pair do |sort_method, n|
208
- printer.print(output = '', :sort_method => sort_method)
209
- times = graph_output_nth_column_values(output, n)
210
- assert_sorted times
211
- end
212
- end
213
-
214
- def test_graph_html_result_sorting_by_total_time_is_default
215
- printer = RubyProf::GraphHtmlPrinter.new(@result)
216
- printer.print(output = '')
217
- total_times = graph_html_output_nth_column_values(output, 3)
218
-
219
- assert_sorted total_times
220
- end
221
-
222
- def test_graph_html_result_sorting
223
- printer = RubyProf::GraphHtmlPrinter.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_html_output_nth_column_values(output, n)
230
- assert_sorted times
231
- end
232
- end
233
-
234
- private
235
- def flat_output_nth_column_values(output, n)
236
- only_method_calls = output.split("\n").select { |line| line =~ /^ +\d+/ }
237
- only_method_calls.collect { |line| line.split(/ +/)[n] }
238
- end
239
-
240
- def graph_output_nth_column_values(output, n)
241
- only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
242
- only_root_calls.collect { |line| line.split(/ +/)[n] }
243
- end
244
-
245
- def graph_html_output_nth_column_values(output, n)
246
- only_root_calls = output.split('<tr class="method">')
247
- only_root_calls.delete_at(0)
248
- only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
249
- end
250
-
251
- def assert_sorted array
252
- array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
253
- assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
254
- end
255
- end
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrintersTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def test_printers
21
+ output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new('')
22
+
23
+ printer = RubyProf::CallInfoPrinter.new(@result)
24
+ printer.print(output)
25
+
26
+ printer = RubyProf::CallTreePrinter.new(@result)
27
+ printer.print()
28
+
29
+ printer = RubyProf::FlatPrinter.new(@result)
30
+ printer.print(output)
31
+
32
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
33
+ printer.print(output)
34
+
35
+ printer = RubyProf::GraphPrinter.new(@result)
36
+ printer.print(output)
37
+ end
38
+
39
+ def test_print_to_files
40
+ output_dir = 'examples2'
41
+
42
+ if ENV['SAVE_NEW_PRINTER_EXAMPLES']
43
+ output_dir = 'examples'
44
+ end
45
+ FileUtils.mkdir_p output_dir
46
+
47
+ printer = RubyProf::DotPrinter.new(@result)
48
+ File.open("#{output_dir}/graph.dot", "w") {|f| printer.print(f)}
49
+
50
+ printer = RubyProf::CallStackPrinter.new(@result)
51
+ File.open("#{output_dir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
52
+
53
+ # printer = RubyProf::MultiPrinter.new(@result)
54
+ # printer.print(:path => "#{output_dir}", :profile => "multi", :application => "primes")
55
+ # for file in ['graph.dot', 'multi.flat.txt', 'multi.graph.html', "multi.callgrind.out.#{$$}", 'multi.stack.html', 'stack.html']
56
+ # existant_file = output_dir + '/' + file
57
+ # assert File.size(existant_file) > 0
58
+ # end
59
+ end
60
+
61
+ def test_refuses_io_objects
62
+ p = RubyProf::MultiPrinter.new(@result)
63
+ begin
64
+ p.print(STDOUT)
65
+ flunk "should have raised an ArgumentError"
66
+ rescue ArgumentError => e
67
+ assert_match(/IO/, e.to_s)
68
+ end
69
+ end
70
+
71
+ def test_refuses_non_hashes
72
+ p = RubyProf::MultiPrinter.new (@result)
73
+ begin
74
+ p.print([])
75
+ flunk "should have raised an ArgumentError"
76
+ rescue ArgumentError => e
77
+ assert_match(/hash/, e.to_s)
78
+ end
79
+ end
80
+
81
+ def test_flat_string
82
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
83
+ assert_match(/prime.rb/, output)
84
+ end
85
+
86
+ def helper_test_flat_string(klass)
87
+ output = ''
88
+
89
+ printer = klass.new(@result)
90
+ printer.print(output)
91
+
92
+ assert_match(/Thread ID: -?\d+/i, output)
93
+ assert_match(/Fiber ID: -?\d+/i, output)
94
+ assert_match(/Total: \d+\.\d+/i, output)
95
+ assert_match(/Object#run_primes/i, output)
96
+ output
97
+ end
98
+
99
+ def test_graph_html_string
100
+ output = ''
101
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
102
+ printer.print(output)
103
+
104
+ assert_match(/<!DOCTYPE html>/i, output)
105
+ assert_match( %r{<th>Total</th>}i, output)
106
+ assert_match(/Object#run_primes/i, output)
107
+ end
108
+
109
+ def test_graph_string
110
+ output = ''
111
+ printer = RubyProf::GraphPrinter.new(@result)
112
+ printer.print(output)
113
+
114
+ assert_match(/Thread ID: -?\d+/i, output)
115
+ assert_match(/Fiber ID: -?\d+/i, output)
116
+ assert_match(/Total Time: \d+\.\d+/i, output)
117
+ assert_match(/Object#run_primes/i, output)
118
+ end
119
+
120
+ def do_nothing
121
+ start = Time.now
122
+ while(Time.now == start)
123
+ end
124
+ end
125
+
126
+ def test_all_with_small_percentiles
127
+ result = RubyProf.profile do
128
+ sleep 2
129
+ do_nothing
130
+ end
131
+
132
+ # RubyProf::CallTreePrinter doesn't "do" a min_percent
133
+ # RubyProf::FlatPrinter only outputs if self time > percent...
134
+ for klass in [RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
135
+ printer = klass.new(result)
136
+ out = ''
137
+ printer.print(out, :min_percent => 0.00000001)
138
+ assert_match(/do_nothing/, out)
139
+ end
140
+ end
141
+ end