ruby-prof 0.13.1 → 1.4.2

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 (209) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +579 -371
  3. data/LICENSE +24 -23
  4. data/README.rdoc +5 -433
  5. data/Rakefile +98 -110
  6. data/bin/ruby-prof +328 -329
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/ext/ruby_prof/extconf.rb +16 -59
  9. data/ext/ruby_prof/rp_aggregate_call_tree.c +59 -0
  10. data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
  11. data/ext/ruby_prof/rp_allocation.c +287 -0
  12. data/ext/ruby_prof/rp_allocation.h +31 -0
  13. data/ext/ruby_prof/rp_call_tree.c +369 -0
  14. data/ext/ruby_prof/rp_call_tree.h +43 -0
  15. data/ext/ruby_prof/rp_call_trees.c +288 -0
  16. data/ext/ruby_prof/rp_call_trees.h +28 -0
  17. data/ext/ruby_prof/rp_measure_allocations.c +50 -65
  18. data/ext/ruby_prof/rp_measure_memory.c +42 -73
  19. data/ext/ruby_prof/rp_measure_process_time.c +65 -71
  20. data/ext/ruby_prof/rp_measure_wall_time.c +64 -42
  21. data/ext/ruby_prof/rp_measurement.c +237 -0
  22. data/ext/ruby_prof/rp_measurement.h +50 -0
  23. data/ext/ruby_prof/rp_method.c +491 -420
  24. data/ext/ruby_prof/rp_method.h +62 -57
  25. data/ext/ruby_prof/rp_profile.c +908 -0
  26. data/ext/ruby_prof/rp_profile.h +35 -0
  27. data/ext/ruby_prof/rp_stack.c +212 -128
  28. data/ext/ruby_prof/rp_stack.h +53 -51
  29. data/ext/ruby_prof/rp_thread.c +362 -268
  30. data/ext/ruby_prof/rp_thread.h +39 -27
  31. data/ext/ruby_prof/ruby_prof.c +52 -695
  32. data/ext/ruby_prof/ruby_prof.h +26 -55
  33. data/ext/ruby_prof/vc/ruby_prof.sln +28 -21
  34. data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +56 -8
  35. data/lib/ruby-prof.rb +52 -67
  36. data/lib/ruby-prof/assets/call_stack_printer.html.erb +710 -0
  37. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  38. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
  39. data/lib/ruby-prof/call_tree.rb +57 -0
  40. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  41. data/lib/ruby-prof/compatibility.rb +99 -169
  42. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  43. data/lib/ruby-prof/measurement.rb +17 -0
  44. data/lib/ruby-prof/method_info.rb +78 -131
  45. data/lib/ruby-prof/printers/abstract_printer.rb +137 -85
  46. data/lib/ruby-prof/printers/call_info_printer.rb +53 -41
  47. data/lib/ruby-prof/printers/call_stack_printer.rb +180 -773
  48. data/lib/ruby-prof/printers/call_tree_printer.rb +151 -92
  49. data/lib/ruby-prof/printers/dot_printer.rb +132 -132
  50. data/lib/ruby-prof/printers/flat_printer.rb +53 -69
  51. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -255
  52. data/lib/ruby-prof/printers/graph_printer.rb +113 -116
  53. data/lib/ruby-prof/printers/multi_printer.rb +127 -56
  54. data/lib/ruby-prof/profile.rb +37 -77
  55. data/lib/ruby-prof/rack.rb +62 -15
  56. data/lib/ruby-prof/task.rb +147 -147
  57. data/lib/ruby-prof/thread.rb +10 -12
  58. data/lib/ruby-prof/version.rb +3 -0
  59. data/lib/unprof.rb +10 -10
  60. data/ruby-prof.gemspec +65 -61
  61. data/test/abstract_printer_test.rb +26 -0
  62. data/test/alias_test.rb +126 -0
  63. data/test/basic_test.rb +43 -128
  64. data/test/call_tree_visitor_test.rb +32 -0
  65. data/test/call_trees_test.rb +66 -0
  66. data/test/duplicate_names_test.rb +32 -32
  67. data/test/dynamic_method_test.rb +53 -74
  68. data/test/enumerable_test.rb +21 -16
  69. data/test/exceptions_test.rb +24 -16
  70. data/test/exclude_methods_test.rb +151 -0
  71. data/test/exclude_threads_test.rb +53 -54
  72. data/test/fiber_test.rb +129 -65
  73. data/test/gc_test.rb +90 -0
  74. data/test/inverse_call_tree_test.rb +175 -0
  75. data/test/line_number_test.rb +158 -71
  76. data/test/marshal_test.rb +113 -0
  77. data/test/measure_allocations.rb +30 -0
  78. data/test/measure_allocations_test.rb +375 -25
  79. data/test/measure_allocations_trace_test.rb +375 -0
  80. data/test/measure_memory_trace_test.rb +1101 -0
  81. data/test/measure_process_time_test.rb +785 -62
  82. data/test/measure_times.rb +56 -0
  83. data/test/measure_wall_time_test.rb +434 -254
  84. data/test/multi_printer_test.rb +71 -82
  85. data/test/no_method_class_test.rb +15 -15
  86. data/test/pause_resume_test.rb +175 -166
  87. data/test/prime.rb +54 -54
  88. data/test/prime_script.rb +6 -0
  89. data/test/printer_call_stack_test.rb +27 -0
  90. data/test/printer_call_tree_test.rb +30 -0
  91. data/test/printer_flat_test.rb +99 -0
  92. data/test/printer_graph_html_test.rb +59 -0
  93. data/test/printer_graph_test.rb +40 -0
  94. data/test/printers_test.rb +141 -257
  95. data/test/printing_recursive_graph_test.rb +81 -0
  96. data/test/profile_test.rb +16 -0
  97. data/test/rack_test.rb +93 -0
  98. data/test/recursive_test.rb +206 -215
  99. data/test/singleton_test.rb +38 -38
  100. data/test/stack_printer_test.rb +64 -78
  101. data/test/start_stop_test.rb +109 -112
  102. data/test/test_helper.rb +13 -115
  103. data/test/thread_test.rb +144 -178
  104. data/test/unique_call_path_test.rb +120 -224
  105. data/test/yarv_test.rb +56 -0
  106. metadata +77 -133
  107. data/doc/LICENSE.html +0 -155
  108. data/doc/README_rdoc.html +0 -648
  109. data/doc/Rack.html +0 -167
  110. data/doc/Rack/RubyProf.html +0 -319
  111. data/doc/RubyProf.html +0 -1000
  112. data/doc/RubyProf/AbstractPrinter.html +0 -580
  113. data/doc/RubyProf/AggregateCallInfo.html +0 -570
  114. data/doc/RubyProf/CallInfo.html +0 -512
  115. data/doc/RubyProf/CallInfoPrinter.html +0 -190
  116. data/doc/RubyProf/CallInfoVisitor.html +0 -332
  117. data/doc/RubyProf/CallStackPrinter.html +0 -1600
  118. data/doc/RubyProf/CallTreePrinter.html +0 -413
  119. data/doc/RubyProf/Cmd.html +0 -669
  120. data/doc/RubyProf/DotPrinter.html +0 -312
  121. data/doc/RubyProf/FlatPrinter.html +0 -229
  122. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -267
  123. data/doc/RubyProf/GraphHtmlPrinter.html +0 -630
  124. data/doc/RubyProf/GraphPrinter.html +0 -209
  125. data/doc/RubyProf/MethodInfo.html +0 -713
  126. data/doc/RubyProf/MultiPrinter.html +0 -407
  127. data/doc/RubyProf/Profile.html +0 -821
  128. data/doc/RubyProf/ProfileTask.html +0 -532
  129. data/doc/RubyProf/Test.html +0 -578
  130. data/doc/RubyProf/Thread.html +0 -262
  131. data/doc/created.rid +0 -32
  132. data/doc/examples/flat_txt.html +0 -191
  133. data/doc/examples/graph_txt.html +0 -305
  134. data/doc/images/add.png +0 -0
  135. data/doc/images/brick.png +0 -0
  136. data/doc/images/brick_link.png +0 -0
  137. data/doc/images/bug.png +0 -0
  138. data/doc/images/bullet_black.png +0 -0
  139. data/doc/images/bullet_toggle_minus.png +0 -0
  140. data/doc/images/bullet_toggle_plus.png +0 -0
  141. data/doc/images/date.png +0 -0
  142. data/doc/images/delete.png +0 -0
  143. data/doc/images/find.png +0 -0
  144. data/doc/images/loadingAnimation.gif +0 -0
  145. data/doc/images/macFFBgHack.png +0 -0
  146. data/doc/images/package.png +0 -0
  147. data/doc/images/page_green.png +0 -0
  148. data/doc/images/page_white_text.png +0 -0
  149. data/doc/images/page_white_width.png +0 -0
  150. data/doc/images/plugin.png +0 -0
  151. data/doc/images/ruby.png +0 -0
  152. data/doc/images/tag_blue.png +0 -0
  153. data/doc/images/tag_green.png +0 -0
  154. data/doc/images/transparent.png +0 -0
  155. data/doc/images/wrench.png +0 -0
  156. data/doc/images/wrench_orange.png +0 -0
  157. data/doc/images/zoom.png +0 -0
  158. data/doc/index.html +0 -647
  159. data/doc/js/darkfish.js +0 -155
  160. data/doc/js/jquery.js +0 -18
  161. data/doc/js/navigation.js +0 -142
  162. data/doc/js/search.js +0 -94
  163. data/doc/js/search_index.js +0 -1
  164. data/doc/js/searcher.js +0 -228
  165. data/doc/rdoc.css +0 -543
  166. data/doc/table_of_contents.html +0 -462
  167. data/examples/empty.png +0 -0
  168. data/examples/flat.txt +0 -55
  169. data/examples/graph.dot +0 -106
  170. data/examples/graph.html +0 -823
  171. data/examples/graph.png +0 -0
  172. data/examples/graph.txt +0 -170
  173. data/examples/minus.png +0 -0
  174. data/examples/multi.flat.txt +0 -23
  175. data/examples/multi.graph.html +0 -906
  176. data/examples/multi.grind.dat +0 -194
  177. data/examples/multi.stack.html +0 -573
  178. data/examples/plus.png +0 -0
  179. data/examples/stack.html +0 -573
  180. data/ext/ruby_prof/rp_call_info.c +0 -407
  181. data/ext/ruby_prof/rp_call_info.h +0 -48
  182. data/ext/ruby_prof/rp_measure.c +0 -48
  183. data/ext/ruby_prof/rp_measure.h +0 -45
  184. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -112
  185. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -65
  186. data/ext/ruby_prof/rp_measure_gc_time.c +0 -57
  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/ext/ruby_prof/version.h +0 -7
  190. data/lib/ruby-prof/aggregate_call_info.rb +0 -72
  191. data/lib/ruby-prof/call_info.rb +0 -89
  192. data/lib/ruby-prof/call_info_visitor.rb +0 -44
  193. data/lib/ruby-prof/images/empty.png +0 -0
  194. data/lib/ruby-prof/images/minus.png +0 -0
  195. data/lib/ruby-prof/images/plus.png +0 -0
  196. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -57
  197. data/lib/ruby-prof/test.rb +0 -150
  198. data/test/aggregate_test.rb +0 -136
  199. data/test/call_info_test.rb +0 -78
  200. data/test/call_info_visitor_test.rb +0 -31
  201. data/test/exec_test.rb +0 -14
  202. data/test/measure_cpu_time_test.rb +0 -220
  203. data/test/measure_gc_runs_test.rb +0 -32
  204. data/test/measure_gc_time_test.rb +0 -36
  205. data/test/measure_memory_test.rb +0 -31
  206. data/test/method_elimination_test.rb +0 -84
  207. data/test/module_test.rb +0 -45
  208. data/test/stack_test.rb +0 -138
  209. data/test/test_suite.rb +0 -37
