1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
|
require './test/test_helper'
require 'backports/2.3.0/queue/close'
require 'backports/ractor/filtered_queue'
class FilteredQueueTest < Test::Unit::TestCase
def setup
@q = ::Backports::FilteredQueue.new
end
def assert_remains(*values)
remain = []
remain << @q.pop until @q.empty?
assert_equal values, remain
end
def test_basic
@q << 1 << 2
x = []
x << @q.pop
@q << 3
x << @q.pop
x << @q.pop
t = Thread.new { sleep(0.1); @q << 4 << 5}
x << @q.pop
t.join
assert_equal([1,2,3,4], x)
assert_remains(5)
end
def test_close
Thread.new { sleep(0.2); @q.close }
assert_raise(::Backports::FilteredQueue::ClosedQueueError) { @q.pop }
assert_raise(::Backports::FilteredQueue::ClosedQueueError) { @q.pop }
assert_raise(::Backports::FilteredQueue::ClosedQueueError) { @q.pop(timeout: 0) }
assert_raise(::Backports::FilteredQueue::ClosedQueueError) { @q << 42 }
end
def test_close_after
@q << 1 << 2
@q.close
assert_equal(1, @q.pop)
assert_equal(2, @q.pop)
assert_raise(::Backports::FilteredQueue::ClosedQueueError) { @q.pop }
end
def test_timeout
assert_raise(::Backports::FilteredQueue::TimeoutError) { @q.pop(timeout: 0) }
Thread.new { sleep(0.2); @q << :done }
assert_raise(::Backports::FilteredQueue::TimeoutError) { @q.pop(timeout: 0.1) }
assert_equal(:done, @q.pop(timeout: 0.2))
end
def assert_eventually_equal(value)
100.times do
return true if value == yield
sleep(0.01)
end
assert value == yield
end
def test_filter
# send 0 to 7 to queue, with filters for 0 to 2.
# start queue with `before` elements already present
(0..4).each do |before|
other = [4,5,6,7]
calls = 0
before.times { @q << other.shift }
t = 3.times.map do |i|
Thread.new do
@q.pop { |n| calls += 1; Thread.pass; n == i }
end
end
Thread.pass
other.each { |i| @q << i }
assert_eventually_equal(3) {@q.num_waiting}
assert_eventually_equal(3 * 4) {calls}
@q << :extra
assert_eventually_equal(3 * 5) {calls}
@q << 0 << 1 << 2 << 3
t.each(&:join)
assert_equal 0, @q.num_waiting
assert_remains 4, 5, 6, 7, :extra, 3
end
end
def test_non_standard_filters
@q << 1 << 2 << 3
@q.pop { break }
@q.pop { raise 'err' } rescue nil
assert_remains 3
end
def test_recursive_filter
[
[0, :other],
[:other, 0],
].each do |a, b|
@q << :first << a << b << :last
inner = nil
a = @q.pop do
inner = @q.pop { |x| x == 0}
false # => ignored
end
assert_equal :first, a
assert_equal 0, inner
assert_remains :other, :last
end
end
end
|