ruby-prof 0.15.8 → 0.15.9

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 (85) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +5 -0
  3. data/README.rdoc +187 -185
  4. data/doc/LICENSE.html +114 -0
  5. data/doc/README_rdoc.html +544 -0
  6. data/doc/Rack.html +95 -0
  7. data/doc/Rack/RubyProf.html +223 -0
  8. data/doc/RubyProf.html +961 -0
  9. data/doc/RubyProf/AbstractPrinter.html +546 -0
  10. data/doc/RubyProf/AggregateCallInfo.html +551 -0
  11. data/doc/RubyProf/CallInfo.html +639 -0
  12. data/doc/RubyProf/CallInfoPrinter.html +120 -0
  13. data/doc/RubyProf/CallInfoVisitor.html +198 -0
  14. data/doc/RubyProf/CallStackPrinter.html +1121 -0
  15. data/doc/RubyProf/CallTreePrinter.html +359 -0
  16. data/doc/RubyProf/Cmd.html +631 -0
  17. data/doc/RubyProf/DotPrinter.html +257 -0
  18. data/doc/RubyProf/FlatPrinter.html +163 -0
  19. data/doc/RubyProf/FlatPrinterWithLineNumbers.html +208 -0
  20. data/doc/RubyProf/GraphHtmlPrinter.html +552 -0
  21. data/doc/RubyProf/GraphPrinter.html +139 -0
  22. data/doc/RubyProf/MethodInfo.html +745 -0
  23. data/doc/RubyProf/MultiPrinter.html +358 -0
  24. data/doc/RubyProf/Profile.html +713 -0
  25. data/doc/RubyProf/ProfileTask.html +490 -0
  26. data/doc/RubyProf/Thread.html +268 -0
  27. data/doc/created.rid +13 -13
  28. data/doc/examples/flat_txt.html +138 -0
  29. data/doc/examples/graph_html.html +909 -0
  30. data/doc/examples/graph_txt.html +247 -0
  31. data/doc/images/add.png +0 -0
  32. data/doc/images/arrow_up.png +0 -0
  33. data/doc/images/brick.png +0 -0
  34. data/doc/images/brick_link.png +0 -0
  35. data/doc/images/bug.png +0 -0
  36. data/doc/images/bullet_black.png +0 -0
  37. data/doc/images/bullet_toggle_minus.png +0 -0
  38. data/doc/images/bullet_toggle_plus.png +0 -0
  39. data/doc/images/date.png +0 -0
  40. data/doc/images/delete.png +0 -0
  41. data/doc/images/find.png +0 -0
  42. data/doc/images/macFFBgHack.png +0 -0
  43. data/doc/images/package.png +0 -0
  44. data/doc/images/page_green.png +0 -0
  45. data/doc/images/page_white_text.png +0 -0
  46. data/doc/images/page_white_width.png +0 -0
  47. data/doc/images/plugin.png +0 -0
  48. data/doc/images/ruby.png +0 -0
  49. data/doc/images/tag_blue.png +0 -0
  50. data/doc/images/tag_green.png +0 -0
  51. data/doc/images/transparent.png +0 -0
  52. data/doc/images/wrench.png +0 -0
  53. data/doc/images/wrench_orange.png +0 -0
  54. data/doc/images/zoom.png +0 -0
  55. data/doc/index.html +571 -0
  56. data/doc/js/navigation.js.gz +0 -0
  57. data/doc/js/search_index.js +1 -1
  58. data/doc/js/search_index.js.gz +0 -0
  59. data/doc/js/searcher.js.gz +0 -0
  60. data/doc/table_of_contents.html +893 -0
  61. data/examples/flat.txt +50 -55
  62. data/examples/graph.html +823 -823
  63. data/examples/graph.txt +139 -170
  64. data/ext/ruby_prof/extconf.rb +6 -1
  65. data/lib/ruby-prof/aggregate_call_info.rb +17 -11
  66. data/lib/ruby-prof/call_info.rb +2 -17
  67. data/lib/ruby-prof/method_info.rb +6 -22
  68. data/lib/ruby-prof/printers/graph_html_printer.rb +0 -2
  69. data/lib/ruby-prof/printers/graph_printer.rb +4 -6
  70. data/lib/ruby-prof/rack.rb +7 -0
  71. data/lib/ruby-prof/thread.rb +0 -4
  72. data/lib/ruby-prof/version.rb +1 -1
  73. data/ruby-prof.gemspec +1 -1
  74. data/test/basic_test.rb +26 -26
  75. data/test/issue137_test.rb +63 -0
  76. data/test/measure_allocations_test.rb +4 -3
  77. data/test/measure_cpu_time_test.rb +6 -6
  78. data/test/measure_process_time_test.rb +8 -8
  79. data/test/pause_resume_test.rb +9 -9
  80. data/test/printers_test.rb +1 -1
  81. data/test/printing_recursive_graph_test.rb +127 -0
  82. data/test/rack_test.rb +49 -1
  83. data/test/recursive_test.rb +41 -37
  84. data/test/test_helper.rb +93 -0
  85. metadata +59 -5
