ruby-prof 0.18.0 → 1.2.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 (129) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES +44 -1
  3. data/LICENSE +2 -2
  4. data/README.rdoc +1 -483
  5. data/Rakefile +3 -6
  6. data/bin/ruby-prof +111 -128
  7. data/ext/ruby_prof/extconf.rb +6 -38
  8. data/ext/ruby_prof/rp_aggregate_call_tree.c +41 -0
  9. data/ext/ruby_prof/rp_aggregate_call_tree.h +13 -0
  10. data/ext/ruby_prof/rp_allocation.c +259 -0
  11. data/ext/ruby_prof/rp_allocation.h +31 -0
  12. data/ext/ruby_prof/rp_call_tree.c +353 -0
  13. data/ext/ruby_prof/rp_call_tree.h +43 -0
  14. data/ext/ruby_prof/rp_call_trees.c +266 -0
  15. data/ext/ruby_prof/rp_call_trees.h +29 -0
  16. data/ext/ruby_prof/rp_measure_allocations.c +25 -51
  17. data/ext/ruby_prof/rp_measure_memory.c +21 -56
  18. data/ext/ruby_prof/rp_measure_process_time.c +37 -43
  19. data/ext/ruby_prof/rp_measure_wall_time.c +40 -21
  20. data/ext/ruby_prof/rp_measurement.c +221 -0
  21. data/ext/ruby_prof/rp_measurement.h +50 -0
  22. data/ext/ruby_prof/rp_method.c +279 -439
  23. data/ext/ruby_prof/rp_method.h +33 -45
  24. data/ext/ruby_prof/rp_profile.c +902 -0
  25. data/ext/ruby_prof/rp_profile.h +36 -0
  26. data/ext/ruby_prof/rp_stack.c +163 -132
  27. data/ext/ruby_prof/rp_stack.h +18 -28
  28. data/ext/ruby_prof/rp_thread.c +192 -124
  29. data/ext/ruby_prof/rp_thread.h +18 -8
  30. data/ext/ruby_prof/ruby_prof.c +36 -778
  31. data/ext/ruby_prof/ruby_prof.h +11 -45
  32. data/ext/ruby_prof/vc/ruby_prof.vcxproj +18 -12
  33. data/lib/ruby-prof.rb +4 -21
  34. data/lib/ruby-prof/assets/call_stack_printer.html.erb +710 -0
  35. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  36. data/lib/ruby-prof/assets/graph_printer.html.erb +355 -0
  37. data/lib/ruby-prof/call_tree.rb +57 -0
  38. data/lib/ruby-prof/call_tree_visitor.rb +36 -0
  39. data/lib/ruby-prof/compatibility.rb +37 -107
  40. data/lib/ruby-prof/exclude_common_methods.rb +198 -0
  41. data/lib/ruby-prof/measurement.rb +17 -0
  42. data/lib/ruby-prof/method_info.rb +47 -90
  43. data/lib/ruby-prof/printers/abstract_printer.rb +73 -50
  44. data/lib/ruby-prof/printers/call_info_printer.rb +24 -12
  45. data/lib/ruby-prof/printers/call_stack_printer.rb +66 -152
  46. data/lib/ruby-prof/printers/call_tree_printer.rb +20 -12
  47. data/lib/ruby-prof/printers/dot_printer.rb +5 -5
  48. data/lib/ruby-prof/printers/flat_printer.rb +6 -24
  49. data/lib/ruby-prof/printers/graph_html_printer.rb +6 -192
  50. data/lib/ruby-prof/printers/graph_printer.rb +11 -14
  51. data/lib/ruby-prof/printers/multi_printer.rb +66 -23
  52. data/lib/ruby-prof/profile.rb +10 -3
  53. data/lib/ruby-prof/thread.rb +5 -20
  54. data/lib/ruby-prof/version.rb +1 -1
  55. data/ruby-prof.gemspec +9 -2
  56. data/test/abstract_printer_test.rb +0 -27
  57. data/test/alias_test.rb +126 -0
  58. data/test/basic_test.rb +1 -86
  59. data/test/call_tree_visitor_test.rb +32 -0
  60. data/test/call_trees_test.rb +66 -0
  61. data/test/dynamic_method_test.rb +0 -2
  62. data/test/exclude_methods_test.rb +17 -12
  63. data/test/fiber_test.rb +214 -23
  64. data/test/gc_test.rb +105 -0
  65. data/test/inverse_call_tree_test.rb +175 -0
  66. data/test/line_number_test.rb +118 -40
  67. data/test/marshal_test.rb +115 -0
  68. data/test/measure_allocations.rb +30 -0
  69. data/test/measure_allocations_test.rb +361 -12
  70. data/test/measure_allocations_trace_test.rb +375 -0
  71. data/test/measure_memory_trace_test.rb +1101 -0
  72. data/test/measure_process_time_test.rb +757 -33
  73. data/test/measure_times.rb +56 -0
  74. data/test/measure_wall_time_test.rb +329 -149
  75. data/test/multi_printer_test.rb +1 -34
  76. data/test/pause_resume_test.rb +24 -15
  77. data/test/prime.rb +1 -1
  78. data/test/prime_script.rb +6 -0
  79. data/test/printer_call_stack_test.rb +28 -0
  80. data/test/printer_call_tree_test.rb +31 -0
  81. data/test/printer_flat_test.rb +68 -0
  82. data/test/printer_graph_html_test.rb +60 -0
  83. data/test/printer_graph_test.rb +41 -0
  84. data/test/printers_test.rb +32 -166
  85. data/test/printing_recursive_graph_test.rb +26 -72
  86. data/test/recursive_test.rb +68 -77
  87. data/test/stack_printer_test.rb +2 -15
  88. data/test/start_stop_test.rb +22 -25
  89. data/test/test_helper.rb +6 -261
  90. data/test/thread_test.rb +11 -54
  91. data/test/unique_call_path_test.rb +25 -107
  92. data/test/yarv_test.rb +1 -0
  93. metadata +43 -41
  94. data/examples/flat.txt +0 -50
  95. data/examples/graph.dot +0 -84
  96. data/examples/graph.html +0 -823
  97. data/examples/graph.txt +0 -139
  98. data/examples/multi.flat.txt +0 -23
  99. data/examples/multi.graph.html +0 -760
  100. data/examples/multi.grind.dat +0 -114
  101. data/examples/multi.stack.html +0 -547
  102. data/examples/stack.html +0 -547
  103. data/ext/ruby_prof/rp_call_info.c +0 -425
  104. data/ext/ruby_prof/rp_call_info.h +0 -53
  105. data/ext/ruby_prof/rp_measure.c +0 -40
  106. data/ext/ruby_prof/rp_measure.h +0 -45
  107. data/ext/ruby_prof/rp_measure_cpu_time.c +0 -136
  108. data/ext/ruby_prof/rp_measure_gc_runs.c +0 -73
  109. data/ext/ruby_prof/rp_measure_gc_time.c +0 -60
  110. data/lib/ruby-prof/aggregate_call_info.rb +0 -76
  111. data/lib/ruby-prof/assets/call_stack_printer.css.html +0 -117
  112. data/lib/ruby-prof/assets/call_stack_printer.js.html +0 -385
  113. data/lib/ruby-prof/call_info.rb +0 -115
  114. data/lib/ruby-prof/call_info_visitor.rb +0 -40
  115. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +0 -83
  116. data/lib/ruby-prof/profile/exclude_common_methods.rb +0 -207
  117. data/lib/ruby-prof/profile/legacy_method_elimination.rb +0 -50
  118. data/test/aggregate_test.rb +0 -136
  119. data/test/block_test.rb +0 -74
  120. data/test/call_info_test.rb +0 -78
  121. data/test/call_info_visitor_test.rb +0 -31
  122. data/test/issue137_test.rb +0 -63
  123. data/test/measure_cpu_time_test.rb +0 -212
  124. data/test/measure_gc_runs_test.rb +0 -32
  125. data/test/measure_gc_time_test.rb +0 -36
  126. data/test/measure_memory_test.rb +0 -33
  127. data/test/method_elimination_test.rb +0 -84
  128. data/test/module_test.rb +0 -45
  129. data/test/stack_test.rb +0 -138
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require_relative './measure_times'
6
+
7
+ class CallTreeVisitorTest < TestCase
8
+ def setup
9
+ # Need to use wall time for this test due to the sleep calls
10
+ RubyProf::measure_mode = RubyProf::WALL_TIME
11
+ end
12
+
13
+ def test_visit
14
+ result = RubyProf.profile do
15
+ RubyProf::C1.sleep_wait
16
+ end
17
+
18
+ visitor = RubyProf::CallTreeVisitor.new(result.threads.first.call_tree)
19
+
20
+ method_names = Array.new
21
+
22
+ visitor.visit do |call_tree, event|
23
+ method_names << call_tree.target.full_name if event == :enter
24
+ end
25
+
26
+ assert_equal(3, method_names.length)
27
+ assert_equal("CallTreeVisitorTest#test_visit", method_names[0])
28
+ assert_equal("<Class::RubyProf::C1>#sleep_wait", method_names[1])
29
+ assert_equal("Kernel#sleep", method_names[2])
30
+ end
31
+ end
32
+
@@ -0,0 +1,66 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ # -- Tests ----
7
+ class CallTreesTest < TestCase
8
+ def some_method_1
9
+ some_method_2
10
+ end
11
+
12
+ def some_method_2
13
+ end
14
+
15
+ def test_call_infos
16
+ result = RubyProf.profile do
17
+ some_method_1
18
+ end
19
+
20
+ thread = result.threads.first
21
+ assert_equal(3, thread.methods.length)
22
+
23
+ method = thread.methods[0]
24
+ assert_equal('CallTreesTest#test_call_infos', method.full_name)
25
+
26
+ call_trees = method.call_trees
27
+ assert_empty(call_trees.callers)
28
+ assert_equal(1, call_trees.callees.length)
29
+ assert_kind_of(RubyProf::AggregateCallTree, call_trees.callees[0])
30
+ assert_equal('CallTreesTest#some_method_1', call_trees.callees[0].target.full_name)
31
+
32
+ method = thread.methods[1]
33
+ assert_equal('CallTreesTest#some_method_1', method.full_name)
34
+
35
+ call_trees = method.call_trees
36
+ assert_equal(1, call_trees.callers.length)
37
+ assert_kind_of(RubyProf::AggregateCallTree, call_trees.callers[0])
38
+ assert_equal('CallTreesTest#test_call_infos', call_trees.callers[0].parent.target.full_name)
39
+ assert_equal(1, call_trees.callees.length)
40
+ assert_kind_of(RubyProf::AggregateCallTree, call_trees.callees[0])
41
+ assert_equal('CallTreesTest#some_method_2', call_trees.callees[0].target.full_name)
42
+
43
+ method = thread.methods[2]
44
+ assert_equal('CallTreesTest#some_method_2', method.full_name)
45
+
46
+ call_trees = method.call_trees
47
+ assert_equal(1, call_trees.callers.length)
48
+ assert_kind_of(RubyProf::AggregateCallTree, call_trees.callers[0])
49
+ assert_equal('CallTreesTest#some_method_1', call_trees.callers[0].parent.target.full_name)
50
+ assert_empty(call_trees.callees)
51
+ end
52
+
53
+ def test_gc
54
+ result = RubyProf.profile do
55
+ some_method_1
56
+ end
57
+
58
+ method = result.threads.first.methods[1]
59
+
60
+ 100.times do |i|
61
+ method.call_trees.callers
62
+ GC.start
63
+ end
64
+ assert(true)
65
+ end
66
+ end
@@ -38,8 +38,6 @@ class DynamicMethodTest < TestCase
38
38
  medley.peach
