summaryrefslogtreecommitdiff
path: root/test/ruby/test_thread_queue.rb
diff options
context:
space:
mode:
Diffstat (limited to 'test/ruby/test_thread_queue.rb')
-rw-r--r--test/ruby/test_thread_queue.rb166
1 files changed, 124 insertions, 42 deletions
diff --git a/test/ruby/test_thread_queue.rb b/test/ruby/test_thread_queue.rb
index e96107cea7..723450ad23 100644
--- a/test/ruby/test_thread_queue.rb
+++ b/test/ruby/test_thread_queue.rb
@@ -54,15 +54,37 @@ class TestThreadQueue < Test::Unit::TestCase
assert_equal 0, to_workers.size
end
+ def test_queue_initialize
+ e = Class.new do
+ include Enumerable
+ def initialize(list) @list = list end
+ def each(&block) @list.each(&block) end
+ end
+
+ all_assertions_foreach(nil,
+ [Array, "Array"],
+ [e, "Enumerable"],
+ [Struct.new(:to_a), "Array-like"],
+ ) do |a, type|
+ q = Thread::Queue.new(a.new([1,2,3]))
+ assert_equal(3, q.size, type)
+ assert_not_predicate(q, :empty?, type)
+ assert_equal(1, q.pop, type)
+ assert_equal(2, q.pop, type)
+ assert_equal(3, q.pop, type)
+ assert_predicate(q, :empty?, type)
+ end
+ end
+
def test_sized_queue_initialize
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
assert_equal 1, q.max
- assert_raise(ArgumentError) { SizedQueue.new(0) }
- assert_raise(ArgumentError) { SizedQueue.new(-1) }
+ assert_raise(ArgumentError) { Thread::SizedQueue.new(0) }
+ assert_raise(ArgumentError) { Thread::SizedQueue.new(-1) }
end
def test_sized_queue_assign_max
- q = SizedQueue.new(2)
+ q = Thread::SizedQueue.new(2)
assert_equal(2, q.max)
q.max = 1
assert_equal(1, q.max)
@@ -82,37 +104,90 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_queue_pop_interrupt
- q = Queue.new
+ q = Thread::Queue.new
t1 = Thread.new { q.pop }
sleep 0.01 until t1.stop?
t1.kill.join
assert_equal(0, q.num_waiting)
end
+ def test_queue_pop_timeout
+ q = Thread::Queue.new
+ q << 1
+ assert_equal 1, q.pop(timeout: 1)
+
+ t1 = Thread.new { q.pop(timeout: 1) }
+ assert_equal t1, t1.join(2)
+ assert_nil t1.value
+
+ t2 = Thread.new { q.pop(timeout: 0.1) }
+ assert_equal t2, t2.join(1)
+ assert_nil t2.value
+ ensure
+ t1&.kill&.join
+ t2&.kill&.join
+ end
+
def test_queue_pop_non_block
- q = Queue.new
+ q = Thread::Queue.new
assert_raise_with_message(ThreadError, /empty/) do
q.pop(true)
end
end
def test_sized_queue_pop_interrupt
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
t1 = Thread.new { q.pop }
sleep 0.01 until t1.stop?
t1.kill.join
assert_equal(0, q.num_waiting)
end
+ def test_sized_queue_pop_timeout
+ q = Thread::SizedQueue.new(1)
+
+ q << 1
+ assert_equal 1, q.pop(timeout: 1)
+
+ t1 = Thread.new { q.pop(timeout: 1) }
+ assert_equal t1, t1.join(2)
+ assert_nil t1.value
+
+ t2 = Thread.new { q.pop(timeout: 0.1) }
+ assert_equal t2, t2.join(1)
+ assert_nil t2.value
+ ensure
+ t1&.kill&.join
+ t2&.kill&.join
+ end
+
def test_sized_queue_pop_non_block
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
assert_raise_with_message(ThreadError, /empty/) do
q.pop(true)
end
end
+ def test_sized_queue_push_timeout
+ q = Thread::SizedQueue.new(1)
+
+ q << 1
+ assert_equal 1, q.size
+
+ t1 = Thread.new { q.push(2, timeout: 1) }
+ assert_equal t1, t1.join(2)
+ assert_nil t1.value
+
+ t2 = Thread.new { q.push(2, timeout: 0.1) }
+ assert_equal t2, t2.join(1)
+ assert_nil t2.value
+ ensure
+ t1&.kill&.join
+ t2&.kill&.join
+ end
+
def test_sized_queue_push_interrupt
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
q.push(1)
assert_raise_with_message(ThreadError, /full/) do
q.push(2, true)
@@ -120,7 +195,7 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_sized_queue_push_non_block
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
q.push(1)
t1 = Thread.new { q.push(2) }
sleep 0.01 until t1.stop?
@@ -129,15 +204,17 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_thr_kill
+ omit "[Bug #18613]" if /freebsd/ =~ RUBY_PLATFORM
+
bug5343 = '[ruby-core:39634]'
Dir.mktmpdir {|d|
- timeout = 60
+ timeout = EnvUtil.apply_timeout_scale(60)
total_count = 250
begin
- assert_normal_exit(<<-"_eom", bug5343, {:timeout => timeout, :chdir=>d})
+ assert_normal_exit(<<-"_eom", bug5343, **{:timeout => timeout, :chdir=>d})
#{total_count}.times do |i|
open("test_thr_kill_count", "w") {|f| f.puts i }
- queue = Queue.new
+ queue = Thread::Queue.new
r, w = IO.pipe
th = Thread.start {
queue.push(nil)
@@ -156,20 +233,20 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_queue_push_return_value
- q = Queue.new
+ q = Thread::Queue.new
retval = q.push(1)
assert_same q, retval
end
def test_queue_clear_return_value
- q = Queue.new
+ q = Thread::Queue.new
retval = q.clear
assert_same q, retval
end
def test_sized_queue_clear
- # Fill queue, then test that SizedQueue#clear wakes up all waiting threads
- sq = SizedQueue.new(2)
+ # Fill queue, then test that Thread::SizedQueue#clear wakes up all waiting threads
+ sq = Thread::SizedQueue.new(2)
2.times { sq << 1 }
t1 = Thread.new do
@@ -190,19 +267,19 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_sized_queue_push_return_value
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
retval = q.push(1)
assert_same q, retval
end
def test_sized_queue_clear_return_value
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
retval = q.clear
assert_same q, retval
end
def test_sized_queue_throttle
- q = SizedQueue.new(1)
+ q = Thread::SizedQueue.new(1)
i = 0
consumer = Thread.new do
while q.pop
@@ -225,7 +302,7 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_queue_thread_raise
- q = Queue.new
+ q = Thread::Queue.new
th1 = Thread.new do
begin
q.pop
@@ -255,7 +332,7 @@ class TestThreadQueue < Test::Unit::TestCase
def test_dup
bug9440 = '[ruby-core:59961] [Bug #9440]'
- q = Queue.new
+ q = Thread::Queue.new
assert_raise(NoMethodError, bug9440) do
q.dup
end
@@ -265,12 +342,12 @@ class TestThreadQueue < Test::Unit::TestCase
def test_dump
bug9674 = '[ruby-core:61677] [Bug #9674]'
- q = Queue.new
+ q = Thread::Queue.new
assert_raise_with_message(TypeError, /#{Queue}/, bug9674) do
Marshal.dump(q)
end
- sq = SizedQueue.new(1)
+ sq = Thread::SizedQueue.new(1)
assert_raise_with_message(TypeError, /#{SizedQueue}/, bug9674) do
Marshal.dump(sq)
end
@@ -282,7 +359,7 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_close
- [->{Queue.new}, ->{SizedQueue.new 3}].each do |qcreate|
+ [->{Thread::Queue.new}, ->{Thread::SizedQueue.new 3}].each do |qcreate|
q = qcreate.call
assert_equal false, q.closed?
q << :something
@@ -321,15 +398,15 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_queue_close_wakeup
- close_wakeup(15, 18){Queue.new}
+ close_wakeup(15, 18){Thread::Queue.new}
end
def test_size_queue_close_wakeup
- close_wakeup(5, 8){SizedQueue.new 9}
+ close_wakeup(5, 8){Thread::SizedQueue.new 9}
end
def test_sized_queue_one_closed_interrupt
- q = SizedQueue.new 1
+ q = Thread::SizedQueue.new 1
q << :one
t1 = Thread.new {
Thread.current.report_on_exception = false
@@ -346,7 +423,7 @@ class TestThreadQueue < Test::Unit::TestCase
# make sure that shutdown state is handled properly by empty? for the non-blocking case
def test_empty_non_blocking
- q = SizedQueue.new 3
+ q = Thread::SizedQueue.new 3
3.times{|i| q << i}
# these all block cos the queue is full
@@ -372,13 +449,13 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_sized_queue_closed_push_non_blocking
- q = SizedQueue.new 7
+ q = Thread::SizedQueue.new 7
q.close
assert_raise_with_message(ClosedQueueError, /queue closed/){q.push(non_block=true)}
end
def test_blocked_pushers
- q = SizedQueue.new 3
+ q = Thread::SizedQueue.new 3
prod_threads = 6.times.map do |i|
thr = Thread.new{
Thread.current.report_on_exception = false
@@ -424,9 +501,9 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_deny_pushers
- [->{Queue.new}, ->{SizedQueue.new 3}].each do |qcreate|
+ [->{Thread::Queue.new}, ->{Thread::SizedQueue.new 3}].each do |qcreate|
q = qcreate[]
- synq = Queue.new
+ synq = Thread::Queue.new
prod_threads = 20.times.map do |i|
Thread.new {
synq.pop
@@ -444,7 +521,7 @@ class TestThreadQueue < Test::Unit::TestCase
# size should account for waiting pushers during shutdown
def sized_queue_size_close
- q = SizedQueue.new 4
+ q = Thread::SizedQueue.new 4
4.times{|i| q << i}
Thread.new{ q << 5 }
Thread.new{ q << 6 }
@@ -456,7 +533,7 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_blocked_pushers_empty
- q = SizedQueue.new 3
+ q = Thread::SizedQueue.new 3
prod_threads = 6.times.map do |i|
Thread.new{
Thread.current.report_on_exception = false
@@ -488,14 +565,14 @@ class TestThreadQueue < Test::Unit::TestCase
# test thread wakeup on one-element SizedQueue with close
def test_one_element_sized_queue
- q = SizedQueue.new 1
+ q = Thread::SizedQueue.new 1
t = Thread.new{ q.pop }
q.close
assert_nil t.value
end
def test_close_twice
- [->{Queue.new}, ->{SizedQueue.new 3}].each do |qcreate|
+ [->{Thread::Queue.new}, ->{Thread::SizedQueue.new 3}].each do |qcreate|
q = qcreate[]
q.close
assert_nothing_raised(ClosedQueueError){q.close}
@@ -503,7 +580,7 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_queue_close_multi_multi
- q = SizedQueue.new rand(800..1200)
+ q = Thread::SizedQueue.new rand(800..1200)
count_items = rand(3000..5000)
count_producers = rand(10..20)
@@ -558,16 +635,21 @@ class TestThreadQueue < Test::Unit::TestCase
def test_queue_with_trap
if ENV['APPVEYOR'] == 'True' && RUBY_PLATFORM.match?(/mswin/)
- skip 'This test fails too often on AppVeyor vs140'
+ omit 'This test fails too often on AppVeyor vs140'
+ end
+ if RUBY_PLATFORM.match?(/mingw/)
+ omit 'This test fails too often on MinGW'
end
+
assert_in_out_err([], <<-INPUT, %w(INT INT exit), [])
- q = Queue.new
+ q = Thread::Queue.new
trap(:INT){
q.push 'INT'
}
Thread.new{
loop{
Process.kill :INT, $$
+ sleep 0.1
}
}
puts q.pop
@@ -577,8 +659,8 @@ class TestThreadQueue < Test::Unit::TestCase
end
def test_fork_while_queue_waiting
- q = Queue.new
- sq = SizedQueue.new(1)
+ q = Thread::Queue.new
+ sq = Thread::SizedQueue.new(1)
thq = Thread.new { q.pop }
thsq = Thread.new { sq.pop }
Thread.pass until thq.stop? && thsq.stop?