@@ -210,7 +210,6 @@ module RubyProf
210
210
  </tr>
211
211
  <!-- Children -->
212
212
  <%
213
- method.recalc_recursion unless method.non_recursive?
214
213
  for callee in method.aggregate_children.sort_by(&:total_time).reverse
215
214
  next if min_time && callee.total_time < min_time
216
215
  %>
@@ -228,7 +227,6 @@ module RubyProf
228
227
  <% end %>
229
228
  <!-- Create divider row -->
230
229
  <tr class="break"><td colspan="9"></td></tr>
231
- <% thread.recalc_recursion unless method.non_recursive? %>
232
230
  <% end %>
233
231
  </tbody>
234
232
  <tfoot>
@@ -36,7 +36,7 @@ module RubyProf
36
36
  @output << sprintf("%#{TIME_WIDTH}s", "wait")
37
37
  @output << sprintf("%#{TIME_WIDTH}s", "child")
38
38
  @output << sprintf("%#{CALL_WIDTH}s", "calls")
39
- @output << " Name"
39
+ @output << " name"
40
40
  @output << "\n"
41
41
  end
42
42
 
@@ -63,16 +63,14 @@ module RubyProf
63
63
  @output << sprintf("%#{TIME_WIDTH}.3f", method.wait_time)
64
64
  @output << sprintf("%#{TIME_WIDTH}.3f", method.children_time)
65
65
  @output << sprintf("%#{CALL_WIDTH}i", method.called)
66
- @output << sprintf(" %s", method.recursive? ? "*" : " ")
66
+ @output << sprintf(" %s", method.recursive? ? "*" : " ")
67
67
  @output << sprintf("%s", method_name(method))
68
68
  if print_file
69
69
  @output << sprintf(" %s:%s", method.source_file, method.line)
70
70
  end
71
71
  @output << "\n"
72
72
 
73
- method.recalc_recursion unless method.non_recursive?
74
73
  print_children(method)
75
- thread.recalc_recursion unless method.non_recursive?
76
74
  end
77
75
  end
78
76
 
@@ -87,7 +85,7 @@ module RubyProf
87
85
 
88
86
  call_called = "#{caller.called}/#{method.called}"
89
87
  @output << sprintf("%#{CALL_WIDTH}s", call_called)
90
- @output << sprintf(" %s", caller.parent.target.full_name)
88
+ @output << sprintf(" %s", caller.parent.target.full_name)
91
89
  @output << "\n"
92
90
  end
93
91
  end
@@ -105,7 +103,7 @@ module RubyProf
105
103
 
106
104
  call_called = "#{child.called}/#{child.target.called}"
107
105
  @output << sprintf("%#{CALL_WIDTH}s", call_called)
108
- @output << sprintf(" %s", child.target.full_name)
106
+ @output << sprintf(" %s", child.target.full_name)
109
107
  @output << "\n"
110
108
  end
111
109
  end
@@ -38,9 +38,16 @@ module Rack
38
38
  end
39
39
  end
40
40
 
41
+ private
42
+
41
43
  def print(data, path)
42
44
  @printer_klasses.each do |printer_klass, base_name|
43
45
  printer = printer_klass.new(data)
46
+
47
+ if base_name.respond_to?(:call)
48
+ base_name = base_name.call
49
+ end
50
+
44
51
  file_name = ::File.join(@tmpdir, "#{path}-#{base_name}")
45
52
  ::File.open(file_name, 'wb') do |file|
46
53
  printer.print(file, @options)
@@ -16,10 +16,6 @@ module RubyProf
16
16
  top_call_infos.each(&:detect_recursion)
17
17
  end
18
18
 
19
- def recalc_recursion
20
- top_call_infos.each(&:recalc_recursion)
21
- end
22
-
23
19
  def total_time
24
20
  self.top_methods.inject(0) do |sum, method_info|
