|
1 | 1 | require 'spec_helper' |
2 | 2 | require_relative 'thread_pool_shared' |
| 3 | +require 'thread' |
3 | 4 |
|
4 | 5 | share_examples_for :fixed_thread_pool do |
5 | 6 |
|
|
13 | 14 |
|
14 | 15 | it_should_behave_like :thread_pool |
15 | 16 |
|
16 | | - context '#initialize' do |
| 17 | + context '#initialize default values' do |
| 18 | + |
| 19 | + subject { described_class.new(5) } |
| 20 | + |
| 21 | + it 'defaults :min_length correctly' do |
| 22 | + subject.min_length.should eq 5 |
| 23 | + end |
| 24 | + |
| 25 | + it 'defaults :max_length correctly' do |
| 26 | + subject.max_length.should eq 5 |
| 27 | + end |
| 28 | + |
| 29 | + it 'defaults :overflow_policy to :abort' do |
| 30 | + subject.overflow_policy.should eq :abort |
| 31 | + end |
| 32 | + |
| 33 | + |
| 34 | + it 'defaults :idletime correctly' do |
| 35 | + subject.idletime.should eq subject.class.const_get(:DEFAULT_THREAD_IDLETIMEOUT) |
| 36 | + end |
| 37 | + |
| 38 | + it 'defaults default :max_queue to zero' do |
| 39 | + subject.max_queue.should eq 0 |
| 40 | + end |
| 41 | + |
| 42 | + end |
| 43 | + |
| 44 | + context '#initialize explicit values' do |
17 | 45 |
|
18 | 46 | it 'raises an exception when the pool length is less than one' do |
19 | 47 | lambda { |
20 | 48 | described_class.new(0) |
21 | 49 | }.should raise_error(ArgumentError) |
22 | 50 | end |
| 51 | + |
| 52 | + |
| 53 | + it 'sets explicit :max_queue correctly' do |
| 54 | + subject = described_class.new(5, :max_queue => 10) |
| 55 | + subject.max_queue.should eq 10 |
| 56 | + end |
| 57 | + |
| 58 | + it 'correctly sets valid :overflow_policy' do |
| 59 | + subject = described_class.new(5, :overflow_policy => :caller_runs) |
| 60 | + subject.overflow_policy.should eq :caller_runs |
| 61 | + end |
| 62 | + |
| 63 | + it "correctly sets valid :idletime" do |
| 64 | + subject = described_class.new(5, :idletime => 10) |
| 65 | + subject.idletime.should eq 10 |
| 66 | + end |
| 67 | + |
| 68 | + it 'raises an exception if given an invalid :overflow_policy' do |
| 69 | + expect { |
| 70 | + described_class.new(5, overflow_policy: :bogus) |
| 71 | + }.to raise_error(ArgumentError) |
| 72 | + end |
| 73 | + |
| 74 | + |
23 | 75 | end |
24 | 76 |
|
25 | 77 | context '#min_length' do |
|
102 | 154 | end |
103 | 155 | end |
104 | 156 |
|
105 | | - context '#idletime' do |
106 | | - |
107 | | - it 'returns zero' do |
108 | | - subject.idletime.should eq 0 |
109 | | - end |
110 | | - end |
111 | 157 |
|
112 | 158 | context '#kill' do |
113 | 159 |
|
|
133 | 179 | pool.kill |
134 | 180 | end |
135 | 181 | end |
| 182 | + |
| 183 | + context 'overflow policy' do |
| 184 | + |
| 185 | + before do |
| 186 | + @queue = Queue.new |
| 187 | + end |
| 188 | + |
| 189 | + # On abort, it should raise an error |
| 190 | + it "raises an error when overflow on abort" do |
| 191 | + subject = described_class.new(2, :max_queue => 2, :overflow_policy => :abort) |
| 192 | + expect { |
| 193 | + 5.times do |i| |
| 194 | + subject.post { sleep 0.1; @queue << i} |
| 195 | + end |
| 196 | + subject.shutdown |
| 197 | + subject.wait_for_termination(1) |
| 198 | + }.to raise_error |
| 199 | + end |
| 200 | + |
| 201 | + # On discard, we'd expect no error, but also not all five results |
| 202 | + it 'discards when overflow is :discard' do |
| 203 | + subject = described_class.new(2, :max_queue => 2, :overflow_policy => :discard) |
| 204 | + 5.times do |i| |
| 205 | + subject.post { sleep 0.1; @queue << i} |
| 206 | + end |
| 207 | + subject.shutdown |
| 208 | + subject.wait_for_termination(1) |
| 209 | + @queue.length.should be < 5 |
| 210 | + end |
| 211 | + |
| 212 | + # To check for caller_runs, we'll check how many unique threads |
| 213 | + # actually ran the block |
| 214 | + |
| 215 | + it 'uses the calling thread for overflow under caller_runs' do |
| 216 | + subject = described_class.new(2, :max_queue => 2, :overflow_policy => :caller_runs) |
| 217 | + 5.times do |i| |
| 218 | + subject.post { sleep 0.1; @queue << Thread.current} |
| 219 | + end |
| 220 | + subject.shutdown |
| 221 | + subject.wait_for_termination(1) |
| 222 | + # Turn the queue into an array |
| 223 | + a = [] |
| 224 | + a << @queue.shift until @queue.empty? |
| 225 | + |
| 226 | + a.size.should eq 5 # one for each run of the block |
| 227 | + a.uniq.size.should eq 3 # one for each of teh two threads, plus the caller |
| 228 | + end |
| 229 | + end |
| 230 | + |
| 231 | + |
136 | 232 | end |
0 commit comments