ruby-prof 0.11.3 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/CHANGES +27 -0
  2. data/README.rdoc +14 -14
  3. data/bin/ruby-prof +275 -266
  4. data/ext/ruby_prof/rp_call_info.c +33 -24
  5. data/ext/ruby_prof/rp_call_info.h +2 -1
  6. data/ext/ruby_prof/rp_measure.c +1 -1
  7. data/ext/ruby_prof/rp_measure.h +1 -1
  8. data/ext/ruby_prof/rp_measure_allocations.c +1 -1
  9. data/ext/ruby_prof/rp_measure_cpu_time.c +1 -1
  10. data/ext/ruby_prof/rp_measure_gc_runs.c +1 -1
  11. data/ext/ruby_prof/rp_measure_gc_time.c +1 -1
  12. data/ext/ruby_prof/rp_measure_memory.c +1 -1
  13. data/ext/ruby_prof/rp_measure_process_time.c +2 -2
  14. data/ext/ruby_prof/rp_measure_wall_time.c +2 -2
  15. data/ext/ruby_prof/rp_method.c +11 -24
  16. data/ext/ruby_prof/rp_method.h +2 -3
  17. data/ext/ruby_prof/rp_stack.c +48 -7
  18. data/ext/ruby_prof/rp_stack.h +3 -3
  19. data/ext/ruby_prof/rp_thread.c +26 -17
  20. data/ext/ruby_prof/rp_thread.h +3 -3
  21. data/ext/ruby_prof/ruby_prof.c +7 -86
  22. data/ext/ruby_prof/ruby_prof.h +1 -1
  23. data/ext/ruby_prof/vc/ruby_prof.sln +12 -6
  24. data/ext/ruby_prof/vc/ruby_prof_18.vcxproj +110 -0
  25. data/ext/ruby_prof/vc/{ruby_prof.vcxproj → ruby_prof_19.vcxproj} +4 -1
  26. data/ext/ruby_prof/vc/ruby_prof_20.vcxproj +112 -0
  27. data/ext/ruby_prof/version.h +4 -4
  28. data/lib/ruby-prof.rb +1 -0
  29. data/lib/ruby-prof/call_info.rb +1 -1
  30. data/lib/ruby-prof/call_info_visitor.rb +4 -2
  31. data/lib/ruby-prof/compatibility.rb +6 -1
  32. data/lib/ruby-prof/method_info.rb +1 -1
  33. data/lib/ruby-prof/printers/call_info_printer.rb +1 -1
  34. data/lib/ruby-prof/printers/call_stack_printer.rb +3 -3
  35. data/lib/ruby-prof/printers/dot_printer.rb +1 -1
  36. data/lib/ruby-prof/printers/flat_printer.rb +4 -4
  37. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +2 -2
  38. data/lib/ruby-prof/printers/graph_html_printer.rb +3 -3
  39. data/lib/ruby-prof/printers/graph_printer.rb +15 -15
  40. data/lib/ruby-prof/thread.rb +22 -0
  41. data/ruby-prof.gemspec +2 -1
  42. data/test/basic_test.rb +77 -45
  43. data/test/call_info_test.rb +78 -0
  44. data/test/call_info_visitor_test.rb +1 -1
  45. data/test/dynamic_method_test.rb +14 -8
  46. data/test/measure_cpu_time_test.rb +23 -12
  47. data/test/measure_process_time_test.rb +21 -170
  48. data/test/measure_wall_time_test.rb +59 -13
  49. data/test/method_elimination_test.rb +30 -19
  50. data/test/pause_resume_test.rb +129 -22
  51. data/test/prime.rb +0 -1
  52. data/test/printers_test.rb +7 -18
  53. data/test/recursive_test.rb +4 -48
  54. data/test/test_helper.rb +30 -10
  55. data/test/test_suite.rb +1 -2
  56. metadata +23 -5
  57. data/test/pause_test.rb +0 -57
  58. data/test/prime_test.rb +0 -13