25
21
  method_info.call_infos.each do |call_info|
@@ -1,3 +1,3 @@
1
1
  module RubyProf
2
- VERSION = "0.15.8"
2
+ VERSION = "0.15.9"
3
3
  end
@@ -51,7 +51,7 @@ EOF
51
51
  spec.required_ruby_version = '>= 1.9.3'
52
52
  spec.date = Time.now.strftime('%Y-%m-%d')
53
53
  spec.homepage = 'https://github.com/ruby-prof/ruby-prof'
54
- spec.add_development_dependency('minitest', '~> 5.5.0')
54
+ spec.add_development_dependency('minitest', '~> 5.8.3')
55
55
  spec.add_development_dependency('rake-compiler')
56
56
  spec.add_development_dependency('rdoc')
57
57
  end
@@ -53,7 +53,7 @@ class BasicTest < TestCase
53
53
  assert_equal(1, profile.threads.count)
54
54
 
55
55
  thread = profile.threads.first
56
- assert_in_delta(0.25, thread.total_time, 0.01)
56
+ assert_in_delta(0.25, thread.total_time, 0.015)
57
57
 
58
58
  top_methods = thread.top_methods.sort
59
59
  assert_equal(2, top_methods.count)
@@ -65,24 +65,24 @@ class BasicTest < TestCase
65
65
 
66
66
  # Check times
67
67
  assert_equal("<Class::RubyProf::C1>#hello", methods[0].full_name)
68
- assert_in_delta(0.1, methods[0].total_time, 0.01)
69
- assert_in_delta(0.0, methods[0].wait_time, 0.01)
70
- assert_in_delta(0.0, methods[0].self_time, 0.01)
68
+ assert_in_delta(0.1, methods[0].total_time, 0.015)
69
+ assert_in_delta(0.0, methods[0].wait_time, 0.015)
70
+ assert_in_delta(0.0, methods[0].self_time, 0.015)
71
71
 
72
72
  assert_equal("BasicTest#start", methods[1].full_name)
73
- assert_in_delta(0.1, methods[1].total_time, 0.01)
74
- assert_in_delta(0.0, methods[1].wait_time, 0.01)
75
- assert_in_delta(0.0, methods[1].self_time, 0.01)
73
+ assert_in_delta(0.1, methods[1].total_time, 0.015)
74
+ assert_in_delta(0.0, methods[1].wait_time, 0.015)
75
+ assert_in_delta(0.0, methods[1].self_time, 0.015)
76
76
 
77
77
  assert_equal("BasicTest#test_leave_method", methods[2].full_name)
78
- assert_in_delta(0.15, methods[2].total_time, 0.01)
79
- assert_in_delta(0.0, methods[2].wait_time, 0.01)
80
- assert_in_delta(0.0, methods[2].self_time, 0.01)
78
+ assert_in_delta(0.15, methods[2].total_time, 0.015)
79
+ assert_in_delta(0.0, methods[2].wait_time, 0.015)
80
+ assert_in_delta(0.0, methods[2].self_time, 0.015)
81
81
 
82
82
  assert_equal("Kernel#sleep", methods[3].full_name)
83
- assert_in_delta(0.25, methods[3].total_time, 0.01)
84
- assert_in_delta(0.0, methods[3].wait_time, 0.01)
85
- assert_in_delta(0.25, methods[3].self_time, 0.01)
83
+ assert_in_delta(0.25, methods[3].total_time, 0.015)
84
+ assert_in_delta(0.0, methods[3].wait_time, 0.015)
85
+ assert_in_delta(0.25, methods[3].self_time, 0.015)
86
86
  end
87
87
 
88
88
  def test_leave_method_2
@@ -94,7 +94,7 @@ class BasicTest < TestCase
94
94
  assert_equal(1, profile.threads.count)
95
95
 
96
96
  thread = profile.threads.first
97
- assert_in_delta(0.3, thread.total_time, 0.01)
97
+ assert_in_delta(0.3, thread.total_time, 0.015)
98
98
 
99
99
  top_methods = thread.top_methods.sort
100
100
  assert_equal(2, top_methods.count)
@@ -106,23 +106,23 @@ class BasicTest < TestCase
106
106
 
107
107
  # Check times
108
108
  assert_equal("BasicTest#start", methods[0].full_name)
