ruby-prof 1.7.1 → 2.0.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 (134) hide show
  1. checksums.yaml +4 -4
  2. data/{CHANGES → CHANGELOG.md} +118 -176
  3. data/README.md +5 -5
  4. data/bin/ruby-prof +1 -4
  5. data/docs/advanced-usage.md +132 -0
  6. data/docs/alternatives.md +98 -0
  7. data/docs/architecture.md +122 -0
  8. data/docs/best-practices.md +27 -0
  9. data/docs/getting-started.md +130 -0
  10. data/docs/history.md +11 -0
  11. data/docs/index.md +45 -0
  12. data/docs/profiling-rails.md +64 -0
  13. data/docs/public/examples/example.rb +33 -0
  14. data/docs/public/examples/generate_reports.rb +92 -0
  15. data/docs/public/examples/reports/call_info.txt +27 -0
  16. data/docs/public/examples/reports/call_stack.html +835 -0
  17. data/docs/public/examples/reports/callgrind.out +150 -0
  18. data/docs/public/examples/reports/flame_graph.html +408 -0
  19. data/docs/public/examples/reports/flat.txt +45 -0
  20. data/docs/public/examples/reports/graph.dot +129 -0
  21. data/docs/public/examples/reports/graph.html +1319 -0
  22. data/docs/public/examples/reports/graph.txt +100 -0
  23. data/docs/public/examples/reports/graphviz_viewer.html +1 -0
  24. data/docs/public/images/call_stack.png +0 -0
  25. data/docs/public/images/class_diagram.png +0 -0
  26. data/docs/public/images/dot_printer.png +0 -0
  27. data/docs/public/images/flame_graph.png +0 -0
  28. data/docs/public/images/flat.png +0 -0
  29. data/docs/public/images/graph.png +0 -0
  30. data/docs/public/images/graph_html.png +0 -0
  31. data/docs/public/images/ruby-prof-logo.svg +1 -0
  32. data/docs/reports.md +150 -0
  33. data/docs/stylesheets/extra.css +80 -0
  34. data/ext/ruby_prof/extconf.rb +23 -22
  35. data/ext/ruby_prof/rp_allocation.c +0 -15
  36. data/ext/ruby_prof/rp_allocation.h +29 -33
  37. data/ext/ruby_prof/rp_call_tree.c +3 -0
  38. data/ext/ruby_prof/rp_call_tree.h +1 -4
  39. data/ext/ruby_prof/rp_call_trees.c +296 -296
  40. data/ext/ruby_prof/rp_call_trees.h +25 -28
  41. data/ext/ruby_prof/rp_measure_allocations.c +47 -47
  42. data/ext/ruby_prof/rp_measure_process_time.c +64 -66
  43. data/ext/ruby_prof/rp_measure_wall_time.c +52 -64
  44. data/ext/ruby_prof/rp_measurement.c +0 -5
  45. data/ext/ruby_prof/rp_measurement.h +49 -53
  46. data/ext/ruby_prof/rp_method.c +554 -551
  47. data/ext/ruby_prof/rp_method.h +1 -4
  48. data/ext/ruby_prof/rp_profile.c +1 -1
  49. data/ext/ruby_prof/rp_profile.h +1 -5
  50. data/ext/ruby_prof/rp_stack.c +212 -212
  51. data/ext/ruby_prof/rp_stack.h +50 -53
  52. data/ext/ruby_prof/rp_thread.h +1 -4
  53. data/ext/ruby_prof/ruby_prof.c +50 -50
  54. data/ext/ruby_prof/ruby_prof.h +4 -6
  55. data/ext/ruby_prof/vc/ruby_prof.vcxproj +7 -8
  56. data/lib/ruby-prof/assets/call_stack_printer.html.erb +746 -711
  57. data/lib/ruby-prof/assets/flame_graph_printer.html.erb +412 -0
  58. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -355
  59. data/lib/ruby-prof/call_tree.rb +57 -57
  60. data/lib/ruby-prof/call_tree_visitor.rb +36 -36
  61. data/lib/ruby-prof/exclude_common_methods.rb +204 -204
  62. data/lib/ruby-prof/measurement.rb +17 -17
  63. data/lib/ruby-prof/printers/abstract_printer.rb +142 -138
  64. data/lib/ruby-prof/printers/call_info_printer.rb +53 -53
  65. data/lib/ruby-prof/printers/call_stack_printer.rb +168 -180
  66. data/lib/ruby-prof/printers/call_tree_printer.rb +132 -145
  67. data/lib/ruby-prof/printers/dot_printer.rb +177 -132
  68. data/lib/ruby-prof/printers/flame_graph_printer.rb +79 -0
  69. data/lib/ruby-prof/printers/flat_printer.rb +52 -52
  70. data/lib/ruby-prof/printers/graph_html_printer.rb +62 -63
  71. data/lib/ruby-prof/printers/graph_printer.rb +112 -113
  72. data/lib/ruby-prof/printers/multi_printer.rb +134 -127
  73. data/lib/ruby-prof/profile.rb +13 -0
  74. data/lib/ruby-prof/rack.rb +114 -105
  75. data/lib/ruby-prof/task.rb +147 -147
  76. data/lib/ruby-prof/thread.rb +20 -20
  77. data/lib/ruby-prof/version.rb +3 -3
  78. data/lib/ruby-prof.rb +50 -52
  79. data/lib/unprof.rb +10 -10
  80. data/ruby-prof.gemspec +66 -65
  81. data/test/abstract_printer_test.rb +25 -27
  82. data/test/alias_test.rb +203 -117
  83. data/test/call_tree_builder.rb +126 -126
  84. data/test/call_tree_visitor_test.rb +27 -27
  85. data/test/call_trees_test.rb +66 -66
  86. data/test/duplicate_names_test.rb +32 -32
  87. data/test/dynamic_method_test.rb +50 -62
  88. data/test/enumerable_test.rb +23 -21
  89. data/test/exceptions_test.rb +24 -24
  90. data/test/exclude_methods_test.rb +363 -257
  91. data/test/exclude_threads_test.rb +48 -48
  92. data/test/fiber_test.rb +195 -195
  93. data/test/gc_test.rb +104 -102
  94. data/test/inverse_call_tree_test.rb +174 -174
  95. data/test/line_number_test.rb +563 -289
  96. data/test/marshal_test.rb +144 -145
  97. data/test/measure_allocations.rb +26 -26
  98. data/test/measure_allocations_test.rb +1511 -1081
  99. data/test/measure_process_time_test.rb +3286 -2477
  100. data/test/measure_times.rb +56 -56
  101. data/test/measure_wall_time_test.rb +773 -568
  102. data/test/measurement_test.rb +82 -82
  103. data/test/merge_test.rb +146 -146
  104. data/test/method_info_test.rb +100 -95
  105. data/test/multi_printer_test.rb +52 -66
  106. data/test/no_method_class_test.rb +15 -15
  107. data/test/pause_resume_test.rb +171 -171
  108. data/test/prime.rb +54 -54
  109. data/test/prime_script.rb +5 -5
  110. data/test/printer_call_stack_test.rb +28 -27
  111. data/test/printer_call_tree_test.rb +30 -30
  112. data/test/printer_flame_graph_test.rb +82 -0
  113. data/test/printer_flat_test.rb +99 -99
  114. data/test/printer_graph_html_test.rb +62 -59
  115. data/test/printer_graph_test.rb +42 -40
  116. data/test/printers_test.rb +162 -135
  117. data/test/printing_recursive_graph_test.rb +81 -81
  118. data/test/profile_test.rb +101 -101
  119. data/test/rack_test.rb +103 -93
  120. data/test/recursive_test.rb +796 -622
  121. data/test/scheduler.rb +4 -0
  122. data/test/singleton_test.rb +39 -38
  123. data/test/stack_printer_test.rb +61 -61
  124. data/test/start_stop_test.rb +106 -106
  125. data/test/test_helper.rb +24 -20
  126. data/test/thread_test.rb +229 -231
  127. data/test/unique_call_path_test.rb +123 -136
  128. data/test/yarv_test.rb +56 -60
  129. metadata +68 -16
  130. data/ext/ruby_prof/rp_measure_memory.c +0 -46
  131. data/lib/ruby-prof/compatibility.rb +0 -113
  132. data/test/compatibility_test.rb +0 -49
  133. data/test/crash2.rb +0 -144
  134. data/test/measure_memory_test.rb +0 -1456
