ruby-prof 0.18.0-x64-mingw32

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 (108) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGES +500 -0
  3. data/LICENSE +25 -0
  4. data/README.rdoc +487 -0
  5. data/Rakefile +113 -0
  6. data/bin/ruby-prof +345 -0
  7. data/bin/ruby-prof-check-trace +45 -0
  8. data/examples/flat.txt +50 -0
  9. data/examples/graph.dot +84 -0
  10. data/examples/graph.html +823 -0
  11. data/examples/graph.txt +139 -0
  12. data/examples/multi.flat.txt +23 -0
  13. data/examples/multi.graph.html +760 -0
  14. data/examples/multi.grind.dat +114 -0
  15. data/examples/multi.stack.html +547 -0
  16. data/examples/stack.html +547 -0
  17. data/ext/ruby_prof/extconf.rb +68 -0
  18. data/ext/ruby_prof/rp_call_info.c +425 -0
  19. data/ext/ruby_prof/rp_call_info.h +53 -0
  20. data/ext/ruby_prof/rp_measure.c +40 -0
  21. data/ext/ruby_prof/rp_measure.h +45 -0
  22. data/ext/ruby_prof/rp_measure_allocations.c +76 -0
  23. data/ext/ruby_prof/rp_measure_cpu_time.c +136 -0
  24. data/ext/ruby_prof/rp_measure_gc_runs.c +73 -0
  25. data/ext/ruby_prof/rp_measure_gc_time.c +60 -0
  26. data/ext/ruby_prof/rp_measure_memory.c +77 -0
  27. data/ext/ruby_prof/rp_measure_process_time.c +71 -0
  28. data/ext/ruby_prof/rp_measure_wall_time.c +45 -0
  29. data/ext/ruby_prof/rp_method.c +630 -0
  30. data/ext/ruby_prof/rp_method.h +75 -0
  31. data/ext/ruby_prof/rp_stack.c +173 -0
  32. data/ext/ruby_prof/rp_stack.h +63 -0
  33. data/ext/ruby_prof/rp_thread.c +277 -0
  34. data/ext/ruby_prof/rp_thread.h +27 -0
  35. data/ext/ruby_prof/ruby_prof.c +794 -0
  36. data/ext/ruby_prof/ruby_prof.h +60 -0
  37. data/ext/ruby_prof/vc/ruby_prof.sln +31 -0
  38. data/ext/ruby_prof/vc/ruby_prof.vcxproj +141 -0
  39. data/lib/2.6.3/ruby_prof.so +0 -0
  40. data/lib/ruby-prof.rb +68 -0
  41. data/lib/ruby-prof/aggregate_call_info.rb +76 -0
  42. data/lib/ruby-prof/assets/call_stack_printer.css.html +117 -0
  43. data/lib/ruby-prof/assets/call_stack_printer.js.html +385 -0
  44. data/lib/ruby-prof/assets/call_stack_printer.png +0 -0
  45. data/lib/ruby-prof/call_info.rb +115 -0
  46. data/lib/ruby-prof/call_info_visitor.rb +40 -0
  47. data/lib/ruby-prof/compatibility.rb +179 -0
  48. data/lib/ruby-prof/method_info.rb +121 -0
  49. data/lib/ruby-prof/printers/abstract_printer.rb +104 -0
  50. data/lib/ruby-prof/printers/call_info_printer.rb +41 -0
  51. data/lib/ruby-prof/printers/call_stack_printer.rb +265 -0
  52. data/lib/ruby-prof/printers/call_tree_printer.rb +143 -0
  53. data/lib/ruby-prof/printers/dot_printer.rb +132 -0
  54. data/lib/ruby-prof/printers/flat_printer.rb +70 -0
  55. data/lib/ruby-prof/printers/flat_printer_with_line_numbers.rb +83 -0
  56. data/lib/ruby-prof/printers/graph_html_printer.rb +249 -0
  57. data/lib/ruby-prof/printers/graph_printer.rb +116 -0
  58. data/lib/ruby-prof/printers/multi_printer.rb +84 -0
  59. data/lib/ruby-prof/profile.rb +26 -0
  60. data/lib/ruby-prof/profile/exclude_common_methods.rb +207 -0
  61. data/lib/ruby-prof/profile/legacy_method_elimination.rb +50 -0
  62. data/lib/ruby-prof/rack.rb +174 -0
  63. data/lib/ruby-prof/task.rb +147 -0
  64. data/lib/ruby-prof/thread.rb +35 -0
  65. data/lib/ruby-prof/version.rb +3 -0
  66. data/lib/unprof.rb +10 -0
  67. data/ruby-prof.gemspec +58 -0
  68. data/test/abstract_printer_test.rb +53 -0
  69. data/test/aggregate_test.rb +136 -0
  70. data/test/basic_test.rb +128 -0
  71. data/test/block_test.rb +74 -0
  72. data/test/call_info_test.rb +78 -0
  73. data/test/call_info_visitor_test.rb +31 -0
  74. data/test/duplicate_names_test.rb +32 -0
  75. data/test/dynamic_method_test.rb +55 -0
  76. data/test/enumerable_test.rb +21 -0
  77. data/test/exceptions_test.rb +24 -0
  78. data/test/exclude_methods_test.rb +146 -0
  79. data/test/exclude_threads_test.rb +53 -0
  80. data/test/fiber_test.rb +79 -0
  81. data/test/issue137_test.rb +63 -0
  82. data/test/line_number_test.rb +80 -0
  83. data/test/measure_allocations_test.rb +26 -0
  84. data/test/measure_cpu_time_test.rb +212 -0
  85. data/test/measure_gc_runs_test.rb +32 -0
  86. data/test/measure_gc_time_test.rb +36 -0
  87. data/test/measure_memory_test.rb +33 -0
  88. data/test/measure_process_time_test.rb +61 -0
  89. data/test/measure_wall_time_test.rb +255 -0
  90. data/test/method_elimination_test.rb +84 -0
  91. data/test/module_test.rb +45 -0
  92. data/test/multi_printer_test.rb +104 -0
  93. data/test/no_method_class_test.rb +15 -0
  94. data/test/pause_resume_test.rb +166 -0
  95. data/test/prime.rb +54 -0
  96. data/test/printers_test.rb +275 -0
  97. data/test/printing_recursive_graph_test.rb +127 -0
  98. data/test/rack_test.rb +157 -0
  99. data/test/recursive_test.rb +215 -0
  100. data/test/singleton_test.rb +38 -0
  101. data/test/stack_printer_test.rb +77 -0
  102. data/test/stack_test.rb +138 -0
  103. data/test/start_stop_test.rb +112 -0
  104. data/test/test_helper.rb +267 -0
  105. data/test/thread_test.rb +187 -0
  106. data/test/unique_call_path_test.rb +202 -0
  107. data/test/yarv_test.rb +55 -0
  108. metadata +199 -0