109
- assert_in_delta(0.1, methods[0].total_time, 0.01)
110
- assert_in_delta(0.0, methods[0].wait_time, 0.01)
111
- assert_in_delta(0.0, methods[0].self_time, 0.01)
109
+ assert_in_delta(0.1, methods[0].total_time, 0.015)
110
+ assert_in_delta(0.0, methods[0].wait_time, 0.015)
111
+ assert_in_delta(0.0, methods[0].self_time, 0.015)
112
112
 
113
113
  assert_equal("BasicTest#test_leave_method_2", methods[1].full_name)
114
- assert_in_delta(0.2, methods[1].total_time, 0.01)
115
- assert_in_delta(0.0, methods[1].wait_time, 0.01)
116
- assert_in_delta(0.0, methods[1].self_time, 0.01)
114
+ assert_in_delta(0.2, methods[1].total_time, 0.015)
115
+ assert_in_delta(0.0, methods[1].wait_time, 0.015)
116
+ assert_in_delta(0.0, methods[1].self_time, 0.015)
117
117
 
118
118
  assert_equal("Kernel#sleep", methods[2].full_name)
119
- assert_in_delta(0.3, methods[2].total_time, 0.01)
120
- assert_in_delta(0.0, methods[2].wait_time, 0.01)
121
- assert_in_delta(0.3, methods[2].self_time, 0.01)
119
+ assert_in_delta(0.3, methods[2].total_time, 0.015)
120
+ assert_in_delta(0.0, methods[2].wait_time, 0.015)
121
+ assert_in_delta(0.3, methods[2].self_time, 0.015)
122
122
 
123
123
  assert_equal("<Class::RubyProf::C1>#hello", methods[3].full_name)
124
- assert_in_delta(0.3, methods[3].total_time, 0.01)
125
- assert_in_delta(0.0, methods[3].wait_time, 0.01)
126
- assert_in_delta(0.0, methods[3].self_time, 0.01)
124
+ assert_in_delta(0.3, methods[3].total_time, 0.015)
125
+ assert_in_delta(0.0, methods[3].wait_time, 0.015)
126
+ assert_in_delta(0.0, methods[3].self_time, 0.015)
127
127
  end
128
128
  end
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ # issue 137 is about correctly attributing time of recursive children
7
+
8
+ class RecursiveChildrenTest < TestCase
9
+ class SlowClass
10
+ def time_sink
11
+ 1234567890 ** 100 == 0
12
+ end
13
+ end
14
+
15
+ class SlowSearcher
16
+ def do_find(slow_objects)
17
+ slow_objects.find(&:time_sink)
18
+ end
19
+ end
20
+
21
+ class MainClass
22
+ def self.main_method
23
+ slow_objects = [SlowClass.new] * 100_000
24
+ slow_searcher = SlowSearcher.new
25
+ slow_searcher.do_find(slow_objects)
26
+ end
27
+ end
28
+
29
+ include PrinterTestHelper
30
+
31
+ def setup
32
+ # Need to use wall time for this test due to the sleep calls
33
+ RubyProf::measure_mode = RubyProf::WALL_TIME
34
+ end
35
+
36
+ def test_simple
37
+ result = RubyProf.profile do
38
+ # make array each recursive
39
+ [1].each do
40
+ MainClass.main_method
41
+ end
42
+ end
43
+
44
+ # methods = result.threads.first.methods.sort.reverse
45
+
46
+ printer = RubyProf::GraphPrinter.new(result)
47
+
48
+ buffer = ''
49
+ printer.print(StringIO.new(buffer))
50
+
51
+ puts buffer if ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1"
52
+
53
+ parsed_output = MetricsArray.parse(buffer)
54
+
55
+ assert( enum_find = parsed_output.metrics_for("Enumerable#find") )
56
+ assert( array_each = enum_find.child("Array#each") )
57
+
58
+ assert_operator enum_find.metrics.total, :>=, array_each.total
59
+ assert_operator enum_find.metrics.total, :>, 0
60
+ assert_in_delta enum_find.metrics.total, array_each.total, 0.02
61
+ end
62
+
63
+ end
@@ -16,10 +16,11 @@ class MeasureAllocationsTest < TestCase
16
16
  if RubyProf::ALLOCATIONS_ENABLED
17
17
  def test_allocations
18
18
  t = RubyProf.measure_allocations
19
- assert_kind_of Integer, t
20
-
19
+ refute_empty("a" + "b")
21
20
  u = RubyProf.measure_allocations
22
- assert u > t, [t, u].inspect
21
+ assert_kind_of Integer, t
22
+ assert_kind_of Integer, u
23
+ assert_operator t, :<, u
23
24
  end
