ruby-prof 1.4.4-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +608 -0
  3. data/LICENSE +25 -0
  4. data/README.md +5 -0
  5. data/Rakefile +98 -0
  6. data/bin/ruby-prof +328 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/ext/ruby_prof/extconf.rb +22 -0
  9. data/ext/ruby_prof/rp_aggregate_call_tree.c +59 -0
  10. data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
  11. data/ext/ruby_prof/rp_allocation.c +287 -0
  12. data/ext/ruby_prof/rp_allocation.h +31 -0
  13. data/ext/ruby_prof/rp_call_tree.c +367 -0
  14. data/ext/ruby_prof/rp_call_tree.h +43 -0
  15. data/ext/ruby_prof/rp_call_trees.c +288 -0
  16. data/ext/ruby_prof/rp_call_trees.h +28 -0
  17. data/ext/ruby_prof/rp_measure_allocations.c +47 -0
  18. data/ext/ruby_prof/rp_measure_memory.c +46 -0
  19. data/ext/ruby_prof/rp_measure_process_time.c +66 -0
  20. data/ext/ruby_prof/rp_measure_wall_time.c +64 -0
  21. data/ext/ruby_prof/rp_measurement.c +237 -0
  22. data/ext/ruby_prof/rp_measurement.h +50 -0
  23. data/ext/ruby_prof/rp_method.c +491 -0
  24. data/ext/ruby_prof/rp_method.h +62 -0
  25. data/ext/ruby_prof/rp_profile.c +915 -0
  26. data/ext/ruby_prof/rp_profile.h +35 -0
  27. data/ext/ruby_prof/rp_stack.c +212 -0
  28. data/ext/ruby_prof/rp_stack.h +53 -0
  29. data/ext/ruby_prof/rp_thread.c +362 -0
  30. data/ext/ruby_prof/rp_thread.h +39 -0
  31. data/ext/ruby_prof/ruby_prof.c +52 -0
  32. data/ext/ruby_prof/ruby_prof.h +26 -0
  33. data/ext/ruby_prof/vc/ruby_prof.sln +39 -0
  34. data/ext/ruby_prof/vc/ruby_prof.vcxproj +160 -0
  35. data/lib/3.1/ruby_prof.so +0 -0
  36. data/lib/ruby-prof/assets/call_stack_printer.html.erb +711 -0
  37. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  38. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
  39. data/lib/ruby-prof/call_tree.rb +57 -0
  40. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  41. data/lib/ruby-prof/compatibility.rb +99 -0
  42. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  43. data/lib/ruby-prof/measurement.rb +17 -0
  44. data/lib/ruby-prof/method_info.rb +78 -0
  45. data/lib/ruby-prof/printers/abstract_printer.rb +137 -0
  46. data/lib/ruby-prof/printers/call_info_printer.rb +53 -0
  47. data/lib/ruby-prof/printers/call_stack_printer.rb +180 -0
  48. data/lib/ruby-prof/printers/call_tree_printer.rb +147 -0
  49. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  50. data/lib/ruby-prof/printers/flat_printer.rb +53 -0
  51. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -0
  52. data/lib/ruby-prof/printers/graph_printer.rb +113 -0
  53. data/lib/ruby-prof/printers/multi_printer.rb +127 -0
  54. data/lib/ruby-prof/profile.rb +37 -0
  55. data/lib/ruby-prof/rack.rb +95 -0
  56. data/lib/ruby-prof/task.rb +147 -0
  57. data/lib/ruby-prof/thread.rb +20 -0
  58. data/lib/ruby-prof/version.rb +3 -0
  59. data/lib/ruby-prof.rb +52 -0
  60. data/lib/unprof.rb +10 -0
  61. data/ruby-prof.gemspec +64 -0
  62. data/test/abstract_printer_test.rb +26 -0
  63. data/test/alias_test.rb +122 -0
  64. data/test/basic_test.rb +43 -0
  65. data/test/call_tree_visitor_test.rb +32 -0
  66. data/test/call_trees_test.rb +66 -0
  67. data/test/duplicate_names_test.rb +32 -0
  68. data/test/dynamic_method_test.rb +67 -0
  69. data/test/enumerable_test.rb +21 -0
  70. data/test/exceptions_test.rb +24 -0
  71. data/test/exclude_methods_test.rb +151 -0
  72. data/test/exclude_threads_test.rb +53 -0
  73. data/test/fiber_test.rb +129 -0
  74. data/test/gc_test.rb +100 -0
  75. data/test/inverse_call_tree_test.rb +175 -0
  76. data/test/line_number_test.rb +158 -0
  77. data/test/marshal_test.rb +145 -0
  78. data/test/measure_allocations.rb +26 -0
  79. data/test/measure_allocations_test.rb +333 -0
  80. data/test/measure_memory_test.rb +688 -0
  81. data/test/measure_process_time_test.rb +1614 -0
  82. data/test/measure_times.rb +56 -0
  83. data/test/measure_wall_time_test.rb +426 -0
  84. data/test/multi_printer_test.rb +71 -0
  85. data/test/no_method_class_test.rb +15 -0
  86. data/test/pause_resume_test.rb +175 -0
  87. data/test/prime.rb +54 -0
  88. data/test/prime_script.rb +6 -0
  89. data/test/printer_call_stack_test.rb +27 -0
  90. data/test/printer_call_tree_test.rb +30 -0
  91. data/test/printer_flat_test.rb +99 -0
  92. data/test/printer_graph_html_test.rb +59 -0
  93. data/test/printer_graph_test.rb +40 -0
  94. data/test/printers_test.rb +141 -0
  95. data/test/printing_recursive_graph_test.rb +81 -0
  96. data/test/profile_test.rb +16 -0
  97. data/test/rack_test.rb +93 -0
  98. data/test/recursive_test.rb +430 -0
  99. data/test/singleton_test.rb +38 -0
  100. data/test/stack_printer_test.rb +64 -0
  101. data/test/start_stop_test.rb +109 -0
  102. data/test/test_helper.rb +13 -0
  103. data/test/thread_test.rb +144 -0
  104. data/test/unique_call_path_test.rb +136 -0
  105. data/test/yarv_test.rb +60 -0
  106. metadata +187 -0
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require_relative 'measure_times'
6
+
7
+ class PauseResumeTest < TestCase
8
+ def setup
9
+ # Need to use wall time for this test due to the sleep calls
10
+ RubyProf::measure_mode = RubyProf::WALL_TIME
11
+ end
12
+
13
+ def test_pause_resume
14
+ # Measured
15
+ RubyProf.start
16
+ RubyProf::C1.sleep_wait
17
+
18
+ # Not measured
19
+ RubyProf.pause
20
+ sleep 1
21
+ RubyProf::C1.sleep_wait
22
+
23
+ # Measured
24
+ RubyProf.resume
25
+ RubyProf::C1.sleep_wait
26
+
27
+ result = RubyProf.stop
28
+
29
+ # Length should be 3:
30
+ # PauseResumeTest#test_pause_resume
31
+ # <Class::RubyProf::C1>#sleep_wait
32
+ # Kernel#sleep
33
+
34
+ methods = result.threads.first.methods.sort_by {|method_info| method_info.full_name}
35
+ # remove methods called by pause/resume
36
+ called_methods = ['Array#include?', 'Fixnum#==', 'Kernel#respond_to?', 'Kernel#respond_to_missing?']
37
+ methods.reject!{|m| called_methods.include?(m.full_name) }
38
+ # TODO: fix pause/resume to not include those methods in the first place
39
+ assert_equal(3, methods.length)
40
+
41
+ # Check the names
42
+ assert_equal('<Class::RubyProf::C1>#sleep_wait', methods[0].full_name)
43
+ assert_equal('Kernel#sleep', methods[1].full_name)
44
+ assert_equal('PauseResumeTest#test_pause_resume', methods[2].full_name)
45
+
46
+ # Check times
47
+ assert_in_delta(0.22, methods[0].total_time, 0.02)
48
+ assert_in_delta(0, methods[0].wait_time, 0.02)
49
+ assert_in_delta(0, methods[0].self_time, 0.02)
50
+
51
+ assert_in_delta(0.22, methods[1].total_time, 0.02)
52
+ assert_in_delta(0, methods[1].wait_time, 0.02)
53
+ assert_in_delta(0.22, methods[1].self_time, 0.02)
54
+
55
+ assert_in_delta(0.22, methods[2].total_time, 0.02)
56
+ assert_in_delta(0, methods[2].wait_time, 0.02)
57
+ assert_in_delta(0, methods[2].self_time, 0.02)
58
+ end
59
+
60
+ # pause/resume in the same frame
61
+ def test_pause_resume_1
62
+ profile = RubyProf::Profile.new
63
+
64
+ profile.start
65
+ method_1a
66
+
67
+ profile.pause
68
+ method_1b
69
+
70
+ profile.resume
71
+ method_1c
72
+
73
+ result = profile.stop
74
+ assert_in_delta(0.65, result.threads[0].methods.select {|m| m.full_name =~ /test_pause_resume_1$/}[0].total_time, 0.05)
75
+ end
76
+ def method_1a; sleep 0.22 end
77
+ def method_1b; sleep 1 end
78
+ def method_1c; sleep 0.4 end
79
+
80
+ # pause in parent frame, resume in child
81
+ def test_pause_resume_2
82
+ profile = RubyProf::Profile.new
83
+
84
+ profile.start
85
+ method_2a
86
+
87
+ profile.pause
88
+ sleep 0.5
89
+ method_2b(profile)
90
+
91
+ result = profile.stop
92
+ assert_in_delta(0.6, result.threads[0].methods.select{|m| m.full_name =~ /test_pause_resume_2$/}[0].total_time, 0.05)
93
+ end
94
+ def method_2a; sleep 0.22 end
95
+ def method_2b(profile); sleep 0.5; profile.resume; sleep 0.4 end
96
+
97
+ # pause in child frame, resume in parent
98
+ def test_pause_resume_3
99
+ profile = RubyProf::Profile.new
100
+
101
+ profile.start
102
+ method_3a(profile)
103
+
104
+ sleep 0.5
105
+ profile.resume
106
+ method_3b
107
+
108
+ result = profile.stop
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
120
+ end
121
+
122
+ def test_pause_seq
123
+ profile = RubyProf::Profile.new
124
+ profile.start ; assert !profile.paused?
125
+ profile.pause ; assert profile.paused?
126
+ profile.resume; assert !profile.paused?
127
+ profile.pause ; assert profile.paused?
128
+ profile.pause ; assert profile.paused?
129
+ profile.resume; assert !profile.paused?
130
+ profile.resume; assert !profile.paused?
131
+ profile.stop ; assert !profile.paused?
132
+ end
133
+
134
+ def test_pause_block
135
+ profile = RubyProf::Profile.new
136
+ profile.start
137
+ profile.pause
138
+ assert profile.paused?
139
+
140
+ times_block_invoked = 0
141
+ retval= profile.resume{
142
+ times_block_invoked += 1
143
+ 120 + times_block_invoked
144
+ }
145
+ assert_equal 1, times_block_invoked
146
+ assert profile.paused?
147
+
148
+ assert_equal 121, retval, "resume() should return the result of the given block."
149
+
150
+ profile.stop
151
+ end
152
+
153
+ def test_pause_block_with_error
154
+ profile = RubyProf::Profile.new
155
+ profile.start
156
+ profile.pause
157
+ assert profile.paused?
158
+
159
+ begin
160
+ profile.resume{ raise }
161
+ flunk 'Exception expected.'
162
+ rescue
163
+ assert profile.paused?
164
+ end
165
+
166
+ profile.stop
167
+ end
168
+
169
+ def test_resume_when_not_paused
170
+ profile = RubyProf::Profile.new
171
+ profile.start ; assert !profile.paused?
172
+ profile.resume; assert !profile.paused?
173
+ profile.stop ; assert !profile.paused?
174
+ end
175
+ end
data/test/prime.rb ADDED
@@ -0,0 +1,54 @@
1
+ # A silly little test program that finds prime numbers. It
2
+ # is intentionally badly designed to show off the use
3
+ # of ruby-prof.
4
+ #
5
+ # Source from http://people.cs.uchicago.edu/~bomb154/154/maclabs/profilers-lab/
6
+
7
+ def make_random_array(length, maxnum)
8
+ result = Array.new(length)
9
+ result.each_index do |i|
10
+ result[i] = rand(maxnum)
11
+ end
12
+
13
+ result
14
+ end
15
+
16
+ def is_prime(x)
17
+ y = 2
18
+ y.upto(x-1) do |i|
19
+ return false if (x % i) == 0
20
+ end
21
+ true
22
+ end
23
+
24
+ def find_primes(arr)
25
+ result = arr.select do |value|
26
+ is_prime(value)
27
+ end
28
+ result
29
+ end
30
+
31
+ def find_largest(primes)
32
+ largest = primes.first
33
+
34
+ # Intentionally use upto for example purposes
35
+ # (upto is also called from is_prime)
36
+ 0.upto(primes.length-1) do |i|
37
+ prime = primes[i]
38
+ if prime > largest
39
+ largest = prime
40
+ end
41
+ end
42
+ largest
43
+ end
44
+
45
+ def run_primes(length=10, maxnum=1_000)
46
+ # Create random numbers
47
+ random_array = make_random_array(length, maxnum)
48
+
49
+ # Find the primes
50
+ primes = find_primes(random_array)
51
+
52
+ # Find the largest primes
53
+ find_largest(primes)
54
+ end
@@ -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,27 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterCallStackTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def test_graph_html_string
20
+ output = ''
21
+ printer = RubyProf::CallStackPrinter.new(@result)
22
+ printer.print(output)
23
+
24
+ assert_match(/<!DOCTYPE html>/i, output)
25
+ assert_match(/Object#run_primes/i, output)
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterCallTreeTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def test_call_tree_string
20
+ printer = RubyProf::CallTreePrinter.new(@result)
21
+
22
+ printer.print(:path => Dir.tmpdir)
23
+ main_output_file_name = File.join(Dir.tmpdir, "callgrind.out.#{$$}")
24
+ assert(File.exist?(main_output_file_name))
25
+ output = File.read(main_output_file_name)
26
+ assert_match(/fn=Object::find_primes/i, output)
27
+ assert_match(/events: wall_time/i, output)
28
+ refute_match(/d\d\d\d\d\d/, output) # old bug looked [in error] like Object::run_primes(d5833116)
29
+ end
30
+ end
@@ -0,0 +1,99 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'stringio'
7
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrinterFlatTest < TestCase
12
+ def run_profile
13
+ RubyProf.profile(:measure_mode => RubyProf::WALL_TIME) do
14
+ run_primes(1000, 5000)
15
+ end
16
+ end
17
+
18
+ def flat_output_nth_column_values(output, n)
19
+ only_method_calls = output.split("\n").select { |line| line =~ /^\s+\d+/ }
20
+ only_method_calls.collect { |line| line.split(/\s+/)[n] }
21
+ end
22
+
23
+ def helper_test_flat_string(klass)
24
+ output = StringIO.new
25
+
26
+ printer = klass.new(self.run_profile)
27
+ printer.print(output)
28
+
29
+ assert_match(/Thread ID: -?\d+/i, output.string)
30
+ assert_match(/Fiber ID: -?\d+/i, output.string)
31
+ assert_match(/Total: \d+\.\d+/i, output.string)
32
+ assert_match(/Object#run_primes/i, output.string)
33
+ output.string
34
+ end
35
+
36
+ def assert_sorted(array)
37
+ array = array.map(&:to_f) # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
38
+ assert_equal(array, array.sort.reverse)
39
+ end
40
+
41
+ def test_flat_string
42
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
43
+ assert_match(/prime.rb/, output)
44
+ end
45
+
46
+ def test_flat_result_sorting_by_self_time_is_default
47
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
48
+
49
+ output = StringIO.new
50
+ printer.print(output)
51
+ self_times = flat_output_nth_column_values(output.string, 3)
52
+
53
+ assert_sorted self_times
54
+ end
55
+
56
+ def test_flat_result_sorting
57
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
58
+
59
+ sort_method_with_column_number = {:total_time => 2, :self_time => 3, :wait_time => 4, :children_time => 5}
60
+
61
+ sort_method_with_column_number.each_pair do |sort_method, n|
62
+ output = StringIO.new
63
+ printer.print(output, :sort_method => sort_method)
64
+
65
+ times = flat_output_nth_column_values(output.string, n)
66
+ assert_sorted(times)
67
+ end
68
+ end
69
+
70
+ def test_flat_result_max_percent
71
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
72
+
73
+ output = StringIO.new
74
+ printer.print(output, max_percent: 1)
75
+ self_percents = flat_output_nth_column_values(output.string, 1).map(&:to_f)
76
+
77
+ assert self_percents.max < 1
78
+ end
79
+
80
+ def test_flat_result_filter_by_total_time
81
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
82
+
83
+ output = StringIO.new
84
+ printer.print(output, filter_by: :total_time, min_percent: 50)
85
+ total_times = flat_output_nth_column_values(output.string, 2).map(&:to_f)
86
+
87
+ assert (total_times.min / total_times.max) >= 0.5
88
+ end
89
+
90
+ def test_flat_result_filter_by_self_time
91
+ printer = RubyProf::FlatPrinter.new(self.run_profile)
92
+
93
+ output = StringIO.new
94
+ printer.print(output, filter_by: :self_time, min_percent: 0.1)
95
+ self_percents = flat_output_nth_column_values(output.string, 1).map(&:to_f)
96
+
97
+ assert self_percents.min >= 0.1
98
+ end
99
+ end
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterGraphHtmlTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def graph_html_output_nth_column_values(output, n)
20
+ only_root_calls = output.split('<tr class="method">')
21
+ only_root_calls.delete_at(0)
22
+ only_root_calls.collect {|line| line.scan(/[\d\.]+/)[n - 1] }
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_html_string
31
+ output = ''
32
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
33
+ printer.print(output)
34
+
35
+ assert_match(/<!DOCTYPE html>/i, output)
36
+ assert_match( %r{<th>Total</th>}i, output)
37
+ assert_match(/Object#run_primes/i, output)
38
+ end
39
+
40
+ def test_graph_html_result_sorting_by_total_time_is_default
41
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
42
+ printer.print(output = '')
43
+ total_times = graph_html_output_nth_column_values(output, 3)
44
+
45
+ assert_sorted total_times
46
+ end
47
+
48
+ def test_graph_html_result_sorting
49
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
50
+
51
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
52
+
53
+ sort_method_with_column_number.each_pair do |sort_method, n|
54
+ printer.print(output = '', :sort_method => sort_method)
55
+ times = graph_html_output_nth_column_values(output, n)
56
+ assert_sorted times
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrinterGraphTest < TestCase
11
+ def setup
12
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
13
+ RubyProf::measure_mode = RubyProf::WALL_TIME
14
+ @result = RubyProf.profile do
15
+ run_primes(1000, 5000)
16
+ end
17
+ end
18
+
19
+ def graph_output_nth_column_values(output, n)
20
+ only_root_calls = output.split("\n").select { |line| line =~ /^ +[\d\.]+%/ }
21
+ only_root_calls.collect { |line| line.split(/ +/)[n] }
22
+ end
23
+
24
+ def assert_sorted(array)
25
+ array = array.map {|n| n.to_f} # allow for > 10s times to sort right, since lexographically 4.0 > 10.0
26
+ assert_equal(array, array.sort.reverse, "Array #{array.inspect} is not sorted")
27
+ end
28
+
29
+ def test_graph_results_sorting
30
+ printer = RubyProf::GraphPrinter.new(@result)
31
+
32
+ sort_method_with_column_number = {:total_time => 3, :self_time => 4, :wait_time => 5, :children_time => 6}
33
+
34
+ sort_method_with_column_number.each_pair do |sort_method, n|
35
+ printer.print(output = '', :sort_method => sort_method)
36
+ times = graph_output_nth_column_values(output, n)
37
+ assert_sorted times
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'fileutils'
6
+ require 'stringio'
7
+ require 'tmpdir'
8
+ require_relative 'prime'
9
+
10
+ # -- Tests ----
11
+ class PrintersTest < 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_printers
21
+ output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new('')
22
+
23
+ printer = RubyProf::CallStackPrinter.new(@result)
24
+ printer.print(output)
25
+
26
+ printer = RubyProf::CallTreePrinter.new(@result)
27
+ printer.print()
28
+
29
+ printer = RubyProf::FlatPrinter.new(@result)
30
+ printer.print(output)
31
+
32
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
33
+ printer.print(output)
34
+
35
+ printer = RubyProf::GraphPrinter.new(@result)
36
+ printer.print(output)
37
+ end
38
+
39
+ def test_print_to_files
40
+ output_dir = 'tmp/examples2'
41
+
42
+ if ENV['SAVE_NEW_PRINTER_EXAMPLES']
43
+ output_dir = 'tmp/examples'
44
+ end
45
+ FileUtils.mkdir_p output_dir
46
+
47
+ printer = RubyProf::DotPrinter.new(@result)
48
+ File.open("#{output_dir}/graph.dot", "w") {|f| printer.print(f)}
49
+
50
+ printer = RubyProf::CallStackPrinter.new(@result)
51
+ File.open("#{output_dir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
52
+
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
59
+ end
60
+
61
+ def test_refuses_io_objects
62
+ p = RubyProf::MultiPrinter.new(@result)
63
+ begin
64
+ p.print(STDOUT)
65
+ flunk "should have raised an ArgumentError"
66
+ rescue ArgumentError => e
67
+ assert_match(/IO/, e.to_s)
68
+ end
69
+ end
70
+
71
+ def test_refuses_non_hashes
72
+ p = RubyProf::MultiPrinter.new (@result)
73
+ begin
74
+ p.print([])
75
+ flunk "should have raised an ArgumentError"
76
+ rescue ArgumentError => e
77
+ assert_match(/hash/, e.to_s)
78
+ end
79
+ end
80
+
81
+ def test_flat_string
82
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
83
+ assert_match(/prime.rb/, output)
84
+ end
85
+
86
+ def helper_test_flat_string(klass)
87
+ output = ''
88
+
89
+ printer = klass.new(@result)
90
+ printer.print(output)
91
+
92
+ assert_match(/Thread ID: -?\d+/i, output)
93
+ assert_match(/Fiber ID: -?\d+/i, output)
94
+ assert_match(/Total: \d+\.\d+/i, output)
95
+ assert_match(/Object#run_primes/i, output)
96
+ output
97
+ end
98
+
99
+ def test_graph_html_string
100
+ output = ''
101
+ printer = RubyProf::GraphHtmlPrinter.new(@result)
102
+ printer.print(output)
103
+
104
+ assert_match(/<!DOCTYPE html>/i, output)
105
+ assert_match( %r{<th>Total</th>}i, output)
106
+ assert_match(/Object#run_primes/i, output)
107
+ end
108
+
109
+ def test_graph_string
110
+ output = ''
111
+ printer = RubyProf::GraphPrinter.new(@result)
112
+ printer.print(output)
113
+
114
+ assert_match(/Thread ID: -?\d+/i, output)
115
+ assert_match(/Fiber ID: -?\d+/i, output)
116
+ assert_match(/Total Time: \d+\.\d+/i, output)
117
+ assert_match(/Object#run_primes/i, output)
118
+ end
119
+
120
+ def do_nothing
121
+ start = Time.now
122
+ while(Time.now == start)
123
+ end
124
+ end
125
+
126
+ def test_all_with_small_percentiles
127
+ result = RubyProf.profile do
128
+ sleep 2
129
+ do_nothing
130
+ end
131
+
132
+ # RubyProf::CallTreePrinter doesn't "do" a min_percent
133
+ # RubyProf::FlatPrinter only outputs if self time > percent...
134
+ for klass in [RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
135
+ printer = klass.new(result)
136
+ out = ''
137
+ printer.print(out, :min_percent => 0.00000001)
138
+ assert_match(/do_nothing/, out)
139
+ end
140
+ end
141
+ end