ruby-prof 0.15.8 → 0.15.9

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