ruby-prof 0.11.3 → 0.12.1

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 (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
+