ruby-prof 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. data/CHANGES +54 -1
  2. data/README +134 -7
  3. data/Rakefile +40 -58
  4. data/bin/ruby-prof +21 -6
  5. data/ext/extconf.rb +13 -0
  6. data/ext/measure_allocations.h +16 -1
  7. data/ext/measure_cpu_time.h +15 -3
  8. data/ext/measure_gc_runs.h +76 -0
  9. data/ext/measure_gc_time.h +57 -0
  10. data/ext/measure_memory.h +61 -2
  11. data/ext/measure_process_time.h +13 -2
  12. data/ext/measure_wall_time.h +12 -1
  13. data/ext/mingw/Rakefile +23 -0
  14. data/ext/mingw/build.rake +38 -0
  15. data/ext/ruby_prof.c +685 -633
  16. data/ext/ruby_prof.h +188 -0
  17. data/ext/vc/ruby_prof.sln +20 -0
  18. data/ext/vc/ruby_prof.vcproj +241 -0
  19. data/ext/version.h +4 -0
  20. data/lib/ruby-prof.rb +4 -0
  21. data/lib/ruby-prof/call_info.rb +47 -0
  22. data/lib/ruby-prof/call_tree_printer.rb +9 -1
  23. data/lib/ruby-prof/graph_html_printer.rb +6 -5
  24. data/lib/ruby-prof/graph_printer.rb +3 -2
  25. data/lib/ruby-prof/method_info.rb +85 -0
  26. data/lib/ruby-prof/task.rb +1 -2
  27. data/lib/ruby-prof/test.rb +148 -0
  28. data/rails/environment/profile.rb +24 -0
  29. data/rails/example/example_test.rb +9 -0
  30. data/rails/profile_test_helper.rb +21 -0
  31. data/test/basic_test.rb +173 -80
  32. data/test/duplicate_names_test.rb +2 -3
  33. data/test/exceptions_test.rb +15 -0
  34. data/test/exclude_threads_test.rb +54 -0
  35. data/test/line_number_test.rb +18 -14
  36. data/test/measurement_test.rb +121 -0
  37. data/test/module_test.rb +5 -8
  38. data/test/no_method_class_test.rb +4 -5
  39. data/test/prime.rb +3 -5
  40. data/test/prime_test.rb +1 -12
  41. data/test/printers_test.rb +10 -13
  42. data/test/profile_unit_test.rb +10 -12
  43. data/test/recursive_test.rb +202 -92
  44. data/test/singleton_test.rb +1 -2
  45. data/test/stack_test.rb +138 -0
  46. data/test/start_stop_test.rb +95 -0
  47. data/test/test_suite.rb +7 -3
  48. data/test/thread_test.rb +111 -87
  49. data/test/unique_call_path_test.rb +206 -0
  50. metadata +40 -42
  51. data/ext/extconf.rb.rej +0 -13
  52. data/lib/ruby-prof/call_tree_printer.rb.rej +0 -27
  53. data/lib/ruby-prof/profile_test_case.rb +0 -80
  54. data/rails_plugin/ruby-prof/init.rb +0 -8
  55. data/rails_plugin/ruby-prof/lib/profiling.rb +0 -57
  56. data/test/measure_mode_test.rb +0 -79
  57. data/test/prime1.rb +0 -17
  58. data/test/prime2.rb +0 -26
  59. data/test/prime3.rb +0 -17
  60. data/test/start_test.rb +0 -24
  61. data/test/test_helper.rb +0 -55
  62. data/test/timing_test.rb +0 -133
@@ -0,0 +1,4 @@
1
+ #define RUBY_PROF_VERSION "0.7.0"
2
+ #define RUBY_PROF_VERSION_MAJ 0
3
+ #define RUBY_PROF_VERSION_MIN 7
4
+ #define RUBY_PROF_VERSION_MIC 0
@@ -1,10 +1,14 @@
1
1
  require "ruby_prof.so"
2
2
 
3
+ require "ruby-prof/method_info"
4
+ require "ruby-prof/call_info"
3
5
  require "ruby-prof/flat_printer"
