ruby-prof 1.4.4-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +608 -0
  3. data/LICENSE +25 -0
  4. data/README.md +5 -0
  5. data/Rakefile +98 -0
  6. data/bin/ruby-prof +328 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/ext/ruby_prof/extconf.rb +22 -0
  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 +367 -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 +47 -0
  18. data/ext/ruby_prof/rp_measure_memory.c +46 -0
  19. data/ext/ruby_prof/rp_measure_process_time.c +66 -0
  20. data/ext/ruby_prof/rp_measure_wall_time.c +64 -0
  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 -0
  24. data/ext/ruby_prof/rp_method.h +62 -0
  25. data/ext/ruby_prof/rp_profile.c +915 -0
  26. data/ext/ruby_prof/rp_profile.h +35 -0
  27. data/ext/ruby_prof/rp_stack.c +212 -0
  28. data/ext/ruby_prof/rp_stack.h +53 -0
  29. data/ext/ruby_prof/rp_thread.c +362 -0
  30. data/ext/ruby_prof/rp_thread.h +39 -0
  31. data/ext/ruby_prof/ruby_prof.c +52 -0
  32. data/ext/ruby_prof/ruby_prof.h +26 -0
  33. data/ext/ruby_prof/vc/ruby_prof.sln +39 -0
  34. data/ext/ruby_prof/vc/ruby_prof.vcxproj +160 -0
  35. data/lib/3.1/ruby_prof.so +0 -0
  36. data/lib/ruby-prof/assets/call_stack_printer.html.erb +711 -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 -0
  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 -0
  45. data/lib/ruby-prof/printers/abstract_printer.rb +137 -0
  46. data/lib/ruby-prof/printers/call_info_printer.rb +53 -0
  47. data/lib/ruby-prof/printers/call_stack_printer.rb +180 -0
  48. data/lib/ruby-prof/printers/call_tree_printer.rb +147 -0
  49. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  50. data/lib/ruby-prof/printers/flat_printer.rb +53 -0
  51. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -0
  52. data/lib/ruby-prof/printers/graph_printer.rb +113 -0
  53. data/lib/ruby-prof/printers/multi_printer.rb +127 -0
  54. data/lib/ruby-prof/profile.rb +37 -0
  55. data/lib/ruby-prof/rack.rb +95 -0
  56. data/lib/ruby-prof/task.rb +147 -0
  57. data/lib/ruby-prof/thread.rb +20 -0
  58. data/lib/ruby-prof/version.rb +3 -0
  59. data/lib/ruby-prof.rb +52 -0
  60. data/lib/unprof.rb +10 -0
  61. data/ruby-prof.gemspec +64 -0
  62. data/test/abstract_printer_test.rb +26 -0
  63. data/test/alias_test.rb +122 -0
  64. data/test/basic_test.rb +43 -0
  65. data/test/call_tree_visitor_test.rb +32 -0
  66. data/test/call_trees_test.rb +66 -0
  67. data/test/duplicate_names_test.rb +32 -0
  68. data/test/dynamic_method_test.rb +67 -0
  69. data/test/enumerable_test.rb +21 -0
  70. data/test/exceptions_test.rb +24 -0
  71. data/test/exclude_methods_test.rb +151 -0
  72. data/test/exclude_threads_test.rb +53 -0
  73. data/test/fiber_test.rb +129 -0
  74. data/test/gc_test.rb +100 -0
  75. data/test/inverse_call_tree_test.rb +175 -0
  76. data/test/line_number_test.rb +158 -0
  77. data/test/marshal_test.rb +145 -0
  78. data/test/measure_allocations.rb +26 -0
  79. data/test/measure_allocations_test.rb +333 -0
  80. data/test/measure_memory_test.rb +688 -0
  81. data/test/measure_process_time_test.rb +1614 -0
  82. data/test/measure_times.rb +56 -0
  83. data/test/measure_wall_time_test.rb +426 -0
  84. data/test/multi_printer_test.rb +71 -0
  85. data/test/no_method_class_test.rb +15 -0
  86. data/test/pause_resume_test.rb +175 -0
  87. data/test/prime.rb +54 -0
  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 -0
  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 +430 -0
  99. data/test/singleton_test.rb +38 -0
  100. data/test/stack_printer_test.rb +64 -0
  101. data/test/start_stop_test.rb +109 -0
  102. data/test/test_helper.rb +13 -0
  103. data/test/thread_test.rb +144 -0
  104. data/test/unique_call_path_test.rb +136 -0
  105. data/test/yarv_test.rb +60 -0
  106. metadata +187 -0
