ruby-prof 0.16.2 → 1.1.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 (203) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGES +532 -467
  3. data/LICENSE +24 -24
  4. data/README.rdoc +5 -454
  5. data/Rakefile +110 -113
  6. data/bin/ruby-prof +380 -340
  7. data/bin/ruby-prof-check-trace +45 -45
  8. data/ext/ruby_prof/extconf.rb +36 -64
  9. data/ext/ruby_prof/rp_allocation.c +279 -0
  10. data/ext/ruby_prof/rp_allocation.h +31 -0
  11. data/ext/ruby_prof/rp_call_info.c +271 -407
  12. data/ext/ruby_prof/rp_call_info.h +35 -48
  13. data/ext/ruby_prof/rp_measure_allocations.c +52 -76
  14. data/ext/ruby_prof/rp_measure_memory.c +42 -77
  15. data/ext/ruby_prof/rp_measure_process_time.c +67 -71
  16. data/ext/ruby_prof/rp_measure_wall_time.c +62 -45
  17. data/ext/ruby_prof/rp_measurement.c +230 -0
  18. data/ext/ruby_prof/rp_measurement.h +50 -0
  19. data/ext/ruby_prof/rp_method.c +630 -411
  20. data/ext/ruby_prof/rp_method.h +70 -52
  21. data/ext/ruby_prof/rp_profile.c +895 -0
  22. data/ext/ruby_prof/rp_profile.h +37 -0
  23. data/ext/ruby_prof/rp_stack.c +196 -128
  24. data/ext/ruby_prof/rp_stack.h +56 -51
  25. data/ext/ruby_prof/rp_thread.c +337 -273
  26. data/ext/ruby_prof/rp_thread.h +36 -27
  27. data/ext/ruby_prof/ruby_prof.c +48 -671
  28. data/ext/ruby_prof/ruby_prof.h +17 -56
  29. data/ext/ruby_prof/vc/ruby_prof.sln +20 -21
  30. data/ext/ruby_prof/vc/{ruby_prof_20.vcxproj → ruby_prof.vcxproj} +38 -5
  31. data/lib/ruby-prof.rb +52 -58
  32. data/lib/ruby-prof/assets/call_stack_printer.html.erb +713 -0
  33. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  34. data/lib/ruby-prof/assets/graph_printer.html.erb +356 -0
  35. data/lib/ruby-prof/call_info.rb +57 -126
  36. data/lib/ruby-prof/call_info_visitor.rb +38 -40
  37. data/lib/ruby-prof/compatibility.rb +109 -178
  38. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  39. data/lib/ruby-prof/measurement.rb +14 -0
  40. data/lib/ruby-prof/method_info.rb +90 -129
  41. data/lib/ruby-prof/printers/abstract_printer.rb +127 -85
  42. data/lib/ruby-prof/printers/call_info_printer.rb +51 -41
  43. data/lib/ruby-prof/printers/call_stack_printer.rb +182 -260
  44. data/lib/ruby-prof/printers/call_tree_printer.rb +151 -130
  45. data/lib/ruby-prof/printers/dot_printer.rb +132 -132
  46. data/lib/ruby-prof/printers/flat_printer.rb +52 -70
  47. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -244
  48. data/lib/ruby-prof/printers/graph_printer.rb +114 -116
  49. data/lib/ruby-prof/printers/multi_printer.rb +127 -58
  50. data/lib/ruby-prof/profile.rb +33 -55
  51. data/lib/ruby-prof/rack.rb +171 -95
  52. data/lib/ruby-prof/task.rb +147 -147
  53. data/lib/ruby-prof/thread.rb +35 -41
  54. data/lib/ruby-prof/version.rb +3 -3
  55. data/lib/unprof.rb +10 -10
  56. data/ruby-prof.gemspec +58 -57
  57. data/test/abstract_printer_test.rb +26 -0
  58. data/test/alias_test.rb +129 -0
  59. data/test/basic_test.rb +129 -128
  60. data/test/call_info_visitor_test.rb +31 -31
  61. data/test/duplicate_names_test.rb +32 -32
  62. data/test/dynamic_method_test.rb +53 -55
  63. data/test/enumerable_test.rb +21 -21
  64. data/test/exceptions_test.rb +24 -16
  65. data/test/exclude_methods_test.rb +146 -0
  66. data/test/exclude_threads_test.rb +53 -53
  67. data/test/fiber_test.rb +73 -79
  68. data/test/gc_test.rb +96 -0
  69. data/test/line_number_test.rb +161 -71
  70. data/test/marshal_test.rb +119 -0
  71. data/test/measure_allocations.rb +30 -0
  72. data/test/measure_allocations_test.rb +385 -26
  73. data/test/measure_allocations_trace_test.rb +385 -0
  74. data/test/measure_memory_trace_test.rb +756 -0
  75. data/test/measure_process_time_test.rb +849 -63
  76. data/test/measure_times.rb +54 -0
  77. data/test/measure_wall_time_test.rb +459 -255
  78. data/test/multi_printer_test.rb +71 -83
  79. data/test/no_method_class_test.rb +15 -15
  80. data/test/parser_timings.rb +24 -0
  81. data/test/pause_resume_test.rb +166 -166
  82. data/test/prime.rb +56 -54
  83. data/test/printer_call_stack_test.rb +28 -0
  84. data/test/printer_call_tree_test.rb +31 -0
  85. data/test/printer_flat_test.rb +68 -0
  86. data/test/printer_graph_html_test.rb +60 -0
  87. data/test/printer_graph_test.rb +41 -0
  88. data/test/printers_test.rb +141 -255
  89. data/test/printing_recursive_graph_test.rb +81 -127
  90. data/test/rack_test.rb +157 -93
  91. data/test/recursive_test.rb +210 -215
  92. data/test/singleton_test.rb +38 -38
  93. data/test/stack_printer_test.rb +64 -78
  94. data/test/start_stop_test.rb +109 -112
  95. data/test/test_helper.rb +24 -264
  96. data/test/thread_test.rb +144 -187
  97. data/test/unique_call_path_test.rb +190 -202
  98. data/test/yarv_test.rb +56 -55
  99. metadata +34 -114
  100. data/doc/LICENSE.html +0 -114
  101. data/doc/README_rdoc.html +0 -603
  102. data/doc/Rack.html +0 -95
  103. data/doc/Rack/RubyProf.html +0 -226
  104. data/doc/RubyProf.html +0 -962
  105. data/doc/RubyProf/AbstractPrinter.html +0 -546
  106. data/doc/RubyProf/AggregateCallInfo.html +0 -551
  107. data/doc/RubyProf/CallInfo.html +0 -639
  108. data/doc/RubyProf/CallInfoPrinter.html +0 -120
  109. data/doc/RubyProf/CallInfoVisitor.html +0 -198
  110. data/doc/RubyProf/CallStackPrinter.html +0 -1121
  111. data/doc/RubyProf/CallTreePrinter.html +0 -641
  112. data/doc/RubyProf/Cmd.html +0 -631
  113. data/doc/RubyProf/DotPrinter.html +0 -257
  114. data/doc/RubyProf/FlatPrinter.html +0 -163
  115. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +0 -208
  116. data/doc/RubyProf/GraphHtmlPrinter.html +0 -552
  117. data/doc/RubyProf/GraphPrinter.html +0 -139
  118. data/doc/RubyProf/MethodInfo.html +0 -745
  119. data/doc/RubyProf/MultiPrinter.html +0 -360
  120. data/doc/RubyProf/Profile.html +0 -763
  121. data/doc/RubyProf/ProfileTask.html +0 -490
  122. data/doc/RubyProf/Thread.html +0 -310
  123. data/doc/created.rid +0 -31
  124. data/doc/css/fonts.css +0 -167
  125. data/doc/css/rdoc.css +0 -590
  126. data/doc/examples/flat_txt.html +0 -138
  127. data/doc/examples/graph_html.html +0 -909
  128. data/doc/examples/graph_txt.html +0 -247
  129. data/doc/fonts/Lato-Light.ttf +0 -0
  130. data/doc/fonts/Lato-LightItalic.ttf +0 -0
  131. data/doc/fonts/Lato-Regular.ttf +0 -0
  132. data/doc/fonts/Lato-RegularItalic.ttf +0 -0
  133. data/doc/fonts/SourceCodePro-Bold.ttf +0 -0
  134. data/doc/fonts/SourceCodePro-Regular.ttf +0 -0
  135. data/doc/images/add.png +0 -0
  136. data/doc/images/arrow_up.png +0 -0
  137. data/doc/images/brick.png +0 -0
  138. data/doc/images/brick_link.png +0 -0
  139. data/doc/images/bug.png +0 -0
  140. data/doc/images/bullet_black.png +0 -0
  141. data/doc/images/bullet_toggle_minus.png +0 -0
  142. data/doc/images/bullet_toggle_plus.png +0 -0
  143. data/doc/images/date.png +0 -0
  144. data/doc/images/delete.png +0 -0
  145. data/doc/images/find.png +0 -0
  146. data/doc/images/loadingAnimation.gif +0 -0
  147. data/doc/images/macFFBgHack.png +0 -0
  148. data/doc/images/package.png +0 -0
  149. data/doc/images/page_green.png +0 -0
  150. data/doc/images/page_white_text.png +0 -0
  151. data/doc/images/page_white_width.png +0 -0
  152. data/doc/images/plugin.png +0 -0
  153. data/doc/images/ruby.png +0 -0
  154. data/doc/images/tag_blue.png +0 -0
  155. data/doc/images/tag_green.png +0 -0
  156. data/doc/images/transparent.png +0 -0
  157. data/doc/images/wrench.png +0 -0
  158. data/doc/images/wrench_orange.png +0 -0
  159. data/doc/images/zoom.png +0 -0
  160. data/doc/index.html +0 -626
  161. data/doc/js/darkfish.js +0 -161
  162. data/doc/js/jquery.js +0 -4
  163. data/doc/js/navigation.js +0 -142
  164. data/doc/js/navigation.js.gz +0 -0
  165. data/doc/js/search.js +0 -109
  166. data/doc/js/search_index.js +0 -1
  167. data/doc/js/search_index.js.gz +0 -0
  168. data/doc/js/searcher.js +0 -228
  169. data/doc/js/searcher.js.gz +0 -0
  170. data/doc/table_of_contents.html +0 -942
  171. data/examples/cachegrind.out.1 +0 -114
  172. data/examples/cachegrind.out.1.32313213 +0 -114
  173. data/examples/flat.txt +0 -50
  174. data/examples/graph.dot +0 -84
  175. data/examples/graph.html +0 -823
  176. data/examples/graph.txt +0 -139
  177. data/examples/multi.flat.txt +0 -23
  178. data/examples/multi.graph.html +0 -760
  179. data/examples/multi.grind.dat +0 -114
  180. data/examples/multi.stack.html +0 -547
  181. data/examples/stack.html +0 -547
  182. data/ext/ruby_prof/rp_measure.c +0 -40
  183. data/ext/ruby_prof/rp_measure.h +0 -45
  184. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
  185. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
  186. data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
  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/lib/ruby-prof/aggregate_call_info.rb +0 -76
  190. data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
  191. data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
  192. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -64
  193. data/test/aggregate_test.rb +0 -136
  194. data/test/block_test.rb +0 -74
  195. data/test/call_info_test.rb +0 -78
  196. data/test/issue137_test.rb +0 -63
  197. data/test/measure_cpu_time_test.rb +0 -213
  198. data/test/measure_gc_runs_test.rb +0 -32
  199. data/test/measure_gc_time_test.rb +0 -36
  200. data/test/measure_memory_test.rb +0 -33
  201. data/test/method_elimination_test.rb +0 -84
  202. data/test/module_test.rb +0 -45
  203. data/test/stack_test.rb +0 -138
