ruby-prof 1.4.5-x64-mingw-ucrt → 1.5.0-x64-mingw-ucrt

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.
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../test_helper', __FILE__)
4
+
5
+ class MeasurementTest < Minitest::Test
6
+ def test_initialize
7
+ measurement = RubyProf::Measurement.new(3.3, 2.2, 1.1, 4)
8
+ assert_equal(3.3, measurement.total_time)
9
+ assert_equal(2.2, measurement.self_time)
10
+ assert_equal(1.1, measurement.wait_time)
11
+ assert_equal(4, measurement.called)
12
+ end
13
+
14
+ def test_clone
15
+ measurement_1 = RubyProf::Measurement.new(3.3, 2.2, 1.1, 4)
16
+ measurement_2 = measurement_1.clone
17
+
18
+ refute(measurement_1.equal?(measurement_2))
19
+ refute(measurement_1.eql?(measurement_2))
20
+ refute(measurement_1 == measurement_2)
21
+
22
+ assert_equal(measurement_1.total_time, measurement_2.total_time)
23
+ assert_equal(measurement_1.self_time, measurement_2.self_time)
24
+ assert_equal(measurement_1.wait_time, measurement_2.wait_time)
25
+ assert_equal(measurement_1.called, measurement_2.called)
26
+ end
27
+
28
+ def test_dup
29
+ measurement_1 = RubyProf::Measurement.new(3.3, 2.2, 1.1, 4)
30
+ measurement_2 = measurement_1.dup
31
+
32
+ refute(measurement_1.equal?(measurement_2))
33
+ refute(measurement_1.eql?(measurement_2))
34
+ refute(measurement_1 == measurement_2)
35
+
36
+ assert_equal(measurement_1.total_time, measurement_2.total_time)
37
+ assert_equal(measurement_1.self_time, measurement_2.self_time)
38
+ assert_equal(measurement_1.wait_time, measurement_2.wait_time)
39
+ assert_equal(measurement_1.called, measurement_2.called)
40
+ end
41
+
42
+ def test_merge!
43
+ measurement1 = RubyProf::Measurement.new(3.3, 2.2, 1.1, 4)
44
+ measurement2 = RubyProf::Measurement.new(3, 2, 1, 3)
45
+
46
+ measurement1.merge!(measurement2)
47
+
48
+ assert_equal(6.3, measurement1.total_time)
49
+ assert_equal(4.2, measurement1.self_time)
50
+ assert_equal(2.1, measurement1.wait_time)
51
+ assert_equal(7, measurement1.called)
52
+
53
+ assert_equal(3, measurement2.total_time)
54
+ assert_equal(2, measurement2.self_time)
55
+ assert_equal(1, measurement2.wait_time)
56
+ assert_equal(3, measurement2.called)
57
+ end
58
+
59
+ def test_set_total_time
60
+ measurement = RubyProf::Measurement.new(4, 3, 1, 1)
61
+ measurement.total_time = 5.1
62
+ assert_equal(5.1, measurement.total_time)
63
+ end
64
+
65
+ def test_set_self_time
66
+ measurement = RubyProf::Measurement.new(4, 3, 1, 1)
67
+ measurement.self_time = 3.1
68
+ assert_equal(3.1, measurement.self_time)
69
+ end
70
+
71
+ def test_set_wait_time
72
+ measurement = RubyProf::Measurement.new(4, 3, 1, 1)
73
+ measurement.wait_time = 1.1
74
+ assert_equal(1.1, measurement.wait_time)
75
+ end
76
+
77
+ def test_set_called
78
+ measurement = RubyProf::Measurement.new(4, 3, 1, 1)
79
+ measurement.called = 2
80
+ assert_equal(2, measurement.called)
81
+ end
82
+ end
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('../test_helper', __FILE__)
4
+ require 'base64'
5
+
6
+ class MethodInfoTest < Minitest::Test
7
+ def test_initialize
8
+ method_info = RubyProf::MethodInfo.new(Base64, :encode64)
9
+ assert_equal("Base64", method_info.klass_name)
10
+ assert_equal(:encode64, method_info.method_name)
11
+ assert_equal("Base64#encode64", method_info.full_name)
12
+ assert_equal(0, method_info.klass_flags)
13
+ assert_match(/base64\.rb/, method_info.source_file)
14
+ assert_kind_of(Integer, method_info.line)
15
+ refute(method_info.recursive?)
16
+
17
+ assert_kind_of(RubyProf::Measurement, method_info.measurement)
18
+ assert_kind_of(RubyProf::CallTrees, method_info.call_trees)
19
+ assert_empty(method_info.allocations)
20
+ end
21
+
22
+ def test_initialize_nil_klass
23
+ error = assert_raises(NoMethodError) do
24
+ RubyProf::MethodInfo.new(nil, nil)
25
+ end
26
+ assert_match(/undefined method `instance_method' for nil:NilClass/, error.message)
27
+ end
28
+
29
+ def test_initialize_nil_method_name
30
+ error = assert_raises(TypeError) do
31
+ RubyProf::MethodInfo.new(Base64, nil)
32
+ end
33
+ assert_equal("nil is not a symbol nor a string", error.to_s)
34
+ end
35
+
36
+ def test_initialize_unknown_location
37
+ method_info = RubyProf::MethodInfo.new(Array, :size)
38
+ assert_equal('Array', method_info.klass_name)
39
+ assert_equal(:size, method_info.method_name)
40
+ assert_nil(method_info.source_file)
41
+ assert_equal(0, method_info.line)
42
+ end
43
+
44
+ def test_measurement
45
+ method_info = RubyProf::MethodInfo.new(Base64, :encode64)
46
+ assert_equal(0, method_info.total_time)
47
+ assert_equal(0, method_info.self_time)
48
+ assert_equal(0, method_info.wait_time)
49
+ assert_equal(0, method_info.children_time)
50
+ assert_equal(0, method_info.called)
51
+ end
52
+
53
+ def test_compare
54
+ method_info_1 = RubyProf::MethodInfo.new(Base64, :encode64)
55
+ method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
56
+ assert_equal(0, method_info_1 <=> method_info_2)
57
+
58
+ method_info_1 = RubyProf::MethodInfo.new(Base64, :decode64)
59
+ method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
60
+ assert_equal(-1, method_info_1 <=> method_info_2)
61
+
62
+ method_info_1 = RubyProf::MethodInfo.new(Base64, :encode64)
63
+ method_info_2 = RubyProf::MethodInfo.new(Base64, :decode64)
64
+ assert_equal(1, method_info_1 <=> method_info_2)
65
+ end
66
+
67
+ def test_eql?
68
+ method_info_1 = RubyProf::MethodInfo.new(Base64, :encode64)
69
+ method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
70
+ assert(method_info_1.eql?(method_info_2))
71
+ end
72
+
73
+ def test_equal?
74
+ method_info_1 = RubyProf::MethodInfo.new(Base64, :encode64)
75
+ method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
76
+ refute(method_info_1.equal?(method_info_2))
77
+ end
78
+
79
+ def test_equality
80
+ method_info_1 = RubyProf::MethodInfo.new(Base64, :encode64)
81
+ method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
82
+ assert(method_info_1 == method_info_2)
83
+ end
84
+
85
+ def test_hash
86
+ method_info_1 = RubyProf::MethodInfo.new(Base64, :encode64)
87
+ method_info_2 = RubyProf::MethodInfo.new(Base64, :encode64)
88
+ assert_equal(method_info_1.hash, method_info_2.hash)
89
+ end
90
+
91
+ def test_to_s
92
+ method_info = RubyProf::MethodInfo.new(Base64, :encode64)
93
+ assert_equal("Base64#encode64 (c: 0, tt: 0.0, st: 0.0, wt: 0.0, ct: 0.0)", method_info.to_s)
94
+ end
95
+ end
data/test/profile_test.rb CHANGED
@@ -2,6 +2,7 @@
2
2
  # encoding: UTF-8
3
3
 
4
4
  require File.expand_path('../test_helper', __FILE__)
5
+ require_relative './call_tree_builder'
5
6
 
6
7
  class ProfileTest < TestCase
7
8
  def test_measure_mode
@@ -13,4 +14,88 @@ class ProfileTest < TestCase
13
14
  profile = RubyProf::Profile.new(:measure_mode => RubyProf::PROCESS_TIME)
14
15
  assert_equal("process_time", profile.measure_mode_string)
15
16
  end
17
+
18
+ def test_add_thread
19
+ profile = RubyProf::Profile.new
20
+ assert_empty(profile.threads)
21
+
22
+ method_info = RubyProf::MethodInfo.new(Array, :size)
23
+ call_tree = RubyProf::CallTree.new(method_info)
24
+ thread = RubyProf::Thread.new(call_tree, Thread.current, Fiber.current)
25
+
26
+ profile.add_thread(thread)
27
+ assert_equal(1, profile.threads.size)
28
+ assert(thread.equal?(profile.threads.first))
29
+ end
30
+
31
+ def test_add_threads
32
+ call_tree_1 = create_call_tree_1
33
+ ruby_thread_1 = Thread.new { }
34
+ thread_1 = RubyProf::Thread.new(call_tree_1, ruby_thread_1, Fiber.current)
35
+
36
+ call_tree_2 = create_call_tree_2
37
+ ruby_thread_2 = Thread.new { }
38
+ thread_2 = RubyProf::Thread.new(call_tree_2, ruby_thread_2, Fiber.current)
39
+
40
+ profile = RubyProf::Profile.new
41
+ profile.add_thread(thread_1)
42
+ profile.add_thread(thread_2)
43
+ assert_equal(1, profile.threads.count)
44
+ end
45
+
46
+ def test_add_fibers
47
+ call_tree_1 = create_call_tree_1
48
+ fiber_1 = Fiber.new { }
49
+ thread_1 = RubyProf::Thread.new(call_tree_1, Thread.current, fiber_1)
50
+
51
+ call_tree_2 = create_call_tree_2
52
+ fiber_2 = Fiber.new { }
53
+ thread_2 = RubyProf::Thread.new(call_tree_2, Thread.current, fiber_2)
54
+
55
+ profile = RubyProf::Profile.new
56
+ profile.add_thread(thread_1)
57
+ profile.add_thread(thread_2)
58
+ assert_equal(2, profile.threads.count)
59
+ end
60
+
61
+ def test_remove_thread
62
+ profile = RubyProf::Profile.new
63
+ assert_empty(profile.threads)
64
+
65
+ method_info = RubyProf::MethodInfo.new(Array, :size)
66
+ call_tree = RubyProf::CallTree.new(method_info)
67
+ thread = RubyProf::Thread.new(call_tree, Thread.current, Fiber.current)
68
+
69
+ profile.add_thread(thread)
70
+ assert_equal(1, profile.threads.size)
71
+ assert(thread.equal?(profile.threads.first))
72
+
73
+ removed = profile.remove_thread(thread)
74
+ assert_equal(0, profile.threads.size)
75
+ assert(removed.equal?(thread))
76
+ end
77
+
78
+ def test_merge
79
+ call_tree_1 = create_call_tree_1
80
+ fiber_1 = Thread.new { }
81
+ thread_1 = RubyProf::Thread.new(call_tree_1, Thread.current, fiber_1)
82
+
83
+ call_tree_2 = create_call_tree_2
84
+ fiber_2 = Thread.new { }
85
+ thread_2 = RubyProf::Thread.new(call_tree_2, Thread.current, fiber_2)
86
+
87
+ profile = RubyProf::Profile.new
88
+ profile.add_thread(thread_1)
89
+ profile.add_thread(thread_2)
90
+
91
+ profile.merge!
92
+ assert_equal(1, profile.threads.count)
93
+
94
+ assert_equal(thread_1, profile.threads.first)
95
+
96
+ assert_in_delta(11.6, thread_1.call_tree.total_time, 0.00001)
97
+ assert_in_delta(0, thread_1.call_tree.self_time, 0.00001)
98
+ assert_in_delta(0.0, thread_1.call_tree.wait_time, 0.00001)
99
+ assert_in_delta(11.6, thread_1.call_tree.children_time, 0.00001)
100
+ end
16
101
  end
@@ -375,7 +375,7 @@ class RecursiveTest < TestCase
375
375
  assert_in_delta(5, method.total_time, 0.1)
376
376
  assert_in_delta(0, method.self_time, 0.1)
377
377
  assert_in_delta(0, method.wait_time, 0.01)
378
- assert_in_delta(5, method.children_time, 0.05)
378
+ assert_in_delta(5, method.children_time, 0.1)
379
379
 
380
380
  assert_equal(2, method.call_trees.callers.length)
381
381
  call_tree = method.call_trees.callers[0]
data/test/scheduler.rb ADDED
@@ -0,0 +1,354 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is an example and simplified scheduler for test purposes.
4
+ # It is not efficient for a large number of file descriptors as it uses IO.select().
5
+ # Production Fiber schedulers should use epoll/kqueue/etc.
6
+
7
+ require 'fiber'
8
+ require 'socket'
9
+
10
+ begin
11
+ require 'io/nonblock'
12
+ rescue LoadError
13
+ # Ignore.
14
+ end
15
+
16
+ class Scheduler
17
+ def initialize
18
+ @readable = {}
19
+ @writable = {}
20
+ @waiting = {}
21
+
22
+ @closed = false
23
+
24
+ @lock = Thread::Mutex.new
25
+ @blocking = Hash.new.compare_by_identity
26
+ @ready = []
27
+
28
+ @urgent = IO.pipe
29
+ end
30
+
31
+ attr :readable
32
+ attr :writable
33
+ attr :waiting
34
+
35
+ def next_timeout
36
+ _fiber, timeout = @waiting.min_by{|key, value| value}
37
+
38
+ if timeout
39
+ offset = timeout - current_time
40
+
41
+ if offset < 0
42
+ return 0
43
+ else
44
+ return offset
45
+ end
46
+ end
47
+ end
48
+
49
+ def run
50
+ # $stderr.puts [__method__, Fiber.current].inspect
51
+
52
+ while @readable.any? or @writable.any? or @waiting.any? or @blocking.any?
53
+ # Can only handle file descriptors up to 1024...
54
+ readable, writable = IO.select(@readable.keys + [@urgent.first], @writable.keys, [], next_timeout)
55
+
56
+ # puts "readable: #{readable}" if readable&.any?
57
+ # puts "writable: #{writable}" if writable&.any?
58
+
59
+ selected = {}
60
+
61
+ readable&.each do |io|
62
+ if fiber = @readable.delete(io)
63
+ @writable.delete(io) if @writable[io] == fiber
64
+ selected[fiber] = IO::READABLE
65
+ elsif io == @urgent.first
66
+ @urgent.first.read_nonblock(1024)
67
+ end
68
+ end
69
+
70
+ writable&.each do |io|
71
+ if fiber = @writable.delete(io)
72
+ @readable.delete(io) if @readable[io] == fiber
73
+ selected[fiber] = selected.fetch(fiber, 0) | IO::WRITABLE
74
+ end
75
+ end
76
+
77
+ selected.each do |fiber, events|
78
+ fiber.resume(events)
79
+ end
80
+
81
+ if @waiting.any?
82
+ time = current_time
83
+ waiting, @waiting = @waiting, {}
84
+
85
+ waiting.each do |fiber, timeout|
86
+ if fiber.alive?
87
+ if timeout <= time
88
+ fiber.resume
89
+ else
90
+ @waiting[fiber] = timeout
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ if @ready.any?
97
+ ready = nil
98
+
99
+ @lock.synchronize do
100
+ ready, @ready = @ready, []
101
+ end
102
+
103
+ ready.each do |fiber|
104
+ fiber.resume
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ def scheduler_close
111
+ close(true)
112
+ end
113
+
114
+ def close(internal = false)
115
+ # $stderr.puts [__method__, Fiber.current].inspect
116
+
117
+ unless internal
118
+ if Fiber.scheduler == self
119
+ return Fiber.set_scheduler(nil)
120
+ end
121
+ end
122
+
123
+ if @closed
124
+ raise "Scheduler already closed!"
125
+ end
126
+
127
+ self.run
128
+ ensure
129
+ if @urgent
130
+ @urgent.each(&:close)
131
+ @urgent = nil
132
+ end
133
+
134
+ @closed ||= true
135
+
136
+ # We freeze to detect any unintended modifications after the scheduler is closed:
137
+ self.freeze
138
+ end
139
+
140
+ def closed?
141
+ @closed
142
+ end
143
+
144
+ def current_time
145
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
146
+ end
147
+
148
+ def timeout_after(duration, klass, message, &block)
149
+ fiber = Fiber.current
150
+
151
+ self.fiber do
152
+ sleep(duration)
153
+
154
+ if fiber&.alive?
155
+ fiber.raise(klass, message)
156
+ end
157
+ end
158
+
159
+ begin
160
+ yield(duration)
161
+ ensure
162
+ fiber = nil
163
+ end
164
+ end
165
+
166
+ def process_wait(pid, flags)
167
+ # $stderr.puts [__method__, pid, flags, Fiber.current].inspect
168
+
169
+ # This is a very simple way to implement a non-blocking wait:
170
+ Thread.new do
171
+ Process::Status.wait(pid, flags)
172
+ end.value
173
+ end
174
+
175
+ def io_wait(io, events, duration)
176
+ # $stderr.puts [__method__, io, events, duration, Fiber.current].inspect
177
+
178
+ unless (events & IO::READABLE).zero?
179
+ @readable[io] = Fiber.current
180
+ end
181
+
182
+ unless (events & IO::WRITABLE).zero?
183
+ @writable[io] = Fiber.current
184
+ end
185
+
186
+ Fiber.yield
187
+ ensure
188
+ @readable.delete(io)
189
+ @writable.delete(io)
190
+ end
191
+
192
+ def io_select(...)
193
+ # Emulate the operation using a non-blocking thread:
194
+ Thread.new do
195
+ IO.select(...)
196
+ end.value
197
+ end
198
+
199
+ # Used for Kernel#sleep and Thread::Mutex#sleep
200
+ def kernel_sleep(duration = nil)
201
+ # $stderr.puts [__method__, duration, Fiber.current].inspect
202
+ self.block(:sleep, duration)
203
+
204
+ return true
205
+ end
206
+
207
+ # Used when blocking on synchronization (Thread::Mutex#lock,
208
+ # Thread::Queue#pop, Thread::SizedQueue#push, ...)
209
+ def block(blocker, timeout = nil)
210
+ # $stderr.puts [__method__, blocker, timeout].inspect
211
+
212
+ fiber = Fiber.current
213
+
214
+ if timeout
215
+ @waiting[fiber] = current_time + timeout
216
+ begin
217
+ Fiber.yield
218
+ ensure
219
+ # Remove from @waiting in the case #unblock was called before the timeout expired:
220
+ @waiting.delete(fiber)
221
+ end
222
+ else
223
+ @blocking[fiber] = true
224
+ begin
225
+ Fiber.yield
226
+ ensure
227
+ @blocking.delete(fiber)
228
+ end
229
+ end
230
+ end
231
+
232
+ # Used when synchronization wakes up a previously-blocked fiber
233
+ # (Thread::Mutex#unlock, Thread::Queue#push, ...).
234
+ # This might be called from another thread.
235
+ def unblock(blocker, fiber)
236
+ # $stderr.puts [__method__, blocker, fiber].inspect
237
+ # $stderr.puts blocker.backtrace.inspect
238
+ # $stderr.puts fiber.backtrace.inspect
239
+
240
+ @lock.synchronize do
241
+ @ready << fiber
242
+ end
243
+
244
+ io = @urgent.last
245
+ io.write_nonblock('.')
246
+ end
247
+
248
+ def fiber(&block)
249
+ fiber = Fiber.new(blocking: false, &block)
250
+
251
+ fiber.resume
252
+
253
+ return fiber
254
+ end
255
+
256
+ def address_resolve(hostname)
257
+ Thread.new do
258
+ Addrinfo.getaddrinfo(hostname, nil).map(&:ip_address).uniq
259
+ end.value
260
+ end
261
+ end
262
+
263
+ class IOBufferScheduler < Scheduler
264
+ EAGAIN = -Errno::EAGAIN::Errno
265
+
266
+ def io_read(io, buffer, length, offset)
267
+ total = 0
268
+ io.nonblock = true
269
+
270
+ while true
271
+ maximum_size = buffer.size - offset
272
+ result = blocking{buffer.read(io, maximum_size, offset)}
273
+
274
+ if result > 0
275
+ total += result
276
+ offset += result
277
+ break if total >= length
278
+ elsif result == 0
279
+ break
280
+ elsif result == EAGAIN
281
+ if length > 0
282
+ self.io_wait(io, IO::READABLE, nil)
283
+ else
284
+ return result
285
+ end
286
+ elsif result < 0
287
+ return result
288
+ end
289
+ end
290
+
291
+ return total
292
+ end
293
+
294
+ def io_write(io, buffer, length, offset)
295
+ total = 0
296
+ io.nonblock = true
297
+
298
+ while true
299
+ maximum_size = buffer.size - offset
300
+ result = blocking{buffer.write(io, maximum_size, offset)}
301
+
302
+ if result > 0
303
+ total += result
304
+ offset += result
305
+ break if total >= length
306
+ elsif result == 0
307
+ break
308
+ elsif result == EAGAIN
309
+ if length > 0
310
+ self.io_wait(io, IO::WRITABLE, nil)
311
+ else
312
+ return result
313
+ end
314
+ elsif result < 0
315
+ return result
316
+ end
317
+ end
318
+
319
+ return total
320
+ end
321
+
322
+ def blocking(&block)
323
+ Fiber.blocking(&block)
324
+ end
325
+ end
326
+
327
+ class BrokenUnblockScheduler < Scheduler
328
+ def unblock(blocker, fiber)
329
+ super
330
+
331
+ raise "Broken unblock!"
332
+ end
333
+ end
334
+
335
+ class SleepingUnblockScheduler < Scheduler
336
+ # This method is invoked when the thread is exiting.
337
+ def unblock(blocker, fiber)
338
+ super
339
+
340
+ # This changes the current thread state to `THREAD_RUNNING` which causes `thread_join_sleep` to hang.
341
+ sleep(0.1)
342
+ end
343
+ end
344
+
345
+ class SleepingBlockingScheduler < Scheduler
346
+ def kernel_sleep(duration = nil)
347
+ # Deliberaly sleep in a blocking state which can trigger a deadlock if the implementation is not correct.
348
+ Fiber.blocking{sleep 0.0001}
349
+
350
+ self.block(:sleep, duration)
351
+
352
+ return true
353
+ end
354
+ end
data/test/thread_test.rb CHANGED
@@ -4,6 +4,7 @@
4
4
  require File.expand_path('../test_helper', __FILE__)
5
5
  require 'timeout'
6
6
  require 'benchmark'
7
+ require_relative './call_tree_builder'
7
8
 
8
9
  # -- Tests ----
9
10
  class ThreadTest < TestCase
@@ -12,6 +13,31 @@ class ThreadTest < TestCase
12
13
  RubyProf::measure_mode = RubyProf::WALL_TIME
13
14
  end
14
15
 
16
+ def test_initialize
17
+ method_info = RubyProf::MethodInfo.new(Array, :size)
18
+ call_tree = RubyProf::CallTree.new(method_info)
19
+ thread = RubyProf::Thread.new(call_tree, Thread.current, Fiber.current)
20
+
21
+ assert_equal(call_tree, thread.call_tree)
22
+ assert(thread)
23
+ assert(thread.id)
24
+ assert(thread.fiber_id)
25
+ end
26
+
27
+ def test_merge
28
+ call_tree_1 = create_call_tree_1
29
+ thread_1 = RubyProf::Thread.new(call_tree_1, Thread.current, Fiber.current)
30
+
31
+ call_tree_2 = create_call_tree_2
32
+ thread_2 = RubyProf::Thread.new(call_tree_2, Thread.current, Fiber.current)
33
+
34
+ thread_1.merge!(thread_2)
35
+ assert_in_delta(11.6, thread_1.call_tree.total_time, 0.00001)
36
+ assert_in_delta(0, thread_1.call_tree.self_time, 0.00001)
37
+ assert_in_delta(0.0, thread_1.call_tree.wait_time, 0.00001)
38
+ assert_in_delta(11.6, thread_1.call_tree.children_time, 0.00001)
39
+ end
40
+
15
41
  def test_thread_count
16
42
  RubyProf.start
17
43
 
@@ -71,10 +97,10 @@ class ThreadTest < TestCase
71
97
  method = methods[0]
72
98
  assert_equal('ThreadTest#test_thread_timings', method.full_name)
73
99
  assert_equal(1, method.called)
74
- assert_in_delta(1, method.total_time, 0.05)
100
+ assert_in_delta(1, method.total_time, 0.1)
75
101
  assert_in_delta(0, method.self_time, 0.05)
76
102
  assert_in_delta(0, method.wait_time, 0.05)
77
- assert_in_delta(1, method.children_time, 0.05)
103
+ assert_in_delta(1, method.children_time, 0.1)
78
104
  assert_equal(0, method.call_trees.callers.length)
79
105
 
80
106
  method = methods[1]