@@ -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
data/test/rack_test.rb ADDED
@@ -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
@@ -0,0 +1,430 @@
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
+
50
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.1')
51
+ assert_equal(3, methods.length)
52
+
53
+ # Method 0: RecursiveTest#test_simple
54
+ method = methods[0]
55
+ assert_equal('RecursiveTest#test_simple', method.full_name)
56
+ assert_equal(1, method.called)
57
+ refute(method.recursive?)
58
+ assert_in_delta(2, method.total_time, 0.1)
59
+ assert_in_delta(0, method.self_time, 0.01)
60
+ assert_in_delta(0, method.wait_time, 0.01)
61
+ assert_in_delta(2, method.children_time, 0.1)
62
+
63
+ assert_equal(0, method.call_trees.callers.length)
64
+
65
+ assert_equal(1, method.call_trees.callees.length)
66
+ call_tree = method.call_trees.callees[0]
67
+ assert_equal('SimpleRecursion#simple', call_tree.target.full_name)
68
+
69
+ # Method 1: SimpleRecursion#simple
70
+ method = methods[1]
71
+ assert_equal('SimpleRecursion#simple', method.full_name)
72
+ assert_equal(2, method.called)
73
+ assert(method.recursive?)
74
+ assert_in_delta(2, method.total_time, 0.1)
75
+ assert_in_delta(0, method.self_time, 0.1)
76
+ assert_in_delta(0, method.wait_time, 0.1)
77
+ assert_in_delta(2, method.children_time, 0.1)
78
+
79
+ assert_equal(2, method.call_trees.callers.length)
80
+ call_tree = method.call_trees.callers[0]
81
+ assert_equal('RecursiveTest#test_simple', call_tree.parent.target.full_name)
82
+
83
+ call_tree = method.call_trees.callers[1]
84
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
85
+
86
+ assert_equal(2, method.call_trees.callees.length)
87
+ call_tree = method.call_trees.callees[0]
88
+ assert_equal('Kernel#sleep', call_tree.target.full_name)
89
+
90
+ call_tree = method.call_trees.callees[1]
91
+ assert_equal('SimpleRecursion#simple', call_tree.target.full_name)
92
+
93
+ # Method 2: Kernel#sleep
94
+ method = methods[2]
95
+ assert_equal('Kernel#sleep', method.full_name)
96
+ assert_equal(2, method.called)
97
+ refute(method.recursive?)
98
+
99
+ assert_in_delta(2, method.total_time, 0.1)
100
+ assert_in_delta(2, method.self_time, 0.1)
101
+ assert_in_delta(0, method.wait_time, 0.1)
102
+ assert_in_delta(0, method.children_time, 0.1)
103
+
104
+ assert_equal(1, method.call_trees.callers.length)
105
+ call_tree = method.call_trees.callers[0]
106
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
107
+ assert_equal(0, method.call_trees.callees.length)
108
+
109
+ assert_equal(0, method.call_trees.callees.length)
110
+ else
111
+ assert_equal(5, methods.length)
112
+
113
+ # Method 0: RecursiveTest#test_simple
114
+ method = methods[0]
115
+ assert_equal('RecursiveTest#test_simple', method.full_name)
116
+ assert_equal(1, method.called)
117
+ refute(method.recursive?)
118
+ assert_in_delta(2, method.total_time, 0.1)
119
+ assert_in_delta(0, method.self_time, 0.01)
120
+ assert_in_delta(0, method.wait_time, 0.01)
121
+ assert_in_delta(2, method.children_time, 0.1)
122
+
123
+ assert_equal(0, method.call_trees.callers.length)
124
+
125
+ assert_equal(1, method.call_trees.callees.length)
126
+ call_tree = method.call_trees.callees[0]
127
+ assert_equal('SimpleRecursion#simple', call_tree.target.full_name)
128
+
129
+ # Method 1: SimpleRecursion#simple
130
+ method = methods[1]
131
+ assert_equal('SimpleRecursion#simple', method.full_name)
132
+ assert_equal(2, method.called)
133
+ assert(method.recursive?)
134
+ assert_in_delta(2, method.total_time, 0.1)
135
+ assert_in_delta(0, method.self_time, 0.1)
136
+ assert_in_delta(0, method.wait_time, 0.1)
137
+ assert_in_delta(2, method.children_time, 0.1)
138
+
139
+ assert_equal(2, method.call_trees.callers.length)
140
+ call_tree = method.call_trees.callers[0]
141
+ assert_equal('RecursiveTest#test_simple', call_tree.parent.target.full_name)
142
+
143
+ call_tree = method.call_trees.callers[1]
144
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
145
+
146
+ assert_equal(4, method.call_trees.callees.length)
147
+ call_tree = method.call_trees.callees[0]
148
+ assert_equal('Kernel#sleep', call_tree.target.full_name)
149
+
150
+ call_tree = method.call_trees.callees[1]
151
+ assert_equal('Integer#==', call_tree.target.full_name)
152
+
153
+ call_tree = method.call_trees.callees[2]
154
+ assert_equal('Integer#-', call_tree.target.full_name)
155
+
156
+ call_tree = method.call_trees.callees[3]
157
+ assert_equal('SimpleRecursion#simple', call_tree.target.full_name)
158
+
159
+ # Method 2: Kernel#sleep
160
+ method = methods[2]
161
+ assert_equal('Kernel#sleep', method.full_name)
162
+ assert_equal(2, method.called)
163
+ refute(method.recursive?)
164
+
165
+ assert_in_delta(2, method.total_time, 0.1)
166
+ assert_in_delta(2, method.self_time, 0.1)
167
+ assert_in_delta(0, method.wait_time, 0.1)
168
+ assert_in_delta(0, method.children_time, 0.1)
169
+
170
+ assert_equal(1, method.call_trees.callers.length)
171
+ call_tree = method.call_trees.callers[0]
172
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
173
+ assert_equal(0, method.call_trees.callees.length)
174
+
175
+ assert_equal(0, method.call_trees.callees.length)
176
+
177
+ # Method 3
178
+ method = methods[3]
179
+ assert_equal('Integer#==', method.full_name)
180
+ assert_equal(2, method.called)
181
+ refute(method.recursive?)
182
+
183
+ assert_equal(1, method.call_trees.callers.length)
184
+ call_tree = method.call_trees.callers[0]
185
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
186
+
187
+ assert_equal(0, method.call_trees.callees.length)
188
+
189
+ # Method 4
190
+ method = methods[4]
191
+ assert_equal('Integer#-', method.full_name)
192
+ assert_equal(1, method.called)
193
+ refute(method.recursive?)
194
+
195
+ assert_equal(1, method.call_trees.callers.length)
196
+ call_tree = method.call_trees.callers[0]
197
+ assert_equal('SimpleRecursion#simple', call_tree.parent.target.full_name)
198
+
199
+ assert_equal(0, method.call_trees.callees.length)
200
+ end
201
+ end
202
+
203
+ def test_cycle
204
+ result = RubyProf.profile do
205
+ render
206
+ end
207
+
208
+ methods = result.threads.first.methods.sort.reverse
209
+
210
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.1')
211
+ assert_equal(5, methods.length)
212
+
213
+ # Method 0
214
+ method = methods[0]
215
+ assert_equal('RecursiveTest#test_cycle', method.full_name)
216
+ assert_equal(1, method.called)
217
+ refute(method.recursive?)
218
+ assert_in_delta(5, method.total_time, 0.1)
219
+ assert_in_delta(0, method.self_time, 0.01)
220
+ assert_in_delta(0, method.wait_time, 0.01)
221
+ assert_in_delta(5, method.children_time, 0.1)
222
+
223
+ assert_equal(0, method.call_trees.callers.length)
224
+
225
+ assert_equal(1, method.call_trees.callees.length)
226
+ call_tree = method.call_trees.callees[0]
227
+ assert_equal('SimpleRecursion#render', call_tree.target.full_name)
228
+
229
+ # Method 1
230
+ method = methods[1]
231
+ assert_equal('SimpleRecursion#render', method.full_name)
232
+ assert_equal(1, method.called)
233
+ refute(method.recursive?)
234
+ assert_in_delta(5, method.total_time, 0.1)
235
+ assert_in_delta(0, method.self_time, 0.01)
236
+ assert_in_delta(0, method.wait_time, 0.01)
237
+ assert_in_delta(5, method.children_time, 0.1)
238
+
239
+ assert_equal(1, method.call_trees.callers.length)
240
+ call_tree = method.call_trees.callers[0]
241
+ assert_equal('RecursiveTest#test_cycle', call_tree.parent.target.full_name)
242
+
243
+ assert_equal(1, method.call_trees.callees.length)
244
+ call_tree = method.call_trees.callees[0]
245
+ assert_equal('Integer#times', call_tree.target.full_name)
246
+
247
+ # Method 2
248
+ method = methods[2]
249
+ assert_equal('Integer#times', method.full_name)
250
+ assert_equal(2, method.called)
251
+ assert(method.recursive?)
252
+ assert_in_delta(5, method.total_time, 0.1)
253
+ assert_in_delta(0, method.self_time, 0.1)
254
+ assert_in_delta(0, method.wait_time, 0.1)
255
+ assert_in_delta(5, method.children_time, 0.1)
256
+
257
+ assert_equal(2, method.call_trees.callers.length)
258
+ call_tree = method.call_trees.callers[0]
259
+ assert_equal('SimpleRecursion#render', call_tree.parent.target.full_name)
260
+
261
+ call_tree = method.call_trees.callers[1]
262
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
263
+
264
+ assert_equal(1, method.call_trees.callees.length)
265
+ call_tree = method.call_trees.callees[0]
266
+ assert_equal('SimpleRecursion#render_partial', call_tree.target.full_name)
267
+
268
+ # Method 3
269
+ method = methods[3]
270
+ assert_equal('SimpleRecursion#render_partial', method.full_name)
271
+ assert_equal(5, method.called)
272
+ assert(method.recursive?)
273
+ assert_in_delta(5, method.total_time, 0.1)
274
+ assert_in_delta(0, method.self_time, 0.1)
275
+ assert_in_delta(0, method.wait_time, 0.01)
276
+ assert_in_delta(5, method.children_time, 0.05)
277
+
278
+ assert_equal(2, method.call_trees.callers.length)
279
+ call_tree = method.call_trees.callers[0]
280
+ assert_equal('Integer#times', call_tree.parent.target.full_name)
281
+
282
+ call_tree = method.call_trees.callers[1]
283
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
284
+
285
+ assert_equal(3, method.call_trees.callees.length)
286
+ call_tree = method.call_trees.callees[0]
287
+ assert_equal('Kernel#sleep', call_tree.target.full_name)
288
+
289
+ call_tree = method.call_trees.callees[1]
290
+ assert_equal('SimpleRecursion#render_partial', call_tree.target.full_name)
291
+
292
+ call_tree = method.call_trees.callees[2]
293
+ assert_equal('Integer#times', call_tree.target.full_name)
294
+
295
+ # Method 4
296
+ method = methods[4]
297
+ assert_equal('Kernel#sleep', method.full_name)
298
+ assert_equal(5, method.called)
299
+ refute(method.recursive?)
300
+ assert_in_delta(5, method.total_time, 0.1)
301
+ assert_in_delta(5, method.self_time, 0.1)
302
+ assert_in_delta(0, method.wait_time, 0.01)
303
+ assert_in_delta(0, method.children_time, 0.01)
304
+
305
+ assert_equal(1, method.call_trees.callers.length)
306
+ call_tree = method.call_trees.callers[0]
307
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
308
+
309
+ assert_equal(0, method.call_trees.callees.length)
310
+ else
311
+ assert_equal(6, methods.length)
312
+
313
+ # Method 0
314
+ method = methods[0]
315
+ assert_equal('RecursiveTest#test_cycle', method.full_name)
316
+ assert_equal(1, method.called)
317
+ refute(method.recursive?)
318
+ assert_in_delta(5, method.total_time, 0.1)
319
+ assert_in_delta(0, method.self_time, 0.01)
320
+ assert_in_delta(0, method.wait_time, 0.01)
321
+ assert_in_delta(5, method.children_time, 0.1)
322
+
323
+ assert_equal(0, method.call_trees.callers.length)
324
+
325
+ assert_equal(1, method.call_trees.callees.length)
326
+ call_tree = method.call_trees.callees[0]
327
+ assert_equal('SimpleRecursion#render', call_tree.target.full_name)
328
+
329
+ # Method 1
330
+ method = methods[1]
331
+ assert_equal('SimpleRecursion#render', method.full_name)
332
+ assert_equal(1, method.called)
333
+ refute(method.recursive?)
334
+ assert_in_delta(5, method.total_time, 0.1)
335
+ assert_in_delta(0, method.self_time, 0.01)
336
+ assert_in_delta(0, method.wait_time, 0.01)
337
+ assert_in_delta(5, method.children_time, 0.1)
338
+
339
+ assert_equal(1, method.call_trees.callers.length)
340
+ call_tree = method.call_trees.callers[0]
341
+ assert_equal('RecursiveTest#test_cycle', call_tree.parent.target.full_name)
342
+
343
+ assert_equal(1, method.call_trees.callees.length)
344
+ call_tree = method.call_trees.callees[0]
345
+ assert_equal('Integer#times', call_tree.target.full_name)
346
+
347
+ # Method 2
348
+ method = methods[2]
349
+ assert_equal('Integer#times', method.full_name)
350
+ assert_equal(2, method.called)
351
+ assert(method.recursive?)
352
+ assert_in_delta(5, method.total_time, 0.1)
353
+ assert_in_delta(0, method.self_time, 0.1)
354
+ assert_in_delta(0, method.wait_time, 0.1)
355
+ assert_in_delta(5, method.children_time, 0.1)
356
+
357
+ assert_equal(2, method.call_trees.callers.length)
358
+ call_tree = method.call_trees.callers[0]
359
+ assert_equal('SimpleRecursion#render', call_tree.parent.target.full_name)
360
+
361
+ call_tree = method.call_trees.callers[1]
362
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
363
+
364
+ assert_equal(2, method.call_trees.callees.length)
365
+ call_tree = method.call_trees.callees[0]
366
+ assert_equal('SimpleRecursion#render_partial', call_tree.target.full_name)
367
+ call_tree = method.call_trees.callees[1]
368
+ assert_equal('Integer#+', call_tree.target.full_name)
369
+
370
+ # Method 3
371
+ method = methods[3]
372
+ assert_equal('SimpleRecursion#render_partial', method.full_name)
373
+ assert_equal(5, method.called)
374
+ assert(method.recursive?)
375
+ assert_in_delta(5, method.total_time, 0.1)
376
+ assert_in_delta(0, method.self_time, 0.1)
377
+ assert_in_delta(0, method.wait_time, 0.01)
378
+ assert_in_delta(5, method.children_time, 0.05)
379
+
380
+ assert_equal(2, method.call_trees.callers.length)
381
+ call_tree = method.call_trees.callers[0]
382
+ assert_equal('Integer#times', call_tree.parent.target.full_name)
383
+
384
+ call_tree = method.call_trees.callers[1]
385
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
386
+
387
+ assert_equal(3, method.call_trees.callees.length)
388
+ call_tree = method.call_trees.callees[0]
389
+ assert_equal('Kernel#sleep', call_tree.target.full_name)
390
+
391
+ call_tree = method.call_trees.callees[1]
392
+ assert_equal('SimpleRecursion#render_partial', call_tree.target.full_name)
393
+
394
+ call_tree = method.call_trees.callees[2]
395
+ assert_equal('Integer#times', call_tree.target.full_name)
396
+
397
+ # Method 4
398
+ method = methods[4]
399
+ assert_equal('Kernel#sleep', method.full_name)
400
+ assert_equal(5, method.called)
401
+ refute(method.recursive?)
402
+ assert_in_delta(5, method.total_time, 0.1)
403
+ assert_in_delta(5, method.self_time, 0.1)
404
+ assert_in_delta(0, method.wait_time, 0.01)
405
+ assert_in_delta(0, method.children_time, 0.01)
406
+
407
+ assert_equal(1, method.call_trees.callers.length)
408
+ call_tree = method.call_trees.callers[0]
409
+ assert_equal('SimpleRecursion#render_partial', call_tree.parent.target.full_name)
410
+
411
+ assert_equal(0, method.call_trees.callees.length)
412
+
413
+ # Method 5
414
+ method = methods[5]
415
+ assert_equal('Integer#+', method.full_name)
416
+ assert_equal(2, method.called)
417
+ refute(method.recursive?)
418
+ assert_in_delta(0, method.total_time, 0.1)
419
+ assert_in_delta(0, method.self_time, 0.1)
420
+ assert_in_delta(0, method.wait_time, 0.01)
421
+ assert_in_delta(0, method.children_time, 0.01)
422
+
423
+ assert_equal(1, method.call_trees.callers.length)
424
+ call_tree = method.call_trees.callers[0]
425
+ assert_equal('Integer#times', call_tree.parent.target.full_name)
426
+
427
+ assert_equal(0, method.call_trees.callees.length)
428
+ end
429
+ end
430
+ end
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'timeout'
6
+
7
+ # -- Test for bug [#5657]
8
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=5657&group_id=1814&atid=7060
9
+
10
+
11
+ class A
12
+ attr_accessor :as
13
+ def initialize
14
+ @as = []
15
+ class << @as
16
+ def <<(an_a)
17
+ super
18
+ end
19
+ end
20
+ end
21
+
22
+ def <<(an_a)
23
+ @as << an_a
24
+ end
25
+ end
26
+
27
+ class SingletonTest < TestCase
28
+ def test_singleton
29
+ result = RubyProf.profile do
30
+ a = A.new
31
+ a << :first_thing
32
+ assert_equal(1, a.as.size)
33
+ end
34
+ printer = RubyProf::FlatPrinter.new(result)
35
+ output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : ''
36
+ printer.print(output)
37
+ end
38
+ end