ruby-prof 0.13.1 → 1.4.2

Sign up to get free protection for your applications and to get access to all the features.
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