@@ -1,135 +1,162 @@
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 so we can use sleep in our test and get same measurements on linux and windows
15
- @result = RubyProf::Profile.profile(measure_mode: RubyProf::WALL_TIME) 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(:path => Dir.tmpdir)
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
- printer = RubyProf::DotPrinter.new(@result)
41
- File.open("#{Dir.tmpdir}/graph.dot", "w") {|f| printer.print(f)}
42
-
43
- printer = RubyProf::CallStackPrinter.new(@result)
44
- File.open("#{Dir.tmpdir}/stack.html", "w") {|f| printer.print(f, :application => "primes")}
45
-
46
- printer = RubyProf::MultiPrinter.new(@result)
47
- printer.print(:path => Dir.tmpdir, :profile => "multi", :application => "primes")
48
-
49
- ['graph.dot', 'multi.flat.txt', 'multi.graph.html', "multi.callgrind.out.#{$$}", 'multi.stack.html', 'stack.html'].each do |file_name|
50
- file_path = File.join(Dir.tmpdir, file_name)
51
- refute(File.empty?(file_path))
52
- end
53
- end
54
-
55
- def test_refuses_io_objects
56
- p = RubyProf::MultiPrinter.new(@result)
57
- begin
58
- p.print(STDOUT)
59
- flunk "should have raised an ArgumentError"
60
- rescue ArgumentError => e
61
- assert_match(/IO/, e.to_s)
62
- end
63
- end
64
-
65
- def test_refuses_non_hashes
66
- p = RubyProf::MultiPrinter.new (@result)
67
- begin
68
- p.print([])
69
- flunk "should have raised an ArgumentError"
70
- rescue ArgumentError => e
71
- assert_match(/hash/, e.to_s)
72
- end
73
- end
74
-
75
- def test_flat_string
76
- output = helper_test_flat_string(RubyProf::FlatPrinter)
77
- assert_match(/prime.rb/, output)
78
- end
79
-
80
- def helper_test_flat_string(klass)
81
- output = ''
82
-
83
- printer = klass.new(@result)
84
- printer.print(output)
85
-
86
- assert_match(/Thread ID: -?\d+/i, output)
87
- assert_match(/Fiber ID: -?\d+/i, output)
88
- assert_match(/Total: \d+\.\d+/i, output)
89
- assert_match(/Object#run_primes/i, output)
90
- output
91
- end
92
-
93
- def test_graph_html_string
94
- output = ''
95
- printer = RubyProf::GraphHtmlPrinter.new(@result)
96
- printer.print(output)
97
-
98
- assert_match(/<!DOCTYPE html>/i, output)
99
- assert_match( %r{<th>Total</th>}i, output)
100
- assert_match(/Object#run_primes/i, output)
101
- end
102
-
103
- def test_graph_string
104
- output = ''
105
- printer = RubyProf::GraphPrinter.new(@result)
106
- printer.print(output)
107
-
108
- assert_match(/Thread ID: -?\d+/i, output)
109
- assert_match(/Fiber ID: -?\d+/i, output)
110
- assert_match(/Total Time: \d+\.\d+/i, output)
111
- assert_match(/Object#run_primes/i, output)
112
- end
113
-
114
- def do_nothing
115
- start = Time.now
116
- while(Time.now == start)
117
- end
118
- end
119
-
120
- def test_all_with_small_percentiles
121
- result = RubyProf::Profile.profile do
122
- sleep 2
123
- do_nothing
124
- end
125
-
126
- # RubyProf::CallTreePrinter doesn't "do" a min_percent
127
- # RubyProf::FlatPrinter only outputs if self time > percent...
128
- for klass in [RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
129
- printer = klass.new(result)
130
- out = ''
131
- printer.print(out, :min_percent => 0.00000001)
132
- assert_match(/do_nothing/, out)
133
- end
134
- end
135
- end
1
+ # encoding: UTF-8
2
+
3
+ require File.expand_path('../test_helper', __FILE__)
4
+ require 'fileutils'
5
+ require 'stringio'
6
+ require 'tmpdir'
7
+ require_relative 'prime'
8
+
9
+ # -- Tests ----
10
+ class PrintersTest < TestCase
11
+ def setup
12
+ super
13
+ # WALL_TIME, PROCESS_TIME, ALLOCATIONS and MEMORY as types of measuremen
14
+ measure_modes = {wall_time: RubyProf::WALL_TIME, process_time: RubyProf::PROCESS_TIME, allocations: RubyProf::ALLOCATIONS}
15
+
16
+ @results = {}
17
+
18
+ measure_modes.each do |key, value|
19
+ @results[key] = RubyProf::Profile.profile(measure_mode: value) do
20
+ run_primes(1000, 5000)
21
+ end
22
+ end
23
+ end
24
+
25
+ def test_printers
26
+ output = ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1" ? STDOUT : StringIO.new
27
+
28
+ printer = RubyProf::CallStackPrinter.new(@results[:wall_time])
29
+ printer.print(output)
30
+
31
+ printer = RubyProf::CallTreePrinter.new(@results[:wall_time])
32
+ printer.print(path: Dir.tmpdir)
33
+
34
+ printer = RubyProf::FlatPrinter.new(@results[:wall_time])
35
+ printer.print(output)
36
+
37
+ printer = RubyProf::GraphHtmlPrinter.new(@results[:wall_time])
38
+ printer.print(output)
39
+
40
+ printer = RubyProf::GraphPrinter.new(@results[:wall_time])
41
+ printer.print(output)
42
+ end
43
+
44
+ def test_print_to_files
45
+ printer = RubyProf::DotPrinter.new(@results[:wall_time])
46
+ File.open("#{Dir.tmpdir}/graph.dot", "w") {|f| printer.print(f)}
47
+
48
+ printer = RubyProf::CallStackPrinter.new(@results[:wall_time])
49
+ File.open("#{Dir.tmpdir}/stack.html", "w") {|f| printer.print(f, application: "primes")}
50
+
51
+ printer = RubyProf::MultiPrinter.new(@results[:wall_time])
52
+ printer.print(path: Dir.tmpdir, profile: "multi", application: "primes")
53
+
54
+ ['graph.dot', 'multi.flat.txt', 'multi.graph.html', "multi.callgrind.out.#{$$}", 'multi.stack.html', 'stack.html'].each do |file_name|
55
+ file_path = File.join(Dir.tmpdir, file_name)
56
+ refute(File.empty?(file_path))
57
+ end
58
+ end
59
+
60
+ def test_refuses_positional_arguments
61
+ p = RubyProf::MultiPrinter.new(@results[:wall_time])
62
+ assert_raises(ArgumentError) do
63
+ p.print(STDOUT)
64
+ end
65
+ end
66
+
67
+ def test_flat_string
68
+ output = helper_test_flat_string(RubyProf::FlatPrinter)
69
+ assert_match(/prime.rb/, output.string)
70
+ end
71
+
72
+ def helper_test_flat_string(klass)
73
+ output = StringIO.new
74
+
75
+ printer = klass.new(@results[:wall_time])
76
+ printer.print(output)
77
+
78
+ assert_match(/Thread ID: -?\d+/i, output.string)
79
+ assert_match(/Fiber ID: -?\d+/i, output.string)
80
+ assert_match(/Total: \d+\.\d+/i, output.string)
81
+ assert_match(/Object#run_primes/i, output.string)
82
+ output
83
+ end
84
+
85
+ def test_graph_html_string
86
+ output = StringIO.new
87
+ printer = RubyProf::GraphHtmlPrinter.new(@results[:wall_time])
88
+ printer.print(output)
89
+
90
+ assert_match(/<!DOCTYPE html>/i, output.string)
91
+ assert_match( %r{<th>Total</th>}i, output.string)
92
+ assert_match(/Object#run_primes/i, output.string)
93
+ end
94
+
95
+ def test_graph_string
96
+ output = StringIO.new
97
+ printer = RubyProf::GraphPrinter.new(@results[:wall_time])
98
+ printer.print(output)
99
+
100
+ assert_match(/Thread ID: -?\d+/i, output.string)
101
+ assert_match(/Fiber ID: -?\d+/i, output.string)
102
+ assert_match(/Total Time: \d+\.\d+/i, output.string)
103
+ assert_match(/Object#run_primes/i, output.string)
104
+ end
105
+
106
+ def do_nothing
107
+ start = Time.now
108
+ while(Time.now == start)
109
+ end
110
+ end
111
+
112
+ def test_all_with_small_percentiles
113
+ result = RubyProf::Profile.profile do
114
+ sleep 2
115
+ do_nothing
116
+ end
117
+
118
+ # RubyProf::CallTreePrinter doesn't "do" a min_percent
119
+ # RubyProf::FlatPrinter only outputs if self time > percent...
120
+ for klass in [RubyProf::GraphPrinter, RubyProf::GraphHtmlPrinter]
121
+ printer = klass.new(result)
122
+ out = StringIO.new
123
+ printer.print(out, min_percent: 0.00000001)
124
+ assert_match(/do_nothing/, out.string)
125
+ end
126
+ end
127
+
128
+ def test_print_footer
129
+ results_keys = [:wall_time, :process_time, :allocations]
130
+ expected_matches = [
131
+ "The percentage of time spent by this method relative to the total time in the entire program.",
132
+ "The total time spent by this method and its children.",
133
+ "The time spent by this method.",
134
+ "The time spent by this method's children.",
135
+ "The percentage of allocations made by this method relative to the total allocations in the entire program.",
136
+ "The total number of allocations made by this method and its children.",
137
+ "The number of allocations made by this method.",
138
+ "The number of allocations made by this method's children.",
139
+ "The percentage of memory used by this method relative to the total memory in the entire program.",
140
+ "The total memory used by this method and its children.",
141
+ "The memory used by this method.",
142
+ "The memory used by this method's children."
143
+ ]
144
+
145
+ results_keys.each do |key|
146
+ output = StringIO.new
147
+ printer = RubyProf::GraphPrinter.new(@results[key])
148
+ printer.print(output)
149
+
150
+ case key
151
+ when :wall_time, :process_time
152
+ matches = expected_matches[0..3]
153
+ when :allocations
154
+ matches = expected_matches[4..7]
155
+ end
156
+
157
+ matches.each do |pattern|
158
+ assert_match(pattern, output.string)
159
+ end
160
+ end
161
+ end
162
+ end
@@ -1,81 +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
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 = StringIO.new
76
+ printer.print(buffer)
77
+ puts buffer.string if ENV['SHOW_RUBY_PROF_PRINTER_OUTPUT'] == "1"
78
+
79
+ refute_nil(buffer.string)
80
+ end
81
+ end
data/test/profile_test.rb CHANGED
@@ -1,101 +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
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