ruby-prof 1.7.1 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. checksums.yaml +4 -4
  2. data/{CHANGES → CHANGELOG.md} +118 -176
  3. data/README.md +5 -5
  4. data/bin/ruby-prof +1 -4
  5. data/docs/advanced-usage.md +132 -0
  6. data/docs/alternatives.md +98 -0
  7. data/docs/architecture.md +122 -0
  8. data/docs/best-practices.md +27 -0
  9. data/docs/getting-started.md +130 -0
  10. data/docs/history.md +11 -0
  11. data/docs/index.md +45 -0
  12. data/docs/profiling-rails.md +64 -0
  13. data/docs/public/examples/example.rb +33 -0
  14. data/docs/public/examples/generate_reports.rb +92 -0
  15. data/docs/public/examples/reports/call_info.txt +27 -0
  16. data/docs/public/examples/reports/call_stack.html +835 -0
  17. data/docs/public/examples/reports/callgrind.out +150 -0
  18. data/docs/public/examples/reports/flame_graph.html +408 -0
  19. data/docs/public/examples/reports/flat.txt +45 -0
  20. data/docs/public/examples/reports/graph.dot +129 -0
  21. data/docs/public/examples/reports/graph.html +1319 -0
  22. data/docs/public/examples/reports/graph.txt +100 -0
  23. data/docs/public/examples/reports/graphviz_viewer.html +1 -0
  24. data/docs/public/images/call_stack.png +0 -0
  25. data/docs/public/images/class_diagram.png +0 -0
  26. data/docs/public/images/dot_printer.png +0 -0
  27. data/docs/public/images/flame_graph.png +0 -0
  28. data/docs/public/images/flat.png +0 -0
  29. data/docs/public/images/graph.png +0 -0
  30. data/docs/public/images/graph_html.png +0 -0
  31. data/docs/public/images/ruby-prof-logo.svg +1 -0
  32. data/docs/reports.md +150 -0
  33. data/docs/stylesheets/extra.css +80 -0
  34. data/ext/ruby_prof/extconf.rb +23 -22
  35. data/ext/ruby_prof/rp_allocation.c +0 -15
  36. data/ext/ruby_prof/rp_allocation.h +29 -33
  37. data/ext/ruby_prof/rp_call_tree.c +3 -0
  38. data/ext/ruby_prof/rp_call_tree.h +1 -4
  39. data/ext/ruby_prof/rp_call_trees.c +296 -296
  40. data/ext/ruby_prof/rp_call_trees.h +25 -28
  41. data/ext/ruby_prof/rp_measure_allocations.c +47 -47
  42. data/ext/ruby_prof/rp_measure_process_time.c +64 -66
  43. data/ext/ruby_prof/rp_measure_wall_time.c +52 -64
  44. data/ext/ruby_prof/rp_measurement.c +0 -5
  45. data/ext/ruby_prof/rp_measurement.h +49 -53
  46. data/ext/ruby_prof/rp_method.c +554 -551
  47. data/ext/ruby_prof/rp_method.h +1 -4
  48. data/ext/ruby_prof/rp_profile.c +1 -1
  49. data/ext/ruby_prof/rp_profile.h +1 -5
  50. data/ext/ruby_prof/rp_stack.c +212 -212
  51. data/ext/ruby_prof/rp_stack.h +50 -53
  52. data/ext/ruby_prof/rp_thread.h +1 -4
  53. data/ext/ruby_prof/ruby_prof.c +50 -50
  54. data/ext/ruby_prof/ruby_prof.h +4 -6
  55. data/ext/ruby_prof/vc/ruby_prof.vcxproj +7 -8
  56. data/lib/ruby-prof/assets/call_stack_printer.html.erb +746 -711
  57. data/lib/ruby-prof/assets/flame_graph_printer.html.erb +412 -0
  58. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -355
  59. data/lib/ruby-prof/call_tree.rb +57 -57
  60. data/lib/ruby-prof/call_tree_visitor.rb +36 -36
  61. data/lib/ruby-prof/exclude_common_methods.rb +204 -204
  62. data/lib/ruby-prof/measurement.rb +17 -17
  63. data/lib/ruby-prof/printers/abstract_printer.rb +142 -138
  64. data/lib/ruby-prof/printers/call_info_printer.rb +53 -53
  65. data/lib/ruby-prof/printers/call_stack_printer.rb +168 -180
  66. data/lib/ruby-prof/printers/call_tree_printer.rb +132 -145
  67. data/lib/ruby-prof/printers/dot_printer.rb +177 -132
  68. data/lib/ruby-prof/printers/flame_graph_printer.rb +79 -0
  69. data/lib/ruby-prof/printers/flat_printer.rb +52 -52
  70. data/lib/ruby-prof/printers/graph_html_printer.rb +62 -63
  71. data/lib/ruby-prof/printers/graph_printer.rb +112 -113
  72. data/lib/ruby-prof/printers/multi_printer.rb +134 -127
  73. data/lib/ruby-prof/profile.rb +13 -0
  74. data/lib/ruby-prof/rack.rb +114 -105
  75. data/lib/ruby-prof/task.rb +147 -147
  76. data/lib/ruby-prof/thread.rb +20 -20
  77. data/lib/ruby-prof/version.rb +3 -3
  78. data/lib/ruby-prof.rb +50 -52
  79. data/lib/unprof.rb +10 -10
  80. data/ruby-prof.gemspec +66 -65
  81. data/test/abstract_printer_test.rb +25 -27
  82. data/test/alias_test.rb +203 -117
  83. data/test/call_tree_builder.rb +126 -126
  84. data/test/call_tree_visitor_test.rb +27 -27
  85. data/test/call_trees_test.rb +66 -66
  86. data/test/duplicate_names_test.rb +32 -32
  87. data/test/dynamic_method_test.rb +50 -62
  88. data/test/enumerable_test.rb +23 -21
  89. data/test/exceptions_test.rb +24 -24
  90. data/test/exclude_methods_test.rb +363 -257
  91. data/test/exclude_threads_test.rb +48 -48
  92. data/test/fiber_test.rb +195 -195
  93. data/test/gc_test.rb +104 -102
  94. data/test/inverse_call_tree_test.rb +174 -174
  95. data/test/line_number_test.rb +563 -289
  96. data/test/marshal_test.rb +144 -145
  97. data/test/measure_allocations.rb +26 -26
  98. data/test/measure_allocations_test.rb +1511 -1081
  99. data/test/measure_process_time_test.rb +3286 -2477
  100. data/test/measure_times.rb +56 -56
  101. data/test/measure_wall_time_test.rb +773 -568
  102. data/test/measurement_test.rb +82 -82
  103. data/test/merge_test.rb +146 -146
  104. data/test/method_info_test.rb +100 -95
  105. data/test/multi_printer_test.rb +52 -66
  106. data/test/no_method_class_test.rb +15 -15
  107. data/test/pause_resume_test.rb +171 -171
  108. data/test/prime.rb +54 -54
  109. data/test/prime_script.rb +5 -5
  110. data/test/printer_call_stack_test.rb +28 -27
  111. data/test/printer_call_tree_test.rb +30 -30
  112. data/test/printer_flame_graph_test.rb +82 -0
  113. data/test/printer_flat_test.rb +99 -99
  114. data/test/printer_graph_html_test.rb +62 -59
  115. data/test/printer_graph_test.rb +42 -40
  116. data/test/printers_test.rb +162 -135
  117. data/test/printing_recursive_graph_test.rb +81 -81
  118. data/test/profile_test.rb +101 -101
  119. data/test/rack_test.rb +103 -93
  120. data/test/recursive_test.rb +796 -622
  121. data/test/scheduler.rb +4 -0
  122. data/test/singleton_test.rb +39 -38
  123. data/test/stack_printer_test.rb +61 -61
  124. data/test/start_stop_test.rb +106 -106
  125. data/test/test_helper.rb +24 -20
  126. data/test/thread_test.rb +229 -231
  127. data/test/unique_call_path_test.rb +123 -136
  128. data/test/yarv_test.rb +56 -60
  129. metadata +68 -16
  130. data/ext/ruby_prof/rp_measure_memory.c +0 -46
  131. data/lib/ruby-prof/compatibility.rb +0 -113
  132. data/test/compatibility_test.rb +0 -49
  133. data/test/crash2.rb +0 -144
  134. data/test/measure_memory_test.rb +0 -1456