39
39
  end
40
40
 
41
- # RubyProf::FlatPrinter.new(result).print(STDOUT)
42
-
43
41
  methods = result.threads.first.methods.sort.reverse
44
42
  expected_method_names = %w(
45
43
  DynamicMethodTest#test_dynamic_method
@@ -43,13 +43,12 @@ class ExcludeMethodsTest < TestCase
43
43
  obj = ExcludeMethodsClass.new
44
44
  prf = RubyProf::Profile.new
45
45
 
46
- result = prf.profile { 5.times {obj.a} }
46
+ result = prf.profile {obj.a}
47
47
  methods = result.threads.first.methods.sort.reverse
48
-
49
48
  assert_equal(10, methods.count)
50
49
  assert_equal('ExcludeMethodsTest#test_methods_can_be_profiled', methods[0].full_name)
51
- assert_equal('Integer#times', methods[1].full_name)
52
- assert_equal('ExcludeMethodsClass#a', methods[2].full_name)
50
+ assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
51
+ assert_equal('Integer#times', methods[2].full_name)
53
52
  assert_equal('ExcludeMethodsClass#b', methods[3].full_name)
54
53
  assert_equal('<Class::ExcludeMethodsClass>#e', methods[4].full_name)
55
54
  assert_equal('<Class::ExcludeMethodsClass>#f', methods[5].full_name)
@@ -65,7 +64,7 @@ class ExcludeMethodsTest < TestCase
65
64
 
66
65
  prf.exclude_methods!(Integer, :times)
67
66
 
68
- result = prf.profile { 5.times {obj.a} }
67
+ result = prf.profile {obj.a}
69
68
  methods = result.threads.first.methods.sort.reverse
70
69
 
71
70
  assert_equal(9, methods.count)
@@ -88,7 +87,7 @@ class ExcludeMethodsTest < TestCase
88
87
  prf.exclude_methods!(ExcludeMethodsClass.singleton_class, :f)
89
88
  prf.exclude_methods!(ExcludeMethodsModule.singleton_class, :d)
90
89
 
91
- result = prf.profile { 5.times {obj.a} }
90
+ result = prf.profile {obj.a}
92
91
  methods = result.threads.first.methods.sort.reverse
93
92
 
94
93
  assert_equal(7, methods.count)
@@ -107,13 +106,19 @@ class ExcludeMethodsTest < TestCase
107
106
 
108
107
  prf.exclude_common_methods!
109
108
 
110
- result = prf.profile { 5.times {obj.a} }
109
+ result = prf.profile {obj.a}
111
110
  methods = result.threads.first.methods.sort.reverse
112
111
 
113
112
  assert_equal(9, methods.count)
114
113
  assert_equal('ExcludeMethodsTest#test_exclude_common_methods1', methods[0].full_name)
115
114
  assert_equal('ExcludeMethodsClass#a', methods[1].full_name)
116
115
  assert_equal('ExcludeMethodsClass#b', methods[2].full_name)
116
+ assert_equal('<Class::ExcludeMethodsClass>#e', methods[3].full_name)
117
+ assert_equal('<Class::ExcludeMethodsClass>#f', methods[4].full_name)
118
+ assert_equal('Kernel#sleep', methods[5].full_name)
119
+ assert_equal('ExcludeMethodsModule#c', methods[6].full_name)
120
+ assert_equal('<Module::ExcludeMethodsModule>#d', methods[7].full_name)
121
+ assert_equal('Kernel#class', methods[8].full_name)
117
122
  end
118
123
 
119
124
  def test_exclude_common_methods2
@@ -130,14 +135,14 @@ class ExcludeMethodsTest < TestCase
130
135
 
131
136
  private
132
137
 
133
- def assert_method_has_been_eliminated(result, eliminated_method)
138
+ def assert_method_has_been_excluded(result, excluded_method)
134
139
  result.threads.each do |thread|
135
140
  thread.methods.each do |method|
136
- method.call_infos.each do |ci|
137
- assert(ci.target != eliminated_method, "broken self")
138
- assert(ci.parent.target != eliminated_method, "broken parent") if ci.parent
141
+ method.call_trees.each do |ci|
142
+ assert(ci.target != excluded_method, "broken self")
143
+ assert(ci.parent.target != excluded_method, "broken parent") if ci.parent
139
144
  ci.children.each do |callee|
140
- assert(callee.target != eliminated_method, "broken kid")
145
+ assert(callee.target != excluded_method, "broken kid")
141
146
  end
142
147
  end
143
148
  end
@@ -2,25 +2,21 @@
2
2
  # encoding: UTF-8
3
3
 
4
4
  require File.expand_path('../test_helper', __FILE__)
5
+ require 'fiber'
5
6
  require 'timeout'
6
7
  require 'set'
7
- begin
8
- require 'fiber'
9
- rescue LoadError
10
- end
11
8
 
12
9
  # -- Tests ----
13
10
  class FiberTest < TestCase
14
-
15
11
  def fiber_test
16
12
  @fiber_ids << Fiber.current.object_id
17
13
  enum = Enumerator.new do |yielder|
18
- [1,2].each do |x|
19
- @fiber_ids << Fiber.current.object_id
20
- sleep 0.1
21
- yielder.yield x
22
- end
14
+ [1,2].each do |x|
15
+ @fiber_ids << Fiber.current.object_id
16
+ sleep 0.1
17
+ yielder.yield x
23
18
  end
19
+ end
24
20
  while true
25
21
  begin
26
22
  enum.next
@@ -41,6 +37,7 @@ class FiberTest < TestCase
41
37
 
42
38
  def test_fibers
43
39
  result = RubyProf.profile { fiber_test }
40
+
44
41
  profiled_fiber_ids = result.threads.map(&:fiber_id)
45
42
  assert_equal(2, result.threads.length)
46
43
  assert_equal([@thread_id], result.threads.map(&:id).uniq)
@@ -49,31 +46,225 @@ class FiberTest < TestCase
49
46
  assert profiled_fiber_ids.include?(@root_fiber)
50
47
  assert(root_fiber_profile = result.threads.detect{|t| t.fiber_id == @root_fiber})
51
48
  assert(enum_fiber_profile = result.threads.detect{|t| t.fiber_id != @root_fiber})
49
+ assert_in_delta(0.33, root_fiber_profile.total_time, 0.05)
50
+ assert_in_delta(0.33, enum_fiber_profile.total_time, 0.05)
52
51
 
53
- assert_in_delta(0.3, root_fiber_profile.total_time, 0.05)
54
- assert_in_delta(0.2, enum_fiber_profile.total_time, 0.05)
52
+ methods = result.threads[0].methods.sort.reverse
53
+ assert_equal(12, methods.count)
55
54
 
56
- assert(method_next = root_fiber_profile.methods.detect{|m| m.full_name == "Enumerator#next"})
57
- assert(method_each = enum_fiber_profile.methods.detect{|m| m.full_name == "Enumerator#each"})
55
+ method = methods[0]
56
+ assert_equal('FiberTest#test_fibers', method.full_name)
57
+ assert_equal(1, method.called)
58
+ assert_in_delta(0.33, method.total_time, 0.05)
59
+ assert_in_delta(0, method.self_time, 0.05)
60
+ assert_in_delta(0, method.wait_time, 0.05)
61
+ assert_in_delta(0.33, method.children_time, 0.05)
58
62
 
59
- assert_in_delta(0.2, method_next.total_time, 0.05)
60
- assert_in_delta(0.2, method_each.total_time, 0.05)
63
+ method = methods[1]
64
+ assert_equal('FiberTest#fiber_test', method.full_name)
65
+ assert_equal(1, method.called)
66
+ assert_in_delta(0.33, method.total_time, 0.05)
67
+ assert_in_delta(0, method.self_time, 0.05)
68
+ assert_in_delta(0, method.wait_time, 0.05)
69
+ assert_in_delta(0.33, method.children_time, 0.05)
70
+
71
+ method = methods[2]
72
+ assert_equal('Enumerator#next', method.full_name)
73
+ assert_equal(3, method.called)
74
+ assert_in_delta(0.22, method.total_time, 0.05)
75
+ assert_in_delta(0, method.self_time, 0.05)
76
+ assert_in_delta(0.22, method.wait_time, 0.05)
77
+ assert_in_delta(0, method.children_time, 0.05)
78
+
79
+ method = methods[3]
80
+ assert_equal('Kernel#sleep', method.full_name)
81
+ assert_equal(1, method.called)
82
+ assert_in_delta(0.11, method.total_time, 0.05)
83
+ assert_in_delta(0.11, method.self_time, 0.05)
84
+ assert_in_delta(0, method.wait_time, 0.05)
85
+ assert_in_delta(0, method.children_time, 0.05)
86
+
87
+ # Since these methods have such short times their order is a bit indeterminate
88
+ method = methods.detect {|method| method.full_name == 'Class#new'}
89
+ assert_equal('Class#new', method.full_name)
90
+ assert_equal(1, method.called)
91
+ assert_in_delta(0, method.total_time, 0.05)
92
+ assert_in_delta(0, method.self_time, 0.05)
93
+ assert_in_delta(0, method.wait_time, 0.05)
94
+ assert_in_delta(0, method.children_time, 0.05)
95
+
96
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
97
+ method = methods.detect {|method| method.full_name == 'Set#<<'}
98
+ assert_equal('Set#<<', method.full_name)
99
+ assert_equal(1, method.called)
100
+ assert_in_delta(0, method.total_time, 0.05)
101
+ assert_in_delta(0, method.self_time, 0.05)
102
+ assert_in_delta(0, method.wait_time, 0.05)
103
+ assert_in_delta(0, method.children_time, 0.05)
104
+ end
105
+
106
+ method = methods.detect {|method| method.full_name == 'Module#==='}
107
+ assert_equal('Module#===', method.full_name)
108
+ assert_equal(1, method.called)
109
+ assert_in_delta(0, method.total_time, 0.05)
110
+ assert_in_delta(0, method.self_time, 0.05)
111
+ assert_in_delta(0, method.wait_time, 0.05)
112
+ assert_in_delta(0, method.children_time, 0.05)
113
+
114
+ method = methods.detect {|method| method.full_name == 'Kernel#object_id'}
115
+ assert_equal('Kernel#object_id', method.full_name)
116
+ assert_equal(1, method.called)
117
+ assert_in_delta(0, method.total_time, 0.05)
118
+ assert_in_delta(0, method.self_time, 0.05)
119
+ assert_in_delta(0, method.wait_time, 0.05)
120
+ assert_in_delta(0, method.children_time, 0.05)
121
+
122
+ method = methods.detect {|method| method.full_name == '<Class::Fiber>#current'}
123
+ assert_equal('<Class::Fiber>#current', method.full_name)
124
+ assert_equal(1, method.called)
125
+ assert_in_delta(0, method.total_time, 0.05)
126
+ assert_in_delta(0, method.self_time, 0.05)
127
+ assert_in_delta(0, method.wait_time, 0.05)
128
+ assert_in_delta(0, method.children_time, 0.05)
129
+
130
+ method = methods.detect {|method| method.full_name == 'Exception#exception'}
131
+ assert_equal('Exception#exception', method.full_name)
132
+ assert_equal(1, method.called)
133
+ assert_in_delta(0, method.total_time, 0.05)
134
+ assert_in_delta(0, method.self_time, 0.05)
135
+ assert_in_delta(0, method.wait_time, 0.05)
136
+ assert_in_delta(0, method.children_time, 0.05)
137
+
138
+ method = methods.detect {|method| method.full_name == 'Exception#backtrace'}
139
+ assert_equal('Exception#backtrace', method.full_name)
140
+ assert_equal(1, method.called)
141
+ assert_in_delta(0, method.total_time, 0.05)
142
+ assert_in_delta(0, method.self_time, 0.05)
143
+ assert_in_delta(0, method.wait_time, 0.05)
144
+ assert_in_delta(0, method.children_time, 0.05)
145
+
146
+ method = methods.detect {|method| method.full_name == 'Enumerator#initialize'}
147
+ assert_equal('Enumerator#initialize', method.full_name)
148
+ assert_equal(1, method.called)
149
+ assert_in_delta(0, method.total_time, 0.05)
150
+ assert_in_delta(0, method.self_time, 0.05)
151
+ assert_in_delta(0, method.wait_time, 0.05)
152
+ assert_in_delta(0, method.children_time, 0.05)
153
+
154
+ methods = result.threads[1].methods.sort.reverse
155
+
156
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.6.0')
157
+ assert_equal(10, methods.count)
158
+ else
159
+ assert_equal(11, methods.count)
160
+ end
161
+
162
+ method = methods[0]
163
+ assert_equal('RubyProf::Profile#_inserted_parent_', method.full_name)
164
+ assert_equal(1, method.called)
165
+ assert_in_delta(0.33, method.total_time, 0.05)
166
+ assert_in_delta(0, method.self_time, 0.05)
167
+ assert_in_delta(0.11, method.wait_time, 0.05)
168
+ assert_in_delta(0.22, method.children_time, 0.05)
169
+
170
+ method = methods[1]
171
+ assert_equal('Enumerator#each', method.full_name)
172
+ assert_equal(1, method.called)
173
+ assert_in_delta(0.22, method.total_time, 0.05)
174
+ assert_in_delta(0, method.self_time, 0.05)
175
+ assert_in_delta(0, method.wait_time, 0.05)
176
+ assert_in_delta(0.22, method.children_time, 0.05)
177
+
178
+ method = methods[2]
179
+ assert_equal('Enumerator::Generator#each', method.full_name)
180
+ assert_equal(1, method.called)
181
+ assert_in_delta(0.22, method.total_time, 0.05)
182
+ assert_in_delta(0, method.self_time, 0.05)
183
+ assert_in_delta(0, method.wait_time, 0.05)
184
+ assert_in_delta(0.22, method.children_time, 0.05)
185
+
186
+ method = methods[3]
187
+ assert_equal('Array#each', method.full_name)
188
+ assert_equal(1, method.called)
189
+ assert_in_delta(0.22, method.total_time, 0.05)
190
+ assert_in_delta(0, method.self_time, 0.05)
191
+ assert_in_delta(0, method.wait_time, 0.05)
192
+ assert_in_delta(0.22, method.children_time, 0.05)
193
+
194
+ method = methods[4]
195
+ assert_equal('Kernel#sleep', method.full_name)
196
+ assert_equal(2, method.called)
197
+ assert_in_delta(0.22, method.total_time, 0.05)
198
+ assert_in_delta(0.22, method.self_time, 0.05)
199
+ assert_in_delta(0, method.wait_time, 0.05)
200
+ assert_in_delta(0, method.children_time, 0.05)
201
+
202
+ # Since these methods have such short times their order is a bit indeterminate
203
+ method = methods.detect {|method| method.full_name == 'Exception#initialize'}
204
+ assert_equal('Exception#initialize', method.full_name)
205
+ assert_equal(1, method.called)
206
+ assert_in_delta(0, method.total_time, 0.05)
207
+ assert_in_delta(0, method.self_time, 0.05)
208
+ assert_in_delta(0, method.wait_time, 0.05)
209
+ assert_in_delta(0, method.children_time, 0.05)
210
+
211
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.5.0')
212
+ method = methods.detect {|method| method.full_name == 'Set#<<'}
213
+ assert_equal('Set#<<', method.full_name)
214
+ assert_equal(2, method.called)
215
+ assert_in_delta(0, method.total_time, 0.05)
216
+ assert_in_delta(0, method.self_time, 0.05)
217
+ assert_in_delta(0, method.wait_time, 0.05)
218
+ assert_in_delta(0, method.children_time, 0.05)
219
+ end
220
+
221
+ method = methods.detect {|method| method.full_name == 'Kernel#object_id'}
222
+ assert_equal('Kernel#object_id', method.full_name)
223
+ assert_equal(2, method.called)
224
+ assert_in_delta(0, method.total_time, 0.05)
225
+ assert_in_delta(0, method.self_time, 0.05)
226
+ assert_in_delta(0, method.wait_time, 0.05)
227
+ assert_in_delta(0, method.children_time, 0.05)
228
+
229
+ method = methods.detect {|method| method.full_name == 'Enumerator::Yielder#yield'}
230
+ assert_equal('Enumerator::Yielder#yield', method.full_name)
231
+ assert_equal(2, method.called)
232
+ assert_in_delta(0, method.total_time, 0.05)
233
+ assert_in_delta(0, method.self_time, 0.05)
234
+ assert_in_delta(0, method.wait_time, 0.05)
235
+ assert_in_delta(0, method.children_time, 0.05)
236
+
237
+ method = methods.detect {|method| method.full_name == '<Class::Fiber>#current'}
238
+ assert_equal('<Class::Fiber>#current', method.full_name)
239
+ assert_equal(2, method.called)
240
+ assert_in_delta(0, method.total_time, 0.05)
241
+ assert_in_delta(0, method.self_time, 0.05)
242
+ assert_in_delta(0, method.wait_time, 0.05)
243
+ assert_in_delta(0, method.children_time, 0.05)
244
+
245
+ #if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7.0')
246
+ # method = methods.detect {|method| method.full_name == 'Numeric#eql?'}
247
+ # assert_equal('Numeric#eql?', method.full_name)
248
+ # assert_equal(1, method.called)
249
+ # assert_in_delta(0, method.total_time, 0.05)
250
+ # assert_in_delta(0, method.self_time, 0.05)
251
+ # assert_in_delta(0, method.wait_time, 0.05)
252
+ # assert_in_delta(0, method.children_time, 0.05)
253
+ #end
61
254
  end
62
255
 
63
256
  def test_merged_fibers
64
257
  result = RubyProf.profile(merge_fibers: true) { fiber_test }
65
258
  assert_equal(1, result.threads.length)
66
259
 
67
- profile = result.threads.first
68
- assert_equal 0, profile.fiber_id
260
+ thread = result.threads.first
261
+ assert_equal(thread.id, thread.fiber_id)
262
+ assert_in_delta(0.3, thread.total_time, 0.05)
69
263
 
70
- assert_in_delta(0.3, profile.total_time, 0.05)
71
-
72
- assert(method_next = profile.methods.detect{|m| m.full_name == "Enumerator#next"})
73
- assert(method_each = profile.methods.detect{|m| m.full_name == "Enumerator#each"})
264
+ assert(method_next = thread.methods.detect{|m| m.full_name == "Enumerator#next"})
265
+ assert(method_each = thread.methods.detect{|m| m.full_name == "Enumerator#each"})
74
266
 
75
267
  assert_in_delta(0.2, method_next.total_time, 0.05)
76
268
  assert_in_delta(0.2, method_each.total_time, 0.05)
77
269
  end
78
-
79
270
  end