ruby-prof 0.18.0 → 1.2.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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +44 -1
  3. data/LICENSE +2 -2
  4. data/README.rdoc +1 -483
  5. data/Rakefile +3 -6
  6. data/bin/ruby-prof +111 -128
  7. data/ext/ruby_prof/extconf.rb +6 -38
  8. data/ext/ruby_prof/rp_aggregate_call_tree.c +41 -0
  9. data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
  10. data/ext/ruby_prof/rp_allocation.c +259 -0
  11. data/ext/ruby_prof/rp_allocation.h +31 -0
  12. data/ext/ruby_prof/rp_call_tree.c +353 -0
  13. data/ext/ruby_prof/rp_call_tree.h +43 -0
  14. data/ext/ruby_prof/rp_call_trees.c +266 -0
  15. data/ext/ruby_prof/rp_call_trees.h +29 -0
  16. data/ext/ruby_prof/rp_measure_allocations.c +25 -51
  17. data/ext/ruby_prof/rp_measure_memory.c +21 -56
  18. data/ext/ruby_prof/rp_measure_process_time.c +37 -43
  19. data/ext/ruby_prof/rp_measure_wall_time.c +40 -21
  20. data/ext/ruby_prof/rp_measurement.c +221 -0
  21. data/ext/ruby_prof/rp_measurement.h +50 -0
  22. data/ext/ruby_prof/rp_method.c +279 -439
  23. data/ext/ruby_prof/rp_method.h +33 -45
  24. data/ext/ruby_prof/rp_profile.c +902 -0
  25. data/ext/ruby_prof/rp_profile.h +36 -0
  26. data/ext/ruby_prof/rp_stack.c +163 -132
  27. data/ext/ruby_prof/rp_stack.h +18 -28
  28. data/ext/ruby_prof/rp_thread.c +192 -124
  29. data/ext/ruby_prof/rp_thread.h +18 -8
  30. data/ext/ruby_prof/ruby_prof.c +36 -778
  31. data/ext/ruby_prof/ruby_prof.h +11 -45
  32. data/ext/ruby_prof/vc/ruby_prof.vcxproj +18 -12
  33. data/lib/ruby-prof.rb +4 -21
  34. data/lib/ruby-prof/assets/call_stack_printer.html.erb +710 -0
  35. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  36. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
  37. data/lib/ruby-prof/call_tree.rb +57 -0
  38. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  39. data/lib/ruby-prof/compatibility.rb +37 -107
  40. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  41. data/lib/ruby-prof/measurement.rb +17 -0
  42. data/lib/ruby-prof/method_info.rb +47 -90
  43. data/lib/ruby-prof/printers/abstract_printer.rb +73 -50
  44. data/lib/ruby-prof/printers/call_info_printer.rb +24 -12
  45. data/lib/ruby-prof/printers/call_stack_printer.rb +66 -152
  46. data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
  47. data/lib/ruby-prof/printers/dot_printer.rb +5 -5
  48. data/lib/ruby-prof/printers/flat_printer.rb +6 -24
  49. data/lib/ruby-prof/printers/graph_html_printer.rb +6 -192
  50. data/lib/ruby-prof/printers/graph_printer.rb +11 -14
  51. data/lib/ruby-prof/printers/multi_printer.rb +66 -23
  52. data/lib/ruby-prof/profile.rb +10 -3
  53. data/lib/ruby-prof/thread.rb +5 -20
  54. data/lib/ruby-prof/version.rb +1 -1
  55. data/ruby-prof.gemspec +9 -2
  56. data/test/abstract_printer_test.rb +0 -27
  57. data/test/alias_test.rb +126 -0
  58. data/test/basic_test.rb +1 -86
  59. data/test/call_tree_visitor_test.rb +32 -0
  60. data/test/call_trees_test.rb +66 -0
  61. data/test/dynamic_method_test.rb +0 -2
  62. data/test/exclude_methods_test.rb +17 -12
  63. data/test/fiber_test.rb +214 -23
  64. data/test/gc_test.rb +105 -0
  65. data/test/inverse_call_tree_test.rb +175 -0
  66. data/test/line_number_test.rb +118 -40
  67. data/test/marshal_test.rb +115 -0
  68. data/test/measure_allocations.rb +30 -0
  69. data/test/measure_allocations_test.rb +361 -12
  70. data/test/measure_allocations_trace_test.rb +375 -0
  71. data/test/measure_memory_trace_test.rb +1101 -0
  72. data/test/measure_process_time_test.rb +757 -33
  73. data/test/measure_times.rb +56 -0
  74. data/test/measure_wall_time_test.rb +329 -149
  75. data/test/multi_printer_test.rb +1 -34
  76. data/test/pause_resume_test.rb +24 -15
  77. data/test/prime.rb +1 -1
  78. data/test/prime_script.rb +6 -0
  79. data/test/printer_call_stack_test.rb +28 -0
  80. data/test/printer_call_tree_test.rb +31 -0
  81. data/test/printer_flat_test.rb +68 -0
  82. data/test/printer_graph_html_test.rb +60 -0
  83. data/test/printer_graph_test.rb +41 -0
  84. data/test/printers_test.rb +32 -166
  85. data/test/printing_recursive_graph_test.rb +26 -72
  86. data/test/recursive_test.rb +68 -77
  87. data/test/stack_printer_test.rb +2 -15
  88. data/test/start_stop_test.rb +22 -25
  89. data/test/test_helper.rb +6 -261
  90. data/test/thread_test.rb +11 -54
  91. data/test/unique_call_path_test.rb +25 -107
  92. data/test/yarv_test.rb +1 -0
  93. metadata +43 -41
  94. data/examples/flat.txt +0 -50
  95. data/examples/graph.dot +0 -84
  96. data/examples/graph.html +0 -823
  97. data/examples/graph.txt +0 -139
  98. data/examples/multi.flat.txt +0 -23
  99. data/examples/multi.graph.html +0 -760
  100. data/examples/multi.grind.dat +0 -114
  101. data/examples/multi.stack.html +0 -547
  102. data/examples/stack.html +0 -547
  103. data/ext/ruby_prof/rp_call_info.c +0 -425
  104. data/ext/ruby_prof/rp_call_info.h +0 -53
  105. data/ext/ruby_prof/rp_measure.c +0 -40
  106. data/ext/ruby_prof/rp_measure.h +0 -45
  107. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
  108. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
  109. data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
  110. data/lib/ruby-prof/aggregate_call_info.rb +0 -76
  111. data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
  112. data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
  113. data/lib/ruby-prof/call_info.rb +0 -115
  114. data/lib/ruby-prof/call_info_visitor.rb +0 -40
  115. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
  116. data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
  117. data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
  118. data/test/aggregate_test.rb +0 -136
  119. data/test/block_test.rb +0 -74
  120. data/test/call_info_test.rb +0 -78
  121. data/test/call_info_visitor_test.rb +0 -31
  122. data/test/issue137_test.rb +0 -63
  123. data/test/measure_cpu_time_test.rb +0 -212
  124. data/test/measure_gc_runs_test.rb +0 -32
  125. data/test/measure_gc_time_test.rb +0 -36
  126. data/test/measure_memory_test.rb +0 -33
  127. data/test/method_elimination_test.rb +0 -84
  128. data/test/module_test.rb +0 -45
  129. data/test/stack_test.rb +0 -138
