440 lines
14 KiB
Ruby
440 lines
14 KiB
Ruby
# encoding: utf-8
|
||
require 'helper'
|
||
require 'connection_pool'
|
||
|
||
class MockUser
|
||
def cache_key
|
||
"users/1/21348793847982314"
|
||
end
|
||
end
|
||
|
||
describe 'ActiveSupport' do
|
||
describe 'active_support caching' do
|
||
|
||
it 'has accessible options' do
|
||
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122', :expires_in => 5.minutes, :frob => 'baz')
|
||
assert_equal 'baz', @dalli.options[:frob]
|
||
end
|
||
|
||
it 'allow mute and silence' do
|
||
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122')
|
||
@dalli.mute do
|
||
assert op_addset_succeeds(@dalli.write('foo', 'bar', nil))
|
||
assert_equal 'bar', @dalli.read('foo', nil)
|
||
end
|
||
refute @dalli.silence?
|
||
@dalli.silence!
|
||
assert_equal true, @dalli.silence?
|
||
end
|
||
|
||
it 'handle nil options' do
|
||
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122')
|
||
assert op_addset_succeeds(@dalli.write('foo', 'bar', nil))
|
||
assert_equal 'bar', @dalli.read('foo', nil)
|
||
assert_equal 18, @dalli.fetch('lkjsadlfk', nil) { 18 }
|
||
assert_equal 18, @dalli.fetch('lkjsadlfk', nil) { 18 }
|
||
assert_equal 1, @dalli.increment('lkjsa', 1, nil)
|
||
assert_equal 2, @dalli.increment('lkjsa', 1, nil)
|
||
assert_equal 1, @dalli.decrement('lkjsa', 1, nil)
|
||
assert_equal true, @dalli.delete('lkjsa')
|
||
end
|
||
|
||
it 'support fetch' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
dvalue = @dalli.fetch('someotherkeywithoutspaces', :expires_in => 1.second) { 123 }
|
||
assert_equal 123, dvalue
|
||
|
||
o = Object.new
|
||
o.instance_variable_set :@foo, 'bar'
|
||
dvalue = @dalli.fetch(rand_key, :raw => true) { o }
|
||
assert_equal o, dvalue
|
||
|
||
dvalue = @dalli.fetch(rand_key) { o }
|
||
assert_equal o, dvalue
|
||
|
||
@dalli.write('false', false)
|
||
dvalue = @dalli.fetch('false') { flunk }
|
||
assert_equal false, dvalue
|
||
|
||
user = MockUser.new
|
||
@dalli.write(user.cache_key, false)
|
||
dvalue = @dalli.fetch(user) { flunk }
|
||
assert_equal false, dvalue
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support keys with spaces on Rails3' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
dvalue = @dalli.fetch('some key with spaces', :expires_in => 1.second) { 123 }
|
||
assert_equal 123, dvalue
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support read_multi' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
x = rand_key
|
||
y = rand_key
|
||
assert_equal({}, @dalli.read_multi(x, y))
|
||
@dalli.write(x, '123')
|
||
@dalli.write(y, 123)
|
||
assert_equal({ x => '123', y => 123 }, @dalli.read_multi(x, y))
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support read_multi with an array' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
x = rand_key
|
||
y = rand_key
|
||
assert_equal({}, @dalli.read_multi([x, y]))
|
||
@dalli.write(x, '123')
|
||
@dalli.write(y, 123)
|
||
assert_equal({}, @dalli.read_multi([x, y]))
|
||
@dalli.write([x, y], '123')
|
||
assert_equal({ [x, y] => '123' }, @dalli.read_multi([x, y]))
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support raw read_multi' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
@dalli.write("abc", 5, :raw => true)
|
||
@dalli.write("cba", 5, :raw => true)
|
||
assert_equal({'abc' => '5', 'cba' => '5' }, @dalli.read_multi("abc", "cba"))
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support read_multi with LocalCache' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
x = rand_key
|
||
y = rand_key
|
||
assert_equal({}, @dalli.read_multi(x, y))
|
||
@dalli.write(x, '123')
|
||
@dalli.write(y, 456)
|
||
|
||
@dalli.with_local_cache do
|
||
assert_equal({ x => '123', y => 456 }, @dalli.read_multi(x, y))
|
||
Dalli::Client.any_instance.expects(:get).with(any_parameters).never
|
||
|
||
dres = @dalli.read(x)
|
||
assert_equal dres, '123'
|
||
end
|
||
|
||
Dalli::Client.any_instance.unstub(:get)
|
||
|
||
# Fresh LocalStore
|
||
@dalli.with_local_cache do
|
||
@dalli.read(x)
|
||
Dalli::Client.any_instance.expects(:get_multi).with([y.to_s]).returns(y.to_s => 456)
|
||
|
||
assert_equal({ x => '123', y => 456}, @dalli.read_multi(x, y))
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'supports fetch_multi' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
|
||
x = rand_key.to_s
|
||
y = rand_key
|
||
hash = { x => 'ABC', y => 'DEF' }
|
||
|
||
@dalli.write(y, '123')
|
||
|
||
results = @dalli.fetch_multi(x, y) { |key| hash[key] }
|
||
|
||
assert_equal({ x => 'ABC', y => '123' }, results)
|
||
assert_equal('ABC', @dalli.read(x))
|
||
assert_equal('123', @dalli.read(y))
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support read, write and delete' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
y = rand_key
|
||
assert_nil @dalli.read(y)
|
||
dres = @dalli.write(y, 123)
|
||
assert op_addset_succeeds(dres)
|
||
|
||
dres = @dalli.read(y)
|
||
assert_equal 123, dres
|
||
|
||
dres = @dalli.delete(y)
|
||
assert_equal true, dres
|
||
|
||
user = MockUser.new
|
||
dres = @dalli.write(user.cache_key, "foo")
|
||
assert op_addset_succeeds(dres)
|
||
|
||
dres = @dalli.read(user)
|
||
assert_equal "foo", dres
|
||
|
||
dres = @dalli.delete(user)
|
||
assert_equal true, dres
|
||
|
||
bigkey = '123456789012345678901234567890'
|
||
@dalli.write(bigkey, 'double width')
|
||
assert_equal 'double width', @dalli.read(bigkey)
|
||
assert_equal({bigkey => "double width"}, @dalli.read_multi(bigkey))
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support read, write and delete with LocalCache' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
y = rand_key.to_s
|
||
@dalli.with_local_cache do
|
||
Dalli::Client.any_instance.expects(:get).with(y, {}).once.returns(123)
|
||
dres = @dalli.read(y)
|
||
assert_equal 123, dres
|
||
|
||
Dalli::Client.any_instance.expects(:get).with(y, {}).never
|
||
|
||
dres = @dalli.read(y)
|
||
assert_equal 123, dres
|
||
|
||
@dalli.write(y, 456)
|
||
dres = @dalli.read(y)
|
||
assert_equal 456, dres
|
||
|
||
@dalli.delete(y)
|
||
Dalli::Client.any_instance.expects(:get).with(y, {}).once.returns(nil)
|
||
dres = @dalli.read(y)
|
||
assert_equal nil, dres
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support unless_exist with LocalCache' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
y = rand_key.to_s
|
||
@dalli.with_local_cache do
|
||
Dalli::Client.any_instance.expects(:add).with(y, 123, nil, {:unless_exist => true}).once.returns(true)
|
||
dres = @dalli.write(y, 123, :unless_exist => true)
|
||
assert_equal true, dres
|
||
|
||
Dalli::Client.any_instance.expects(:add).with(y, 321, nil, {:unless_exist => true}).once.returns(false)
|
||
|
||
dres = @dalli.write(y, 321, :unless_exist => true)
|
||
assert_equal false, dres
|
||
|
||
Dalli::Client.any_instance.expects(:get).with(y, {}).once.returns(123)
|
||
|
||
dres = @dalli.read(y)
|
||
assert_equal 123, dres
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support increment/decrement commands' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
assert op_addset_succeeds(@dalli.write('counter', 0, :raw => true))
|
||
assert_equal 1, @dalli.increment('counter')
|
||
assert_equal 2, @dalli.increment('counter')
|
||
assert_equal 1, @dalli.decrement('counter')
|
||
assert_equal "1", @dalli.read('counter', :raw => true)
|
||
|
||
assert_equal 1, @dalli.increment('counterX')
|
||
assert_equal 2, @dalli.increment('counterX')
|
||
assert_equal 2, @dalli.read('counterX', :raw => true).to_i
|
||
|
||
assert_equal 5, @dalli.increment('counterY1', 1, :initial => 5)
|
||
assert_equal 6, @dalli.increment('counterY1', 1, :initial => 5)
|
||
assert_equal 6, @dalli.read('counterY1', :raw => true).to_i
|
||
|
||
assert_equal nil, @dalli.increment('counterZ1', 1, :initial => nil)
|
||
assert_equal nil, @dalli.read('counterZ1')
|
||
|
||
assert_equal 5, @dalli.decrement('counterY2', 1, :initial => 5)
|
||
assert_equal 4, @dalli.decrement('counterY2', 1, :initial => 5)
|
||
assert_equal 4, @dalli.read('counterY2', :raw => true).to_i
|
||
|
||
assert_equal nil, @dalli.decrement('counterZ2', 1, :initial => nil)
|
||
assert_equal nil, @dalli.read('counterZ2')
|
||
|
||
user = MockUser.new
|
||
assert op_addset_succeeds(@dalli.write(user, 0, :raw => true))
|
||
assert_equal 1, @dalli.increment(user)
|
||
assert_equal 2, @dalli.increment(user)
|
||
assert_equal 1, @dalli.decrement(user)
|
||
assert_equal "1", @dalli.read(user, :raw => true)
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support exist command' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
@dalli.write(:foo, 'a')
|
||
@dalli.write(:false_value, false)
|
||
|
||
assert_equal true, @dalli.exist?(:foo)
|
||
assert_equal true, @dalli.exist?(:false_value)
|
||
|
||
assert_equal false, @dalli.exist?(:bar)
|
||
|
||
user = MockUser.new
|
||
@dalli.write(user, 'foo')
|
||
assert_equal true, @dalli.exist?(user)
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'support other esoteric commands' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
ds = @dalli.stats
|
||
assert_equal 1, ds.keys.size
|
||
assert ds[ds.keys.first].keys.size > 0
|
||
|
||
@dalli.reset
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'respect "raise_errors" option' do
|
||
with_activesupport do
|
||
memcached(29125) do
|
||
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:29125')
|
||
@dalli.write 'foo', 'bar'
|
||
assert_equal @dalli.read('foo'), 'bar'
|
||
|
||
memcached_kill(29125)
|
||
|
||
assert_equal @dalli.read('foo'), nil
|
||
|
||
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:29125', :raise_errors => true)
|
||
|
||
exception = [Dalli::RingError, { :message => "No server available" }]
|
||
|
||
assert_raises(*exception) { @dalli.read 'foo' }
|
||
assert_raises(*exception) { @dalli.read 'foo', :raw => true }
|
||
assert_raises(*exception) { @dalli.write 'foo', 'bar' }
|
||
assert_raises(*exception) { @dalli.exist? 'foo' }
|
||
assert_raises(*exception) { @dalli.increment 'foo' }
|
||
assert_raises(*exception) { @dalli.decrement 'foo' }
|
||
assert_raises(*exception) { @dalli.delete 'foo' }
|
||
assert_equal @dalli.read_multi('foo', 'bar'), {}
|
||
assert_raises(*exception) { @dalli.delete 'foo' }
|
||
assert_raises(*exception) { @dalli.fetch('foo') { 42 } }
|
||
end
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'handle crazy characters from far-away lands' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
key = "fooƒ"
|
||
value = 'bafƒ'
|
||
assert op_addset_succeeds(@dalli.write(key, value))
|
||
assert_equal value, @dalli.read(key)
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'normalize options as expected' do
|
||
with_activesupport do
|
||
memcached do
|
||
@dalli = ActiveSupport::Cache::DalliStore.new('localhost:19122', :expires_in => 1, :namespace => 'foo', :compress => true)
|
||
assert_equal 1, @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:expires_in]
|
||
assert_equal 'foo', @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:namespace]
|
||
assert_equal ["localhost:19122"], @dalli.instance_variable_get(:@data).instance_variable_get(:@servers)
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'handles nil server with additional options' do
|
||
with_activesupport do
|
||
memcached do
|
||
@dalli = ActiveSupport::Cache::DalliStore.new(nil, :expires_in => 1, :namespace => 'foo', :compress => true)
|
||
assert_equal 1, @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:expires_in]
|
||
assert_equal 'foo', @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:namespace]
|
||
assert_equal ["127.0.0.1:11211"], @dalli.instance_variable_get(:@data).instance_variable_get(:@servers)
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'supports connection pooling' do
|
||
with_activesupport do
|
||
memcached do
|
||
@dalli = ActiveSupport::Cache::DalliStore.new('localhost:19122', :expires_in => 1, :namespace => 'foo', :compress => true, :pool_size => 3)
|
||
assert_equal nil, @dalli.read('foo')
|
||
assert @dalli.write('foo', 1)
|
||
assert_equal 1, @dalli.fetch('foo') { raise 'boom' }
|
||
assert_equal true, @dalli.dalli.is_a?(ConnectionPool)
|
||
assert_equal 1, @dalli.increment('bar')
|
||
assert_equal 0, @dalli.decrement('bar')
|
||
assert_equal true, @dalli.delete('bar')
|
||
assert_equal [true], @dalli.clear
|
||
assert_equal 1, @dalli.stats.size
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'allow keys to be frozen' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
key = "foo"
|
||
key.freeze
|
||
assert op_addset_succeeds(@dalli.write(key, "value"))
|
||
end
|
||
end
|
||
end
|
||
|
||
it 'allow keys from a hash' do
|
||
with_activesupport do
|
||
memcached do
|
||
connect
|
||
map = { "one" => "one", "two" => "two" }
|
||
map.each_pair do |k, v|
|
||
assert op_addset_succeeds(@dalli.write(k, v))
|
||
end
|
||
assert_equal map, @dalli.read_multi(*(map.keys))
|
||
end
|
||
end
|
||
end
|
||
|
||
def connect
|
||
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, 'localhost:19122', :expires_in => 10.seconds, :namespace => lambda{33.to_s(36)})
|
||
@dalli.clear
|
||
end
|
||
|
||
def rand_key
|
||
rand(1_000_000_000)
|
||
end
|
||
end
|