@@ -1,7 +1,7 @@
1
- /* Copyright (C) 2005-2011 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
1
+ /* Copyright (C) 2005-2013 Shugo Maeda <shugo@ruby-lang.org> and Charlie Savage <cfis@savagexi.com>
2
2
  Please see the LICENSE file for copyright and distribution information */
3
3
 
4
- #define RUBY_PROF_VERSION "0.11.3" // as a string, for easy parsing from rake files
4
+ #define RUBY_PROF_VERSION "0.12.1" // as a string, for easy parsing from rake files
5
5
  #define RUBY_PROF_VERSION_MAJ 0
6
- #define RUBY_PROF_VERSION_MIN 11
7
- #define RUBY_PROF_VERSION_MIC 2
6
+ #define RUBY_PROF_VERSION_MIN 12
7
+ #define RUBY_PROF_VERSION_MIC 1
@@ -15,6 +15,7 @@ require 'ruby-prof/compatibility'
15
15
  require 'ruby-prof/method_info'
16
16
  require 'ruby-prof/profile'
17
17
  require 'ruby-prof/rack'
18
+ require 'ruby-prof/thread'
18
19
 
19
20
  require 'ruby-prof/printers/abstract_printer'
20
21
  require 'ruby-prof/printers/call_info_printer'
@@ -57,7 +57,7 @@ module RubyProf
57
57
  parent.children.delete(self)
58
58
  end
59
59
 
60
- # find a sepcific call in list of children. returns nil if not found.
60
+ # find a specific call in list of children. returns nil if not found.
61
61
  # note: there can't be more than one child with a given target method. in other words:
62
62
  # x.children.grep{|y|y.target==m}.size <= 1 for all method infos m and call infos x
63
63
  def find_call(other)
@@ -26,8 +26,10 @@ module RubyProf
26
26
  def visit(&block)
27
27
  @block = block
28
28
 
29
- self.thread.top_method.call_infos.each do |call_info|
30
- self.visit_call_info(call_info)
29
+ self.thread.top_methods.each do |method_info|
30
+ method_info.call_infos.each do |call_info|
31
+ self.visit_call_info(call_info)
32
+ end
31
33
  end
32
34
  end
33
35
 
@@ -91,6 +91,11 @@ module RubyProf
91
91
  end
92
92
 
93
93
  # Profiling
94
+ def self.start_script(script)
95
+ start
96
+ load script
97
+ end
98
+
94
99
  def self.start
95
100
  ensure_not_running!
96
101
  @profile = Profile.new(self.measure_mode, self.exclude_threads)
@@ -120,8 +125,8 @@ module RubyProf
120
125
 
121
126
  def self.stop
122
127
  ensure_running!
123
- disable_gc_stats_if_needed
124
128
  result = @profile.stop
129
+ disable_gc_stats_if_needed
125
130
  @profile = nil
126
131
  result
127
132
  end
@@ -14,7 +14,7 @@ module RubyProf
14
14
  elsif self.min_depth > other.min_depth
15
15
  -1
16
16
  else
17
- -1 * (self.full_name <=> other.full_name)
17
+ self.full_name <=> other.full_name
18
18
  end
19
19
  end
20
20
 
@@ -12,7 +12,7 @@ module RubyProf
12
12
 
13
13
  def print_header(thread)
14
14
  @output << "Thread ID: #{thread.id}\n"
15
- @output << "Total Time: #{thread.top_method.total_time}\n"
15
+ @output << "Total Time: #{thread.total_time}\n"
16
16
  @output << "Sort by: #{sort_method}\n"
17
17
  @output << "\n"
18
18
  end
@@ -45,12 +45,12 @@ module RubyProf
45
45
  print_header
46
46
 
47
47
  @overall_threads_time = @result.threads.inject(0) do |val, thread|
48
- val += thread.top_method.total_time
48
+ val += thread.total_time
49
49
  end
50
50
 
51
51
  @result.threads.each do |thread|
52
52
  @current_thread_id = thread.id