@@ -0,0 +1,112 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+
6
+ class StartStopTest < 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 method1
13
+ RubyProf.start
14
+ method2
15
+ end
16
+
17
+ def method2
18
+ method3
19
+ end
20
+
21
+ def method3
22
+ sleep(2)
23
+ @result = RubyProf.stop
24
+ end
25
+
26
+ def test_extra_stop_should_raise
27
+ RubyProf.start
28
+ assert_raises(RuntimeError) do
29
+ RubyProf.start
30
+ end
31
+
32
+ assert_raises(RuntimeError) do
33
+ RubyProf.profile {}
34
+ end
35
+
36
+ RubyProf.stop # ok
37
+ assert_raises(RuntimeError) do
38
+ RubyProf.stop
39
+ end
40
+ end
41
+
42
+
43
+ def test_different_methods
44
+ method1
45
+
46
+ # Ruby prof should be stopped
47
+ assert_equal(false, RubyProf.running?)
48
+
49
+
50
+ # Length should be 4:
51
+ # StartStopTest#method1
52
+ # StartStopTest#method2
53
+ # StartStopTest#method3
54
+ # Kernel#sleep
55
+
56
+ methods = @result.threads.first.methods.sort.reverse
57
+ assert_equal(4, methods.length)
58
+
59
+ # Check StackTest#test_call_sequence
60
+ method = methods[0]
61
+ assert_equal('StartStopTest#method1', method.full_name)
62
+ assert_equal(1, method.called)
63
+ assert_in_delta(2, method.total_time, 0.05)
64
+ assert_in_delta(0, method.wait_time, 0.02)
65
+ assert_in_delta(0, method.self_time, 0.02)
66
+ assert_in_delta(2, method.children_time, 0.05)
67
+ assert_equal(1, method.call_infos.length)
68
+
69
+ call_info = method.call_infos[0]
70
+ assert_equal('StartStopTest#method1', call_info.call_sequence)
71
+ assert_equal(1, call_info.children.length)
72
+
73
+ method = methods[1]
74
+ assert_equal('StartStopTest#method2', method.full_name)
75
+ assert_equal(1, method.called)
76
+ assert_in_delta(2, method.total_time, 0.05)
77
+ assert_in_delta(0, method.wait_time, 0.02)
78
+ assert_in_delta(0, method.self_time, 0.02)
79
+ assert_in_delta(2, method.children_time, 0.05)
80
+ assert_equal(1, method.call_infos.length)
81
+
82
+ call_info = method.call_infos[0]
83
+ assert_equal('StartStopTest#method1->StartStopTest#method2', call_info.call_sequence)
84
+ assert_equal(1, call_info.children.length)
85
+
86
+ method = methods[2]
87
+ assert_equal('StartStopTest#method3', method.full_name)
88
+ assert_equal(1, method.called)
89
+ assert_in_delta(2, method.total_time, 0.02)
90
+ assert_in_delta(0, method.wait_time, 0.02)
91
+ assert_in_delta(0, method.self_time, 0.02)
92
+ assert_in_delta(2, method.children_time, 0.02)
93
+ assert_equal(1, method.call_infos.length)
94
+
95
+ call_info = method.call_infos[0]
96
+ assert_equal('StartStopTest#method1->StartStopTest#method2->StartStopTest#method3', call_info.call_sequence)
97
+ assert_equal(1, call_info.children.length)
98
+
99
+ method = methods[3]
100
+ assert_equal('Kernel#sleep', method.full_name)
101
+ assert_equal(1, method.called)
102
+ assert_in_delta(2, method.total_time, 0.02)
103
+ assert_in_delta(0, method.wait_time, 0.02)
104
+ assert_in_delta(2, method.self_time, 0.02)
105
+ assert_in_delta(0, method.children_time, 0.02)
106
+ assert_equal(1, method.call_infos.length)
107
+
108
+ call_info = method.call_infos[0]
109
+ assert_equal('StartStopTest#method1->StartStopTest#method2->StartStopTest#method3->Kernel#sleep', call_info.call_sequence)
110
+ assert_equal(0, call_info.children.length)
111
+ end
112
+ end
@@ -0,0 +1,267 @@
1
+ # encoding: UTF-8
2
+
3
+ require "rubygems"
4
+ gem "minitest"
5
+
6
+ # To make testing/debugging easier, test within this source tree versus an installed gem
7
+ dir = File.dirname(__FILE__)
8
+ root = File.expand_path(File.join(dir, '..'))
9
+ lib = File.expand_path(File.join(root, 'lib'))
10
+ ext = File.expand_path(File.join(root, 'ext', 'ruby_prof'))
11
+
12
+ $LOAD_PATH << lib
13
+ $LOAD_PATH << ext
14
+
15
+ require 'ruby-prof'
16
+
17
+ # stub deprecation warnings
18
+ module RubyProf
19
+ module SuppressDeprecationWarnings
20
+ def deprecation_warning(*args)
21
+ super if ENV['SHOW_RUBY_PROF_DEPRECATION_WARNINGS'] == '1'
22
+ end
23
+ end
24
+ extend SuppressDeprecationWarnings
25
+ end
26
+
27
+ require 'minitest/autorun'
28
+
29
+ class TestCase < Minitest::Test
30
+ # I know this sucks, but ...
31
+ def assert_nothing_raised(*)
32
+ yield
33
+ end
34
+
35
+ def before_setup
36
+ # make sure to exclude all threads except the one running the test
37
+ # minitest allocates a thread pool and they would otherwise show
38
+ # up in the profile data, breaking tests randomly
39
+ RubyProf.exclude_threads = Thread.list.select{|t| t != Thread.current}
40
+ end
41
+
42
+ def after_teardown
43
+ # reset exclude threads after testing
44
+ RubyProf.exclude_threads = nil
45
+ end
46
+ end
47
+
48
+ require File.expand_path('../prime', __FILE__)
49
+
50
+ # Some classes used in measurement tests
51
+ module RubyProf
52
+ class C1
53
+ def C1.hello
54
+ sleep(0.1)
55
+ end
56
+
57
+ def hello
58
+ sleep(0.2)
59
+ end
60
+ end
61
+
62
+ module M1
63
+ def hello
64
+ sleep(0.3)
65
+ end
66
+ end
67
+
68
+ class C2
69
+ include M1
70
+ extend M1
71
+ end
72
+
73
+ class C3
74
+ def hello
75
+ sleep(0.4)
76
+ end
77
+ end
78
+
79
+ module M4
80
+ def hello
81
+ sleep(0.5)
82
+ end
83
+ end
84
+
85
+ module M5
86
+ include M4
87
+ def goodbye
88
+ hello
89
+ end
90
+ end
91
+
92
+ class C6
93
+ include M5
94
+ def test
95
+ goodbye
96
+ end
97
+ end
98
+
99
+ class C7
100
+ def self.busy_wait
101
+ t = Time.now.to_f
102
+ while Time.now.to_f - t < 0.1; end
103
+ end
104
+
105
+ def self.sleep_wait
106
+ sleep 0.1
107
+ end
108
+
109
+ def busy_wait
110
+ t = Time.now.to_f
111
+ while Time.now.to_f - t < 0.2; end
112
+ end
113
+
114
+ def sleep_wait
115
+ sleep 0.2
116
+ end
117
+ end
118
+
119
+ module M7
120
+ def busy_wait
121
+ t = Time.now.to_f
122
+ while Time.now.to_f - t < 0.3; end
123
+ end
124
+
125
+ def sleep_wait
126
+ sleep 0.3
127
+ end
128
+ end
129
+
130
+ class C8
131
+ include M7
132
+ extend M7
133
+ end
134
+
135
+ def self.ruby_major_version
136
+ match = RUBY_VERSION.match(/(\d)\.(\d)/)
137
+ return Integer(match[1])
138
+ end
139
+
140
+ def self.ruby_minor_version
141
+ match = RUBY_VERSION.match(/(\d)\.(\d)/)
142
+ return Integer(match[2])
143
+ end
144
+
145
+ def self.parent_object
146
+ if ruby_major_version == 1 && ruby_minor_version == 8
147
+ Object
148
+ else
149
+ BasicObject
150
+ end
151
+ end
152
+
153
+ def self.ruby_2?
154
+ ruby_major_version == 2
155
+ end
156
+
157
+ # store printer output in this directory
158
+ def self.tmpdir
159
+ path = File.expand_path('../../tmp', __FILE__)
160
+ unless Dir.exist?(path)
161
+ Dir.mkdir(path)
162
+ end
163
+ path
164
+ end
165
+ end
166
+
167
+ module MemoryTestHelper
168
+ def memory_test_helper
169
+ result = RubyProf.profile {Array.new}
170
+ total = result.threads.first.methods.inject(0) { |sum, m| sum + m.total_time }
171
+ assert(total < 1_000_000, 'Total should not have subtract overflow error')
172
+ total
173
+ end
174
+ end
175
+
176
+ module PrinterTestHelper
177
+ Metrics = Struct.new(:name, :total, :self_t, :wait, :child, :calls)
178
+ class Metrics
179
+ def pp
180
+ "%s[total: %.2f, self: %.2f, wait: %.2f, child: %.2f, calls: %s]" %
181
+ [name, total, self_t, wait, child, calls]
182
+ end
183
+ end
184
+
185
+ Entry = Struct.new(:total_p, :self_p, :metrics, :parents, :children)
186
+ class Entry
187
+ def child(name)
188
+ children.detect{|m| m.name == name}
189
+ end
190
+
191
+ def parent(name)
192
+ parents.detect{|m| m.name == name}
193
+ end
194
+
195
+ def pp
196
+ res = ""
197
+ res << "NODE (total%%: %.2f, self%%: %.2f) %s\n" % [total_p, self_p, metrics.pp]
198
+ res << " PARENTS:\n"
199
+ parents.each {|m| res << " " + m.pp << "\n"}
200
+ res << " CHILDREN:\n"
201
+ children.each {|m| res << " " + m.pp << "\n"}
202
+ res
203
+ end
204
+ end
205
+
206
+ class MetricsArray < Array
207
+ def metrics_for(name)
208
+ detect {|e| e.metrics.name == name}
209
+ end
210
+
211
+ def pp(io = STDOUT)
212
+ entries = map do |e|
213
+ begin
214
+ e.pp
215
+ rescue
216
+ puts $!.message + e.inspect
217
+ ""
218
+ end
219
+ end
220
+ io.puts entries.join("--------------------------------------------------\n")
221
+ end
222
+
223
+ def self.parse(str)
224
+ res = new
225
+ entry = nil
226
+ relatives = []
227
+ state = :preamble
228
+
229
+ str.each_line do |l|
230
+ line = l.chomp.strip
231
+ if line =~ /-----/
232
+ if state == :preamble
233
+ state = :parsing_parents
234
+ entry = Entry.new
235
+ elsif state == :parsing_parents
236
+ entry = Entry.new
237
+ elsif state == :parsing_children
238
+ entry.children = relatives
239
+ res << entry
240
+ entry = Entry.new
241
+ relatives = []
242
+ state = :parsing_parents
243
+ end
244
+ elsif line =~ /^\s*$/ || line =~ /indicates recursively called methods/
245
+ next
246
+ elsif state != :preamble
247
+ elements = line.split(/\s+/)
248
+ method = elements.pop
249
+ numbers = elements[0..-2].map(&:to_f)
250
+ metrics = Metrics.new(method, *numbers[-4..-1], elements[-1])
251
+ if numbers.size == 6
252
+ entry.metrics = metrics
253
+ entry.total_p = numbers[0]
254
+ entry.self_p = numbers[1]
255
+ entry.parents = relatives
256
+ entry.children = relatives = []
257
+ state = :parsing_children
258
+ res << entry
259
+ else
260
+ relatives << metrics
261
+ end
262
+ end
263
+ end
264
+ res
265
+ end
266
+ end
267
+ end
@@ -0,0 +1,187 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: UTF-8
3
+
4
+ require File.expand_path('../test_helper', __FILE__)
5
+ require 'timeout'
6
+ require 'benchmark'
7
+
8
+ # -- Tests ----
9
+ class ThreadTest < TestCase
10
+ def setup
11
+ # Need to use wall time for this test due to the sleep calls
12
+ RubyProf::measure_mode = RubyProf::WALL_TIME
13
+ end
14
+
15
+ def test_thread_count
16
+ RubyProf.start
17
+
18
+ thread = Thread.new do
19
+ sleep(1)
20
+ end
21
+
22
+ thread.join
23
+ result = RubyProf.stop
24
+ assert_equal(2, result.threads.length)
25
+ end
26
+
27
+ def test_thread_identity
28
+ RubyProf.start
29
+ sleep_thread = Thread.new do
30
+ sleep(1)
31
+ end
32
+ sleep_thread.join
33
+ result = RubyProf.stop
34
+
35
+ thread_ids = result.threads.map {|thread| thread.id}.sort
36
+ threads = [Thread.current, sleep_thread]
37
+ assert_equal(2, result.threads.length)
38
+
39
+ assert(thread_ids.include?(threads[0].object_id))
40
+ assert(thread_ids.include?(threads[1].object_id))
41
+
42
+ assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[0]))
43
+ assert(threads.include?(ObjectSpace._id2ref(thread_ids[0])))
44
+
45
+ assert_instance_of(Thread, ObjectSpace._id2ref(thread_ids[1]))
46
+ assert(threads.include?(ObjectSpace._id2ref(thread_ids[1])))
47
+ end
48
+
49
+ def test_thread_timings
50
+ RubyProf.start
51
+ thread = Thread.new do
52
+ sleep 0
53
+ # force it to hit thread.join, below, first
54
+ # thus forcing sleep(1), below, to be counted as (wall) self_time
55
+ # since we currently count time "in some other thread" as self.wait_time
56
+ # for whatever reason
57
+ sleep(1)
58
+ end
59
+ thread.join
60
+ result = RubyProf.stop
61
+
62
+ # Check background thread
63
+ assert_equal(2, result.threads.length)
64
+
65
+ rp_thread = result.threads.detect {|t| t.id == thread.object_id}
66
+ methods = rp_thread.methods.sort.reverse
67
+ # fails on travis. why?
68
+ # expected_methods = ["ThreadTest#test_thread_timings", "Kernel#sleep"]
69
+ # assert_equal(expected_methods, methods.map(&:full_name))
70
+
71
+ method = methods[0]
72
+ assert_equal('ThreadTest#test_thread_timings', method.full_name)
73
+ assert_equal(1, method.called)
74
+ assert_in_delta(1, method.total_time, 0.05)
75
+ assert_in_delta(0, method.self_time, 0.05)
76
+ assert_in_delta(0, method.wait_time, 0.05)
77
+ assert_in_delta(1, method.children_time, 0.05)
78
+ assert_equal(1, method.call_infos.length)
79
+ call_info = method.call_infos[0]
80
+ assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
81
+ assert_equal(1, call_info.children.length)
82
+
83
+ method = methods[1]
84
+ assert_equal('Kernel#sleep', method.full_name)
85
+ assert_equal(2, method.called)
86
+ assert_in_delta(1, method.total_time, 0.05)
87
+ assert_in_delta(1.0, method.self_time, 0.05)
88
+ assert_in_delta(0, method.wait_time, 0.05)
89
+ assert_in_delta(0, method.children_time, 0.05)
90
+
91
+ assert_equal(1, method.call_infos.length)
92
+ call_info = method.call_infos[0]
93
+ assert_equal('ThreadTest#test_thread_timings->Kernel#sleep', call_info.call_sequence)
94
+ assert_equal(0, call_info.children.length)
95
+
96
+ # Check foreground thread
97
+ rp_thread = result.threads.detect {|athread| athread.id == Thread.current.object_id}
98
+ methods = rp_thread.methods.sort.reverse
99
+ assert_equal(4, methods.length)
100
+ methods = methods.sort.reverse
101
+
102
+ method = methods[0]
103
+ assert_equal('ThreadTest#test_thread_timings', method.full_name)
104
+ # the sub calls to Object#new, when popped,
105
+ # cause the parent frame to be created for method #test_thread_timings, which means a +1 when it's popped in the end
106
+ # xxxx a test that shows it the other way, too (never creates parent frame--if that's even possible)
107
+ assert_equal(1, method.called)
108
+ assert_in_delta(1, method.total_time, 0.05)
109
+ assert_in_delta(0, method.self_time, 0.05)
110
+ assert_in_delta(0, method.wait_time, 0.05)
111
+ assert_in_delta(1, method.children_time, 0.05)
112
+
113
+ assert_equal(1, method.call_infos.length)
114
+ call_info = method.call_infos[0]
115
+ assert_equal('ThreadTest#test_thread_timings', call_info.call_sequence)
116
+ assert_equal(2, call_info.children.length)
117
+
118
+ method = methods[1]
119
+ assert_equal('Thread#join', method.full_name)
120
+ assert_equal(1, method.called)
121
+ assert_in_delta(1, method.total_time, 0.05)
122
+ assert_in_delta(0, method.self_time, 0.05)
123
+ assert_in_delta(1.0, method.wait_time, 0.05)
124
+ assert_in_delta(0, method.children_time, 0.05)
125
+
126
+ assert_equal(1, method.call_infos.length)
127
+ call_info = method.call_infos[0]
128
+ assert_equal('ThreadTest#test_thread_timings->Thread#join', call_info.call_sequence)
129
+ assert_equal(0, call_info.children.length)
130
+
131
+ method = methods[2]
132
+ assert_equal('<Class::Thread>#new', method.full_name)
133
+ assert_equal(1, method.called)
134
+ assert_in_delta(0, method.total_time, 0.05)
135
+ assert_in_delta(0, method.self_time, 0.05)
136
+ assert_in_delta(0, method.wait_time, 0.05)
137
+ assert_in_delta(0, method.children_time, 0.05)
138
+
139
+ assert_equal(1, method.call_infos.length)
140
+ call_info = method.call_infos[0]
141
+ assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new', call_info.call_sequence)
142
+ assert_equal(1, call_info.children.length)
143
+
144
+ method = methods[3]
145
+ assert_equal('Thread#initialize', method.full_name)
146
+ assert_equal(1, method.called)
147
+ assert_in_delta(0, method.total_time, 0.05)
148
+ assert_in_delta(0, method.self_time, 0.05)
149
+ assert_in_delta(0, method.wait_time, 0.05)
150
+ assert_in_delta(0, method.children_time, 0.05)
151
+
152
+ assert_equal(1, method.call_infos.length)
153
+ call_info = method.call_infos[0]
154
+ assert_equal('ThreadTest#test_thread_timings-><Class::Thread>#new->Thread#initialize', call_info.call_sequence)
155
+ assert_equal(0, call_info.children.length)
156
+ end
157
+
158
+ # useless test: what does it test?
159
+ def test_thread_back_and_forth
160
+ result = nil
161
+ seconds = Benchmark.realtime do
162
+ result = RubyProf.profile do
163
+ a = Thread.new { 100_000.times { sleep 0 }}
164
+ b = Thread.new { 100_000.times { sleep 0 }}
165
+ a.join
166
+ b.join
167
+ end
168
+ end
169
+ methods = result.threads.map {|thread| thread.methods}
170
+ timings = methods.flatten.sort
171
+ assert(timings[-1].total_time < seconds)
172
+ end
173
+
174
+ # useless test: what does it test?
175
+ def test_thread
176
+ RubyProf.profile do
177
+ begin
178
+ Timeout::timeout(2) do
179
+ while true
180
+ next
181
+ end
182
+ end
183
+ rescue Timeout::Error
184
+ end
185
+ end
186
+ end
187
+ end