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 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
require 'timeout'
describe "DataObjects::Pooling" do
before do
Object.send(:remove_const, :Person) if defined?(Person)
class ::Person
include DataObjects::Pooling
attr_accessor :name
def initialize(name)
@name = name
end
def dispose
@name = nil
end
end
Object.send(:remove_const, :Overwriter) if defined?(Overwriter)
class ::Overwriter
def self.new(*args)
instance = allocate
instance.send(:initialize, *args)
instance.overwritten = true
instance
end
include DataObjects::Pooling
attr_accessor :name
def initialize(name)
@name = name
@overwritten = false
end
def overwritten?
@overwritten
end
def overwritten=(value)
@overwritten = value
end
class << self
remove_method :pool_size if instance_methods(false).any? { |m| m.to_sym == :pool_size }
def pool_size
pool_size = if RUBY_PLATFORM =~ /java/
20
else
2
end
pool_size
end
end
def dispose
@name = nil
end
end
end
after :each do
DataObjects::Pooling.lock.synchronize do
DataObjects::Pooling.pools.each do |pool|
pool.lock.synchronize do
pool.dispose
end
end
end
end
it "should maintain a size of 1" do
bob = Person.new('Bob')
fred = Person.new('Fred')
ted = Person.new('Ted')
Person.__pools.each do |args, pool|
pool.size.should == 1
end
bob.release
fred.release
ted.release
Person.__pools.each do |args, pool|
pool.size.should == 1
end
end
it "should track the initialized pools" do
bob = Person.new('Bob') # Ensure the pool is "primed"
bob.name.should == 'Bob'
bob.instance_variable_get(:@__pool).should_not be_nil
Person.__pools.size.should == 1
bob.release
Person.__pools.size.should == 1
DataObjects::Pooling::pools.should_not be_empty
sleep(1.2)
# NOTE: This assertion is commented out, as our MockConnection objects are
# currently in the pool.
# DataObjects::Pooling::pools.should be_empty
bob.name.should be_nil
end
it "should allow you to overwrite Class#new" do
bob = Overwriter.new('Bob')
bob.should be_overwritten
bob.release
end
it "should allow multiple threads to access the pool" do
t1 = Thread.new do
bob = Person.new('Bob')
sleep(1)
bob.release
end
lambda do
bob = Person.new('Bob')
t1.join
bob.release
end.should_not raise_error(DataObjects::Pooling::InvalidResourceError)
end
it "should allow you to flush a pool" do
bob = Overwriter.new('Bob')
Overwriter.new('Bob').release
bob.release
bob.name.should == 'Bob'
Overwriter.__pools[['Bob']].size.should == 2
Overwriter.__pools[['Bob']].flush!
Overwriter.__pools[['Bob']].size.should == 0
bob.name.should be_nil
end
it "should wake up the scavenger thread when exiting" do
bob = Person.new('Bob')
bob.release
DataObjects.exiting = true
sleep(0.1)
DataObjects::Pooling.scavenger?.should be_false
end
it "should be able to detach an instance from the pool" do
bob = Person.new('Bob')
Person.__pools[['Bob']].size.should == 1
bob.detach
Person.__pools[['Bob']].size.should == 0
end
end
|