@@ -1,257 +1,363 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- module ExcludeMethodsModule
7
- def c
8
- 1.times { |i| ExcludeMethodsModule.d }
9
- end
10
-
11
- def self.d
12
- 1.times { |i| ExcludeMethodsClass.e }
13
- end
14
- end
15
-
16
- class ExcludeMethodsClass
17
- include ExcludeMethodsModule
18
-
19
- def a
20
- 1.times { |i| b }
21
- end
22
-
23
- def b
24
- 1.times { |i| c; self.class.e }
25
- end
26
-
27
- def self.e
28
- 1.times { |i| f }
29
- end
30
-
31
- def self.f
32
- sleep 0.1
33
- end
34
- end
35
-
36
- class ExcludeMethodsTest < TestCase
37
- if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.3')
38
- def test_methods_can_be_profiled
39
- obj = ExcludeMethodsClass.new
40
- prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
41
-
42
- result = prf.profile {obj.a}
43
- methods = result.threads.first.methods.sort.reverse
44
- assert_equal(10, methods.count)
45
- assert_equal('ExcludeMethodsTest#test_methods_can_be_profiled', methods[0].full_name)
46
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
47
- assert_equal('Integer#times', methods[2].full_name)
48
- assert_equal('ExcludeMethodsClass#b', methods[3].full_name)
49
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[4].full_name)
50
- assert_equal('<Class::ExcludeMethodsClass>#f', methods[5].full_name)
51
- assert_equal('Kernel#sleep', methods[6].full_name)
52
- assert_equal('ExcludeMethodsModule#c', methods[7].full_name)
53
- assert_equal('<Module::ExcludeMethodsModule>#d', methods[8].full_name)
54
- assert_equal('Kernel#class', methods[9].full_name)
55
- end
56
-
57
- def test_methods_can_be_hidden1
58
- obj = ExcludeMethodsClass.new
59
- prf = RubyProf::Profile.new
60
-
61
- prf.exclude_methods!(Integer, :times)
62
-
63
- result = prf.profile {obj.a}
64
- methods = result.threads.first.methods.sort.reverse
65
-
66
- assert_equal(9, methods.count)
67
- assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden1', methods[0].full_name)
68
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
69
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
70
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
71
- assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
72
- assert_equal('Kernel#sleep', methods[5].full_name)
73
- assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
74
- assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
75
- assert_equal('Kernel#class', methods[8].full_name)
76
- end
77
-
78
- def test_methods_can_be_hidden2
79
- obj = ExcludeMethodsClass.new
80
- prf = RubyProf::Profile.new
81
-
82
- prf.exclude_methods!(Integer, :times)
83
- prf.exclude_methods!(ExcludeMethodsClass.singleton_class, :f)
84
- prf.exclude_methods!(ExcludeMethodsModule.singleton_class, :d)
85
-
86
- result = prf.profile {obj.a}
87
- methods = result.threads.first.methods.sort.reverse
88
-
89
- assert_equal(7, methods.count)
90
- assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden2', methods[0].full_name)
91
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
92
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
93
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
94
- assert_equal('Kernel#sleep', methods[4].full_name)
95
- assert_equal('ExcludeMethodsModule#c', methods[5].full_name)
96
- assert_equal('Kernel#class', methods[6].full_name)
97
- end
98
-
99
- def test_exclude_common_methods1
100
- obj = ExcludeMethodsClass.new
101
- prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
102
-
103
- prf.exclude_common_methods!
104
-
105
- result = prf.profile {obj.a}
106
- methods = result.threads.first.methods.sort.reverse
107
-
108
- assert_equal(9, methods.count)
109
- assert_equal('ExcludeMethodsTest#test_exclude_common_methods1', methods[0].full_name)
110
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
111
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
112
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
113
- assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
114
- assert_equal('Kernel#sleep', methods[5].full_name)
115
- assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
116
- assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
117
- assert_equal('Kernel#class', methods[8].full_name)
118
- end
119
-
120
- def test_exclude_common_methods2
121
- obj = ExcludeMethodsClass.new
122
-
123
- result = RubyProf::Profile.profile(exclude_common: true) { 5.times {obj.a} }
124
- methods = result.threads.first.methods.sort.reverse
125
-
126
- assert_equal(9, methods.count)
127
- assert_equal('ExcludeMethodsTest#test_exclude_common_methods2', methods[0].full_name)
128
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
129
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
130
- end
131
- else
132
- def test_methods_can_be_profiled
133
- obj = ExcludeMethodsClass.new
134
- prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
135
-
136
- result = prf.profile {obj.a}
137
- methods = result.threads.first.methods.sort.reverse
138
- assert_equal(13, methods.count)
139
- assert_equal('ExcludeMethodsTest#test_methods_can_be_profiled', methods[0].full_name)
140
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
141
- assert_equal('Integer#times', methods[2].full_name)
142
- assert_equal('ExcludeMethodsClass#b', methods[3].full_name)
143
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[4].full_name)
144
- assert_equal('<Class::ExcludeMethodsClass>#f', methods[5].full_name)
145
- assert_equal('Kernel#sleep', methods[6].full_name)
146
- assert_equal('ExcludeMethodsModule#c', methods[7].full_name)
147
- assert_equal('<Module::ExcludeMethodsModule>#d', methods[8].full_name)
148
- assert_equal('Kernel#block_given?', methods[9].full_name)
149
- assert_equal('Integer#succ', methods[10].full_name)
150
- assert_equal('Integer#<', methods[11].full_name)
151
- assert_equal('Kernel#class', methods[12].full_name)
152
- end
153
-
154
- def test_methods_can_be_hidden1
155
- obj = ExcludeMethodsClass.new
156
- prf = RubyProf::Profile.new
157
-
158
- prf.exclude_methods!(Integer, :times)
159
-
160
- result = prf.profile {obj.a}
161
- methods = result.threads.first.methods.sort.reverse
162
-
163
- assert_equal(12, methods.count)
164
- assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden1', methods[0].full_name)
165
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
166
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
167
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
168
- assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
169
- assert_equal('Kernel#sleep', methods[5].full_name)
170
- assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
171
- assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
172
- assert_equal('Kernel#block_given?', methods[8].full_name)
173
- assert_equal('Integer#succ', methods[9].full_name)
174
- assert_equal('Integer#<', methods[10].full_name)
175
- assert_equal('Kernel#class', methods[11].full_name)
176
- end
177
-
178
- def test_methods_can_be_hidden2
179
- obj = ExcludeMethodsClass.new
180
- prf = RubyProf::Profile.new
181
-
182
- prf.exclude_methods!(Integer, :times)
183
- prf.exclude_methods!(ExcludeMethodsClass.singleton_class, :f)
184
- prf.exclude_methods!(ExcludeMethodsModule.singleton_class, :d)
185
-
186
- result = prf.profile {obj.a}
187
- methods = result.threads.first.methods.sort.reverse
188
-
189
- assert_equal(10, methods.count)
190
- assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden2', methods[0].full_name)
191
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
192
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
193
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
194
- assert_equal('Kernel#sleep', methods[4].full_name)
195
- assert_equal('ExcludeMethodsModule#c', methods[5].full_name)
196
- assert_equal('Kernel#block_given?', methods[6].full_name)
197
- assert_equal('Integer#succ', methods[7].full_name)
198
- assert_equal('Integer#<', methods[8].full_name)
199
- assert_equal('Kernel#class', methods[9].full_name)
200
- end
201
-
202
- def test_exclude_common_methods1
203
- obj = ExcludeMethodsClass.new
204
- prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
205
-
206
- prf.exclude_common_methods!
207
-
208
- result = prf.profile {obj.a}
209
- methods = result.threads.first.methods.sort.reverse
210
-
211
- assert_equal(9, methods.count)
212
- assert_equal('ExcludeMethodsTest#test_exclude_common_methods1', methods[0].full_name)
213
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
214
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
215
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
216
- assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
217
- assert_equal('Kernel#sleep', methods[5].full_name)
218
- assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
219
- assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
220
- assert_equal('Kernel#class', methods[8].full_name)
221
- end
222
-
223
- def test_exclude_common_methods2
224
- obj = ExcludeMethodsClass.new
225
-
226
- result = RubyProf::Profile.profile(exclude_common: true) { 5.times {obj.a} }
227
- methods = result.threads.first.methods.sort.reverse
228
-
229
- assert_equal(9, methods.count)
230
- assert_equal('ExcludeMethodsTest#test_exclude_common_methods2', methods[0].full_name)
231
- assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
232
- assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
233
- assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
234
- assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
235
- assert_equal('Kernel#sleep', methods[5].full_name)
236
- assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
237
- assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
238
- assert_equal('Kernel#class', methods[8].full_name)
239
- end
240
- end
241
-
242
- private
243
-
244
- def assert_method_has_been_excluded(result, excluded_method)
245
- result.threads.each do |thread|
246
- thread.methods.each do |method|
247
- method.call_trees.each do |ci|
248
- assert(ci.target != excluded_method, "broken self")
249
- assert(ci.parent.target != excluded_method, "broken parent") if ci.parent
250
- ci.children.each do |callee|
251
- assert(callee.target != excluded_method, "broken kid")
252
- end
253
- end
254
- end
255
- end
256
- end
257
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ module ExcludeMethodsModule
7
+ def c
8
+ 1.times { |i| ExcludeMethodsModule.d }
9
+ end
10
+
11
+ def self.d
12
+ 1.times { |i| ExcludeMethodsClass.e }
13
+ end
14
+ end
15
+
16
+ class ExcludeMethodsClass
17
+ include ExcludeMethodsModule
18
+
19
+ def a
20
+ 1.times { |i| b }
21
+ end
22
+
23
+ def b
24
+ 1.times { |i| c; self.class.e }
25
+ end
26
+
27
+ def self.e
28
+ 1.times { |i| f }
29
+ end
30
+
31
+ def self.f
32
+ sleep 0.1
33
+ end
34
+ end
35
+
36
+ class ExcludeMethodsTest < TestCase
37
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.3')
38
+ def test_methods_can_be_profiled
39
+ obj = ExcludeMethodsClass.new
40
+ prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
41
+
42
+ result = prf.profile {obj.a}
43
+ methods = result.threads.first.methods.sort.reverse
44
+ assert_equal(10, methods.count)
45
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_profiled', methods[0].full_name)
46
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
47
+ assert_equal('Integer#times', methods[2].full_name)
48
+ assert_equal('ExcludeMethodsClass#b', methods[3].full_name)
49
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[4].full_name)
50
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[5].full_name)
51
+ assert_equal('Kernel#sleep', methods[6].full_name)
52
+ assert_equal('ExcludeMethodsModule#c', methods[7].full_name)
53
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[8].full_name)
54
+ assert_equal('Kernel#class', methods[9].full_name)
55
+ end
56
+
57
+ def test_methods_can_be_hidden1
58
+ obj = ExcludeMethodsClass.new
59
+ prf = RubyProf::Profile.new
60
+
61
+ prf.exclude_methods!(Integer, :times)
62
+
63
+ result = prf.profile {obj.a}
64
+ methods = result.threads.first.methods.sort.reverse
65
+
66
+ assert_equal(9, methods.count)
67
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden1', methods[0].full_name)
68
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
69
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
70
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
71
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
72
+ assert_equal('Kernel#sleep', methods[5].full_name)
73
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
74
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
75
+ assert_equal('Kernel#class', methods[8].full_name)
76
+ end
77
+
78
+ def test_methods_can_be_hidden2
79
+ obj = ExcludeMethodsClass.new
80
+ prf = RubyProf::Profile.new
81
+
82
+ prf.exclude_methods!(Integer, :times)
83
+ prf.exclude_methods!(ExcludeMethodsClass.singleton_class, :f)
84
+ prf.exclude_methods!(ExcludeMethodsModule.singleton_class, :d)
85
+
86
+ result = prf.profile {obj.a}
87
+ methods = result.threads.first.methods.sort.reverse
88
+
89
+ assert_equal(7, methods.count)
90
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden2', methods[0].full_name)
91
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
92
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
93
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
94
+ assert_equal('Kernel#sleep', methods[4].full_name)
95
+ assert_equal('ExcludeMethodsModule#c', methods[5].full_name)
96
+ assert_equal('Kernel#class', methods[6].full_name)
97
+ end
98
+
99
+ def test_exclude_common_methods1
100
+ obj = ExcludeMethodsClass.new
101
+ prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
102
+
103
+ prf.exclude_common_methods!
104
+
105
+ result = prf.profile {obj.a}
106
+ methods = result.threads.first.methods.sort.reverse
107
+
108
+ assert_equal(9, methods.count)
109
+ assert_equal('ExcludeMethodsTest#test_exclude_common_methods1', methods[0].full_name)
110
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
111
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
112
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
113
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
114
+ assert_equal('Kernel#sleep', methods[5].full_name)
115
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
116
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
117
+ assert_equal('Kernel#class', methods[8].full_name)
118
+ end
119
+
120
+ def test_exclude_common_methods2
121
+ obj = ExcludeMethodsClass.new
122
+
123
+ result = RubyProf::Profile.profile(exclude_common: true) { 5.times {obj.a} }
124
+ methods = result.threads.first.methods.sort.reverse
125
+
126
+ assert_equal(9, methods.count)
127
+ assert_equal('ExcludeMethodsTest#test_exclude_common_methods2', methods[0].full_name)
128
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
129
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
130
+ end
131
+ elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('3.4')
132
+ def test_methods_can_be_profiled
133
+ obj = ExcludeMethodsClass.new
134
+ prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
135
+
136
+ result = prf.profile {obj.a}
137
+ methods = result.threads.first.methods.sort.reverse
138
+ assert_equal(13, methods.count)
139
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_profiled', methods[0].full_name)
140
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
141
+ assert_equal('Integer#times', methods[2].full_name)
142
+ assert_equal('ExcludeMethodsClass#b', methods[3].full_name)
143
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[4].full_name)
144
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[5].full_name)
145
+ assert_equal('Kernel#sleep', methods[6].full_name)
146
+ assert_equal('ExcludeMethodsModule#c', methods[7].full_name)
147
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[8].full_name)
148
+ assert_equal('Kernel#block_given?', methods[9].full_name)
149
+ assert_equal('Integer#succ', methods[10].full_name)
150
+ assert_equal('Integer#<', methods[11].full_name)
151
+ assert_equal('Kernel#class', methods[12].full_name)
152
+ end
153
+
154
+ def test_methods_can_be_hidden1
155
+ obj = ExcludeMethodsClass.new
156
+ prf = RubyProf::Profile.new
157
+
158
+ prf.exclude_methods!(Integer, :times)
159
+
160
+ result = prf.profile {obj.a}
161
+ methods = result.threads.first.methods.sort.reverse
162
+
163
+ assert_equal(12, methods.count)
164
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden1', methods[0].full_name)
165
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
166
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
167
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
168
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
169
+ assert_equal('Kernel#sleep', methods[5].full_name)
170
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
171
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
172
+ assert_equal('Kernel#block_given?', methods[8].full_name)
173
+ assert_equal('Integer#succ', methods[9].full_name)
174
+ assert_equal('Integer#<', methods[10].full_name)
175
+ assert_equal('Kernel#class', methods[11].full_name)
176
+ end
177
+
178
+ def test_methods_can_be_hidden2
179
+ obj = ExcludeMethodsClass.new
180
+ prf = RubyProf::Profile.new
181
+
182
+ prf.exclude_methods!(Integer, :times)
183
+ prf.exclude_methods!(ExcludeMethodsClass.singleton_class, :f)
184
+ prf.exclude_methods!(ExcludeMethodsModule.singleton_class, :d)
185
+
186
+ result = prf.profile {obj.a}
187
+ methods = result.threads.first.methods.sort.reverse
188
+
189
+ assert_equal(10, methods.count)
190
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden2', methods[0].full_name)
191
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
192
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
193
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
194
+ assert_equal('Kernel#sleep', methods[4].full_name)
195
+ assert_equal('ExcludeMethodsModule#c', methods[5].full_name)
196
+ assert_equal('Kernel#block_given?', methods[6].full_name)
197
+ assert_equal('Integer#succ', methods[7].full_name)
198
+ assert_equal('Integer#<', methods[8].full_name)
199
+ assert_equal('Kernel#class', methods[9].full_name)
200
+ end
201
+
202
+ def test_exclude_common_methods1
203
+ obj = ExcludeMethodsClass.new
204
+ prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
205
+
206
+ prf.exclude_common_methods!
207
+
208
+ result = prf.profile {obj.a}
209
+ methods = result.threads.first.methods.sort.reverse
210
+
211
+ assert_equal(9, methods.count)
212
+ assert_equal('ExcludeMethodsTest#test_exclude_common_methods1', methods[0].full_name)
213
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
214
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
215
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
216
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
217
+ assert_equal('Kernel#sleep', methods[5].full_name)
218
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
219
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
220
+ assert_equal('Kernel#class', methods[8].full_name)
221
+ end
222
+
223
+ def test_exclude_common_methods2
224
+ obj = ExcludeMethodsClass.new
225
+
226
+ result = RubyProf::Profile.profile(exclude_common: true) { 5.times {obj.a} }
227
+ methods = result.threads.first.methods.sort.reverse
228
+
229
+ assert_equal(9, methods.count)
230
+ assert_equal('ExcludeMethodsTest#test_exclude_common_methods2', methods[0].full_name)
231
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
232
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
233
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
234
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
235
+ assert_equal('Kernel#sleep', methods[5].full_name)
236
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
237
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
238
+ assert_equal('Kernel#class', methods[8].full_name)
239
+ end
240
+ else
241
+ def test_methods_can_be_profiled
242
+ obj = ExcludeMethodsClass.new
243
+ prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
244
+
245
+ result = prf.profile {obj.a}
246
+ methods = result.threads.first.methods.sort.reverse
247
+ assert_equal(12, methods.count)
248
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_profiled', methods[0].full_name)
249
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
250
+ assert_equal('Integer#times', methods[2].full_name)
251
+ assert_equal('ExcludeMethodsClass#b', methods[3].full_name)
252
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[4].full_name)
253
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[5].full_name)
254
+ assert_equal('Kernel#sleep', methods[6].full_name)
255
+ assert_equal('ExcludeMethodsModule#c', methods[7].full_name)
256
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[8].full_name)
257
+ assert_equal('Integer#succ', methods[9].full_name)
258
+ assert_equal('Integer#<', methods[10].full_name)
259
+ assert_equal('Kernel#class', methods[11].full_name)
260
+ end
261
+
262
+ def test_methods_can_be_hidden1
263
+ obj = ExcludeMethodsClass.new
264
+ prf = RubyProf::Profile.new
265
+
266
+ prf.exclude_methods!(Integer, :times)
267
+
268
+ result = prf.profile {obj.a}
269
+ methods = result.threads.first.methods.sort.reverse
270
+
271
+ assert_equal(11, methods.count)
272
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden1', methods[0].full_name)
273
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
274
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
275
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
276
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
277
+ assert_equal('Kernel#sleep', methods[5].full_name)
278
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
279
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
280
+ assert_equal('Integer#succ', methods[8].full_name)
281
+ assert_equal('Integer#<', methods[9].full_name)
282
+ assert_equal('Kernel#class', methods[10].full_name)
283
+ end
284
+
285
+ def test_methods_can_be_hidden2
286
+ obj = ExcludeMethodsClass.new
287
+ prf = RubyProf::Profile.new
288
+
289
+ prf.exclude_methods!(Integer, :times)
290
+ prf.exclude_methods!(ExcludeMethodsClass.singleton_class, :f)
291
+ prf.exclude_methods!(ExcludeMethodsModule.singleton_class, :d)
292
+
293
+ result = prf.profile {obj.a}
294
+ methods = result.threads.first.methods.sort.reverse
295
+
296
+ assert_equal(9, methods.count)
297
+ assert_equal('ExcludeMethodsTest#test_methods_can_be_hidden2', methods[0].full_name)
298
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
299
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
300
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
301
+ assert_equal('Kernel#sleep', methods[4].full_name)
302
+ assert_equal('ExcludeMethodsModule#c', methods[5].full_name)
303
+ assert_equal('Integer#succ', methods[6].full_name)
304
+ assert_equal('Integer#<', methods[7].full_name)
305
+ assert_equal('Kernel#class', methods[8].full_name)
306
+ end
307
+
308
+ def test_exclude_common_methods1
309
+ obj = ExcludeMethodsClass.new
310
+ prf = RubyProf::Profile.new(measure_mode: RubyProf::WALL_TIME)
311
+
312
+ prf.exclude_common_methods!
313
+
314
+ result = prf.profile {obj.a}
315
+ methods = result.threads.first.methods.sort.reverse
316
+
317
+ assert_equal(9, methods.count)
318
+ assert_equal('ExcludeMethodsTest#test_exclude_common_methods1', methods[0].full_name)
319
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
320
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
321
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
322
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
323
+ assert_equal('Kernel#sleep', methods[5].full_name)
324
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
325
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
326
+ assert_equal('Kernel#class', methods[8].full_name)
327
+ end
328
+
329
+ def test_exclude_common_methods2
330
+ obj = ExcludeMethodsClass.new
331
+
332
+ result = RubyProf::Profile.profile(exclude_common: true) { 5.times {obj.a} }
333
+ methods = result.threads.first.methods.sort.reverse
334
+
335
+ assert_equal(9, methods.count)
336
+ assert_equal('ExcludeMethodsTest#test_exclude_common_methods2', methods[0].full_name)
337
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
338
+ assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
339
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
340
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
341
+ assert_equal('Kernel#sleep', methods[5].full_name)
342
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
343
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
344
+ assert_equal('Kernel#class', methods[8].full_name)
345
+ end
346
+ end
347
+
348
+ private
349
+
350
+ def assert_method_has_been_excluded(result, excluded_method)
351
+ result.threads.each do |thread|
352
+ thread.methods.each do |method|
353
+ method.call_trees.each do |ci|
354
+ assert(ci.target != excluded_method, "broken self")
355
+ assert(ci.parent.target != excluded_method, "broken parent") if ci.parent
356
+ ci.children.each do |callee|
357
+ assert(callee.target != excluded_method, "broken kid")
358
+ end
359
+ end
360
+ end
361
+ end
362
+ end
363
+ end