@@ -1,54 +1,54 @@
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
+ 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=1_000)
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
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # This file is used to test bin/ruby-prof
5
+ require_relative './prime'
6
+ run_primes(100, 1_000_000)
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterCallStackTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def test_graph_html_string
20
+ output = ''
21
+ printer = RubyProf::CallStackPrinter.new(@result)
22
+ printer.print(output)
23
+
24
+ assert_match(/<!DOCTYPE html>/i, output)
25
+ assert_match(/Object#run_primes/i, output)
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterCallTreeTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def test_call_tree_string
20
+ printer = RubyProf::CallTreePrinter.new(@result)
21
+
22
+ printer.print(:profile => "lolcat", :path => Dir.tmpdir)
23
+ main_output_file_name = File.join(Dir.tmpdir, "lolcat.callgrind.out.#{$$}")
24
+ assert(File.exist?(main_output_file_name))
25
+ output = File.read(main_output_file_name)
26
+ assert_match(/fn=Object::find_primes/i, output)
27
+ assert_match(/events: wall_time/i, output)
28
+ refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
29
+ end
30
+ end
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'stringio'
7
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterFlatTest < TestCase
12
+ def run_profile
13
+ RubyProf.profile(:measure_mode => RubyProf::WALL_TIME) do
14
+ run_primes(1000, 5000)
15
+ end
16
+ end
17
+
18
+ def flat_output_nth_column_values(output, n)
19
+ only_method_calls = output.split("\n").select { |line| line =~ /^\s+\d+/ }
20
+ only_method_calls.collect { |line| line.split(/\s+/)[n] }
21
+ end
22
+
23
+ def helper_test_flat_string(klass)
24
+ output = StringIO.new
25
+
26
+ printer = klass.new(self.run_profile)
27
+ printer.print(output)
28
+
29
+ assert_match(/Thread ID: -?\d+/i, output.string)
30
+ assert_match(/Fiber ID: -?\d+/i, output.string)
31
+ assert_match(/Total: \d+\.\d+/i, output.string)
32
+ assert_match(/Object#run_primes/i, output.string)
33
+ output.string
34
+ end
35
+
36
+ def assert_sorted(array)
37
+ array = array.map(&:to_f) # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
38
+ assert_equal(array, array.sort.reverse)
39
+ end
40
+
41
+ def test_flat_string
42
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
43
+ assert_match(/prime.rb/, output)
44
+ end
45
+
46
+ def test_flat_result_sorting_by_self_time_is_default
47
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
48
+
49
+ output = StringIO.new
50
+ printer.print(output)
51
+ self_times = flat_output_nth_column_values(output.string, 3)
52
+
53
+ assert_sorted self_times
54
+ end
55
+
56
+ def test_flat_result_sorting
57
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
58
+
59
+ sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
60
+
61
+ sort_method_with_column_number.each_pair do |sort_method, n|
62
+ output = StringIO.new
63
+ printer.print(output, :sort_method => sort_method)
64
+
65
+ times = flat_output_nth_column_values(output.string, n)
66
+ assert_sorted(times)
67
+ end
68
+ end
69
+
70
+ def test_flat_result_max_percent
71
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
72
+
73
+ output = StringIO.new
74
+ printer.print(output, max_percent: 1)
75
+ self_percents = flat_output_nth_column_values(output.string, 1).map(&:to_f)
76
+
77
+ assert self_percents.max < 1
78
+ end
79
+
80
+ def test_flat_result_filter_by_total_time
81
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
82
+
83
+ output = StringIO.new
84
+ printer.print(output, filter_by: :total_time, min_percent: 50)
85
+ total_times = flat_output_nth_column_values(output.string, 2).map(&:to_f)
86
+
87
+ assert (total_times.min / total_times.max) >= 0.5
88
+ end
89
+
90
+ def test_flat_result_filter_by_self_time
91
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
92
+
93
+ output = StringIO.new
94
+ printer.print(output, filter_by: :self_time, min_percent: 0.1)
95
+ self_percents = flat_output_nth_column_values(output.string, 1).map(&:to_f)
96
+
97
+ assert self_percents.min >= 0.1
98
+ end
99
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterGraphHtmlTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def graph_html_output_nth_column_values(output, n)
20
+ only_root_calls = output.split('<tr class="method">')
21
+ only_root_calls.delete_at(0)
22
+ only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
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_html_string
31
+ output = ''
32
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
33
+ printer.print(output)
34
+
35
+ assert_match(/<!DOCTYPE html>/i, output)
36
+ assert_match( %r{<th>Total</th>}i, output)
37
+ assert_match(/Object#run_primes/i, output)
38
+ end
39
+
40
+ def test_graph_html_result_sorting_by_total_time_is_default
41
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
42
+ printer.print(output = '')
43
+ total_times = graph_html_output_nth_column_values(output, 3)
44
+
45
+ assert_sorted total_times
46
+ end
47
+
48
+ def test_graph_html_result_sorting
49
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
50
+
51
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
52
+
53
+ sort_method_with_column_number.each_pair do |sort_method, n|
54
+ printer.print(output = '', :sort_method => sort_method)
55
+ times = graph_html_output_nth_column_values(output, n)
56
+ assert_sorted times
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterGraphTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def graph_output_nth_column_values(output, n)
20
+ only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
21
+ only_root_calls.collect { |line| line.split(/ +/)[n] }
22
+ end
23
+
24
+ def assert_sorted(array)
25
+ array = array.map {|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
26
+ assert_equal(array, array.sort.reverse, "Array #{array.inspect} is not sorted")
27
+ end
28
+
29
+ def test_graph_results_sorting
30
+ printer = RubyProf::GraphPrinter.new(@result)
31
+
32
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
33
+
34
+ sort_method_with_column_number.each_pair do |sort_method, n|
35
+ printer.print(output = '', :sort_method => sort_method)
36
+ times = graph_output_nth_column_values(output, n)
37
+ assert_sorted times
38
+ end
39
+ end
40
+ end
@@ -1,257 +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 < Test::Unit::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(200)
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(output)
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 ['empty.png', 'graph.dot', 'minus.png', 'multi.flat.txt', 'multi.graph.html', 'multi.grind.dat', 'multi.stack.html', 'plus.png', '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
- assert_no_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) unless RUBY_VERSION =~ /^1.8/
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
- assert_no_match(/ruby_runtime:0/, output)
88
- assert_match(/called from/, output)
89
-
90
- # should combine common parents
91
- if RUBY_VERSION < '1.9'
92
- assert_equal(3, output.scan(/Object#is_prime/).length)
93
- else
94
- # 1.9 inlines it's Fixnum#- so we don't see as many
95
- assert_equal(2, output.scan(/Object#is_prime/).length)
96
- end
97
- assert_no_match(/\.\/test\/prime.rb/, output) # don't use relative paths
98
- end
99
-
100
- def test_graph_html_string
101
- output = ''
102
- printer = RubyProf::GraphHtmlPrinter.new(@result)
103
- printer.print(output)
104
-
105
- assert_match(/DTD HTML 4\.01/i, output)
106
- assert_match( %r{<th>Total Time</th>}i, output)
107
- assert_match(/Object#run_primes/i, output)
108
- end
109
-
110
- def test_graph_string
111
- output = ''
112
- printer = RubyProf::GraphPrinter.new(@result)
113
- printer.print(output)
114
-
115
- assert_match(/Thread ID: -?\d+/i, output)
116
- assert_match(/Fiber ID: -?\d+/i, output) unless RUBY_VERSION =~ /^1.8/
117
- assert_match(/Total Time: \d+\.\d+/i, output)
118
- assert_match(/Object#run_primes/i, output)
119
- end
120
-
121
- def test_call_tree_string
122
- output = ''
123
- printer = RubyProf::CallTreePrinter.new(@result)
124
- printer.print(output)
125
- assert_match(/fn=Object#find_primes/i, output)
126
- assert_match(/events: wall_time/i, output)
127
- assert_no_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
128
- end
129
-
130
- def do_nothing
131
- start = Time.now
132
- while(Time.now == start)
133
- end
134
- end
135
-
136
- def test_all_with_small_percentiles
137
- result = RubyProf.profile do
138
- sleep 2
139
- do_nothing
140
- end
141
-
142
- # RubyProf::CallTreePrinter doesn't "do" a min_percent
143
- # RubyProf::FlatPrinter only outputs if self time > percent...
144
- # RubyProf::FlatPrinterWithLineNumbers same
145
- for klass in [ RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
146
- printer = klass.new(result)
147
- out = ''
148
- printer.print(out, :min_percent => 0.00000001)
149
- assert_match(/do_nothing/, out)
150
- end
151
-
152
- end
153
-
154
- def test_flat_result_sorting_by_self_time_is_default
155
- printer = RubyProf::FlatPrinter.new(@result)
156
-
157
- printer.print(output = '')
158
- self_times = flat_output_nth_column_values(output, 3)
159
-
160
- assert_sorted self_times
161
- end
162
-
163
- def test_flat_result_sorting
164
- printer = RubyProf::FlatPrinter.new(@result)
165
-
166
- sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
167
-
168
- sort_method_with_column_number.each_pair do |sort_method, n|
169
- printer.print(output = '', :sort_method => sort_method)
170
- times = flat_output_nth_column_values(output, n)
171
- assert_sorted times
172
- end
173
- end
174
-
175
- def test_flat_result_with_line_numbers_sorting_by_self_time_is_default
176
- printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
177
-
178
- printer.print(output = '')
179
- self_times = flat_output_nth_column_values(output, 3)
180
-
181
- assert_sorted self_times
182
- end
183
-
184
- def test_flat_with_line_numbers_result_sorting
185
- printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
186
-
187
- sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
188
-
189
- sort_method_with_column_number.each_pair do |sort_method, n|
190
- printer.print(output = '', :sort_method => sort_method)
191
- times = flat_output_nth_column_values(output, n)
192
- assert_sorted times
193
- end
194
- end
195
-
196
- def test_graph_result_sorting_by_total_time_is_default
197
- printer = RubyProf::GraphPrinter.new(@result)
198
- printer.print(output = '')
199
- total_times = graph_output_nth_column_values(output, 3)
200
-
201
- assert_sorted total_times
202
- end
203
-
204
- def test_graph_results_sorting
205
- printer = RubyProf::GraphPrinter.new(@result)
206
-
207
- sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
208
-
209
- sort_method_with_column_number.each_pair do |sort_method, n|
210
- printer.print(output = '', :sort_method => sort_method)
211
- times = graph_output_nth_column_values(output, n)
212
- assert_sorted times
213
- end
214
- end
215
-
216
- def test_graph_html_result_sorting_by_total_time_is_default
217
- printer = RubyProf::GraphHtmlPrinter.new(@result)
218
- printer.print(output = '')
219
- total_times = graph_html_output_nth_column_values(output, 3)
220
-
221
- assert_sorted total_times
222
- end
223
-
224
- def test_graph_html_result_sorting
225
- printer = RubyProf::GraphHtmlPrinter.new(@result)
226
-
227
- sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
228
-
229
- sort_method_with_column_number.each_pair do |sort_method, n|
230
- printer.print(output = '', :sort_method => sort_method)
231
- times = graph_html_output_nth_column_values(output, n)
232
- assert_sorted times
233
- end
234
- end
235
-
236
- private
237
- def flat_output_nth_column_values(output, n)
238
- only_method_calls = output.split("\n").select { |line| line =~ /^ +\d+/ }
239
- only_method_calls.collect { |line| line.split(/ +/)[n] }
240
- end
241
-
242
- def graph_output_nth_column_values(output, n)
243
- only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
244
- only_root_calls.collect { |line| line.split(/ +/)[n] }
245
- end
246
-
247
- def graph_html_output_nth_column_values(output, n)
248
- only_root_calls = output.split('<tr class="method">')
249
- only_root_calls.delete_at(0)
250
- only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
251
- end
252
-
253
- def assert_sorted array
254
- array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
255
- assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
256
- end
257
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'stringio'
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::CallStackPrinter.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