dalli 2.7.4 → 2.7.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of dalli might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Gemfile +0 -7
- data/History.md +15 -0
- data/LICENSE +1 -1
- data/README.md +14 -6
- data/lib/active_support/cache/dalli_store.rb +39 -9
- data/lib/dalli/client.rb +40 -27
- data/lib/dalli/server.rb +33 -18
- data/lib/dalli/socket.rb +14 -4
- data/lib/dalli/version.rb +1 -1
- metadata +79 -43
- data/Performance.md +0 -42
- data/Rakefile +0 -43
- data/dalli.gemspec +0 -29
- data/test/benchmark_test.rb +0 -243
- data/test/helper.rb +0 -56
- data/test/memcached_mock.rb +0 -201
- data/test/sasl/memcached.conf +0 -1
- data/test/sasl/sasldb +0 -1
- data/test/test_active_support.rb +0 -541
- data/test/test_cas_client.rb +0 -107
- data/test/test_compressor.rb +0 -52
- data/test/test_dalli.rb +0 -682
- data/test/test_encoding.rb +0 -32
- data/test/test_failover.rb +0 -137
- data/test/test_network.rb +0 -64
- data/test/test_rack_session.rb +0 -341
- data/test/test_ring.rb +0 -85
- data/test/test_sasl.rb +0 -105
- data/test/test_serializer.rb +0 -29
- data/test/test_server.rb +0 -110
data/test/helper.rb
DELETED
@@ -1,56 +0,0 @@
|
|
1
|
-
$TESTING = true
|
2
|
-
require 'rubygems'
|
3
|
-
# require 'simplecov'
|
4
|
-
# SimpleCov.start
|
5
|
-
require 'minitest/pride' unless RUBY_ENGINE == 'rbx'
|
6
|
-
require 'minitest/autorun'
|
7
|
-
require 'mocha/setup'
|
8
|
-
require 'memcached_mock'
|
9
|
-
|
10
|
-
ENV['MEMCACHED_SASL_PWDB'] = "#{File.dirname(__FILE__)}/sasl/sasldb"
|
11
|
-
ENV['SASL_CONF_PATH'] = "#{File.dirname(__FILE__)}/sasl/memcached.conf"
|
12
|
-
|
13
|
-
WANT_RAILS_VERSION = ENV['RAILS_VERSION'] || '>= 3.0.0'
|
14
|
-
gem 'rails', WANT_RAILS_VERSION
|
15
|
-
require 'rails'
|
16
|
-
puts "Testing with Rails #{Rails.version}"
|
17
|
-
|
18
|
-
require 'dalli'
|
19
|
-
require 'logger'
|
20
|
-
|
21
|
-
Dalli.logger = Logger.new(STDOUT)
|
22
|
-
Dalli.logger.level = Logger::ERROR
|
23
|
-
|
24
|
-
class MiniTest::Spec
|
25
|
-
include MemcachedMock::Helper
|
26
|
-
|
27
|
-
def assert_error(error, regexp=nil, &block)
|
28
|
-
ex = assert_raises(error, &block)
|
29
|
-
assert_match(regexp, ex.message, "#{ex.class.name}: #{ex.message}\n#{ex.backtrace.join("\n\t")}")
|
30
|
-
end
|
31
|
-
|
32
|
-
def op_cas_succeeds(rsp)
|
33
|
-
rsp.is_a?(Integer) && rsp > 0
|
34
|
-
end
|
35
|
-
|
36
|
-
def op_replace_succeeds(rsp)
|
37
|
-
rsp.is_a?(Integer) && rsp > 0
|
38
|
-
end
|
39
|
-
|
40
|
-
# add and set must have the same return value because of DalliStore#write_entry
|
41
|
-
def op_addset_succeeds(rsp)
|
42
|
-
rsp.is_a?(Integer) && rsp > 0
|
43
|
-
end
|
44
|
-
|
45
|
-
def with_activesupport
|
46
|
-
require 'active_support/all'
|
47
|
-
require 'active_support/cache/dalli_store'
|
48
|
-
yield
|
49
|
-
end
|
50
|
-
|
51
|
-
def with_actionpack
|
52
|
-
require 'action_dispatch'
|
53
|
-
require 'action_controller'
|
54
|
-
yield
|
55
|
-
end
|
56
|
-
end
|
data/test/memcached_mock.rb
DELETED
@@ -1,201 +0,0 @@
|
|
1
|
-
require "socket"
|
2
|
-
require "tempfile"
|
3
|
-
|
4
|
-
$started = {}
|
5
|
-
|
6
|
-
module MemcachedMock
|
7
|
-
UNIX_SOCKET_PATH = (f = Tempfile.new('dalli_test'); f.close; f.path)
|
8
|
-
|
9
|
-
def self.start(port=19123)
|
10
|
-
server = TCPServer.new("localhost", port)
|
11
|
-
session = server.accept
|
12
|
-
yield(session)
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.start_unix(path=UNIX_SOCKET_PATH)
|
16
|
-
begin
|
17
|
-
File.delete(path)
|
18
|
-
rescue Errno::ENOENT
|
19
|
-
end
|
20
|
-
server = UNIXServer.new(path)
|
21
|
-
session = server.accept
|
22
|
-
yield(session)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.delayed_start(port=19123, wait=1)
|
26
|
-
server = TCPServer.new("localhost", port)
|
27
|
-
sleep wait
|
28
|
-
yield(server)
|
29
|
-
end
|
30
|
-
|
31
|
-
module Helper
|
32
|
-
# Forks the current process and starts a new mock Memcached server on
|
33
|
-
# port 22122.
|
34
|
-
#
|
35
|
-
# memcached_mock(lambda {|sock| socket.write('123') }) do
|
36
|
-
# assert_equal "PONG", Dalli::Client.new('localhost:22122').get('abc')
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
def memcached_mock(proc, meth=:start, meth_args=[])
|
40
|
-
return unless supports_fork?
|
41
|
-
begin
|
42
|
-
pid = fork do
|
43
|
-
trap("TERM") { exit }
|
44
|
-
|
45
|
-
MemcachedMock.send(meth, *meth_args) do |*args|
|
46
|
-
proc.call(*args)
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
sleep 0.3 # Give time for the socket to start listening.
|
51
|
-
yield
|
52
|
-
ensure
|
53
|
-
if pid
|
54
|
-
Process.kill("TERM", pid)
|
55
|
-
Process.wait(pid)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
PATHS = %w(
|
61
|
-
/usr/local/bin/
|
62
|
-
/opt/local/bin/
|
63
|
-
/usr/bin/
|
64
|
-
)
|
65
|
-
|
66
|
-
def find_memcached
|
67
|
-
output = `memcached -h | head -1`.strip
|
68
|
-
if output && output =~ /^memcached (\d.\d.\d+)/ && $1 > '1.4'
|
69
|
-
return (puts "Found #{output} in PATH"; '')
|
70
|
-
end
|
71
|
-
PATHS.each do |path|
|
72
|
-
output = `memcached -h | head -1`.strip
|
73
|
-
if output && output =~ /^memcached (\d\.\d\.\d+)/ && $1 > '1.4'
|
74
|
-
return (puts "Found #{output} in #{path}"; path)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
raise Errno::ENOENT, "Unable to find memcached 1.4+ locally"
|
79
|
-
end
|
80
|
-
|
81
|
-
def memcached_persistent(port=21345)
|
82
|
-
dc = start_and_flush_with_retry(port, '', {})
|
83
|
-
yield dc, port if block_given?
|
84
|
-
end
|
85
|
-
|
86
|
-
def sasl_credentials
|
87
|
-
{ :username => 'testuser', :password => 'testtest' }
|
88
|
-
end
|
89
|
-
|
90
|
-
def sasl_env
|
91
|
-
{
|
92
|
-
'MEMCACHED_SASL_PWDB' => "#{File.dirname(__FILE__)}/sasl/sasldb",
|
93
|
-
'SASL_CONF_PATH' => "#{File.dirname(__FILE__)}/sasl/memcached.conf"
|
94
|
-
}
|
95
|
-
end
|
96
|
-
|
97
|
-
def memcached_sasl_persistent(port=21397)
|
98
|
-
dc = start_and_flush_with_retry(port, '-S', sasl_credentials)
|
99
|
-
yield dc, port if block_given?
|
100
|
-
end
|
101
|
-
|
102
|
-
def memcached_cas_persistent(port = 25662)
|
103
|
-
require 'dalli/cas/client'
|
104
|
-
dc = start_and_flush_with_retry(port)
|
105
|
-
yield dc, port if block_given?
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
def memcached_low_mem_persistent(port = 19128)
|
110
|
-
dc = start_and_flush_with_retry(port, '-m 1 -M')
|
111
|
-
yield dc, port if block_given?
|
112
|
-
end
|
113
|
-
|
114
|
-
def start_and_flush_with_retry(port, args = '', client_options = {})
|
115
|
-
dc = nil
|
116
|
-
retry_count = 0
|
117
|
-
while dc.nil? do
|
118
|
-
begin
|
119
|
-
dc = start_and_flush(port, args, client_options, (retry_count == 0))
|
120
|
-
rescue StandardError => e
|
121
|
-
$started[port] = nil
|
122
|
-
retry_count += 1
|
123
|
-
raise e if retry_count >= 3
|
124
|
-
end
|
125
|
-
end
|
126
|
-
dc
|
127
|
-
end
|
128
|
-
|
129
|
-
def start_and_flush(port, args = '', client_options = {}, flush = true)
|
130
|
-
memcached_server(port, args)
|
131
|
-
if "#{port}" =~ /\A\//
|
132
|
-
# unix socket
|
133
|
-
dc = Dalli::Client.new(port, client_options)
|
134
|
-
else
|
135
|
-
dc = Dalli::Client.new(["localhost:#{port}", "127.0.0.1:#{port}"], client_options)
|
136
|
-
end
|
137
|
-
dc.flush_all if flush
|
138
|
-
dc
|
139
|
-
end
|
140
|
-
|
141
|
-
def memcached(port, args='', client_options={})
|
142
|
-
dc = start_and_flush_with_retry(port, args, client_options)
|
143
|
-
yield dc, port if block_given?
|
144
|
-
memcached_kill(port)
|
145
|
-
end
|
146
|
-
|
147
|
-
def memcached_server(port, args='')
|
148
|
-
Memcached.path ||= find_memcached
|
149
|
-
if "#{port}" =~ /\A\//
|
150
|
-
# unix socket
|
151
|
-
port_socket_arg = '-s'
|
152
|
-
begin
|
153
|
-
File.delete(port)
|
154
|
-
rescue Errno::ENOENT
|
155
|
-
end
|
156
|
-
else
|
157
|
-
port_socket_arg = '-p'
|
158
|
-
port = port.to_i
|
159
|
-
end
|
160
|
-
|
161
|
-
cmd = "#{Memcached.path}memcached #{args} #{port_socket_arg} #{port}"
|
162
|
-
|
163
|
-
$started[port] ||= begin
|
164
|
-
pid = IO.popen(cmd).pid
|
165
|
-
at_exit do
|
166
|
-
begin
|
167
|
-
Process.kill("TERM", pid)
|
168
|
-
Process.wait(pid)
|
169
|
-
rescue Errno::ECHILD, Errno::ESRCH
|
170
|
-
end
|
171
|
-
end
|
172
|
-
wait_time = (args && args =~ /\-S/) ? 0.1 : 0.1
|
173
|
-
sleep wait_time
|
174
|
-
pid
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
def supports_fork?
|
179
|
-
!defined?(RUBY_ENGINE) || RUBY_ENGINE != 'jruby'
|
180
|
-
end
|
181
|
-
|
182
|
-
def memcached_kill(port)
|
183
|
-
pid = $started.delete(port)
|
184
|
-
if pid
|
185
|
-
begin
|
186
|
-
Process.kill("TERM", pid)
|
187
|
-
Process.wait(pid)
|
188
|
-
rescue Errno::ECHILD, Errno::ESRCH => e
|
189
|
-
puts e.inspect
|
190
|
-
end
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
module Memcached
|
198
|
-
class << self
|
199
|
-
attr_accessor :path
|
200
|
-
end
|
201
|
-
end
|
data/test/sasl/memcached.conf
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
mech_list: plain
|
data/test/sasl/sasldb
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
testuser:testtest:::::::
|
data/test/test_active_support.rb
DELETED
@@ -1,541 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require 'helper'
|
3
|
-
require 'connection_pool'
|
4
|
-
|
5
|
-
class MockUser
|
6
|
-
def cache_key
|
7
|
-
"users/1/21348793847982314"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
describe 'ActiveSupport' do
|
12
|
-
before do
|
13
|
-
@port = 19987
|
14
|
-
end
|
15
|
-
|
16
|
-
describe 'active_support caching' do
|
17
|
-
|
18
|
-
it 'has accessible options' do
|
19
|
-
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, "localhost:#{@port}", :expires_in => 5.minutes, :frob => 'baz')
|
20
|
-
assert_equal 'baz', @dalli.options[:frob]
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'allow mute and silence' do
|
24
|
-
memcached_persistent(@port) do
|
25
|
-
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, "localhost:#{@port}")
|
26
|
-
@dalli.mute do
|
27
|
-
assert op_addset_succeeds(@dalli.write('foo', 'bar', nil))
|
28
|
-
assert_equal 'bar', @dalli.read('foo', nil)
|
29
|
-
end
|
30
|
-
refute @dalli.silence?
|
31
|
-
@dalli.silence!
|
32
|
-
assert_equal true, @dalli.silence?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'handle nil options' do
|
37
|
-
memcached_persistent(@port) do
|
38
|
-
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, "localhost:#{@port}")
|
39
|
-
assert op_addset_succeeds(@dalli.write('foo', 'bar', nil))
|
40
|
-
assert_equal 'bar', @dalli.read('foo', nil)
|
41
|
-
assert_equal 18, @dalli.fetch('lkjsadlfk', nil) { 18 }
|
42
|
-
assert_equal 18, @dalli.fetch('lkjsadlfk', nil) { 18 }
|
43
|
-
assert_equal 1, @dalli.increment('lkjsa', 1, nil)
|
44
|
-
assert_equal 2, @dalli.increment('lkjsa', 1, nil)
|
45
|
-
assert_equal 1, @dalli.decrement('lkjsa', 1, nil)
|
46
|
-
assert_equal true, @dalli.delete('lkjsa')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'support fetch' do
|
51
|
-
with_activesupport do
|
52
|
-
memcached_persistent(@port) do
|
53
|
-
connect(@port)
|
54
|
-
dvalue = @dalli.fetch('someotherkeywithoutspaces', :expires_in => 1.second) { 123 }
|
55
|
-
assert_equal 123, dvalue
|
56
|
-
|
57
|
-
o = Object.new
|
58
|
-
o.instance_variable_set :@foo, 'bar'
|
59
|
-
dvalue = @dalli.fetch(rand_key, :raw => true) { o }
|
60
|
-
assert_equal o, dvalue
|
61
|
-
|
62
|
-
dvalue = @dalli.fetch(rand_key) { o }
|
63
|
-
assert_equal o, dvalue
|
64
|
-
|
65
|
-
@dalli.write('false', false)
|
66
|
-
dvalue = @dalli.fetch('false') { flunk }
|
67
|
-
assert_equal false, dvalue
|
68
|
-
|
69
|
-
user = MockUser.new
|
70
|
-
@dalli.write(user.cache_key, false)
|
71
|
-
dvalue = @dalli.fetch(user) { flunk }
|
72
|
-
assert_equal false, dvalue
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
it 'support keys with spaces on Rails3' do
|
78
|
-
with_activesupport do
|
79
|
-
memcached_persistent(@port) do
|
80
|
-
connect(@port)
|
81
|
-
dvalue = @dalli.fetch('some key with spaces', :expires_in => 1.second) { 123 }
|
82
|
-
assert_equal 123, dvalue
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'support read_multi' do
|
88
|
-
with_activesupport do
|
89
|
-
memcached_persistent(@port) do
|
90
|
-
connect(@port)
|
91
|
-
x = rand_key
|
92
|
-
y = rand_key
|
93
|
-
assert_equal({}, @dalli.read_multi(x, y))
|
94
|
-
@dalli.write(x, '123')
|
95
|
-
@dalli.write(y, 123)
|
96
|
-
assert_equal({ x => '123', y => 123 }, @dalli.read_multi(x, y))
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
it 'support read_multi with an array' do
|
102
|
-
with_activesupport do
|
103
|
-
memcached_persistent(@port) do
|
104
|
-
connect(@port)
|
105
|
-
x = rand_key
|
106
|
-
y = rand_key
|
107
|
-
assert_equal({}, @dalli.read_multi([x, y]))
|
108
|
-
@dalli.write(x, '123')
|
109
|
-
@dalli.write(y, 123)
|
110
|
-
assert_equal({}, @dalli.read_multi([x, y]))
|
111
|
-
@dalli.write([x, y], '123')
|
112
|
-
assert_equal({ [x, y] => '123' }, @dalli.read_multi([x, y]))
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'support read_multi with an empty array' do
|
118
|
-
with_activesupport do
|
119
|
-
memcached_persistent(@port) do
|
120
|
-
connect(@port)
|
121
|
-
assert_equal({}, @dalli.read_multi([]))
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
it 'support raw read_multi' do
|
127
|
-
with_activesupport do
|
128
|
-
memcached_persistent(@port) do
|
129
|
-
connect(@port)
|
130
|
-
@dalli.write("abc", 5, :raw => true)
|
131
|
-
@dalli.write("cba", 5, :raw => true)
|
132
|
-
assert_equal({'abc' => '5', 'cba' => '5' }, @dalli.read_multi("abc", "cba"))
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
it 'support read_multi with LocalCache' do
|
138
|
-
with_activesupport do
|
139
|
-
memcached_persistent(@port) do
|
140
|
-
connect(@port)
|
141
|
-
x = rand_key
|
142
|
-
y = rand_key
|
143
|
-
assert_equal({}, @dalli.read_multi(x, y))
|
144
|
-
@dalli.write(x, '123')
|
145
|
-
@dalli.write(y, 456)
|
146
|
-
|
147
|
-
@dalli.with_local_cache do
|
148
|
-
assert_equal({ x => '123', y => 456 }, @dalli.read_multi(x, y))
|
149
|
-
Dalli::Client.any_instance.expects(:get).with(any_parameters).never
|
150
|
-
|
151
|
-
dres = @dalli.read(x)
|
152
|
-
assert_equal dres, '123'
|
153
|
-
end
|
154
|
-
|
155
|
-
Dalli::Client.any_instance.unstub(:get)
|
156
|
-
|
157
|
-
# Fresh LocalStore
|
158
|
-
@dalli.with_local_cache do
|
159
|
-
@dalli.read(x)
|
160
|
-
Dalli::Client.any_instance.expects(:get_multi).with([y.to_s]).returns(y.to_s => 456)
|
161
|
-
|
162
|
-
assert_equal({ x => '123', y => 456}, @dalli.read_multi(x, y))
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
it 'supports fetch_multi' do
|
169
|
-
with_activesupport do
|
170
|
-
memcached_persistent(@port) do
|
171
|
-
connect(@port)
|
172
|
-
|
173
|
-
x = rand_key.to_s
|
174
|
-
y = rand_key
|
175
|
-
hash = { x => 'ABC', y => 'DEF' }
|
176
|
-
|
177
|
-
@dalli.write(y, '123')
|
178
|
-
|
179
|
-
results = @dalli.fetch_multi(x, y) { |key| hash[key] }
|
180
|
-
|
181
|
-
assert_equal({ x => 'ABC', y => '123' }, results)
|
182
|
-
assert_equal('ABC', @dalli.read(x))
|
183
|
-
assert_equal('123', @dalli.read(y))
|
184
|
-
end
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
it 'support read, write and delete' do
|
189
|
-
with_activesupport do
|
190
|
-
memcached_persistent(@port) do
|
191
|
-
connect(@port)
|
192
|
-
y = rand_key
|
193
|
-
assert_nil @dalli.read(y)
|
194
|
-
dres = @dalli.write(y, 123)
|
195
|
-
assert op_addset_succeeds(dres)
|
196
|
-
|
197
|
-
dres = @dalli.read(y)
|
198
|
-
assert_equal 123, dres
|
199
|
-
|
200
|
-
dres = @dalli.delete(y)
|
201
|
-
assert_equal true, dres
|
202
|
-
|
203
|
-
user = MockUser.new
|
204
|
-
dres = @dalli.write(user.cache_key, "foo")
|
205
|
-
assert op_addset_succeeds(dres)
|
206
|
-
|
207
|
-
dres = @dalli.read(user)
|
208
|
-
assert_equal "foo", dres
|
209
|
-
|
210
|
-
dres = @dalli.delete(user)
|
211
|
-
assert_equal true, dres
|
212
|
-
|
213
|
-
dres = @dalli.write(:false_value, false)
|
214
|
-
assert op_addset_succeeds(dres)
|
215
|
-
dres = @dalli.read(:false_value)
|
216
|
-
assert_equal false, dres
|
217
|
-
|
218
|
-
bigkey = '123456789012345678901234567890'
|
219
|
-
@dalli.write(bigkey, 'double width')
|
220
|
-
assert_equal 'double width', @dalli.read(bigkey)
|
221
|
-
assert_equal({bigkey => "double width"}, @dalli.read_multi(bigkey))
|
222
|
-
end
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
it 'support read, write and delete with local namespace' do
|
227
|
-
with_activesupport do
|
228
|
-
memcached_persistent(@port) do
|
229
|
-
connect(@port, '')
|
230
|
-
key = 'key_with_namespace'
|
231
|
-
namespace_value = @dalli.fetch(key, :namespace => 'namespace') { 123 }
|
232
|
-
assert_equal 123, namespace_value
|
233
|
-
|
234
|
-
res = @dalli.read(key, :namespace => 'namespace')
|
235
|
-
assert_equal 123, res
|
236
|
-
|
237
|
-
res = @dalli.delete(key, :namespace => 'namespace')
|
238
|
-
assert_equal true, res
|
239
|
-
|
240
|
-
res = @dalli.write(key, "foo", :namespace => 'namespace')
|
241
|
-
assert op_addset_succeeds(res)
|
242
|
-
|
243
|
-
res = @dalli.read(key, :namespace => 'namespace')
|
244
|
-
assert_equal "foo", res
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
it 'support multi_read and multi_fetch with local namespace' do
|
250
|
-
with_activesupport do
|
251
|
-
memcached_persistent(@port) do
|
252
|
-
connect(@port, '')
|
253
|
-
x = rand_key.to_s
|
254
|
-
y = rand_key
|
255
|
-
namespace = 'namespace'
|
256
|
-
hash = { x => 'ABC', y => 'DEF' }
|
257
|
-
|
258
|
-
results = @dalli.fetch_multi(x, y, :namespace => namespace) { |key| hash[key] }
|
259
|
-
|
260
|
-
assert_equal({ x => 'ABC', y => 'DEF' }, results)
|
261
|
-
assert_equal('ABC', @dalli.read(x, :namespace => namespace))
|
262
|
-
assert_equal('DEF', @dalli.read(y, :namespace => namespace))
|
263
|
-
|
264
|
-
@dalli.write("abc", 5, :namespace => 'namespace')
|
265
|
-
@dalli.write("cba", 5, :namespace => 'namespace')
|
266
|
-
assert_equal({'abc' => 5, 'cba' => 5 }, @dalli.read_multi("abc", "cba", :namespace => 'namespace'))
|
267
|
-
end
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
it 'support read, write and delete with LocalCache' do
|
272
|
-
with_activesupport do
|
273
|
-
memcached_persistent(@port) do
|
274
|
-
connect(@port)
|
275
|
-
y = rand_key.to_s
|
276
|
-
@dalli.with_local_cache do
|
277
|
-
Dalli::Client.any_instance.expects(:get).with(y, {}).once.returns(123)
|
278
|
-
dres = @dalli.read(y)
|
279
|
-
assert_equal 123, dres
|
280
|
-
|
281
|
-
Dalli::Client.any_instance.expects(:get).with(y, {}).never
|
282
|
-
|
283
|
-
dres = @dalli.read(y)
|
284
|
-
assert_equal 123, dres
|
285
|
-
|
286
|
-
@dalli.write(y, 456)
|
287
|
-
dres = @dalli.read(y)
|
288
|
-
assert_equal 456, dres
|
289
|
-
|
290
|
-
@dalli.delete(y)
|
291
|
-
Dalli::Client.any_instance.expects(:get).with(y, {}).once.returns(nil)
|
292
|
-
dres = @dalli.read(y)
|
293
|
-
assert_equal nil, dres
|
294
|
-
end
|
295
|
-
end
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
it 'support unless_exist with LocalCache' do
|
300
|
-
with_activesupport do
|
301
|
-
memcached_persistent(@port) do
|
302
|
-
connect(@port)
|
303
|
-
y = rand_key.to_s
|
304
|
-
@dalli.with_local_cache do
|
305
|
-
Dalli::Client.any_instance.expects(:add).with(y, 123, nil, {:unless_exist => true}).once.returns(true)
|
306
|
-
dres = @dalli.write(y, 123, :unless_exist => true)
|
307
|
-
assert_equal true, dres
|
308
|
-
|
309
|
-
Dalli::Client.any_instance.expects(:add).with(y, 321, nil, {:unless_exist => true}).once.returns(false)
|
310
|
-
|
311
|
-
dres = @dalli.write(y, 321, :unless_exist => true)
|
312
|
-
assert_equal false, dres
|
313
|
-
|
314
|
-
Dalli::Client.any_instance.expects(:get).with(y, {}).once.returns(123)
|
315
|
-
|
316
|
-
dres = @dalli.read(y)
|
317
|
-
assert_equal 123, dres
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
it 'support increment/decrement commands' do
|
324
|
-
with_activesupport do
|
325
|
-
memcached_persistent(@port) do
|
326
|
-
connect(@port)
|
327
|
-
assert op_addset_succeeds(@dalli.write('counter', 0, :raw => true))
|
328
|
-
assert_equal 1, @dalli.increment('counter')
|
329
|
-
assert_equal 2, @dalli.increment('counter')
|
330
|
-
assert_equal 1, @dalli.decrement('counter')
|
331
|
-
assert_equal "1", @dalli.read('counter', :raw => true)
|
332
|
-
|
333
|
-
assert_equal 1, @dalli.increment('counterX')
|
334
|
-
assert_equal 2, @dalli.increment('counterX')
|
335
|
-
assert_equal 2, @dalli.read('counterX', :raw => true).to_i
|
336
|
-
|
337
|
-
assert_equal 5, @dalli.increment('counterY1', 1, :initial => 5)
|
338
|
-
assert_equal 6, @dalli.increment('counterY1', 1, :initial => 5)
|
339
|
-
assert_equal 6, @dalli.read('counterY1', :raw => true).to_i
|
340
|
-
|
341
|
-
assert_equal nil, @dalli.increment('counterZ1', 1, :initial => nil)
|
342
|
-
assert_equal nil, @dalli.read('counterZ1')
|
343
|
-
|
344
|
-
assert_equal 5, @dalli.decrement('counterY2', 1, :initial => 5)
|
345
|
-
assert_equal 4, @dalli.decrement('counterY2', 1, :initial => 5)
|
346
|
-
assert_equal 4, @dalli.read('counterY2', :raw => true).to_i
|
347
|
-
|
348
|
-
assert_equal nil, @dalli.decrement('counterZ2', 1, :initial => nil)
|
349
|
-
assert_equal nil, @dalli.read('counterZ2')
|
350
|
-
|
351
|
-
user = MockUser.new
|
352
|
-
assert op_addset_succeeds(@dalli.write(user, 0, :raw => true))
|
353
|
-
assert_equal 1, @dalli.increment(user)
|
354
|
-
assert_equal 2, @dalli.increment(user)
|
355
|
-
assert_equal 1, @dalli.decrement(user)
|
356
|
-
assert_equal "1", @dalli.read(user, :raw => true)
|
357
|
-
end
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
|
-
it 'support exist command' do
|
362
|
-
with_activesupport do
|
363
|
-
memcached_persistent(@port) do
|
364
|
-
connect(@port)
|
365
|
-
@dalli.write(:foo, 'a')
|
366
|
-
@dalli.write(:false_value, false)
|
367
|
-
|
368
|
-
assert_equal true, @dalli.exist?(:foo)
|
369
|
-
assert_equal true, @dalli.exist?(:false_value)
|
370
|
-
|
371
|
-
assert_equal false, @dalli.exist?(:bar)
|
372
|
-
|
373
|
-
user = MockUser.new
|
374
|
-
@dalli.write(user, 'foo')
|
375
|
-
assert_equal true, @dalli.exist?(user)
|
376
|
-
end
|
377
|
-
end
|
378
|
-
end
|
379
|
-
|
380
|
-
it 'support other esoteric commands' do
|
381
|
-
with_activesupport do
|
382
|
-
memcached_persistent(@port) do
|
383
|
-
connect(@port)
|
384
|
-
ds = @dalli.stats
|
385
|
-
assert_equal 1, ds.keys.size
|
386
|
-
assert ds[ds.keys.first].keys.size > 0
|
387
|
-
|
388
|
-
@dalli.reset
|
389
|
-
end
|
390
|
-
end
|
391
|
-
end
|
392
|
-
|
393
|
-
it 'respect "raise_errors" option' do
|
394
|
-
with_activesupport do
|
395
|
-
new_port = 29333
|
396
|
-
memcached_persistent(new_port) do
|
397
|
-
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, "localhost:#{new_port}")
|
398
|
-
@dalli.write 'foo', 'bar'
|
399
|
-
assert_equal @dalli.read('foo'), 'bar'
|
400
|
-
|
401
|
-
memcached_kill(new_port)
|
402
|
-
|
403
|
-
assert_equal @dalli.read('foo'), nil
|
404
|
-
|
405
|
-
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, "localhost:#{new_port}", :raise_errors => true)
|
406
|
-
|
407
|
-
exception = [Dalli::RingError, { :message => "No server available" }]
|
408
|
-
|
409
|
-
assert_raises(*exception) { @dalli.read 'foo' }
|
410
|
-
assert_raises(*exception) { @dalli.read 'foo', :raw => true }
|
411
|
-
assert_raises(*exception) { @dalli.write 'foo', 'bar' }
|
412
|
-
assert_raises(*exception) { @dalli.exist? 'foo' }
|
413
|
-
assert_raises(*exception) { @dalli.increment 'foo' }
|
414
|
-
assert_raises(*exception) { @dalli.decrement 'foo' }
|
415
|
-
assert_raises(*exception) { @dalli.delete 'foo' }
|
416
|
-
assert_equal @dalli.read_multi('foo', 'bar'), {}
|
417
|
-
assert_raises(*exception) { @dalli.delete 'foo' }
|
418
|
-
assert_raises(*exception) { @dalli.fetch('foo') { 42 } }
|
419
|
-
end
|
420
|
-
end
|
421
|
-
end
|
422
|
-
|
423
|
-
describe 'instruments' do
|
424
|
-
it 'payload hits' do
|
425
|
-
with_activesupport do
|
426
|
-
memcached_persistent(@port) do
|
427
|
-
connect(@port)
|
428
|
-
|
429
|
-
payload = {}
|
430
|
-
dres = @dalli.write('false', false)
|
431
|
-
assert op_addset_succeeds(dres)
|
432
|
-
foo = @dalli.fetch('burrito') do 'tacos' end
|
433
|
-
assert 'tacos', foo
|
434
|
-
|
435
|
-
# NOTE: mocha stubbing for yields
|
436
|
-
# makes the result of the block nil in all cases
|
437
|
-
# there was a ticket about this:
|
438
|
-
# http://floehopper.lighthouseapp.com/projects/22289/tickets/14-8687-blocks-return-value-is-dropped-on-stubbed-yielding-methods
|
439
|
-
@dalli.stubs(:instrument).yields payload
|
440
|
-
|
441
|
-
@dalli.read('false')
|
442
|
-
assert_equal true, payload.delete(:hit)
|
443
|
-
|
444
|
-
|
445
|
-
foo = @dalli.fetch('unset_key') do 'tacos' end
|
446
|
-
assert_equal false, payload.delete(:hit)
|
447
|
-
|
448
|
-
@dalli.fetch('burrito') do 'tacos' end
|
449
|
-
assert_equal true, payload.delete(:hit)
|
450
|
-
|
451
|
-
@dalli.unstub(:instrument)
|
452
|
-
end
|
453
|
-
end
|
454
|
-
end
|
455
|
-
end
|
456
|
-
end
|
457
|
-
|
458
|
-
it 'handle crazy characters from far-away lands' do
|
459
|
-
with_activesupport do
|
460
|
-
memcached_persistent(@port) do
|
461
|
-
connect(@port)
|
462
|
-
key = "fooƒ"
|
463
|
-
value = 'bafƒ'
|
464
|
-
assert op_addset_succeeds(@dalli.write(key, value))
|
465
|
-
assert_equal value, @dalli.read(key)
|
466
|
-
end
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
it 'normalize options as expected' do
|
471
|
-
with_activesupport do
|
472
|
-
memcached_persistent(@port) do
|
473
|
-
@dalli = ActiveSupport::Cache::DalliStore.new("localhost:#{@port}", :expires_in => 1, :namespace => 'foo', :compress => true)
|
474
|
-
assert_equal 1, @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:expires_in]
|
475
|
-
assert_equal 'foo', @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:namespace]
|
476
|
-
assert_equal ["localhost:#{@port}"], @dalli.instance_variable_get(:@data).instance_variable_get(:@servers)
|
477
|
-
end
|
478
|
-
end
|
479
|
-
end
|
480
|
-
|
481
|
-
it 'handles nil server with additional options' do
|
482
|
-
with_activesupport do
|
483
|
-
memcached_persistent(@port) do
|
484
|
-
@dalli = ActiveSupport::Cache::DalliStore.new(nil, :expires_in => 1, :namespace => 'foo', :compress => true)
|
485
|
-
assert_equal 1, @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:expires_in]
|
486
|
-
assert_equal 'foo', @dalli.instance_variable_get(:@data).instance_variable_get(:@options)[:namespace]
|
487
|
-
assert_equal ["127.0.0.1:11211"], @dalli.instance_variable_get(:@data).instance_variable_get(:@servers)
|
488
|
-
end
|
489
|
-
end
|
490
|
-
end
|
491
|
-
|
492
|
-
it 'supports connection pooling' do
|
493
|
-
with_activesupport do
|
494
|
-
memcached_persistent(@port) do
|
495
|
-
@dalli = ActiveSupport::Cache::DalliStore.new("localhost:#{@port}", :expires_in => 1, :namespace => 'foo', :compress => true, :pool_size => 3)
|
496
|
-
assert_equal nil, @dalli.read('foo')
|
497
|
-
assert @dalli.write('foo', 1)
|
498
|
-
assert_equal 1, @dalli.fetch('foo') { raise 'boom' }
|
499
|
-
assert_equal true, @dalli.dalli.is_a?(ConnectionPool)
|
500
|
-
assert_equal 1, @dalli.increment('bar')
|
501
|
-
assert_equal 0, @dalli.decrement('bar')
|
502
|
-
assert_equal true, @dalli.delete('bar')
|
503
|
-
assert_equal [true], @dalli.clear
|
504
|
-
assert_equal 1, @dalli.stats.size
|
505
|
-
end
|
506
|
-
end
|
507
|
-
end
|
508
|
-
|
509
|
-
it 'allow keys to be frozen' do
|
510
|
-
with_activesupport do
|
511
|
-
memcached_persistent(@port) do
|
512
|
-
connect(@port)
|
513
|
-
key = "foo"
|
514
|
-
key.freeze
|
515
|
-
assert op_addset_succeeds(@dalli.write(key, "value"))
|
516
|
-
end
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
|
-
it 'allow keys from a hash' do
|
521
|
-
with_activesupport do
|
522
|
-
memcached_persistent(@port) do
|
523
|
-
connect(@port)
|
524
|
-
map = { "one" => "one", "two" => "two" }
|
525
|
-
map.each_pair do |k, v|
|
526
|
-
assert op_addset_succeeds(@dalli.write(k, v))
|
527
|
-
end
|
528
|
-
assert_equal map, @dalli.read_multi(*(map.keys))
|
529
|
-
end
|
530
|
-
end
|
531
|
-
end
|
532
|
-
|
533
|
-
def connect(port = 19122, namespace = lambda{33.to_s(36)})
|
534
|
-
@dalli = ActiveSupport::Cache.lookup_store(:dalli_store, "localhost:#{port}", :expires_in => 10.seconds, :namespace => namespace)
|
535
|
-
@dalli.clear
|
536
|
-
end
|
537
|
-
|
538
|
-
def rand_key
|
539
|
-
rand(1_000_000_000)
|
540
|
-
end
|
541
|
-
end
|