ruby-prof 1.8.0-x64-mswin64-140

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 (108) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +665 -0
  3. data/LICENSE +25 -0
  4. data/README.md +5 -0
  5. data/Rakefile +98 -0
  6. data/bin/ruby-prof +341 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/ext/ruby_prof/extconf.rb +23 -0
  9. data/ext/ruby_prof/rp_allocation.c +327 -0
  10. data/ext/ruby_prof/rp_allocation.h +32 -0
  11. data/ext/ruby_prof/rp_call_tree.c +502 -0
  12. data/ext/ruby_prof/rp_call_tree.h +47 -0
  13. data/ext/ruby_prof/rp_call_trees.c +296 -0
  14. data/ext/ruby_prof/rp_call_trees.h +28 -0
  15. data/ext/ruby_prof/rp_measure_allocations.c +47 -0
  16. data/ext/ruby_prof/rp_measure_memory.c +46 -0
  17. data/ext/ruby_prof/rp_measure_process_time.c +64 -0
  18. data/ext/ruby_prof/rp_measure_wall_time.c +52 -0
  19. data/ext/ruby_prof/rp_measurement.c +359 -0
  20. data/ext/ruby_prof/rp_measurement.h +52 -0
  21. data/ext/ruby_prof/rp_method.c +551 -0
  22. data/ext/ruby_prof/rp_method.h +66 -0
  23. data/ext/ruby_prof/rp_profile.c +933 -0
  24. data/ext/ruby_prof/rp_profile.h +36 -0
  25. data/ext/ruby_prof/rp_stack.c +212 -0
  26. data/ext/ruby_prof/rp_stack.h +53 -0
  27. data/ext/ruby_prof/rp_thread.c +433 -0
  28. data/ext/ruby_prof/rp_thread.h +39 -0
  29. data/ext/ruby_prof/ruby_prof.c +50 -0
  30. data/ext/ruby_prof/ruby_prof.h +35 -0
  31. data/ext/ruby_prof/vc/ruby_prof.sln +39 -0
  32. data/ext/ruby_prof/vc/ruby_prof.vcxproj +158 -0
  33. data/lib/ruby-prof/assets/call_stack_printer.html.erb +711 -0
  34. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  35. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
  36. data/lib/ruby-prof/call_tree.rb +57 -0
  37. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  38. data/lib/ruby-prof/compatibility.rb +113 -0
  39. data/lib/ruby-prof/exclude_common_methods.rb +204 -0
  40. data/lib/ruby-prof/measurement.rb +17 -0
  41. data/lib/ruby-prof/method_info.rb +87 -0
  42. data/lib/ruby-prof/printers/abstract_printer.rb +156 -0
  43. data/lib/ruby-prof/printers/call_info_printer.rb +53 -0
  44. data/lib/ruby-prof/printers/call_stack_printer.rb +180 -0
  45. data/lib/ruby-prof/printers/call_tree_printer.rb +145 -0
  46. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  47. data/lib/ruby-prof/printers/flat_printer.rb +53 -0
  48. data/lib/ruby-prof/printers/graph_html_printer.rb +63 -0
  49. data/lib/ruby-prof/printers/graph_printer.rb +113 -0
  50. data/lib/ruby-prof/printers/multi_printer.rb +127 -0
  51. data/lib/ruby-prof/profile.rb +70 -0
  52. data/lib/ruby-prof/rack.rb +105 -0
  53. data/lib/ruby-prof/task.rb +147 -0
  54. data/lib/ruby-prof/thread.rb +20 -0
  55. data/lib/ruby-prof/version.rb +3 -0
  56. data/lib/ruby-prof.rb +52 -0
  57. data/lib/unprof.rb +10 -0
  58. data/ruby-prof.gemspec +67 -0
  59. data/test/abstract_printer_test.rb +27 -0
  60. data/test/alias_test.rb +117 -0
  61. data/test/call_tree_builder.rb +126 -0
  62. data/test/call_tree_test.rb +94 -0
  63. data/test/call_tree_visitor_test.rb +27 -0
  64. data/test/call_trees_test.rb +66 -0
  65. data/test/compatibility_test.rb +49 -0
  66. data/test/duplicate_names_test.rb +32 -0
  67. data/test/dynamic_method_test.rb +50 -0
  68. data/test/enumerable_test.rb +23 -0
  69. data/test/exceptions_test.rb +24 -0
  70. data/test/exclude_methods_test.rb +363 -0
  71. data/test/exclude_threads_test.rb +48 -0
  72. data/test/fiber_test.rb +195 -0
  73. data/test/gc_test.rb +104 -0
  74. data/test/inverse_call_tree_test.rb +174 -0
  75. data/test/line_number_test.rb +426 -0
  76. data/test/marshal_test.rb +145 -0
  77. data/test/measure_allocations.rb +26 -0
  78. data/test/measure_allocations_test.rb +1172 -0
  79. data/test/measure_process_time_test.rb +3330 -0
  80. data/test/measure_times.rb +56 -0
  81. data/test/measure_wall_time_test.rb +635 -0
  82. data/test/measurement_test.rb +82 -0
  83. data/test/merge_test.rb +146 -0
  84. data/test/method_info_test.rb +100 -0
  85. data/test/multi_printer_test.rb +66 -0
  86. data/test/no_method_class_test.rb +15 -0
  87. data/test/pause_resume_test.rb +171 -0
  88. data/test/prime.rb +54 -0
  89. data/test/prime_script.rb +6 -0
  90. data/test/printer_call_stack_test.rb +27 -0
  91. data/test/printer_call_tree_test.rb +30 -0
  92. data/test/printer_flat_test.rb +99 -0
  93. data/test/printer_graph_html_test.rb +59 -0
  94. data/test/printer_graph_test.rb +40 -0
  95. data/test/printers_test.rb +178 -0
  96. data/test/printing_recursive_graph_test.rb +81 -0
  97. data/test/profile_test.rb +101 -0
  98. data/test/rack_test.rb +93 -0
  99. data/test/recursive_test.rb +796 -0
  100. data/test/scheduler.rb +363 -0
  101. data/test/singleton_test.rb +38 -0
  102. data/test/stack_printer_test.rb +61 -0
  103. data/test/start_stop_test.rb +106 -0
  104. data/test/test_helper.rb +21 -0
  105. data/test/thread_test.rb +229 -0
  106. data/test/unique_call_path_test.rb +123 -0
  107. data/test/yarv_test.rb +56 -0
  108. metadata +228 -0
