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 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
describe :sizedqueue_enq, shared: true do
it "blocks if queued elements exceed size" do
q = @object.call(1)
q.size.should == 0
q.send(@method, :first_element)
q.size.should == 1
blocked_thread = Thread.new { q.send(@method, :second_element) }
sleep 0.01 until blocked_thread.stop?
q.size.should == 1
q.pop.should == :first_element
blocked_thread.join
q.size.should == 1
q.pop.should == :second_element
q.size.should == 0
end
it "raises a ThreadError if queued elements exceed size when not blocking" do
q = @object.call(2)
non_blocking = true
add_to_queue = -> { q.send(@method, Object.new, non_blocking) }
q.size.should == 0
add_to_queue.call
q.size.should == 1
add_to_queue.call
q.size.should == 2
add_to_queue.should raise_error(ThreadError)
end
it "interrupts enqueuing threads with ClosedQueueError when the queue is closed" do
q = @object.call(1)
q << 1
t = Thread.new {
-> { q.send(@method, 2) }.should raise_error(ClosedQueueError, "queue closed")
}
Thread.pass until q.num_waiting == 1
q.close
t.join
q.pop.should == 1
end
describe "with a timeout" do
ruby_version_is "3.2" do
it "returns self if the item was pushed in time" do
q = @object.call(1)
q << 1
t = Thread.new {
q.send(@method, 2, timeout: TIME_TOLERANCE).should == q
}
Thread.pass until t.status == "sleep" && q.num_waiting == 1
q.pop
t.join
end
it "does nothing if the timeout is nil" do
q = @object.call(1)
q << 1
t = Thread.new {
q.send(@method, 2, timeout: nil).should == q
}
t.join(0.2).should == nil
q.pop
t.join
end
it "returns nil if no space is available and timeout is 0" do
q = @object.call(1)
q.send(@method, 1, timeout: 0).should == q
q.send(@method, 2, timeout: 0).should == nil
end
it "returns nil if no space is available in time" do
q = @object.call(1)
q << 1
Thread.new {
q.send(@method, 2, timeout: 0.001).should == nil
}.join
end
it "raise TypeError if timeout is not a valid numeric" do
q = @object.call(1)
-> {
q.send(@method, 2, timeout: "1")
}.should raise_error(TypeError, "no implicit conversion to float from string")
-> {
q.send(@method, 2, timeout: false)
}.should raise_error(TypeError, "no implicit conversion to float from false")
end
it "raise ArgumentError if non_block = true is passed too" do
q = @object.call(1)
-> {
q.send(@method, 2, true, timeout: 1)
}.should raise_error(ArgumentError, "can't set a timeout if non_block is enabled")
end
it "raise ClosedQueueError when closed before enqueued" do
q = @object.call(1)
q.close
-> { q.send(@method, 2, timeout: 1) }.should raise_error(ClosedQueueError, "queue closed")
end
it "interrupts enqueuing threads with ClosedQueueError when the queue is closed" do
q = @object.call(1)
q << 1
t = Thread.new {
-> { q.send(@method, 1, timeout: TIME_TOLERANCE) }.should raise_error(ClosedQueueError, "queue closed")
}
Thread.pass until q.num_waiting == 1
q.close
t.join
q.pop.should == 1
end
end
end
end
|