24
25
  end
25
26
  end
@@ -35,13 +35,13 @@ class MeasureCpuTimeTest < TestCase
35
35
  assert_equal('<Class::RubyProf::C7>#hello', methods[1].full_name)
36
36
 
37
37
  # Check times
38
- assert_in_delta(0.1, methods[0].total_time, 0.02)
39
- assert_in_delta(0, methods[0].wait_time, 0.02)
40
- assert_in_delta(0, methods[0].self_time, 0.02)
38
+ assert_in_delta(0.1, methods[0].total_time, 0.03)
39
+ assert_in_delta(0, methods[0].wait_time, 0.03)
40
+ assert_in_delta(0, methods[0].self_time, 0.03)
41
41
 
42
- assert_in_delta(0.1, methods[1].total_time, 0.02)
43
- assert_in_delta(0, methods[1].wait_time, 0.02)
44
- assert_in_delta(0, methods[1].self_time, 0.02)
42
+ assert_in_delta(0.1, methods[1].total_time, 0.03)
43
+ assert_in_delta(0, methods[1].wait_time, 0.03)
44
+ assert_in_delta(0, methods[1].self_time, 0.03)
45
45
  end
46
46
 
47
47
  def test_instance_methods
@@ -31,15 +31,15 @@ class MeasureProcessTimeTest < TestCase
31
31
 
32
32
  methods = result.threads.first.methods.sort.reverse
33
33
 
34
- # WTF?
35
- if RUBY_VERSION =~ /^1\.9\.3/
36
- assert_equal 16, methods.length
37
- elsif RUBY_VERSION =~ /^2\.0/
38
- assert_equal 15, methods.length
39
- else # if RUBY_VERSION =~ /^2\.1/
40
- assert_equal 14, methods.length
41
- end
34
+ expected_number_of_methods =
35
+ case RUBY_VERSION
36
+ when /^1\.9\.3/ then 16
37
+ when /^2\.0/ then 15
38
+ when /^2\.(1|2)/ then 14
39
+ else 13
40
+ end
42
41
  # puts methods.map(&:full_name).inspect
42
+ assert_equal expected_number_of_methods, methods.length
43
43
 
44
44
  # Check times
45
45
  assert_equal("MeasureProcessTimeTest#test_primes", methods[0].full_name)
@@ -43,17 +43,17 @@ class PauseResumeTest < TestCase
43
43
  assert_equal('PauseResumeTest#test_pause_resume', methods[2].full_name)
44
44
 
45
45
  # Check times
46
- assert_in_delta(0.2, methods[0].total_time, 0.01)
47
- assert_in_delta(0, methods[0].wait_time, 0.01)
48
- assert_in_delta(0, methods[0].self_time, 0.01)
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
49
 
50
- assert_in_delta(0.2, methods[1].total_time, 0.01)
51
- assert_in_delta(0, methods[1].wait_time, 0.01)
52
- assert_in_delta(0.2, methods[1].self_time, 0.01)
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
53
 
54
- assert_in_delta(0.2, methods[2].total_time, 0.01)
55
- assert_in_delta(0, methods[2].wait_time, 0.01)
56
- assert_in_delta(0, methods[2].self_time, 0.01)
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
57
  end
58
58
 
59
59
  # pause/resume in the same frame
@@ -11,7 +11,7 @@ class PrintersTest < TestCase
11
11
  # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
12
12
  RubyProf::measure_mode = RubyProf::WALL_TIME
13
13
  @result = RubyProf.profile do
14
- run_primes(200)
14
+ run_primes(1000, 5000)
15
15
  end
16
16
  end
17
17
 