4
6
  require "ruby-prof/graph_printer"
5
7
  require "ruby-prof/graph_html_printer"
6
8
  require "ruby-prof/call_tree_printer"
7
9
 
10
+ require "ruby-prof/test"
11
+
8
12
  module RubyProf
9
13
  # See if the user specified the clock mode via
10
14
  # the RUBY_PROF_MEASURE_MODE environment variable
@@ -0,0 +1,47 @@
1
+ module RubyProf
2
+ class CallInfo
3
+ def depth
4
+ result = 0
5
+ call_info = self.parent
6
+
7
+ while call_info
8
+ result += 1
9
+ call_info = call_info.parent
10
+ end
11
+ result
12
+ end
13
+
14
+ def children_time
15
+ children.inject(0) do |sum, call_info|
16
+ sum += call_info.total_time
17
+ end
18
+ end
19
+
20
+ def stack
21
+ @stack ||= begin
22
+ methods = Array.new
23
+ call_info = self
24
+
25
+ while call_info
26
+ methods << call_info.target
27
+ call_info = call_info.parent
28
+ end
29
+ methods.reverse
30
+ end
31
+ end
32
+
33
+ def call_sequence
34
+ @call_sequence ||= begin
35
+ stack.map {|method| method.full_name}.join('->')
36
+ end
37
+ end
38
+
39
+ def root?
40
+ self.parent.nil?
41
+ end
42
+
43
+ def to_s
44
+ "#{call_sequence}"
45
+ end
46
+ end
47
+ end
@@ -27,8 +27,16 @@ module RubyProf
27
27
  when RubyProf.const_defined?(:MEMORY) && RubyProf::MEMORY
28
28
  @value_scale = 1
29
29
  @output << 'memory'
30
+ when RubyProf.const_defined?(:GC_RUNS) && RubyProf::GC_RUNS
31
+ @value_scale = 1
32
+ @output << 'gc_runs'
33
+ when RubyProf.const_defined?(:GC_TIME) && RubyProf::GC_TIME
34
+ @value_scale = 1000000
35
+ @output << 'gc_time'
36
+ else
37
+ raise "Unknown measure mode: #{RubyProf.measure_mode}"
30
38
  end
31
- @output << "\n\n"
39
+ @output << "\n\n"
32
40
 
33
41
  print_threads
34
42
  end
@@ -115,6 +115,7 @@ module RubyProf
115
115
  font-family: Verdana, Arial, Helvetica, sans-serif;
116
116
  font-size: 9pt;
117
117
  line-height: normal;
118
+ width: 100%;
118
119
  }
119
120
 