53
- @overall_time = thread.top_method.total_time
53
+ @overall_time = thread.total_time
54
54
  @output.print "<div class=\"thread\">Thread: #{thread.id} (#{"%4.2f%%" % ((@overall_time/@overall_threads_time)*100)} ~ #{@overall_time})</div>"
55
55
  @output.print "<ul name=\"thread\">"
56
56
  thread.methods.each do |m|
@@ -58,7 +58,7 @@ module RubyProf
58
58
  next unless m.root?
59
59
  m.call_infos.each do |ci|
60
60
  next unless ci.root?
61
- print_stack ci, thread.top_method.total_time
61
+ print_stack ci, thread.total_time
62
62
  end
63
63
  end
64
64
  @output.print "</ul>"
@@ -79,7 +79,7 @@ module RubyProf
79
79
  end
80
80
 
81
81
  def print_thread(thread)
82
- total_time = thread.top_method.total_time
82
+ total_time = thread.total_time
83
83
  thread.methods.sort_by(&sort_method).reverse_each do |method|
84
84
  total_percentage = (method.total_time/total_time) * 100
85
85
 
@@ -28,14 +28,14 @@ module RubyProf
28
28
 
29
29
  def print_header(thread)
30
30
  @output << "Thread ID: %d\n" % thread.id
31
- @output << "Total: %0.6f\n" % thread.top_method.total_time
31
+ @output << "Total: %0.6f\n" % thread.total_time
32
32
  @output << "Sort by: #{sort_method}\n"
33
33
  @output << "\n"
34
- @output << " %self total self wait child calls name\n"
34
+ @output << " %self total self wait child calls name\n"
35
35
  end
36
36
 
37
37
  def print_methods(thread)
38
- total_time = thread.top_method.total_time
38
+ total_time = thread.total_time
39
39
  methods = thread.methods.sort_by(&sort_method).reverse
40
40
 
41
41
  sum = 0
@@ -47,7 +47,7 @@ module RubyProf
47
47
  #self_time_called = method.called > 0 ? method.self_time/method.called : 0
48
48
  #total_time_called = method.called > 0? method.total_time/method.called : 0
49
49
 