@@ -0,0 +1,127 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'stringio'
6
+ require 'fileutils'
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: 70238775664960
29
+ Fiber ID: 70238784046840
30
+ Total Time: 2.040249824523926
31
+ Sort by: total_time
32
+
33
+ %total %self total self wait child calls Name
34
+ --------------------------------------------------------------------------------
35
+ 100.00% 0.00% 2.040 0.000 0.000 2.040 1 PrintingRecursiveGraphTest#setup
36
+ 2.040 0.000 0.000 2.040 1/1 PRGT#run
37
+ --------------------------------------------------------------------------------
38
+ 2.040 0.000 0.000 2.040 1/1 PrintingRecursiveGraphTest#setup
39
+ 100.00% 0.00% 2.040 0.000 0.000 2.040 1 PRGT#run
40
+ 2.040 0.000 0.000 2.040 1/5 Integer#times
41
+ --------------------------------------------------------------------------------
42
+ 0.409 0.000 0.000 0.409 2/5 Prgt#f
43
+ 1.631 0.000 0.000 1.631 2/5 PRGT#g
44
+ 2.040 0.000 0.000 2.040 1/5 PRGT#run
45
+ 100.00% 0.00% 2.040 0.000 0.000 2.040 5 *Integer#times
46
+ 2.040 2.040 0.000 0.000 12/12 Kernel#sleep
47
+ 1.631 0.000 0.000 1.631 2/2 PRGT#g
48
+ 0.409 0.000 0.000 0.409 2/2 PRGT#f
49
+ --------------------------------------------------------------------------------
50
+ 2.040 2.040 0.000 0.000 12/12 Integer#times
51
+ 99.99% 99.99% 2.040 2.040 0.000 0.000 12 Kernel#sleep
52
+ --------------------------------------------------------------------------------
53
+ 1.631 0.000 0.000 1.631 2/2 Integer#times
54
+ 79.94% 0.00% 1.631 0.000 0.000 1.631 2 PRGT#g
55
+ 1.631 0.000 0.000 1.631 2/5 Integer#times
56
+ --------------------------------------------------------------------------------
57
+ 0.409 0.000 0.000 0.409 2/2 Integer#times
58
+ 20.05% 0.00% 0.409 0.000 0.000 0.409 2 PRGT#f
59
+ 0.409 0.000 0.000 0.409 2/5 Integer#times
60
+
61
+ * indicates recursively called methods
62
+ =end
63
+
64
+ class PrintingRecursiveGraphTest < TestCase
65
+ include PrinterTestHelper
66
+
67
+ def setup
68
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
69
+ RubyProf::measure_mode = RubyProf::WALL_TIME
70
+ @result = RubyProf.profile do
71
+ PRGT.run
72
+ end
73
+ end
74
+
75
+ def test_printing_rescursive_graph
76
+ printer = RubyProf::GraphPrinter.new(@result)
77
+
78
+ buffer = ''
79
+ printer.print(StringIO.new(buffer))
80
+
81
+ puts buffer if ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1"
82
+
83
+ parsed_output = MetricsArray.parse(buffer)
84
+
85
+ assert( integer_times = parsed_output.metrics_for("*Integer#times") )
86
+
87
+ actual_parents = integer_times.parents.map(&:name)
88
+ expected_parents = %w(PRGT#f PRGT#g PRGT#run)
89
+ assert_equal expected_parents, actual_parents
90
+
91
+ actual_children = integer_times.children.map(&:name)
92
+ expected_children = %w(Kernel#sleep PRGT#g PRGT#f)
93
+ assert_equal expected_children, actual_children
94
+
95
+ assert( fp = integer_times.parent("PRGT#f") )
96
+ assert_in_delta(fp.total, fp.child, 0.01)
97
+ assert_equal("2/5", fp.calls)
98
+
99
+ assert( gp = integer_times.parent("PRGT#g") )
100
+ assert_in_delta(gp.total, gp.child, 0.01)
101
+ assert_equal("2/5", gp.calls)
102
+
103
+ assert( rp = integer_times.parent("PRGT#run") )
104
+ assert_in_delta(rp.total, rp.child, 0.01)
105
+ assert_equal("1/5", rp.calls)
106
+
107
+ assert_in_delta(4*fp.total, gp.total, 0.05)
108
+ assert_in_delta(fp.total + gp.total, rp.total, 0.05)
109
+ assert_in_delta(integer_times.metrics.total, rp.total, 0.05)
110
+
111
+ assert( fc = integer_times.child("PRGT#f") )
112
+ assert_in_delta(fc.total, fc.child, 0.01)
113
+ assert_equal("2/2", fc.calls)
114
+
115
+ assert( gc = integer_times.child("PRGT#g") )
116
+ assert_in_delta(gc.total, gc.child, 0.01)
117
+ assert_equal("2/2", gc.calls)
118
+
119
+ assert( ks = integer_times.child("Kernel#sleep") )
120
+ assert_in_delta(ks.total, ks.self_t, 0.01)
121
+ assert_equal("12/12", ks.calls)
122
+
123
+ assert_in_delta(4*fc.total, gc.total, 0.05)
124
+ assert_in_delta(fp.total + gc.total, ks.total, 0.05)
125
+ assert_in_delta(integer_times.metrics.total, ks.total, 0.05)
126
+ end
127
+ end