@@ -54,40 +54,11 @@ class MultiPrinterTest < TestCase
54
54
  end
55
55
  end
56
56
 
57
- def test_all_profiles_can_be_created
58
- start_time = Time.now
59
- RubyProf.start
60
- 5.times{MSTPT.new.a}
61
- result = RubyProf.stop
62
- end_time = Time.now
63
- expected_time = end_time - start_time
64
- graph = print(result)[1]
65
- re = Regexp.new('
66
- \s*<table>
67
- \s*<tr>
68
- \s*<th>Thread ID</th>
69
- \s*(<th>Fiber ID</th>)?
70
- \s*<th>Total Time</th>
71
- \s*</tr>
72
- \s*
73
- \s*<tr>
74
- \s*(<td>([\.0-9]+)</td>)?
75
- \s*<td><a href="#-?\d+">-?\d+</a></td>
76
- \s*<td>([\.0-9e]+)</td>
77
- \s*</tr>
78
- \s*
79
- \s*</table>')
80
- assert_match(re, graph)
81
- graph =~ re
82
- display_time = $4.to_f
83
- assert_in_delta expected_time, display_time, 0.001
84
- end
85
-
86
57
  private
87
58
 
88
59
  def print(result)
89
60
  test = caller.first =~ /in `(.*)'/ ? $1 : "test"
90
- path = RubyProf.tmpdir
61
+ path = Dir.tmpdir
91
62
  profile = "ruby_prof_#{test}"
92
63
  printer = RubyProf::MultiPrinter.new(result)
93
64
  printer.print(:path => path, :profile => profile,
@@ -95,10 +66,6 @@ class MultiPrinterTest < TestCase
95
66
  if RUBY_PLATFORM =~ /darwin/ && ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT']=="1"
96
67
  system("open '#{printer.stack_profile}'")
97
68
  end
98
- # if GC.respond_to?(:dump_file_and_line_info)
99
- # GC.start
100
- # GC.dump_file_and_line_info("heap.dump")
101
- # end
102
69
  [File.read(printer.stack_profile), File.read(printer.graph_profile)]
103
70
  end
104
71
  end
@@ -2,6 +2,7 @@
2
2
  # encoding: UTF-8
3
3
 
4
4
  require File.expand_path('../test_helper', __FILE__)
5
+ require_relative 'measure_times'
5
6
 
6
7
  class PauseResumeTest < TestCase
7
8
  def setup
@@ -12,22 +13,22 @@ class PauseResumeTest < TestCase
12
13
  def test_pause_resume
13
14
  # Measured
14
15
  RubyProf.start
15
- RubyProf::C1.hello
16
+ RubyProf::C1.sleep_wait
16
17
 
17
18
  # Not measured
18
19
  RubyProf.pause
19
20
  sleep 1
20
- RubyProf::C1.hello
21
+ RubyProf::C1.sleep_wait
21
22
 
22
23
  # Measured
23
24
  RubyProf.resume
24
- RubyProf::C1.hello
25
+ RubyProf::C1.sleep_wait
25
26
 
26
27
  result = RubyProf.stop
27
28
 
28
29
  # Length should be 3:
29
30
  # PauseResumeTest#test_pause_resume
30
- # <Class::RubyProf::C1>#hello
31
+ # <Class::RubyProf::C1>#sleep_wait
31
32
  # Kernel#sleep
32
33
 
33
34
  methods = result.threads.first.methods.sort_by {|method_info| method_info.full_name}
@@ -38,20 +39,20 @@ class PauseResumeTest < TestCase
38
39
  assert_equal(3, methods.length)
39
40
 
40
41
  # Check the names
41
- assert_equal('<Class::RubyProf::C1>#hello', methods[0].full_name)
42
+ assert_equal('<Class::RubyProf::C1>#sleep_wait', methods[0].full_name)
42
43
  assert_equal('Kernel#sleep', methods[1].full_name)
43
44
  assert_equal('PauseResumeTest#test_pause_resume', methods[2].full_name)
44
45
 
45
46
  # Check times
46
- assert_in_delta(0.2, methods[0].total_time, 0.02)
47
+ assert_in_delta(0.22, methods[0].total_time, 0.02)
47
48
  assert_in_delta(0, methods[0].wait_time, 0.02)
48
49
  assert_in_delta(0, methods[0].self_time, 0.02)
49
50
 
50
- assert_in_delta(0.2, methods[1].total_time, 0.02)
51
+ assert_in_delta(0.22, methods[1].total_time, 0.02)
51
52
  assert_in_delta(0, methods[1].wait_time, 0.02)
52
- assert_in_delta(0.2, methods[1].self_time, 0.02)
53
+ assert_in_delta(0.22, methods[1].self_time, 0.02)
53
54
 
54
- assert_in_delta(0.2, methods[2].total_time, 0.02)
55
+ assert_in_delta(0.22, methods[2].total_time, 0.02)
55
56
  assert_in_delta(0, methods[2].wait_time, 0.02)
56
57
  assert_in_delta(0, methods[2].self_time, 0.02)
57
58
  end
@@ -70,9 +71,9 @@ class PauseResumeTest < TestCase
70
71
  method_1c
71
72
 
72
73
  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
+ assert_in_delta(0.65, result.threads[0].methods.select {|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
74
75
  end
75
- def method_1a; sleep 0.2 end
76
+ def method_1a; sleep 0.22 end
76
77
  def method_1b; sleep 1 end
77
78
  def method_1c; sleep 0.4 end
78
79
 
@@ -90,7 +91,7 @@ class PauseResumeTest < TestCase
90
91
  result = profile.stop
91
92
  assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
92
93
  end
93
- def method_2a; sleep 0.2 end
94
+ def method_2a; sleep 0.22 end
94
95
  def method_2b(profile); sleep 0.5; profile.resume; sleep 0.4 end
95
96
 
96
97
  # pause in child frame, resume in parent
@@ -105,10 +106,18 @@ class PauseResumeTest < TestCase
105
106
  method_3b
106
107
 
107
108
  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
+ assert_in_delta(0.65, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_3$/}[0].total_time, 0.05)
110
+ end
111
+
112
+ def method_3a(profile)
113
+ sleep 0.22
114
+ profile.pause
115
+ sleep 0.5
116
+ end
117
+
118
+ def method_3b
119
+ sleep 0.4
109
120
  end
110
- def method_3a(profile); sleep 0.2; profile.pause; sleep 0.5 end
111
- def method_3b; sleep 0.4 end
112
121
 
113
122
  def test_pause_seq
114
123
  profile = RubyProf::Profile.new
@@ -42,7 +42,7 @@ def find_largest(primes)
42
42
  largest
43
43
  end
44
44
 
45
- def run_primes(length=10, maxnum=1000)
45
+ def run_primes(length=10, maxnum=1_000)
46
46
  # Create random numbers
47
47
  random_array = make_random_array(length, maxnum)
48
48
 
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ # This file is used to test bin/ruby-prof
5
+ require_relative './prime'
6
+ run_primes(100, 1_000_000)
@@ -0,0 +1,28 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterCallStackTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def test_graph_html_string
21
+ output = ''
22
+ printer = RubyProf::CallStackPrinter.new(@result)
23
+ printer.print(output)
24
+
25
+ assert_match(/<!DOCTYPE html>/i, output)
26
+ assert_match(/Object#run_primes/i, output)
27
+ end
28
+ end
@@ -0,0 +1,31 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterCallTreeTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def test_call_tree_string
21
+ printer = RubyProf::CallTreePrinter.new(@result)
22
+
23
+ printer.print(:profile => "lolcat", :path => Dir.tmpdir)
24
+ main_output_file_name = File.join(Dir.tmpdir, "lolcat.callgrind.out.#{$$}")
25
+ assert(File.exist?(main_output_file_name))
26
+ output = File.read(main_output_file_name)
27
+ assert_match(/fn=Object::find_primes/i, output)
28
+ assert_match(/events: wall_time/i, output)
29
+ refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
30
+ end
31
+ end
@@ -0,0 +1,68 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterFlatTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def flat_output_nth_column_values(output, n)
21
+ only_method_calls = output.split("\n").select { |line| line =~ /^ +\d+/ }
22
+ only_method_calls.collect { |line| line.split(/ +/)[n] }
23
+ end
24
+
25
+ def assert_sorted array
26
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
27
+ assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
28
+ end
29
+
30
+ def test_flat_string
31
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
32
+ assert_match(/prime.rb/, output)
33
+ end
34
+
35
+ def helper_test_flat_string(klass)
36
+ output = ''
37
+
38
+ printer = klass.new(@result)
39
+ printer.print(output)
40
+
41
+ assert_match(/Thread ID: -?\d+/i, output)
42
+ assert_match(/Fiber ID: -?\d+/i, output)
43
+ assert_match(/Total: \d+\.\d+/i, output)
44
+ assert_match(/Object#run_primes/i, output)
45
+ output
46
+ end
47
+
48
+ def test_flat_result_sorting_by_self_time_is_default
49
+ printer = RubyProf::FlatPrinter.new(@result)
50
+
51
+ printer.print(output = '')
52
+ self_times = flat_output_nth_column_values(output, 3)
53
+
54
+ assert_sorted self_times
55
+ end
56
+
57
+ def test_flat_result_sorting
58
+ printer = RubyProf::FlatPrinter.new(@result)
59
+
60
+ sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
61
+
62
+ sort_method_with_column_number.each_pair do |sort_method, n|
63
+ printer.print(output = '', :sort_method => sort_method)
64
+ times = flat_output_nth_column_values(output, n)
65
+ assert_sorted times
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,60 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterGraphHtmlTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def graph_html_output_nth_column_values(output, n)
21
+ only_root_calls = output.split('<tr class="method">')
22
+ only_root_calls.delete_at(0)
23
+ only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
24
+ end
25
+
26
+ def assert_sorted array
27
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
28
+ assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
29
+ end
30
+
31
+ def test_graph_html_string
32
+ output = ''
33
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
34
+ printer.print(output)
35
+
36
+ assert_match(/<!DOCTYPE html>/i, output)
37
+ assert_match( %r{<th>Total</th>}i, output)
38
+ assert_match(/Object#run_primes/i, output)
39
+ end
40
+
41
+ def test_graph_html_result_sorting_by_total_time_is_default
42
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
43
+ printer.print(output = '')
44
+ total_times = graph_html_output_nth_column_values(output, 3)
45
+
46
+ assert_sorted total_times
47
+ end
48
+
49
+ def test_graph_html_result_sorting
50
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
51
+
52
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
53
+
54
+ sort_method_with_column_number.each_pair do |sort_method, n|
55
+ printer.print(output = '', :sort_method => sort_method)
56
+ times = graph_html_output_nth_column_values(output, n)
57
+ assert_sorted times
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,41 @@
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
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterGraphTest < TestCase
12
+ def setup
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ RubyProf::measure_mode = RubyProf::WALL_TIME
15
+ @result = RubyProf.profile do
16
+ run_primes(1000, 5000)
17
+ end
18
+ end
19
+
20
+ def graph_output_nth_column_values(output, n)
21
+ only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
22
+ only_root_calls.collect { |line| line.split(/ +/)[n] }
23
+ end
24
+
25
+ def assert_sorted array
26
+ array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
27
+ assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
28
+ end
29
+
30
+ def test_graph_results_sorting
31
+ printer = RubyProf::GraphPrinter.new(@result)
32
+
33
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
34
+
35
+ sort_method_with_column_number.each_pair do |sort_method, n|
36
+ printer.print(output = '', :sort_method => sort_method)
37
+ times = graph_output_nth_column_values(output, n)
38
+ assert_sorted times
39
+ end
40
+ end
41
+ end
@@ -4,6 +4,8 @@
4
4
  require File.expand_path('../test_helper', __FILE__)
5
5
  require 'stringio'
6
6
  require 'fileutils'
7
+ require 'tmpdir'
8
+ require_relative 'prime'
7
9
 
8
10
  # -- Tests ----
9
11
  class PrintersTest < TestCase
@@ -16,51 +18,44 @@ class PrintersTest < TestCase
16
18
  end
17
19
 
18
20
  def test_printers
19
- assert_nothing_raised do
20
- output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new('')
21
+ output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new('')
21
22
 
22
- printer = RubyProf::CallInfoPrinter.new(@result)
23
- printer.print(output)
24
-
25
- printer = RubyProf::CallTreePrinter.new(@result)
26
- printer.print()
23
+ printer = RubyProf::CallStackPrinter.new(@result)
24
+ printer.print(output)
27
25
 
28
- printer = RubyProf::FlatPrinter.new(@result)
29
- printer.print(output)
26
+ printer = RubyProf::CallTreePrinter.new(@result)
27
+ printer.print()
30
28
 
31
- printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
32
- printer.print(output)
29
+ printer = RubyProf::FlatPrinter.new(@result)
30
+ printer.print(output)
33
31
 
34
- printer = RubyProf::GraphHtmlPrinter.new(@result)
35
- printer.print(output)
32
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
33
+ printer.print(output)
36
34
 
37
- printer = RubyProf::GraphPrinter.new(@result)
38
- printer.print(output)
39
- end
35
+ printer = RubyProf::GraphPrinter.new(@result)
36
+ printer.print(output)
40
37
  end
41
38
 
42
39
  def test_print_to_files
43
- assert_nothing_raised do
44
- output_dir = 'examples2'
40
+ output_dir = 'examples2'
45
41
 
46
- if ENV['SAVE_NEW_PRINTER_EXAMPLES']
47
- output_dir = 'examples'
48
- end
49
- FileUtils.mkdir_p output_dir
42
+ if ENV['SAVE_NEW_PRINTER_EXAMPLES']
43
+ output_dir = 'examples'
44
+ end
45
+ FileUtils.mkdir_p output_dir
50
46
 
51
- printer = RubyProf::DotPrinter.new(@result)
52
- File.open("#{output_dir}/graph.dot", "w") {|f| printer.print(f)}
47
+ printer = RubyProf::DotPrinter.new(@result)
48
+ File.open("#{output_dir}/graph.dot", "w") {|f| printer.print(f)}
53
49
 
54
- printer = RubyProf::CallStackPrinter.new(@result)
55
- File.open("#{output_dir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
50
+ printer = RubyProf::CallStackPrinter.new(@result)
51
+ File.open("#{output_dir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
56
52
 
57
- printer = RubyProf::MultiPrinter.new(@result)
58
- printer.print(:path => "#{output_dir}", :profile => "multi", :application => "primes")
59
- for file in ['graph.dot', 'multi.flat.txt', 'multi.graph.html', "multi.callgrind.out.#{$$}", 'multi.stack.html', 'stack.html']
60
- existant_file = output_dir + '/' + file
61
- assert File.size(existant_file) > 0
62
- end
63
- end
53
+ # printer = RubyProf::MultiPrinter.new(@result)
54
+ # printer.print(:path => "#{output_dir}", :profile => "multi", :application => "primes")
55
+ # for file in ['graph.dot', 'multi.flat.txt', 'multi.graph.html', "multi.callgrind.out.#{$$}", 'multi.stack.html', 'stack.html']
56
+ # existant_file = output_dir + '/' + file
57
+ # assert File.size(existant_file) > 0
58
+ # end
64
59
  end
65
60
 
66
61
  def test_refuses_io_objects
@@ -85,7 +80,7 @@ class PrintersTest < TestCase
85
80
 
86
81
  def test_flat_string
87
82
  output = helper_test_flat_string(RubyProf::FlatPrinter)
88
- refute_match(/prime.rb/, output)
83
+ assert_match(/prime.rb/, output)
89
84
  end
90
85
 
91
86
  def helper_test_flat_string(klass)
@@ -101,25 +96,13 @@ class PrintersTest < TestCase
101
96
  output
102
97
  end
103
98
 
104
- def test_flat_string_with_numbers
105
- output = helper_test_flat_string RubyProf::FlatPrinterWithLineNumbers
106
- assert_match(/prime.rb/, output)
107
- refute_match(/ruby_runtime:0/, output)
108
- assert_match(/called from/, output)
109
-
110
- # should combine common parents
111
- # 1.9 inlines it's Fixnum#- so we don't see as many
112
- assert_equal(2, output.scan(/Object#is_prime/).length)
113
- refute_match(/\.\/test\/prime.rb/, output) # don't use relative paths
114
- end
115
-
116
99
  def test_graph_html_string
117
100
  output = ''
118
101
  printer = RubyProf::GraphHtmlPrinter.new(@result)
119
102
  printer.print(output)
120
103
 
121
- assert_match(/DTD HTML 4\.01/i, output)
122
- assert_match( %r{<th>Total Time</th>}i, output)
104
+ assert_match(/<!DOCTYPE html>/i, output)
105
+ assert_match( %r{<th>Total</th>}i, output)
123
106
  assert_match(/Object#run_primes/i, output)
124
107
  end
125
108
 
@@ -134,17 +117,6 @@ class PrintersTest < TestCase
134
117
  assert_match(/Object#run_primes/i, output)
135
118
  end
136
119
 
137
- def test_call_tree_string
138
- printer = RubyProf::CallTreePrinter.new(@result)
139
- printer.print(:profile => "lolcat", :path => RubyProf.tmpdir)
140
- main_output_file_name = File.join(RubyProf.tmpdir, "lolcat.callgrind.out.#{$$}")
141
- assert(File.exist?(main_output_file_name))
142
- output = File.read(main_output_file_name)
143
- assert_match(/fn=Object::find_primes/i, output)
144
- assert_match(/events: wall_time/i, output)
145
- refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
146
- end
147
-
148
120
  def do_nothing
149
121
  start = Time.now
150
122
  while(Time.now == start)
@@ -159,117 +131,11 @@ class PrintersTest < TestCase
159
131
 
160
132
  # RubyProf::CallTreePrinter doesn't "do" a min_percent
161
133
  # RubyProf::FlatPrinter only outputs if self time > percent...
162
- # RubyProf::FlatPrinterWithLineNumbers same
163
- for klass in [ RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
134
+ for klass in [RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
164
135
  printer = klass.new(result)
165
136
  out = ''
166
137
  printer.print(out, :min_percent => 0.00000001)
167
138
  assert_match(/do_nothing/, out)
168
139
  end
169
-
170
- end
171
-
172
- def test_flat_result_sorting_by_self_time_is_default
173
- printer = RubyProf::FlatPrinter.new(@result)
174
-
175
- printer.print(output = '')
176
- self_times = flat_output_nth_column_values(output, 3)
177
-
178
- assert_sorted self_times
179
- end
180
-
181
- def test_flat_result_sorting
182
- printer = RubyProf::FlatPrinter.new(@result)
183
-
184
- sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
185
-
186
- sort_method_with_column_number.each_pair do |sort_method, n|
187
- printer.print(output = '', :sort_method => sort_method)
188
- times = flat_output_nth_column_values(output, n)
189
- assert_sorted times
190
- end
191
- end
192
-
193
- def test_flat_result_with_line_numbers_sorting_by_self_time_is_default
194
- printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
195
-
196
- printer.print(output = '')
197
- self_times = flat_output_nth_column_values(output, 3)
198
-
199
- assert_sorted self_times
200
- end
201
-
202
- def test_flat_with_line_numbers_result_sorting
203
- printer = RubyProf::FlatPrinterWithLineNumbers.new(@result)
204
-
205
- sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
206
-
207
- sort_method_with_column_number.each_pair do |sort_method, n|
208
- printer.print(output = '', :sort_method => sort_method)
209
- times = flat_output_nth_column_values(output, n)
210
- assert_sorted times
211
- end
212
- end
213
-
214
- def test_graph_result_sorting_by_total_time_is_default
215
- printer = RubyProf::GraphPrinter.new(@result)
216
- printer.print(output = '')
217
- total_times = graph_output_nth_column_values(output, 3)
218
-
219
- assert_sorted total_times
220
- end
221
-
222
- def test_graph_results_sorting
223
- printer = RubyProf::GraphPrinter.new(@result)
224
-
225
- sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
226
-
227
- sort_method_with_column_number.each_pair do |sort_method, n|
228
- printer.print(output = '', :sort_method => sort_method)
229
- times = graph_output_nth_column_values(output, n)
230
- assert_sorted times
231
- end
232
- end
233
-
234
- def test_graph_html_result_sorting_by_total_time_is_default
235
- printer = RubyProf::GraphHtmlPrinter.new(@result)
236
- printer.print(output = '')
237
- total_times = graph_html_output_nth_column_values(output, 3)
238
-
239
- assert_sorted total_times
240
- end
241
-
242
- def test_graph_html_result_sorting
243
- printer = RubyProf::GraphHtmlPrinter.new(@result)
244
-
245
- sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
246
-
247
- sort_method_with_column_number.each_pair do |sort_method, n|
248
- printer.print(output = '', :sort_method => sort_method)
249
- times = graph_html_output_nth_column_values(output, n)
250
- assert_sorted times
251
- end
252
- end
253
-
254
- private
255
- def flat_output_nth_column_values(output, n)
256
- only_method_calls = output.split("\n").select { |line| line =~ /^ +\d+/ }
257
- only_method_calls.collect { |line| line.split(/ +/)[n] }
258
- end
259
-
260
- def graph_output_nth_column_values(output, n)
261
- only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
262
- only_root_calls.collect { |line| line.split(/ +/)[n] }
263
- end
264
-
265
- def graph_html_output_nth_column_values(output, n)
266
- only_root_calls = output.split('<tr class="method">')
267
- only_root_calls.delete_at(0)
268
- only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
269
- end
270
-
271
- def assert_sorted array
272
- array = array.map{|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
273
- assert_equal array, array.sort.reverse, "Array #{array.inspect} is not sorted"
274
140
  end
275
141
  end