@@ -1,83 +1,71 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- # Test data
7
- # A
8
- # / \
9
- # B C
10
- # \
11
- # B
12
-
13
- class MSTPT
14
- def a
15
- 100.times{b}
16
- 300.times{c}
17
- c;c;c
18
- end
19
-
20
- def b
21
- sleep 0
22
- end
23
-
24
- def c
25
- 5.times{b}
26
- end
27
- end
28
-
29
- class MultiPrinterTest < TestCase
30
- def setup
31
- # Need to use wall time for this test due to the sleep calls
32
- RubyProf::measure_mode = RubyProf::WALL_TIME
33
- end
34
-
35
- def test_all_profiles_can_be_created
36
- start_time = Time.now
37
- RubyProf.start
38
- 5.times{MSTPT.new.a}
39
- result = RubyProf.stop
40
- end_time = Time.now
41
- expected_time = end_time - start_time
42
- stack = graph = nil
43
- assert_nothing_raised { stack, graph = print(result) }
44
- re = Regexp.new('
45
- \s*<table>
46
- \s*<tr>
47
- \s*<th>Thread ID</th>
48
- \s*(<th>Fiber ID</th>)?
49
- \s*<th>Total Time</th>
50
- \s*</tr>
51
- \s*
52
- \s*<tr>
53
- \s*(<td>([\.0-9]+)</td>)?
54
- \s*<td><a href="#-?\d+">-?\d+</a></td>
55
- \s*<td>([\.0-9e]+)</td>
56
- \s*</tr>
57
- \s*
58
- \s*</table>')
59
- assert_match(re, graph)
60
- graph =~ re
61
- display_time = $4.to_f
62
- assert_in_delta expected_time, display_time, 0.001
63
- end
64
-
65
- private
66
-
67
- def print(result)
68
- test = caller.first =~ /in `(.*)'/ ? $1 : "test"
69
- path = RubyProf.tmpdir
70
- profile = "ruby_prof_#{test}"
71
- printer = RubyProf::MultiPrinter.new(result)
72
- printer.print(:path => path, :profile => profile,
73
- :threshold => 0, :min_percent => 0, :title => "ruby_prof #{test}")
74
- if RUBY_PLATFORM =~ /darwin/ && ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT']=="1"
75
- system("open '#{printer.stack_profile}'")
76
- end
77
- # if GC.respond_to?(:dump_file_and_line_info)
78
- # GC.start
79
- # GC.dump_file_and_line_info("heap.dump")
80
- # end
81
- [File.read(printer.stack_profile), File.read(printer.graph_profile)]
82
- end
83
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ # Test data
7
+ # A
8
+ # / \
9
+ # B C
10
+ # \
11
+ # B
12
+
13
+ class MSTPT
14
+ def a
15
+ 100.times{b}
16
+ 300.times{c}
17
+ c;c;c
18
+ end
19
+
20
+ def b
21
+ sleep 0
22
+ end
23
+
24
+ def c
25
+ 5.times{b}
26
+ end
27
+ end
28
+
29
+ class MultiPrinterTest < TestCase
30
+ def setup
31
+ # Need to use wall time for this test due to the sleep calls
32
+ RubyProf::measure_mode = RubyProf::WALL_TIME
33
+ end
34
+
35
+ def test_refuses_io_objects
36
+ # we don't need a real profile for this test
37
+ p = RubyProf::MultiPrinter.new nil
38
+ begin
39
+ p.print(STDOUT)
40
+ flunk "should have raised an ArgumentError"
41
+ rescue ArgumentError => e
42
+ assert_match(/IO/, e.to_s)
43
+ end
44
+ end
45
+
46
+ def test_refuses_non_hashes
47
+ # we don't need a real profile for this test
48
+ p = RubyProf::MultiPrinter.new nil
49
+ begin
50
+ p.print([])
51
+ flunk "should have raised an ArgumentError"
52
+ rescue ArgumentError => e
53
+ assert_match(/hash/, e.to_s)
54
+ end
55
+ end
56
+
57
+ private
58
+
59
+ def print(result)
60
+ test = caller.first =~ /in `(.*)'/ ? $1 : "test"
61
+ path = Dir.tmpdir
62
+ profile = "ruby_prof_#{test}"
63
+ printer = RubyProf::MultiPrinter.new(result)
64
+ printer.print(:path => path, :profile => profile,
65
+ :threshold => 0, :min_percent => 0, :title => "ruby_prof #{test}")
66
+ if RUBY_PLATFORM =~ /darwin/ && ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT']=="1"
67
+ system("open '#{printer.stack_profile}'")
68
+ end
69
+ [File.read(printer.stack_profile), File.read(printer.graph_profile)]
70
+ end
71
+ end
@@ -1,15 +1,15 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- # Make sure this works with no class or method
7
- result = RubyProf.profile do
8
- sleep 1
9
- end
10
-
11
- methods = result.threads.first.methods
12
- global_method = methods.sort_by {|method| method.full_name}.first
13
- if global_method.full_name != 'Global#[No method]'
14
- raise(RuntimeError, "Wrong method name. Expected: Global#[No method]. Actual: #{global_method.full_name}")
15
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ # Make sure this works with no class or method
7
+ result = RubyProf.profile do
8
+ sleep 1
9
+ end
10
+
11
+ methods = result.threads.first.methods
12
+ global_method = methods.sort_by {|method| method.full_name}.first
13
+ if global_method.full_name != 'Kernel#sleep'
14
+ raise(RuntimeError, "Wrong method name. Expected: Global#[No method]. Actual: #{global_method.full_name}")
15
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ require 'ruby-prof'
4
+
5
+ require 'parser/current'
6
+ Parser::Builders::Default.emit_lambda = true
7
+ Parser::Builders::Default.emit_procarg0 = true
8
+ Parser::Builders::Default.emit_encoding = true
9
+ Parser::Builders::Default.emit_index = true
10
+
11
+ start = Time.now
12
+ result = RubyProf.profile(:measure_mode => RubyProf::ALLOCATIONS, :track_allocations => true) do
13
+ code = File.read('C:/msys64/usr/local/src/ruby-2.6.3/lib/rdoc/markdown.rb')
14
+ parse = Parser::CurrentRuby.parse(code)
15
+ end
16
+
17
+ finish = Time.now
18
+
19
+ puts "#{finish - start} seconds"
20
+
21
+ printer = RubyProf::GraphHtmlPrinter.new(result)
22
+ File.open('c:/temp/graph.html', 'wb') do |file|
23
+ printer.print(file)
24
+ end
@@ -1,166 +1,166 @@
1
- #!/usr/bin/env ruby
2
- # encoding: UTF-8
3
-
4
- require File.expand_path('../test_helper', __FILE__)
5
-
6
- class PauseResumeTest < TestCase
7
- def setup
8
- # Need to use wall time for this test due to the sleep calls
9
- RubyProf::measure_mode = RubyProf::WALL_TIME
10
- end
11
-
12
- def test_pause_resume
13
- # Measured
14
- RubyProf.start
15
- RubyProf::C1.hello
16
-
17
- # Not measured
18
- RubyProf.pause
19
- sleep 1
20
- RubyProf::C1.hello
21
-
22
- # Measured
23
- RubyProf.resume
24
- RubyProf::C1.hello
25
-
26
- result = RubyProf.stop
27
-
28
- # Length should be 3:
29
- # PauseResumeTest#test_pause_resume
30
- # <Class::RubyProf::C1>#hello
31
- # Kernel#sleep
32
-
33
- methods = result.threads.first.methods.sort_by {|method_info| method_info.full_name}
34
- # remove methods called by pause/resume
35
- called_methods = ['Array#include?', 'Fixnum#==', 'Kernel#respond_to?', 'Kernel#respond_to_missing?']
36
- methods.reject!{|m| called_methods.include?(m.full_name) }
37
- # TODO: fix pause/resume to not include those methods in the first place
38
- assert_equal(3, methods.length)
39
-
40
- # Check the names
41
- assert_equal('<Class::RubyProf::C1>#hello', methods[0].full_name)
42
- assert_equal('Kernel#sleep', methods[1].full_name)
43
- assert_equal('PauseResumeTest#test_pause_resume', methods[2].full_name)
44
-
45
- # Check times
46
- assert_in_delta(0.2, methods[0].total_time, 0.02)
47
- assert_in_delta(0, methods[0].wait_time, 0.02)
48
- assert_in_delta(0, methods[0].self_time, 0.02)
49
-
50
- assert_in_delta(0.2, methods[1].total_time, 0.02)
51
- assert_in_delta(0, methods[1].wait_time, 0.02)
52
- assert_in_delta(0.2, methods[1].self_time, 0.02)
53
-
54
- assert_in_delta(0.2, methods[2].total_time, 0.02)
55
- assert_in_delta(0, methods[2].wait_time, 0.02)
56
- assert_in_delta(0, methods[2].self_time, 0.02)
57
- end
58
-
59
- # pause/resume in the same frame
60
- def test_pause_resume_1
61
- profile = RubyProf::Profile.new
62
-
63
- profile.start
64
- method_1a
65
-
66
- profile.pause
67
- method_1b
68
-
69
- profile.resume
70
- method_1c
71
-
72
- result = profile.stop
73
- assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
74
- end
75
- def method_1a; sleep 0.2 end
76
- def method_1b; sleep 1 end
77
- def method_1c; sleep 0.4 end
78
-
79
- # pause in parent frame, resume in child
80
- def test_pause_resume_2
81
- profile = RubyProf::Profile.new
82
-
83
- profile.start
84
- method_2a
85
-
86
- profile.pause
87
- sleep 0.5
88
- method_2b(profile)
89
-
90
- result = profile.stop
91
- assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
92
- end
93
- def method_2a; sleep 0.2 end
94
- def method_2b(profile); sleep 0.5; profile.resume; sleep 0.4 end
95
-
96
- # pause in child frame, resume in parent
97
- def test_pause_resume_3
98
- profile = RubyProf::Profile.new
99
-
100
- profile.start
101
- method_3a(profile)
102
-
103
- sleep 0.5
104
- profile.resume
105
- method_3b
106
-
107
- result = profile.stop
108
- assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_3$/}[0].total_time, 0.05)
109
- end
110
- def method_3a(profile); sleep 0.2; profile.pause; sleep 0.5 end
111
- def method_3b; sleep 0.4 end
112
-
113
- def test_pause_seq
114
- profile = RubyProf::Profile.new
115
- profile.start ; assert !profile.paused?
116
- profile.pause ; assert profile.paused?
117
- profile.resume; assert !profile.paused?
118
- profile.pause ; assert profile.paused?
119
- profile.pause ; assert profile.paused?
120
- profile.resume; assert !profile.paused?
121
- profile.resume; assert !profile.paused?
122
- profile.stop ; assert !profile.paused?
123
- end
124
-
125
- def test_pause_block
126
- profile = RubyProf::Profile.new
127
- profile.start
128
- profile.pause
129
- assert profile.paused?
130
-
131
- times_block_invoked = 0
132
- retval= profile.resume{
133
- times_block_invoked += 1
134
- 120 + times_block_invoked
135
- }
136
- assert_equal 1, times_block_invoked
137
- assert profile.paused?
138
-
139
- assert_equal 121, retval, "resume() should return the result of the given block."
140
-
141
- profile.stop
142
- end
143
-
144
- def test_pause_block_with_error
145
- profile = RubyProf::Profile.new
146
- profile.start
147
- profile.pause
148
- assert profile.paused?
149
-
150
- begin
151
- profile.resume{ raise }
152
- flunk 'Exception expected.'
153
- rescue
154
- assert profile.paused?
155
- end
156
-
157
- profile.stop
158
- end
159
-
160
- def test_resume_when_not_paused
161
- profile = RubyProf::Profile.new
162
- profile.start ; assert !profile.paused?
163
- profile.resume; assert !profile.paused?
164
- profile.stop ; assert !profile.paused?
165
- end
166
- end
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class PauseResumeTest < TestCase
7
+ def setup
8
+ # Need to use wall time for this test due to the sleep calls
9
+ RubyProf::measure_mode = RubyProf::WALL_TIME
10
+ end
11
+
12
+ def test_pause_resume
13
+ # Measured
14
+ RubyProf.start
15
+ RubyProf::C1.sleep_wait
16
+
17
+ # Not measured
18
+ RubyProf.pause
19
+ sleep 1
20
+ RubyProf::C1.sleep_wait
21
+
22
+ # Measured
23
+ RubyProf.resume
24
+ RubyProf::C1.sleep_wait
25
+
26
+ result = RubyProf.stop
27
+
28
+ # Length should be 3:
29
+ # PauseResumeTest#test_pause_resume
30
+ # <Class::RubyProf::C1>#sleep_wait
31
+ # Kernel#sleep
32
+
33
+ methods = result.threads.first.methods.sort_by {|method_info| method_info.full_name}
34
+ # remove methods called by pause/resume
35
+ called_methods = ['Array#include?', 'Fixnum#==', 'Kernel#respond_to?', 'Kernel#respond_to_missing?']
36
+ methods.reject!{|m| called_methods.include?(m.full_name) }
37
+ # TODO: fix pause/resume to not include those methods in the first place
38
+ assert_equal(3, methods.length)
39
+
40
+ # Check the names
41
+ assert_equal('<Class::RubyProf::C1>#sleep_wait', methods[0].full_name)
42
+ assert_equal('Kernel#sleep', methods[1].full_name)
43
+ assert_equal('PauseResumeTest#test_pause_resume', methods[2].full_name)
44
+
45
+ # Check times
46
+ assert_in_delta(0.2, methods[0].total_time, 0.02)
47
+ assert_in_delta(0, methods[0].wait_time, 0.02)
48
+ assert_in_delta(0, methods[0].self_time, 0.02)
49
+
50
+ assert_in_delta(0.2, methods[1].total_time, 0.02)
51
+ assert_in_delta(0, methods[1].wait_time, 0.02)
52
+ assert_in_delta(0.2, methods[1].self_time, 0.02)
53
+
54
+ assert_in_delta(0.2, methods[2].total_time, 0.02)
55
+ assert_in_delta(0, methods[2].wait_time, 0.02)
56
+ assert_in_delta(0, methods[2].self_time, 0.02)
57
+ end
58
+
59
+ # pause/resume in the same frame
60
+ def test_pause_resume_1
61
+ profile = RubyProf::Profile.new
62
+
63
+ profile.start
64
+ method_1a
65
+
66
+ profile.pause
67
+ method_1b
68
+
69
+ profile.resume
70
+ method_1c
71
+
72
+ result = profile.stop
73
+ assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
74
+ end
75
+ def method_1a; sleep 0.2 end
76
+ def method_1b; sleep 1 end
77
+ def method_1c; sleep 0.4 end
78
+
79
+ # pause in parent frame, resume in child
80
+ def test_pause_resume_2
81
+ profile = RubyProf::Profile.new
82
+
83
+ profile.start
84
+ method_2a
85
+
86
+ profile.pause
87
+ sleep 0.5
88
+ method_2b(profile)
89
+
90
+ result = profile.stop
91
+ assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
92
+ end
93
+ def method_2a; sleep 0.2 end
94
+ def method_2b(profile); sleep 0.5; profile.resume; sleep 0.4 end
95
+
96
+ # pause in child frame, resume in parent
97
+ def test_pause_resume_3
98
+ profile = RubyProf::Profile.new
99
+
100
+ profile.start
101
+ method_3a(profile)
102
+
103
+ sleep 0.5
104
+ profile.resume
105
+ method_3b
106
+
107
+ result = profile.stop
108
+ assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_3$/}[0].total_time, 0.05)
109
+ end
110
+ def method_3a(profile); sleep 0.2; profile.pause; sleep 0.5 end
111
+ def method_3b; sleep 0.4 end
112
+
113
+ def test_pause_seq
114
+ profile = RubyProf::Profile.new
115
+ profile.start ; assert !profile.paused?
116
+ profile.pause ; assert profile.paused?
117
+ profile.resume; assert !profile.paused?
118
+ profile.pause ; assert profile.paused?
119
+ profile.pause ; assert profile.paused?
120
+ profile.resume; assert !profile.paused?
121
+ profile.resume; assert !profile.paused?
122
+ profile.stop ; assert !profile.paused?
123
+ end
124
+
125
+ def test_pause_block
126
+ profile = RubyProf::Profile.new
127
+ profile.start
128
+ profile.pause
129
+ assert profile.paused?
130
+
131
+ times_block_invoked = 0
132
+ retval= profile.resume{
133
+ times_block_invoked += 1
134
+ 120 + times_block_invoked
135
+ }
136
+ assert_equal 1, times_block_invoked
137
+ assert profile.paused?
138
+
139
+ assert_equal 121, retval, "resume() should return the result of the given block."
140
+
141
+ profile.stop
142
+ end
143
+
144
+ def test_pause_block_with_error
145
+ profile = RubyProf::Profile.new
146
+ profile.start
147
+ profile.pause
148
+ assert profile.paused?
149
+
150
+ begin
151
+ profile.resume{ raise }
152
+ flunk 'Exception expected.'
153
+ rescue
154
+ assert profile.paused?
155
+ end
156
+
157
+ profile.stop
158
+ end
159
+
160
+ def test_resume_when_not_paused
161
+ profile = RubyProf::Profile.new
162
+ profile.start ; assert !profile.paused?
163
+ profile.resume; assert !profile.paused?
164
+ profile.stop ; assert !profile.paused?
165
+ end
166
+ end