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
@@ -0,0 +1,81 @@
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
+
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: 1307675084040
29
+ Fiber ID: 1307708787440
30
+ Total Time: 2.0939999999973224
31
+ Sort by:
32
+
33
+ %total %self total self wait child calls name
34
+ --------------------------------------------------------------------------------
35
+ 1.657 0.000 0.000 1.657 2/2 Integer#times
36
+ 79.13% 0.00% 1.657 0.000 0.000 1.657 2 PRGT#g
37
+ 1.657 0.000 0.000 1.657 2/5 Integer#times
38
+ --------------------------------------------------------------------------------
39
+ 2.094 2.094 0.000 0.000 12/12 Integer#times
40
+ 100.00% 100.00% 2.094 2.094 0.000 0.000 12 Kernel#sleep
41
+ --------------------------------------------------------------------------------
42
+ 0.437 0.000 0.000 0.437 2/2 Integer#times
43
+ 20.87% 0.00% 0.437 0.000 0.000 0.437 2 PRGT#f
44
+ 0.437 0.000 0.000 0.437 2/5 Integer#times
45
+ --------------------------------------------------------------------------------
46
+ 0.437 0.000 0.000 0.437 2/5 PRGT#f
47
+ 1.657 0.000 0.000 1.657 2/5 PRGT#g
48
+ 2.094 0.000 0.000 2.094 1/5 PRGT#run
49
+ 100.00% 0.00% 2.094 0.000 0.000 2.094 5 *Integer#times
50
+ 2.094 2.094 0.000 0.000 12/12 Kernel#sleep
51
+ 1.657 0.000 0.000 1.657 2/2 PRGT#g
52
+ 0.437 0.000 0.000 0.437 2/2 PRGT#f
53
+ --------------------------------------------------------------------------------
54
+ 2.094 0.000 0.000 2.094 1/1 PrintingRecursiveGraphTest#setup
55
+ 100.00% 0.00% 2.094 0.000 0.000 2.094 1 PRGT#run
56
+ 2.094 0.000 0.000 2.094 1/5 Integer#times
57
+ --------------------------------------------------------------------------------
58
+ 100.00% 0.00% 2.094 0.000 0.000 2.094 1 PrintingRecursiveGraphTest#setup
59
+ 2.094 0.000 0.000 2.094 1/1 PRGT#run
60
+
61
+ * indicates recursively called methods
62
+ =end
63
+
64
+ class PrintingRecursiveGraphTest < TestCase
65
+ def setup
66
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
67
+ RubyProf::measure_mode = RubyProf::WALL_TIME
68
+ @result = RubyProf.profile do
69
+ PRGT.run
70
+ end
71
+ end
72
+
73
+ def test_printing_rescursive_graph
74
+ printer = RubyProf::GraphPrinter.new(@result)
75
+ buffer = ''
76
+ printer.print(StringIO.new(buffer))
77
+ puts buffer if ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1"
78
+
79
+ refute_nil(buffer)
80
+ end
81
+ end
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class ProfileTest < TestCase
7
+ def test_measure_mode
8
+ profile = RubyProf::Profile.new(:measure_mode => RubyProf::PROCESS_TIME)
9
+ assert_equal(RubyProf::PROCESS_TIME, profile.measure_mode)
10
+ end
11
+
12
+ def test_measure_mode_string
13
+ profile = RubyProf::Profile.new(:measure_mode => RubyProf::PROCESS_TIME)
14
+ assert_equal("process_time", profile.measure_mode_string)
15
+ end
16
+ end
@@ -0,0 +1,93 @@
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
+ class RackTest < TestCase
28
+ def test_create_print_path
29
+ path = Dir.mktmpdir
30
+ Dir.delete(path)
31
+
32
+ Rack::RubyProf.new(FakeRackApp.new, :path => path)
33
+
34
+ assert(Dir.exist?(path))
35
+ end
36
+
37
+ def test_create_profile_reports
38
+ path = Dir.mktmpdir
39
+
40
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path)
41
+
42
+ adapter.call(:fake_env)
43
+
44
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
45
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
46
+ assert(File.exist?(file_path))
47
+ end
48
+ end
49
+
50
+ def test_skip_paths
51
+ path = Dir.mktmpdir
52
+
53
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :skip_paths => [%r{\.json$}])
54
+
55
+ adapter.call(:fake_env)
56
+
57
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
58
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
59
+ assert(!File.exist?(file_path))
60
+ end
61
+ end
62
+
63
+ def test_only_paths
64
+ path = Dir.mktmpdir
65
+
66
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :only_paths => [%r{\.json$}])
67
+
68
+ adapter.call({path: '/path/to/resource.json'})
69
+
70
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
71
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
72
+ assert(File.exist?(file_path))
73
+ end
74
+
75
+ adapter.call({path: '/path/to/resource.html'})
76
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
77
+ file_path = ::File.join(path, "path-to-resource.html-#{base_name}")
78
+ assert(!File.exist?(file_path))
79
+ end
80
+ end
81
+
82
+ def test_allows_lazy_filename_setting
83
+ path = Dir.mktmpdir
84
+
85
+ printer = {::RubyProf::FlatPrinter => lambda { 'dynamic.txt' }}
86
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :printers => printer)
87
+
88
+ adapter.call(:fake_env)
89
+
90
+ file_path = ::File.join(path, 'path-to-resource.json-dynamic.txt')
91
+ assert(File.exist?(file_path))
92
+ end
93
+ end
@@ -1,215 +1,206 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- # Simple recursive test
7
- def simple(n)
8
- sleep(1)
9
- n -= 1
10
- return if n == 0
11
- simple(n)
12
- end
13
-
14
-
15
- # More complicated recursive test
16
- def render_partial(i)
17
- sleep(1)
18
- case i
19
- when 0
20
- render_partial(10)
21
- when 1
22
- 2.times do |j|
23
- render_partial(j + 10)
24
- end
25
- end
26
- end
27
-
28
- def render
29
- 2.times do |i|
30
- render_partial(i)
31
- end
32
- end
33
-
34
- # -- Tests ----
35
- class RecursiveTest < Test::Unit::TestCase
36
- def setup
37
- # Need to use wall time for this test due to the sleep calls
38
- RubyProf::measure_mode = RubyProf::WALL_TIME
39
- end
40
-
41
- def test_simple
42
- result = RubyProf.profile do
43
- simple(2)
44
- end
45
-
46
- # Remove Fixnum+, Fixnum== for less than Ruby 1.9
47
- result.eliminate_methods!(%w(Fixnum#== Fixnum#-))
48
-
49
- methods = result.threads.first.methods.sort.reverse
50
- assert_equal(3, methods.length)
51
-
52
- # Method 0: RecursiveTest#test_simple
53
- method = methods[0]
54
- assert_equal('RecursiveTest#test_simple', method.full_name)
55
- assert_equal(1, method.called)
56
- assert_in_delta(2, method.total_time, 0.1)
57
- assert_in_delta(0, method.self_time, 0.01)
58
- assert_in_delta(0, method.wait_time, 0.01)
59
- assert_in_delta(2, method.children_time, 0.1)
60
-
61
- assert_equal(1, method.call_infos.length)
62
- call_info = method.call_infos[0]
63
- assert(!call_info.recursive)
64
- assert_equal('RecursiveTest#test_simple', call_info.call_sequence)
65
- assert_equal(1, call_info.children.length)
66
-
67
- # Method 1: Object#simple
68
- method = methods[1]
69
- assert_equal('Object#simple', method.full_name)
70
- assert_equal(2, method.called)
71
- assert_in_delta(2, method.total_time, 0.1)
72
- assert_in_delta(0, method.self_time, 0.1)
73
- assert_in_delta(0, method.wait_time, 0.1)
74
- assert_in_delta(2, method.children_time, 0.1)
75
-
76
- assert_equal(2, method.call_infos.length)
77
-
78
- call_info = method.call_infos.first
79
- assert_equal(2, call_info.children.length)
80
- assert_equal('RecursiveTest#test_simple->Object#simple', call_info.call_sequence)
81
- assert(!call_info.recursive)
82
-
83
- call_info = method.call_infos.last
84
- assert_equal(1, call_info.children.length)
85
- assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple', call_info.call_sequence)
86
- assert(call_info.recursive)
87
-
88
- method = methods[2]
89
- assert_equal('Kernel#sleep', method.full_name)
90
- assert_equal(2, method.called)
91
- assert_in_delta(2, method.total_time, 0.1)
92
- assert_in_delta(2, method.self_time, 0.1)
93
- assert_in_delta(0, method.wait_time, 0.1)
94
- assert_in_delta(0, method.children_time, 0.1)
95
-
96
- assert_equal(2, method.call_infos.length)
97
- call_info = method.call_infos[0]
98
- assert_equal('RecursiveTest#test_simple->Object#simple->Kernel#sleep', call_info.call_sequence)
99
- assert_equal(0, call_info.children.length)
100
- assert(!call_info.recursive)
101
-
102
- call_info = method.call_infos[1]
103
- assert_equal('RecursiveTest#test_simple->Object#simple->Object#simple->Kernel#sleep', call_info.call_sequence)
104
- assert_equal(0, call_info.children.length)
105
- assert(!call_info.recursive)
106
- end
107
-
108
- def test_cycle
109
- result = RubyProf.profile do
110
- render
111
- end
112
-
113
- methods = result.threads.first.methods.sort.reverse
114
- if RUBY_VERSION < '1.9' # Fixnum#+, Fixnum#===, Kernel#===
115
- assert_equal(8, methods.length)
116
- else
117
- assert_equal(5, methods.length)
118
- end
119
-
120
- method = methods[0]
121
- assert_equal('RecursiveTest#test_cycle', method.full_name)
122
- assert_equal(1, method.called)
123
- assert_in_delta(5, method.total_time, 0.1)
124
- assert_in_delta(0, method.self_time, 0.01)
125
- assert_in_delta(0, method.wait_time, 0.01)
126
- assert_in_delta(5, method.children_time, 0.1)
127
-
128
- assert_equal(1, method.call_infos.length)
129
- call_info = method.call_infos[0]
130
- assert_equal('RecursiveTest#test_cycle', call_info.call_sequence)
131
- assert_equal(1, call_info.children.length)
132
- assert(!call_info.recursive)
133
-
134
- method = methods[1]
135
- assert_equal('Object#render', method.full_name)
136
- assert_equal(1, method.called)
137
- assert_in_delta(5, method.total_time, 0.1)
138
- assert_in_delta(0, method.self_time, 0.01)
139
- assert_in_delta(0, method.wait_time, 0.01)
140
- assert_in_delta(5, method.children_time, 0.1)
141
-
142
- assert_equal(1, method.call_infos.length)
143
- call_info = method.call_infos[0]
144
- assert_equal('RecursiveTest#test_cycle->Object#render', call_info.call_sequence)
145
- assert_equal(1, call_info.children.length)
146
- assert(!call_info.recursive)
147
-
148
- method = methods[2]
149
- assert_equal('Integer#times', method.full_name)
150
- assert_equal(2, method.called)
151
- assert_in_delta(5, method.total_time, 0.1)
152
- assert_in_delta(0, method.self_time, 0.1)
153
- assert_in_delta(0, method.wait_time, 0.1)
154
- assert_in_delta(5, method.children_time, 0.1)
155
-
156
- assert_equal(2, method.call_infos.length)
157
- call_info = method.call_infos[0]
158
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times', call_info.call_sequence)
159
- assert_equal(1, call_info.children.length)
160
- assert(!call_info.recursive)
161
-
162
- call_info = method.call_infos[1]
163
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times', call_info.call_sequence)
164
- assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
165
- assert(call_info.recursive)
166
-
167
- method = methods[3]
168
- assert_equal('Object#render_partial', method.full_name)
169
- assert_equal(5, method.called)
170
- assert_in_delta(5, method.total_time, 0.1)
171
- assert_in_delta(0, method.self_time, 0.1)
172
- assert_in_delta(0, method.wait_time, 0.01)
173
- assert_in_delta(5, method.children_time, 0.05)
174
-
175
- assert_equal(3, method.call_infos.length)
176
- call_info = method.call_infos[0]
177
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial', call_info.call_sequence)
178
- assert_equal(3 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
179
- assert(!call_info.recursive)
180
-
181
- call_info = method.call_infos[1]
182
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Object#render_partial', call_info.call_sequence)
183
- assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
184
- assert(call_info.recursive)
185
-
186
- call_info = method.call_infos[2]
187
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times->Object#render_partial', call_info.call_sequence)
188
- assert_equal(1 + (RUBY_VERSION < '1.9.0' ? 1 : 0), call_info.children.length)
189
- assert(call_info.recursive)
190
-
191
- method = methods[4]
192
- assert_equal('Kernel#sleep', method.full_name)
193
- assert_equal(5, method.called)
194
- assert_in_delta(5, method.total_time, 0.1)
195
- assert_in_delta(5, method.self_time, 0.1)
196
- assert_in_delta(0, method.wait_time, 0.01)
197
- assert_in_delta(0, method.children_time, 0.01)
198
-
199
- assert_equal(3, method.call_infos.length)
200
- call_info = method.call_infos[0]
201
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Kernel#sleep', call_info.call_sequence)
202
- assert_equal(0, call_info.children.length)
203
- assert(!call_info.recursive)
204
-
205
- call_info = method.call_infos[1]
206
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Object#render_partial->Kernel#sleep', call_info.call_sequence)
207
- assert_equal(0, call_info.children.length)
208
- assert(!call_info.recursive)
209
-
210
- call_info = method.call_infos[2]
211
- assert_equal('RecursiveTest#test_cycle->Object#render->Integer#times->Object#render_partial->Integer#times->Object#render_partial->Kernel#sleep', call_info.call_sequence)
212
- assert_equal(0, call_info.children.length)
213
- assert(!call_info.recursive)
214
- end
215
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ module SimpleRecursion
7
+ # Simple recursive test
8
+ def simple(n)
9
+ sleep(1)
10
+ return if n == 0
11
+ simple(n-1)
12
+ end
13
+
14
+ # More complicated recursive test
15
+ def render_partial(i)
16
+ sleep(1)
17
+ case i
18
+ when 0
19
+ render_partial(10)
20
+ when 1
21
+ 2.times do |j|
22
+ render_partial(j + 10)
23
+ end
24
+ end
25
+ end
26
+
27
+ def render
28
+ 2.times do |i|
29
+ render_partial(i)
30
+ end
31
+ end
32
+ end
33
+
34
+ # -- Tests ----
35
+ class RecursiveTest < TestCase
36
+ def setup
37
+ # Need to use wall time for this test due to the sleep calls
38
+ RubyProf::measure_mode = RubyProf::WALL_TIME
39
+ end
40
+
41
+ include SimpleRecursion
42
+
43
+ def test_simple
44
+ result = RubyProf.profile do
45
+ simple(1)
46
+ end
47
+
48
+ methods = result.threads.first.methods.sort.reverse
49
+ assert_equal(3, methods.length)
50
+
51
+ # Method 0: RecursiveTest#test_simple
52
+ method = methods[0]
53
+ assert_equal('RecursiveTest#test_simple', method.full_name)
54
+ assert_equal(1, method.called)
55
+ refute(method.recursive?)
56
+ assert_in_delta(2, method.total_time, 0.1)
57
+ assert_in_delta(0, method.self_time, 0.01)
58
+ assert_in_delta(0, method.wait_time, 0.01)
59
+ assert_in_delta(2, method.children_time, 0.1)
60
+
61
+ assert_equal(0, method.call_trees.callers.length)
62
+
63
+ assert_equal(1, method.call_trees.callees.length)
64
+ call_tree = method.call_trees.callees[0]
65
+ assert_equal('SimpleRecursion#simple', call_tree.target.full_name)
66
+
67
+ # Method 1: SimpleRecursion#simple
68
+ method = methods[1]
69
+ assert_equal('SimpleRecursion#simple', method.full_name)
70
+ assert_equal(2, method.called)
71
+ assert(method.recursive?)
72
+ assert_in_delta(2, method.total_time, 0.1)
73
+ assert_in_delta(0, method.self_time, 0.1)
74
+ assert_in_delta(0, method.wait_time, 0.1)
75
+ assert_in_delta(2, method.children_time, 0.1)
76
+
77
+ assert_equal(2, method.call_trees.callers.length)
78
+ call_tree = method.call_trees.callers[0]
79
+ assert_equal('RecursiveTest#test_simple', call_tree.parent.target.full_name)
80
+
81
+ call_tree = method.call_trees.callers[1]
82
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
83
+
84
+ assert_equal(2, method.call_trees.callees.length)
85
+ call_tree = method.call_trees.callees[0]
86
+ assert_equal('Kernel#sleep', call_tree.target.full_name)
87
+
88
+ call_tree = method.call_trees.callees[1]
89
+ assert_equal('SimpleRecursion#simple', call_tree.target.full_name)
90
+
91
+ # Method 2: Kernel#sleep
92
+ method = methods[2]
93
+ assert_equal('Kernel#sleep', method.full_name)
94
+ assert_equal(2, method.called)
95
+ refute(method.recursive?)
96
+ assert_in_delta(2, method.total_time, 0.1)
97
+ assert_in_delta(2, method.self_time, 0.1)
98
+ assert_in_delta(0, method.wait_time, 0.1)
99
+ assert_in_delta(0, method.children_time, 0.1)
100
+
101
+ assert_equal(1, method.call_trees.callers.length)
102
+ call_tree = method.call_trees.callers[0]
103
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
104
+ assert_equal(0, method.call_trees.callees.length)
105
+
106
+ assert_equal(0, method.call_trees.callees.length)
107
+ end
108
+
109
+ def test_cycle
110
+ result = RubyProf.profile do
111
+ render
112
+ end
113
+
114
+ methods = result.threads.first.methods.sort.reverse
115
+ assert_equal(5, methods.length)
116
+
117
+ method = methods[0]
118
+ assert_equal('RecursiveTest#test_cycle', method.full_name)
119
+ assert_equal(1, method.called)
120
+ refute(method.recursive?)
121
+ assert_in_delta(5, method.total_time, 0.1)
122
+ assert_in_delta(0, method.self_time, 0.01)
123
+ assert_in_delta(0, method.wait_time, 0.01)
124
+ assert_in_delta(5, method.children_time, 0.1)
125
+
126
+ assert_equal(0, method.call_trees.callers.length)
127
+
128
+ assert_equal(1, method.call_trees.callees.length)
129
+ call_tree = method.call_trees.callees[0]
130
+ assert_equal('SimpleRecursion#render', call_tree.target.full_name)
131
+
132
+ method = methods[1]
133
+ assert_equal('SimpleRecursion#render', method.full_name)
134
+ assert_equal(1, method.called)
135
+ refute(method.recursive?)
136
+ assert_in_delta(5, method.total_time, 0.1)
137
+ assert_in_delta(0, method.self_time, 0.01)
138
+ assert_in_delta(0, method.wait_time, 0.01)
139
+ assert_in_delta(5, method.children_time, 0.1)
140
+
141
+ assert_equal(1, method.call_trees.callers.length)
142
+ call_tree = method.call_trees.callers[0]
143
+ assert_equal('RecursiveTest#test_cycle', call_tree.parent.target.full_name)
144
+
145
+ assert_equal(1, method.call_trees.callees.length)
146
+ call_tree = method.call_trees.callees[0]
147
+ assert_equal('Integer#times', call_tree.target.full_name)
148
+
149
+ method = methods[2]
150
+ assert_equal('Integer#times', method.full_name)
151
+ assert_equal(2, method.called)
152
+ assert(method.recursive?)
153
+ assert_in_delta(5, method.total_time, 0.1)
154
+ assert_in_delta(0, method.self_time, 0.1)
155
+ assert_in_delta(0, method.wait_time, 0.1)
156
+ assert_in_delta(5, method.children_time, 0.1)
157
+
158
+ assert_equal(2, method.call_trees.callers.length)
159
+ call_tree = method.call_trees.callers[0]
160
+ assert_equal('SimpleRecursion#render', call_tree.parent.target.full_name)
161
+
162
+ call_tree = method.call_trees.callers[1]
163
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
164
+
165
+ assert_equal(1, method.call_trees.callees.length)
166
+ call_tree = method.call_trees.callees[0]
167
+ assert_equal('SimpleRecursion#render_partial', call_tree.target.full_name)
168
+
169
+ method = methods[3]
170
+ assert_equal('SimpleRecursion#render_partial', method.full_name)
171
+ assert_equal(5, method.called)
172
+ assert(method.recursive?)
173
+ assert_in_delta(5, method.total_time, 0.1)
174
+ assert_in_delta(0, method.self_time, 0.1)
175
+ assert_in_delta(0, method.wait_time, 0.01)
176
+ assert_in_delta(5, method.children_time, 0.05)
177
+
178
+ assert_equal(2, method.call_trees.callers.length)
179
+ call_tree = method.call_trees.callers[0]
180
+ assert_equal('Integer#times', call_tree.parent.target.full_name)
181
+
182
+ call_tree = method.call_trees.callers[1]
183
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
184
+
185
+ assert_equal(3, method.call_trees.callees.length)
186
+ call_tree = method.call_trees.callees[0]
187
+ assert_equal('Kernel#sleep', call_tree.target.full_name)
188
+
189
+ call_tree = method.call_trees.callees[1]
190
+ assert_equal('SimpleRecursion#render_partial', call_tree.target.full_name)
191
+
192
+ call_tree = method.call_trees.callees[2]
193
+ assert_equal('Integer#times', call_tree.target.full_name)
194
+
195
+ method = methods[4]
196
+ assert_equal('Kernel#sleep', method.full_name)
197
+ assert_equal(5, method.called)
198
+ refute(method.recursive?)
199
+ assert_in_delta(5, method.total_time, 0.1)
200
+ assert_in_delta(5, method.self_time, 0.1)
201
+ assert_in_delta(0, method.wait_time, 0.01)
202
+ assert_in_delta(0, method.children_time, 0.01)
203
+
204
+ assert_equal(0, method.call_trees.callees.length)
205
+ end
206
+ end