120
121
  th {
@@ -152,7 +153,6 @@ module RubyProf
152
153
 
153
154
  .method_name {
154
155
  text-align: left;
155
- max-width: 25em;
156
156
  }
157
157
  </style>
158
158
  </head>
@@ -198,8 +198,9 @@ module RubyProf
198
198
  self_percentage = (method.self_time/total_time) * 100 %>
199
199
 
200
200
  <!-- Parents -->
201
- <% for caller in method.parents %>
202
- <% next if min_time && caller.total_time < min_time %>
201
+ <% for caller in method.call_infos
202
+ next unless caller.parent
203
+ next if min_time && caller.total_time < min_time %>
203
204
  <tr>
204
205
  <td>&nbsp;</td>
205
206
  <td>&nbsp;</td>
@@ -209,8 +210,8 @@ module RubyProf
209
210
  <td><%= sprintf("%#{TIME_WIDTH}.2f", caller.children_time) %></td>
210
211
  <% called = "#{caller.called}/#{method.called}" %>
211
212
  <td><%= sprintf("%#{CALL_WIDTH}s", called) %></td>
212
- <td class="method_name"><%= create_link(thread_id, caller.target) %></td>
213
- <td><a href="file://<%=h srcfile=File.expand_path(caller.target.source_file) %>#line=<%= linenum=caller.line %>" title="<%=h srcfile %>:<%= linenum %>"><%= caller.line %></a></td>
213
+ <td class="method_name"><%= create_link(thread_id, caller.parent.target) %></td>
214
+ <td><a href="file://<%=h srcfile=File.expand_path(caller.parent.target.source_file) %>#line=<%= linenum=caller.line %>" title="<%=h srcfile %>:<%= linenum %>"><%= caller.line %></a></td>
214
215
  </tr>
215
216
  <% end %>
216
217
 
@@ -127,7 +127,8 @@ module RubyProf
127
127
  end
128
128
 
129
129
  def print_parents(thread_id, method)
130
- method.parents.each do |caller|
130
+ method.call_infos.each do |caller|
131
+ next unless caller.parent
131
132
  @output << " " * 2 * PERCENTAGE_WIDTH
132
133
  @output << sprintf("%#{TIME_WIDTH}.2f", caller.total_time)
133
134
  @output << sprintf("%#{TIME_WIDTH}.2f", caller.self_time)
@@ -136,7 +137,7 @@ module RubyProf
136
137
 
137
138
  call_called = "#{caller.called}/#{method.called}"
138
139
  @output << sprintf("%#{CALL_WIDTH}s", call_called)
139
- @output << sprintf(" %s", caller.target.full_name)
140
+ @output << sprintf(" %s", caller.parent.target.full_name)
140
141
  @output << "\n"
141
142
  end
142
143
  end
@@ -0,0 +1,85 @@
1
+ module RubyProf
2
+ class MethodInfo
3
+ include Comparable
4
+
5
+ def <=>(other)
6
+ if self.total_time < other.total_time
7
+ -1
8
+ elsif self.total_time > other.total_time
9
+ 1
10
+ elsif self.min_depth < other.min_depth
11
+ 1
12
+ elsif self.min_depth > other.min_depth
13
+ -1
14
+ else
15
+ -1 * (self.full_name <=> other.full_name)
16
+ end
17
+ end
18
+
19
+ def called
20
+ @called ||= begin
21
+ call_infos.inject(0) do |sum, call_info|
22
+ sum += call_info.called
23
+ end
24
+ end
25
+ end
26
+
27
+ def total_time
28
+ @total_time ||= begin
29
+ call_infos.inject(0) do |sum, call_info|
30
+ sum += call_info.total_time
31
+ end
32
+ end
33
+ end
34
+
35
+ def self_time
36
+ @self_time ||= begin
37
+ call_infos.inject(0) do |sum, call_info|
38
+ sum += call_info.self_time
39
+ end
40
+ end
41
+ end
42
+
43
+ def wait_time
44
+ @wait_time ||= begin
45
+ call_infos.inject(0) do |sum, call_info|
46
+ sum += call_info.wait_time
47
+ end
48
+ end
49
+ end
50
+
51
+ def children
52
+ @children ||= begin
53
+ call_infos.map do |call_info|
54
+ call_info.children
55
+ end.flatten
56
+ end
57
+ end
58
+
59
+ def children_time
60
+ @children_time ||= begin
61
+ call_infos.inject(0) do |sum, call_info|
62
+ sum += call_info.children_time
63
+ end
64
+ end
65
+ end
66
+
67
+ def min_depth
68
+ call_infos.map do |call_info|
69
+ call_info.depth
70
+ end.min
71
+ end
72
+
73
+ def root?
74
+ @root ||= begin
75
+ call_infos.find do |call_info|
76
+ not call_info.root?
77
+ end.nil?
78
+ end
79
+ end
80
+
81
+ def to_s
82
+ full_name
83
+ end
84
+ end
85
+ end
@@ -143,5 +143,4 @@ module RubyProf
143
143
  ENV['OPTIONS'] || @options.join(" ") || ""
144
144
  end
145
145
  end
146
- end
147
-
146
+ end
@@ -0,0 +1,148 @@
1
+ # Now load ruby-prof and away we go
2
+ require 'fileutils'
3
+ require 'ruby-prof'
4
+ require 'benchmark'
5
+
6
+ module RubyProf
7
+ module Test
8
+ PROFILE_OPTIONS = {
9
+ :measure_modes => [RubyProf::PROCESS_TIME],
10
+ :count => 10,
11
+ :printers => [RubyProf::FlatPrinter, RubyProf::GraphHtmlPrinter],
12
+ :min_percent => 0.05,
13
+ :output_dir => Dir.pwd }
14
+
15
+ def output_dir
16
+ PROFILE_OPTIONS[:output_dir]
17
+ end
18
+
19
+ def run(result)
20
+ return if @method_name.to_s == "default_test"
21
+
22
+ yield(self.class::STARTED, name)
23
+ @_result = result
24
+ run_warmup
25
+ PROFILE_OPTIONS[:measure_modes].each do |measure_mode|
26
+ data = run_profile(measure_mode)
27
+ report_profile(data, measure_mode)
28
+ result.add_run
29
+ end
30
+ yield(self.class::FINISHED, name)
31
+ end
32
+
33
+ def run_test
34
+ begin
35
+ setup
36
+ yield
37
+ rescue ::Test::Unit::AssertionFailedError => e
38
+ add_failure(e.message, e.backtrace)
39
+ rescue StandardError, ScriptError
40
+ add_error($!)
41
+ ensure
42
+ begin
43
+ teardown
44
+ rescue ::Test::Unit::AssertionFailedError => e
45
+ add_failure(e.message, e.backtrace)
46
+ rescue StandardError, ScriptError
47
+ add_error($!)
48
+ end
49
+ end
50
+ end
51
+
52
+ def run_warmup
53
+ print "\n#{self.class.name}##{method_name}"
54
+
55
+ run_test do
56
+ bench = Benchmark.realtime do
57
+ __send__(@method_name)
58
+ end
59
+ puts " (%.2fs warmup)" % bench
60
+ end
61
+ end
62
+
63
+ def run_profile(measure_mode)
64
+ RubyProf.measure_mode = measure_mode
65
+
66
+ print ' '
67
+ PROFILE_OPTIONS[:count].times do |i|
68
+ run_test do
69
+ begin
70
+ print '.'
71
+ $stdout.flush
72
+ GC.disable
73
+
74
+ RubyProf.resume do
75
+ __send__(@method_name)
76
+ end
77
+ ensure
78
+ GC.enable
79
+ end
80
+ end
81
+ end
82
+
83
+ data = RubyProf.stop
84
+ bench = data.threads.values.inject(0) do |total, method_infos|
85
+ top = method_infos.sort.last
86
+ total += top.total_time
87
+ total
88
+ end
89
+
90
+ puts "\n #{measure_mode_name(measure_mode)}: #{format_profile_total(bench, measure_mode)}\n"
91
+
92
+ data
93
+ end
94
+
95
+ def format_profile_total(total, measure_mode)
96
+ case measure_mode
97
+ when RubyProf::PROCESS_TIME, RubyProf::WALL_TIME
98
+ "%.2f seconds" % total
99
+ when RubyProf::MEMORY
100
+ "%.2f kilobytes" % total
101
+ when RubyProf::ALLOCATIONS
102
+ "%d allocations" % total
103
+ else
104
+ "%.2f #{measure_mode}"
105
+ end
106
+ end
107
+
108
+ def report_profile(data, measure_mode)
109
+ PROFILE_OPTIONS[:printers].each do |printer_klass|
110
+ printer = printer_klass.new(data)
111
+
112
+ # Makes sure the output directory exits
113
+ FileUtils.mkdir_p(output_dir)
114
+
115
+ # Open the file
116
+ file_name = report_filename(printer, measure_mode)
117
+
118
+ File.open(file_name, 'wb') do |file|
119
+ printer.print(file, PROFILE_OPTIONS)
120
+ end
121
+ end
122
+ end
123
+
124
+ # The report filename is test_name + measure_mode + report_type
125
+ def report_filename(printer, measure_mode)
126
+ suffix =
127
+ case printer
128
+ when RubyProf::FlatPrinter; 'flat.txt'
129
+ when RubyProf::GraphPrinter; 'graph.txt'
130
+ when RubyProf::GraphHtmlPrinter; 'graph.html'
131
+ when RubyProf::CallTreePrinter; 'tree.txt'
132
+ else printer.to_s.downcase
133
+ end
134
+
135
+ "#{output_dir}/#{method_name}_#{measure_mode_name(measure_mode)}_#{suffix}"
136
+ end
137
+
138
+ def measure_mode_name(measure_mode)
139
+ case measure_mode
140
+ when RubyProf::PROCESS_TIME; 'process_time'
141
+ when RubyProf::WALL_TIME; 'wall_time'
142
+ when RubyProf::MEMORY; 'memory'
143
+ when RubyProf::ALLOCATIONS; 'allocations'
144
+ else "measure#{measure_mode}"
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,24 @@
1
+ # Settings specified here will take precedence over those in config/environment.rb
2
+ # The profile environment should match the same settings
3
+ # as the production environment to give a reasonalbe
4
+ # approximation of performance. However, it should
5
+ # definitely not use the production databse!
6
+
7
+
8
+ # Cache classes - otherwise your code
9
+ # will run approximately 5 times slower and the
10
+ # profiling results will be overwhelmed by Rails
11
+ # dependency loading mechanism
12
+ config.cache_classes = true
13
+
14
+ # Don't check template timestamps - once again this
15
+ # is to avoid IO times overwhelming profile results
16
+ config.action_view.cache_template_loading = true
17
+
18
+ # This is debatable, but turn off action controller
19
+ # caching to see how long it really takes to run
20
+ # queries and render templates
21
+ config.action_controller.perform_caching = false
22
+
23
+ # Turn off most logging
24
+ config.log_level = :info
@@ -0,0 +1,9 @@
1
+ require File.dirname(__FILE__) + '../profile_test_helper'
2
+
3
+ class ExampleTest < Test::Unit::TestCase
4
+ include RubyProf::Test
5
+
6
+ def test_stuff
7
+ puts "Test method"
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # Load profile environment
2
+ env = ENV["RAILS_ENV"] = "profile"
3
+ require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
4
+
5
+ # Load Rails testing infrastructure
6
+ require 'test_help'
7
+
8
+ # Now we can load test_helper since we've already loaded the
9
+ # profile RAILS environment.
10
+ require File.expand_path(File.join(RAILS_ROOT, 'test', 'test_helper'))
11
+
12
+ # Reset the current environment back to profile
13
+ # since test_helper reset it to test
14
+ ENV["RAILS_ENV"] = env
15
+
16
+ # Now load ruby-prof and away we go
17
+ require 'ruby-prof'
18
+
19
+ # Setup output directory to Rails tmp directory
20
+ RubyProf::Test::PROFILE_OPTIONS[:output_dir] =
21
+ File.expand_path(File.join(RAILS_ROOT, 'tmp', 'profile'))
@@ -2,10 +2,6 @@
2
2
 
3
3
  require 'test/unit'
4
4
  require 'ruby-prof'
5
- require 'test_helper'
6
-
7
- # Need to use wall time for this test due to the sleep calls
8
- RubyProf::measure_mode = RubyProf::WALL_TIME
9
5
 
10
6
  class C1
11
7
  def C1.hello
@@ -55,6 +51,11 @@ class C6
55
51
  end
56
52
 
57
53
  class BasicTest < Test::Unit::TestCase
54
+ def setup
55
+ # Need to use wall time for this test due to the sleep calls
56
+ RubyProf::measure_mode = RubyProf::WALL_TIME
57
+ end
58
+
58
59
  def test_running
59
60
  assert(!RubyProf.running?)
60
61
  RubyProf.start
@@ -62,13 +63,13 @@ class BasicTest < Test::Unit::TestCase
62
63
  RubyProf.stop
63
64
  assert(!RubyProf.running?)
64
65
  end
65
-
66
+
66
67
  def test_double_profile
67
68
  RubyProf.start
68
69
  assert_raise(RuntimeError) do
69
70
  RubyProf.start
70
71
  end
71
-
72
+
72
73
  assert_raise(RuntimeError) do
73
74
  RubyProf.profile do
74
75
  puts 1
@@ -76,115 +77,207 @@ class BasicTest < Test::Unit::TestCase
76
77
  end
77
78
  RubyProf.stop
78
79
  end
79
-
80
+
80
81
  def test_no_block
81
82
  assert_raise(ArgumentError) do
82
83
  RubyProf.profile
83
84
  end
84
85
  end
85
-
86
- def test_class_and_instance_methods
86
+
87
+ def test_class_methods
87
88
  result = RubyProf.profile do
88
89
  C1.hello
89
- C1.new.hello
90
90
  end
91
-
92
- methods = result.threads.values.first
93
-
94
- # Length should be 7:
95
- # 1 test_class_and_instance_methods (this method)
96
- # 1 Class.new
97
- # 1 Class:Object allocate
98
- # 1 for Object.initialize
99
- # 1 for Class hello
100
- # 1 for Object hello
101
- # 1 sleep
102
- assert_equal(7, methods.length)
103
-
91
+
92
+ # Length should be 3:
93
+ # BasicTest#test_class_methods
94
+ # <Class::C1>#hello
95
+ # Kernel#sleep
96
+
97
+ methods = result.threads.values.first.sort.reverse
98
+ assert_equal(3, methods.length)
99
+
104
100
  # Check the names
105
- methods = methods.sort.reverse
106
-
107
- assert_equal('BasicTest#test_class_and_instance_methods', methods[0].full_name)
108
- assert_equal('Kernel#sleep', methods[1].full_name)
109
- assert_equal('C1#hello', methods[2].full_name)
110
- assert_equal('<Class::C1>#hello', methods[3].full_name)
111
-
112
- # The last three methods have total times of zero
113
- assert_equal(0, methods[4].total_time)
114
- assert_equal(0, methods[5].total_time)
115
- assert_equal(0, methods[6].total_time)
116
-
117
- #assert_equal('Class#new', methods[4].full_name)
118
- #assert_equal('<Class::Object>#allocate', methods[5].full_name)
119
- #assert_equal('Object#initialize', methods[6].full_name)
101
+ assert_equal('BasicTest#test_class_methods', methods[0].full_name)
102
+ assert_equal('<Class::C1>#hello', methods[1].full_name)
103
+ assert_equal('Kernel#sleep', methods[2].full_name)
104
+
105
+ # Check times
106
+ assert_in_delta(0.1, methods[0].total_time, 0.01)
107
+ assert_in_delta(0, methods[0].wait_time, 0.01)
108
+ assert_in_delta(0, methods[0].self_time, 0.01)
109
+
110
+ assert_in_delta(0.1, methods[1].total_time, 0.01)
111
+ assert_in_delta(0, methods[1].wait_time, 0.01)
112
+ assert_in_delta(0, methods[1].self_time, 0.01)
113
+
114
+ assert_in_delta(0.1, methods[2].total_time, 0.01)
115
+ assert_in_delta(0, methods[2].wait_time, 0.01)
116
+ assert_in_delta(0.1, methods[2].self_time, 0.01)
120
117
  end
121
-
118
+
119
+ def test_instance_methods
120
+ result = RubyProf.profile do
121
+ C1.new.hello
122
+ end
123
+
124
+ # Methods called
125
+ # BasicTest#test_instance_methods
126
+ # Class.new
127
+ # Class:Object#allocate
128
+ # for Object#initialize
129
+ # C1#hello
130
+ # Kernel#sleep
131
+
132
+ methods = result.threads.values.first.sort.reverse
133
+ assert_equal(6, methods.length)
134
+
135
+ assert_equal('BasicTest#test_instance_methods', methods[0].full_name)
136
+ assert_equal('C1#hello', methods[1].full_name)
137
+ assert_equal('Kernel#sleep', methods[2].full_name)
138
+ assert_equal('Class#new', methods[3].full_name)
139
+ assert_equal('<Class::Object>#allocate', methods[4].full_name)
140
+ assert_equal('Object#initialize', methods[5].full_name)
141
+
142
+ # Check times
143
+ assert_in_delta(0.2, methods[0].total_time, 0.01)
144
+ assert_in_delta(0, methods[0].wait_time, 0.01)
145
+ assert_in_delta(0, methods[0].self_time, 0.01)
146
+
147
+ assert_in_delta(0.2, methods[1].total_time, 0.01)
148
+ assert_in_delta(0, methods[1].wait_time, 0.01)
149
+ assert_in_delta(0, methods[1].self_time, 0.01)
150
+
151
+ assert_in_delta(0.2, methods[2].total_time, 0.01)
152
+ assert_in_delta(0, methods[2].wait_time, 0.01)
153
+ assert_in_delta(0.2, methods[2].self_time, 0.01)
154
+
155
+ assert_in_delta(0, methods[3].total_time, 0.01)
156
+ assert_in_delta(0, methods[3].wait_time, 0.01)
157
+ assert_in_delta(0, methods[3].self_time, 0.01)
158
+
159
+ assert_in_delta(0, methods[4].total_time, 0.01)
160
+ assert_in_delta(0, methods[4].wait_time, 0.01)
161
+ assert_in_delta(0, methods[4].self_time, 0.01)
162
+
163
+ assert_in_delta(0, methods[5].total_time, 0.01)
164
+ assert_in_delta(0, methods[5].wait_time, 0.01)
165
+ assert_in_delta(0, methods[5].self_time, 0.01)
166
+ end
167
+
122
168
  def test_module_methods
123
169
  result = RubyProf.profile do
124
170
  C2.hello
171
+ end
172
+
173
+ # Methods:
174
+ # BasicTest#test_module_methods
175
+ # M1#hello
176
+ # Kernel#sleep
177
+
178
+ methods = result.threads.values.first.sort.reverse
179
+ assert_equal(3, methods.length)
180
+
181
+ assert_equal('BasicTest#test_module_methods', methods[0].full_name)
182
+ assert_equal('M1#hello', methods[1].full_name)
183
+ assert_equal('Kernel#sleep', methods[2].full_name)
184
+
185
+ # Check times
186
+ assert_in_delta(0.3, methods[0].total_time, 0.01)
187
+ assert_in_delta(0, methods[0].wait_time, 0.01)
188
+ assert_in_delta(0, methods[0].self_time, 0.01)
189
+
190
+ assert_in_delta(0.3, methods[1].total_time, 0.01)
191
+ assert_in_delta(0, methods[1].wait_time, 0.01)
192
+ assert_in_delta(0, methods[1].self_time, 0.01)
193
+
194
+ assert_in_delta(0.3, methods[2].total_time, 0.01)
195
+ assert_in_delta(0, methods[2].wait_time, 0.01)
196
+ assert_in_delta(0.3, methods[2].self_time, 0.01)
197
+ end
198
+
199
+ def test_module_instance_methods
200
+ result = RubyProf.profile do
125
201
  C2.new.hello
126
202
  end
127
-
128
- methods = result.threads.values.first
129
-
130
- # Length should be 6:
131
- # 1 BasicTest#test_module_methods (this method)
132
- # 1 Class#new
133
- # 1 <Class::Object>#allocate
134
- # 1 Object#initialize
135
- # 1 M1#hello
136
- # 1 Kernel#sleep
137
203
 
204
+ # Methods:
205
+ # BasicTest#test_module_instance_methods
206
+ # Class#new
207
+ # <Class::Object>#allocate
208
+ # Object#initialize
209
+ # M1#hello
210
+ # Kernel#sleep
211
+
212
+ methods = result.threads.values.first.sort.reverse
138
213
  assert_equal(6, methods.length)
139
214
 
140
- # Check the names
141
- methods = methods.sort.reverse
142
-
143
- assert_equal('BasicTest#test_module_methods', methods[0].full_name)
144
- assert_equal('Kernel#sleep', methods[1].full_name)
145
- assert_equal('M1#hello', methods[2].full_name)
146
-
147
- # The last three methods have times of zero
148
- assert_equal(0, methods[3].total_time)
149
- assert_equal(0, methods[4].total_time)
150
- assert_equal(0, methods[5].total_time)
151
-
152
- #assert_equal('<Class::Object>#allocate', methods[3].full_name)
153
- #assert_equal('Class#new', methods[4].full_name)
154
- #assert_equal('Object#initialize', methods[5].full_name)
215
+ assert_equal('BasicTest#test_module_instance_methods', methods[0].full_name)
216
+ assert_equal('M1#hello', methods[1].full_name)
217
+ assert_equal('Kernel#sleep', methods[2].full_name)
218
+ assert_equal('Class#new', methods[3].full_name)
219
+ assert_equal('<Class::Object>#allocate', methods[4].full_name)
220
+ assert_equal('Object#initialize', methods[5].full_name)
221
+
222
+ # Check times
223
+ assert_in_delta(0.3, methods[0].total_time, 0.01)
224
+ assert_in_delta(0, methods[0].wait_time, 0.01)
225
+ assert_in_delta(0, methods[0].self_time, 0.01)
226
+
227
+ assert_in_delta(0.3, methods[1].total_time, 0.01)
228
+ assert_in_delta(0, methods[1].wait_time, 0.01)
229
+ assert_in_delta(0, methods[1].self_time, 0.01)
230
+
231
+ assert_in_delta(0.3, methods[2].total_time, 0.01)
232
+ assert_in_delta(0, methods[2].wait_time, 0.01)
233
+ assert_in_delta(0.3, methods[2].self_time, 0.01)
234
+
235
+ assert_in_delta(0, methods[3].total_time, 0.01)
236
+ assert_in_delta(0, methods[3].wait_time, 0.01)
237
+ assert_in_delta(0, methods[3].self_time, 0.01)
238
+
239
+ assert_in_delta(0, methods[4].total_time, 0.01)
240
+ assert_in_delta(0, methods[4].wait_time, 0.01)
241
+ assert_in_delta(0, methods[4].self_time, 0.01)
242
+
243
+ assert_in_delta(0, methods[5].total_time, 0.01)
244
+ assert_in_delta(0, methods[5].wait_time, 0.01)
245
+ assert_in_delta(0, methods[5].self_time, 0.01)
155
246
  end
156
-
247
+
157
248
  def test_singleton
158
249
  c3 = C3.new
159
-
250
+
160
251
  class << c3
161
252
  def hello
162
253
  end
163
254
  end
164
-
255
+
165
256
  result = RubyProf.profile do
166
257
  c3.hello
167
258
  end
168
-
169
- methods = result.threads.values.first
170
-
171
- # Length should be 2 - one for top level
172
- # and one for the singleton method.
259
+
260
+ methods = result.threads.values.first.sort.reverse
173
261
  assert_equal(2, methods.length)
174
-
175
- # Check singleton method
176
- methods = methods.sort.reverse
177
-
262
+
178
263
  assert_equal('BasicTest#test_singleton', methods[0].full_name)
179
264
  assert_equal('<Object::C3>#hello', methods[1].full_name)
265
+
266
+ assert_in_delta(0, methods[0].total_time, 0.01)
267
+ assert_in_delta(0, methods[0].wait_time, 0.01)
268
+ assert_in_delta(0, methods[0].self_time, 0.01)
269
+
270
+ assert_in_delta(0, methods[1].total_time, 0.01)
271
+ assert_in_delta(0, methods[1].wait_time, 0.01)
272
+ assert_in_delta(0, methods[1].self_time, 0.01)
180
273
  end
181
-
274
+
182
275
  def test_traceback
183
276
  RubyProf.start
184
277
  assert_raise(NoMethodError) do
185
278
  RubyProf.xxx
186
279
  end
187
-
280
+
188
281
  RubyProf.stop
189
- end
190
- end
282
+ end
283
+ end