@@ -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.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
+ super
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ @result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) 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
+ super
13
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
14
+ @result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) 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,178 @@
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
+ super
14
+ # WALL_TIME, PROCESS_TIME, ALLOCATIONS and MEMORY as types of measuremen
15
+ measure_modes = {wall_time: RubyProf::WALL_TIME, process_time: RubyProf::PROCESS_TIME, allocations: RubyProf::ALLOCATIONS, memory: RubyProf::MEMORY}
16
+
17
+ @results = {}
18
+
19
+ measure_modes.each do |key, value|
20
+ @results[key] = RubyProf::Profile.profile(measure_mode: value) do
21
+ run_primes(1000, 5000)
22
+ end
23
+ end
24
+ end
25
+
26
+ def test_printers
27
+ output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new('')
28
+
29
+ printer = RubyProf::CallStackPrinter.new(@results[:wall_time])
30
+ printer.print(output)
31
+
32
+ printer = RubyProf::CallTreePrinter.new(@results[:wall_time])
33
+ printer.print(:path => Dir.tmpdir)
34
+
35
+ printer = RubyProf::FlatPrinter.new(@results[:wall_time])
36
+ printer.print(output)
37
+
38
+ printer = RubyProf::GraphHtmlPrinter.new(@results[:wall_time])
39
+ printer.print(output)
40
+
41
+ printer = RubyProf::GraphPrinter.new(@results[:wall_time])
42
+ printer.print(output)
43
+ end
44
+
45
+ def test_print_to_files
46
+ printer = RubyProf::DotPrinter.new(@results[:wall_time])
47
+ File.open("#{Dir.tmpdir}/graph.dot", "w") {|f| printer.print(f)}
48
+
49
+ printer = RubyProf::CallStackPrinter.new(@results[:wall_time])
50
+ File.open("#{Dir.tmpdir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
51
+
52
+ printer = RubyProf::MultiPrinter.new(@results[:wall_time])
53
+ printer.print(:path => Dir.tmpdir, :profile => "multi", :application => "primes")
54
+
55
+ ['graph.dot', 'multi.flat.txt', 'multi.graph.html', "multi.callgrind.out.#{$$}", 'multi.stack.html', 'stack.html'].each do |file_name|
56
+ file_path = File.join(Dir.tmpdir, file_name)
57
+ refute(File.empty?(file_path))
58
+ end
59
+ end
60
+
61
+ def test_refuses_io_objects
62
+ p = RubyProf::MultiPrinter.new(@results[:wall_time])
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 (@results[:wall_time])
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(@results[:wall_time])
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(@results[:wall_time])
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(@results[:wall_time])
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.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
+
142
+ def test_print_footer
143
+ results_keys = [:wall_time, :process_time, :allocations, :memory]
144
+ expected_matches = [
145
+ "The percentage of time spent by this method relative to the total time in the entire program.",
146
+ "The total time spent by this method and its children.",
147
+ "The time spent by this method.",
148
+ "The time spent by this method's children.",
149
+ "The percentage of allocations made by this method relative to the total allocations in the entire program.",
150
+ "The total number of allocations made by this method and its children.",
151
+ "The number of allocations made by this method.",
152
+ "The number of allocations made by this method's children.",
153
+ "The percentage of memory used by this method relative to the total memory in the entire program.",
154
+ "The total memory used by this method and its children.",
155
+ "The memory used by this method.",
156
+ "The memory used by this method's children."
157
+ ]
158
+
159
+ results_keys.each do |key|
160
+ output = ''
161
+ printer = RubyProf::GraphPrinter.new(@results[key])
162
+ printer.print(output)
163
+
164
+ case key
165
+ when :wall_time, :process_time
166
+ matches = expected_matches[0..3]
167
+ when :allocations
168
+ matches = expected_matches[4..7]
169
+ when :memory
170
+ matches = expected_matches[8..11]
171
+ end
172
+
173
+ matches.each do |pattern|
174
+ assert_match(pattern, output)
175
+ end
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,81 @@
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
+
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: 1307675084040
29
+ Fiber ID: 1307708787440
30
+ Total Time: 2.0939999999973224
31
+ Sort by:
32
+
33
+ %total %self total self wait child calls name
34
+ --------------------------------------------------------------------------------
35
+ 1.657 0.000 0.000 1.657 2/2 Integer#times
36
+ 79.13% 0.00% 1.657 0.000 0.000 1.657 2 PRGT#g
37
+ 1.657 0.000 0.000 1.657 2/5 Integer#times
38
+ --------------------------------------------------------------------------------
39
+ 2.094 2.094 0.000 0.000 12/12 Integer#times
40
+ 100.00% 100.00% 2.094 2.094 0.000 0.000 12 Kernel#sleep
41
+ --------------------------------------------------------------------------------
42
+ 0.437 0.000 0.000 0.437 2/2 Integer#times
43
+ 20.87% 0.00% 0.437 0.000 0.000 0.437 2 PRGT#f
44
+ 0.437 0.000 0.000 0.437 2/5 Integer#times
45
+ --------------------------------------------------------------------------------
46
+ 0.437 0.000 0.000 0.437 2/5 PRGT#f
47
+ 1.657 0.000 0.000 1.657 2/5 PRGT#g
48
+ 2.094 0.000 0.000 2.094 1/5 PRGT#run
49
+ 100.00% 0.00% 2.094 0.000 0.000 2.094 5 *Integer#times
50
+ 2.094 2.094 0.000 0.000 12/12 Kernel#sleep
51
+ 1.657 0.000 0.000 1.657 2/2 PRGT#g
52
+ 0.437 0.000 0.000 0.437 2/2 PRGT#f
53
+ --------------------------------------------------------------------------------
54
+ 2.094 0.000 0.000 2.094 1/1 PrintingRecursiveGraphTest#setup
55
+ 100.00% 0.00% 2.094 0.000 0.000 2.094 1 PRGT#run
56
+ 2.094 0.000 0.000 2.094 1/5 Integer#times
57
+ --------------------------------------------------------------------------------
58
+ 100.00% 0.00% 2.094 0.000 0.000 2.094 1 PrintingRecursiveGraphTest#setup
59
+ 2.094 0.000 0.000 2.094 1/1 PRGT#run
60
+
61
+ * indicates recursively called methods
62
+ =end
63
+
64
+ class PrintingRecursiveGraphTest < TestCase
65
+ def setup
66
+ super
67
+ # WALL_TIME so we can use sleep in our test and get same measurements on linux and windows
68
+ @result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) do
69
+ PRGT.run
70
+ end
71
+ end
72
+
73
+ def test_printing_rescursive_graph
74
+ printer = RubyProf::GraphPrinter.new(@result)
75
+ buffer = ''
76
+ printer.print(StringIO.new(buffer))
77
+ puts buffer if ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1"
78
+
79
+ refute_nil(buffer)
80
+ end
81
+ end
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require_relative './call_tree_builder'
6
+
7
+ class ProfileTest < TestCase
8
+ def test_measure_mode
9
+ profile = RubyProf::Profile.new(:measure_mode => RubyProf::PROCESS_TIME)
10
+ assert_equal(RubyProf::PROCESS_TIME, profile.measure_mode)
11
+ end
12
+
13
+ def test_measure_mode_string
14
+ profile = RubyProf::Profile.new(:measure_mode => RubyProf::PROCESS_TIME)
15
+ assert_equal("process_time", profile.measure_mode_string)
16
+ end
17
+
18
+ def test_add_thread
19
+ profile = RubyProf::Profile.new
20
+ assert_empty(profile.threads)
21
+
22
+ method_info = RubyProf::MethodInfo.new(Array, :size)
23
+ call_tree = RubyProf::CallTree.new(method_info)
24
+ thread = RubyProf::Thread.new(call_tree, Thread.current, Fiber.current)
25
+
26
+ profile.add_thread(thread)
27
+ assert_equal(1, profile.threads.size)
28
+ assert(thread.equal?(profile.threads.first))
29
+ end
30
+
31
+ def test_add_threads
32
+ call_tree_1 = create_call_tree_1
33
+ ruby_thread_1 = Thread.new { }
34
+ thread_1 = RubyProf::Thread.new(call_tree_1, ruby_thread_1, Fiber.current)
35
+
36
+ call_tree_2 = create_call_tree_2
37
+ ruby_thread_2 = Thread.new { }
38
+ thread_2 = RubyProf::Thread.new(call_tree_2, ruby_thread_2, Fiber.current)
39
+
40
+ profile = RubyProf::Profile.new
41
+ profile.add_thread(thread_1)
42
+ profile.add_thread(thread_2)
43
+ assert_equal(1, profile.threads.count)
44
+ end
45
+
46
+ def test_add_fibers
47
+ call_tree_1 = create_call_tree_1
48
+ fiber_1 = Fiber.new { }
49
+ thread_1 = RubyProf::Thread.new(call_tree_1, Thread.current, fiber_1)
50
+
51
+ call_tree_2 = create_call_tree_2
52
+ fiber_2 = Fiber.new { }
53
+ thread_2 = RubyProf::Thread.new(call_tree_2, Thread.current, fiber_2)
54
+
55
+ profile = RubyProf::Profile.new
56
+ profile.add_thread(thread_1)
57
+ profile.add_thread(thread_2)
58
+ assert_equal(2, profile.threads.count)
59
+ end
60
+
61
+ def test_remove_thread
62
+ profile = RubyProf::Profile.new
63
+ assert_empty(profile.threads)
64
+
65
+ method_info = RubyProf::MethodInfo.new(Array, :size)
66
+ call_tree = RubyProf::CallTree.new(method_info)
67
+ thread = RubyProf::Thread.new(call_tree, Thread.current, Fiber.current)
68
+
69
+ profile.add_thread(thread)
70
+ assert_equal(1, profile.threads.size)
71
+ assert(thread.equal?(profile.threads.first))
72
+
73
+ removed = profile.remove_thread(thread)
74
+ assert_equal(0, profile.threads.size)
75
+ assert(removed.equal?(thread))
76
+ end
77
+
78
+ def test_merge
79
+ call_tree_1 = create_call_tree_1
80
+ fiber_1 = Thread.new { }
81
+ thread_1 = RubyProf::Thread.new(call_tree_1, Thread.current, fiber_1)
82
+
83
+ call_tree_2 = create_call_tree_2
84
+ fiber_2 = Thread.new { }
85
+ thread_2 = RubyProf::Thread.new(call_tree_2, Thread.current, fiber_2)
86
+
87
+ profile = RubyProf::Profile.new
88
+ profile.add_thread(thread_1)
89
+ profile.add_thread(thread_2)
90
+
91
+ profile.merge!
92
+ assert_equal(1, profile.threads.count)
93
+
94
+ assert_equal(thread_1, profile.threads.first)
95
+
96
+ assert_in_delta(11.6, thread_1.call_tree.total_time, 0.00001)
97
+ assert_in_delta(0, thread_1.call_tree.self_time, 0.00001)
98
+ assert_in_delta(0.0, thread_1.call_tree.wait_time, 0.00001)
99
+ assert_in_delta(11.6, thread_1.call_tree.children_time, 0.00001)
100
+ end
101
+ end
data/test/rack_test.rb ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class FakeRackApp
7
+ def call(env)
8
+ end
9
+ end
10
+
11
+ module Rack
12
+ class Request
13
+ def initialize(env)
14
+ if env == :fake_env
15
+ @env = {}
16
+ else
17
+ @env = env
18
+ end
19
+ end
20
+
21
+ def path
22
+ @env[:path] || '/path/to/resource.json'
23
+ end
24
+ end
25
+ end
26
+
27
+ class RackTest < TestCase
28
+ def test_create_print_path
29
+ path = Dir.mktmpdir
30
+ Dir.delete(path)
31
+
32
+ Rack::RubyProf.new(FakeRackApp.new, :path => path)
33
+
34
+ assert(Dir.exist?(path))
35
+ end
36
+
37
+ def test_create_profile_reports
38
+ path = Dir.mktmpdir
39
+
40
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path)
41
+
42
+ adapter.call(:fake_env)
43
+
44
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
45
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
46
+ assert(File.exist?(file_path))
47
+ end
48
+ end
49
+
50
+ def test_skip_paths
51
+ path = Dir.mktmpdir
52
+
53
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :skip_paths => [%r{\.json$}])
54
+
55
+ adapter.call(:fake_env)
56
+
57
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
58
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
59
+ assert(!File.exist?(file_path))
60
+ end
61
+ end
62
+
63
+ def test_only_paths
64
+ path = Dir.mktmpdir
65
+
66
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :only_paths => [%r{\.json$}])
67
+
68
+ adapter.call({path: '/path/to/resource.json'})
69
+
70
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
71
+ file_path = ::File.join(path, "path-to-resource.json-#{base_name}")
72
+ assert(File.exist?(file_path))
73
+ end
74
+
75
+ adapter.call({path: '/path/to/resource.html'})
76
+ %w(flat.txt graph.txt graph.html call_stack.html).each do |base_name|
77
+ file_path = ::File.join(path, "path-to-resource.html-#{base_name}")
78
+ assert(!File.exist?(file_path))
79
+ end
80
+ end
81
+
82
+ def test_allows_lazy_filename_setting
83
+ path = Dir.mktmpdir
84
+
85
+ printer = {::RubyProf::FlatPrinter => lambda { 'dynamic.txt' }}
86
+ adapter = Rack::RubyProf.new(FakeRackApp.new, :path => path, :printers => printer)
87
+
88
+ adapter.call(:fake_env)
89
+
90
+ file_path = ::File.join(path, 'path-to-resource.json-dynamic.txt')
91
+ assert(File.exist?(file_path))
92
+ end
93
+ end