50
- @output << "%6.2f %8.2f %8.2f %8.2f %8.2f %8d %s%s \n" % [
50
+ @output << "%6.2f %9.3f %9.3f %9.3f %9.3f %8d %s%s \n" % [
51
51
  method.self_time / total_time * 100, # %self
52
52
  method.total_time, # total
53
53
  method.self_time, # self
@@ -13,7 +13,7 @@ module RubyProf
13
13
  #
14
14
  class FlatPrinterWithLineNumbers < FlatPrinter
15
15
  def print_methods(thread)
16
- total_time = thread.top_method.total_time
16
+ total_time = thread.total_time
17
17
 
18
18
  methods = thread.methods.sort_by(&sort_method).reverse
19
19
  sum = 0
@@ -25,7 +25,7 @@ module RubyProf
25
25
  #self_time_called = method.called > 0 ? method.self_time/method.called : 0
26
26
  #total_time_called = method.called > 0? method.total_time/method.called : 0
27
27
 
28
- @output << "%6.2f %8.2f %8.2f %8.2f %8.2f %8d %s%s \n" % [
28
+ @output << "%6.2f %9.3f %9.3f %9.3f %9.3f %8d %s%s \n" % [
29
29
  method.self_time / total_time * 100, # %self
30
30
  method.total_time, # total
31
31
  method.self_time, # self
@@ -48,7 +48,7 @@ module RubyProf
48
48
  # specified by the user, since they will not be
49
49
  # printed out.
50
50
  def create_link(thread, method)
51
- overall_time = thread.top_method.total_time
51
+ overall_time = thread.total_time
52
52
  total_percent = (method.total_time/overall_time) * 100
53
53
  if total_percent < min_percent
54
54
  # Just return name
@@ -144,7 +144,7 @@ module RubyProf
144
144
  <% for thread in @result.threads %>
145
145
  <tr>
146
146
  <td><a href="#<%= thread.id %>"><%= thread.id %></a></td>
147
- <td><%= thread.top_method.total_time %></td>
147
+ <td><%= thread.total_time %></td>
148
148
  </tr>
149
149
  <% end %>
150
150
  </table>
@@ -152,7 +152,7 @@ module RubyProf
152
152
  <!-- Methods Tables -->
153
153
  <% for thread in @result.threads
154
154
  methods = thread.methods
155
- total_time = thread.top_method.total_time %>
155
+ total_time = thread.total_time %>
156
156
  <h2><a name="<%= thread.id %>">Thread <%= thread.id %></a></h2>
157
157
 
158
158
  <table>
@@ -15,14 +15,14 @@ module RubyProf
15
15
 
16
16
  class GraphPrinter < AbstractPrinter
17
17
  PERCENTAGE_WIDTH = 8
18
- TIME_WIDTH = 10
18
+ TIME_WIDTH = 11
19
19
  CALL_WIDTH = 17
20
20
 
21
21
  private
22
22
 
23
23
  def print_header(thread)
24
24
  @output << "Thread ID: #{thread.id}\n"
25
- @output << "Total Time: #{thread.top_method.total_time}\n"
25
+ @output << "Total Time: #{thread.total_time}\n"
26
26
  @output << "Sort by: #{sort_method}\n"
27
27
  @output << "\n"
28
28
 
@@ -39,7 +39,7 @@ module RubyProf
39
39
  end
40
40
 
41
41
  def print_methods(thread)
42
- total_time = thread.top_method.total_time
42
+ total_time = thread.total_time
43
43
  # Sort methods from longest to shortest total time
44
44
  methods = thread.methods.sort_by(&sort_method)
45
45
 
@@ -57,10 +57,10 @@ module RubyProf
57
57
  # 1 is for % sign
58
58
  @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", total_percentage)
59
59
  @output << sprintf("%#{PERCENTAGE_WIDTH-1}.2f\%", self_percentage)
60
- @output << sprintf("%#{TIME_WIDTH}.2f", method.total_time)
61
- @output << sprintf("%#{TIME_WIDTH}.2f", method.self_time)
62
- @output << sprintf("%#{TIME_WIDTH}.2f", method.wait_time)
63
- @output << sprintf("%#{TIME_WIDTH}.2f", method.children_time)
60
+ @output << sprintf("%#{TIME_WIDTH}.3f", method.total_time)
61
+ @output << sprintf("%#{TIME_WIDTH}.3f", method.self_time)
62
+ @output << sprintf("%#{TIME_WIDTH}.3f", method.wait_time)
63
+ @output << sprintf("%#{TIME_WIDTH}.3f", method.children_time)
64
64
  @output << sprintf("%#{CALL_WIDTH}i", method.called)
65
65
  @output << sprintf(" %s", method.recursive? ? "*" : " ")
66
66
  @output << sprintf("%s", method_name(method))
@@ -77,10 +77,10 @@ module RubyProf
77
77
  method.aggregate_parents.sort_by(&:total_time).each do |caller|
78
78
  next unless caller.parent
79
79
  @output << " " * 2 * PERCENTAGE_WIDTH
80
- @output << sprintf("%#{TIME_WIDTH}.2f", caller.total_time)
81
- @output << sprintf("%#{TIME_WIDTH}.2f", caller.self_time)
82
- @output << sprintf("%#{TIME_WIDTH}.2f", caller.wait_time)
83
- @output << sprintf("%#{TIME_WIDTH}.2f", caller.children_time)
80
+ @output << sprintf("%#{TIME_WIDTH}.3f", caller.total_time)
81
+ @output << sprintf("%#{TIME_WIDTH}.3f", caller.self_time)
82
+ @output << sprintf("%#{TIME_WIDTH}.3f", caller.wait_time)
83
+ @output << sprintf("%#{TIME_WIDTH}.3f", caller.children_time)
84
84
 
85
85
  call_called = "#{caller.called}/#{method.called}"
86
86
  @output << sprintf("%#{CALL_WIDTH}s", call_called)
@@ -95,10 +95,10 @@ module RubyProf
95
95
 
96
96
  @output << " " * 2 * PERCENTAGE_WIDTH
97
97
 
98
- @output << sprintf("%#{TIME_WIDTH}.2f", child.total_time)
99
- @output << sprintf("%#{TIME_WIDTH}.2f", child.self_time)
100
- @output << sprintf("%#{TIME_WIDTH}.2f", child.wait_time)
101
- @output << sprintf("%#{TIME_WIDTH}.2f", child.children_time)
98
+ @output << sprintf("%#{TIME_WIDTH}.3f", child.total_time)
99
+ @output << sprintf("%#{TIME_WIDTH}.3f", child.self_time)
100
+ @output << sprintf("%#{TIME_WIDTH}.3f", child.wait_time)
101
+ @output << sprintf("%#{TIME_WIDTH}.3f", child.children_time)
102
102
 
103
103
  call_called = "#{child.called}/#{child.target.called}"
104
104
  @output << sprintf("%#{CALL_WIDTH}s", call_called)
@@ -0,0 +1,22 @@
1
+ module RubyProf
2
+ class Thread
3
+ def top_methods
4
+ self.methods.select do |method_info|
5
+ method_info.call_infos.detect do |call_info|
6
+ call_info.parent.nil?
7
+ end
8
+ end
9
+ end
10
+
11
+ def total_time
12
+ self.top_methods.inject(0) do |sum, method_info|
13
+ method_info.call_infos.each do |call_info|
14
+ if call_info.parent.nil?
15
+ sum += call_info.total_time
16
+ end
17
+ end
18
+ sum
19
+ end
20
+ end
21
+ end
22
+ end
@@ -55,5 +55,6 @@ EOF
55
55
  spec.required_ruby_version = '>= 1.8.7'
56
56
  spec.date = DateTime.now
57
57
  spec.homepage = 'https://github.com/rdp/ruby-prof'
58
- spec.add_development_dependency 'rake-compiler'
58
+ spec.add_development_dependency('minitest')
59
+ spec.add_development_dependency('rake-compiler')
59
60
  end
@@ -9,6 +9,11 @@ class BasicTest < Test::Unit::TestCase
9
9
  RubyProf::measure_mode = RubyProf::WALL_TIME
10
10
  end
11
11
 
12
+ def start
13
+ RubyProf.start
14
+ RubyProf::C1.hello
15
+ end
16
+
12
17
  def test_running
13
18
  assert(!RubyProf.running?)
14
19
  RubyProf.start
@@ -40,57 +45,84 @@ class BasicTest < Test::Unit::TestCase
40
45
  RubyProf.stop
41
46
  end
42
47
 
43
- def test_pause_seq
44
- p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
45
- p.start ; assert !p.paused?
46
- p.pause ; assert p.paused?
47
- p.resume; assert !p.paused?
48
- p.pause ; assert p.paused?
49
- p.pause ; assert p.paused?
50
- p.resume; assert !p.paused?
51
- p.resume; assert !p.paused?
52
- p.stop ; assert !p.paused?
53
- end
48
+ def test_leave_method
49
+ start
50
+ sleep 0.15
51
+ profile = RubyProf.stop
54
52
 
55
- def test_pause_block
56
- p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
57
- p.start
58
- p.pause
59
- assert p.paused?
53
+ assert_equal(1, profile.threads.count)
60
54
 
61
- times_block_invoked = 0
62
- retval= p.resume{
63
- times_block_invoked += 1
64
- 120 + times_block_invoked
65
- }
66
- assert_equal 1, times_block_invoked
67
- assert p.paused?
55
+ thread = profile.threads.first
56
+ assert_in_delta(0.25, thread.total_time, 0.01)
68
57
 
69
- assert_equal 121, retval, "resume() should return the result of the given block."
58
+ top_methods = thread.top_methods.sort
59
+ assert_equal(2, top_methods.count)
60
+ assert_equal("BasicTest#start", top_methods[0].full_name)
61
+ assert_equal("BasicTest#test_leave_method", top_methods[1].full_name)
70
62
 
71
- p.stop
72
- end
63
+ assert_equal(4, thread.methods.length)
64
+ methods = profile.threads.first.methods.sort
73
65
 
74
- def test_pause_block_with_error
75
- p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
76
- p.start
77
- p.pause
78
- assert p.paused?
79
-
80
- begin
81
- p.resume{ raise }
82
- flunk 'Exception expected.'
83
- rescue
84
- assert p.paused?
85
- end
66
+ # Check times
67
+ assert_equal("<Class::RubyProf::C1>#hello", methods[0].full_name)
68
+ assert_in_delta(0.1, methods[0].total_time, 0.01)
69
+ assert_in_delta(0.0, methods[0].wait_time, 0.01)
70
+ assert_in_delta(0.0, methods[0].self_time, 0.01)
71
+
72
+ assert_equal("BasicTest#start", methods[1].full_name)
73
+ assert_in_delta(0.1, methods[1].total_time, 0.01)
74
+ assert_in_delta(0.0, methods[1].wait_time, 0.01)
75
+ assert_in_delta(0.0, methods[1].self_time, 0.01)
76
+
77
+ assert_equal("BasicTest#test_leave_method", methods[2].full_name)
78
+ assert_in_delta(0.15, methods[2].total_time, 0.01)
79
+ assert_in_delta(0.0, methods[2].wait_time, 0.01)
80
+ assert_in_delta(0.0, methods[2].self_time, 0.01)
86
81
 
87
- p.stop
82
+ assert_equal("Kernel#sleep", methods[3].full_name)
83
+ assert_in_delta(0.25, methods[3].total_time, 0.01)
84
+ assert_in_delta(0.0, methods[3].wait_time, 0.01)
85
+ assert_in_delta(0.25, methods[3].self_time, 0.01)
88
86
  end
89
87
 
90
- def test_resume_when_not_paused
91
- p= RubyProf::Profile.new(RubyProf::WALL_TIME,[])
92
- p.start ; assert !p.paused?
93
- p.resume; assert !p.paused?
94
- p.stop ; assert !p.paused?
88
+ def test_leave_method_2
89
+ start
90
+ RubyProf::C1.hello
91
+ RubyProf::C1.hello
92
+ profile = RubyProf.stop
93
+
94
+ assert_equal(1, profile.threads.count)
95
+
96
+ thread = profile.threads.first
97
+ assert_in_delta(0.3, thread.total_time, 0.01)
98
+
99
+ top_methods = thread.top_methods.sort
100
+ assert_equal(2, top_methods.count)
101
+ assert_equal("BasicTest#start", top_methods[0].full_name)
102
+ assert_equal("BasicTest#test_leave_method_2", top_methods[1].full_name)
103
+
104
+ assert_equal(4, thread.methods.length)
105
+ methods = profile.threads.first.methods.sort
106
+
107
+ # Check times
108
+ assert_equal("BasicTest#start", methods[0].full_name)
109
+ assert_in_delta(0.1, methods[0].total_time, 0.01)
110
+ assert_in_delta(0.0, methods[0].wait_time, 0.01)
111
+ assert_in_delta(0.0, methods[0].self_time, 0.01)
112
+
113
+ assert_equal("BasicTest#test_leave_method_2", methods[1].full_name)
114
+ assert_in_delta(0.2, methods[1].total_time, 0.01)
115
+ assert_in_delta(0.0, methods[1].wait_time, 0.01)
116
+ assert_in_delta(0.0, methods[1].self_time, 0.01)
117
+
118
+ assert_equal("Kernel#sleep", methods[2].full_name)
119
+ assert_in_delta(0.3, methods[2].total_time, 0.01)
120
+ assert_in_delta(0.0, methods[2].wait_time, 0.01)
121
+ assert_in_delta(0.3, methods[2].self_time, 0.01)
122
+
123
+ assert_equal("<Class::RubyProf::C1>#hello", methods[3].full_name)
124
+ assert_in_delta(0.3, methods[3].total_time, 0.01)
125
+ assert_in_delta(0.0, methods[3].wait_time, 0.01)
126
+ assert_in_delta(0.0, methods[3].self_time, 0.01)
95
127
  end
96
- end
128
+ end
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class CallInfoTest < Test::Unit::TestCase
7
+ def setup
8
+ # Need to use wall time for this test due to the sleep calls
9
+ RubyProf::measure_mode = RubyProf::WALL_TIME
10
+ end
11
+
12
+ # def test_clone
13
+ # result = RubyProf.profile do
14
+ # RubyProf::C1.hello
15
+ # end
16
+ #
17
+ # method = result.threads.first.top_methods.first
18
+ # call_info = method.call_infos.first
19
+ # call_info_clone = call_info.clone
20
+ #
21
+ ## assert_equal(call_info.target, call_info_clone.target)
22
+ # assert_equal(call_info.total_time, call_info_clone.total_time)
23
+ # end
24
+
25
+ def test_merge
26
+ result1 = RubyProf.profile do
27
+ RubyProf::C1.hello
28
+ end
29
+
30
+ methods = result1.threads.first.methods.sort.reverse
31
+ assert_equal(3, methods.length)
32
+
33
+ assert_equal('CallInfoTest#test_merge', methods[0].full_name)
34
+ assert_in_delta(0.1, methods[0].total_time, 0.01)
35
+ assert_in_delta(0, methods[0].wait_time, 0.01)
36
+ assert_in_delta(0, methods[0].self_time, 0.01)
37
+ assert_equal(1, methods[0].called)
38
+
39
+ assert_equal('<Class::RubyProf::C1>#hello', methods[1].full_name)
40
+ assert_in_delta(0.1, methods[1].total_time, 0.01)
41
+ assert_in_delta(0, methods[1].wait_time, 0.01)
42
+ assert_in_delta(0, methods[1].self_time, 0.01)
43
+ assert_equal(1, methods[1].called)
44
+
45
+ assert_equal('Kernel#sleep', methods[2].full_name)
46
+ assert_in_delta(0.1, methods[2].total_time, 0.01)
47
+ assert_in_delta(0, methods[2].wait_time, 0.01)
48
+ assert_in_delta(0.1, methods[2].self_time, 0.01)
49
+ assert_equal(1, methods[2].called)
50
+
51
+ result2 = RubyProf.profile do
52
+ RubyProf::C1.hello
53
+ end
54
+
55
+ # Merge the trees
56
+ methods = result1.threads.first.methods.sort.reverse
57
+ assert_equal(3, methods.length)
58
+
59
+ assert_equal('CallInfoTest#test_merge', methods[0].full_name)
60
+ assert_in_delta(0.1, methods[0].total_time, 0.01)
61
+ assert_in_delta(0, methods[0].wait_time, 0.01)
62
+ assert_in_delta(0, methods[0].self_time, 0.01)
63
+ assert_equal(1, methods[0].called)
64
+
65
+ assert_equal('<Class::RubyProf::C1>#hello', methods[1].full_name)
66
+ assert_in_delta(0.1, methods[1].total_time, 0.01)
67
+ assert_in_delta(0, methods[1].wait_time, 0.01)
68
+ assert_in_delta(0, methods[1].self_time, 0.01)
69
+ assert_equal(1, methods[1].called)
70
+
71
+ assert_equal('Kernel#sleep', methods[2].full_name)
72
+ assert_in_delta(0.1, methods[2].total_time, 0.01)
73
+ assert_in_delta(0, methods[2].wait_time, 0.01)
74
+ assert_in_delta(0.1, methods[2].self_time, 0.01)
75
+ assert_equal(1, methods[2].called)
76
+ end
77
+ end
78
+