dalli 0.9.10 → 0.10.0
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.
- data/History.md +12 -0
- data/README.md +2 -2
- data/lib/action_dispatch/middleware/session/dalli_store.rb +4 -7
- data/lib/active_support/cache/dalli_store.rb +16 -8
- data/lib/active_support/cache/dalli_store23.rb +44 -45
- data/lib/dalli/client.rb +1 -1
- data/lib/dalli/server.rb +27 -17
- data/lib/dalli/version.rb +1 -1
- data/test/memcached_mock.rb +1 -1
- data/test/test_active_support.rb +35 -7
- data/test/test_dalli.rb +22 -9
- metadata +3 -3
data/History.md
CHANGED
@@ -1,6 +1,18 @@
|
|
1
1
|
Dalli Changelog
|
2
2
|
=====================
|
3
3
|
|
4
|
+
0.10.0
|
5
|
+
======
|
6
|
+
|
7
|
+
Warning: this release changed how Rails marshals data with Dalli. Unfortunately previous versions double marshalled values. It is possible that data stored with previous versions of Dalli will not work with this version.
|
8
|
+
|
9
|
+
IT IS HIGHLY RECOMMENDED YOU FLUSH YOUR CACHE BEFORE UPGRADING.
|
10
|
+
|
11
|
+
- Rework how the Rails cache store does value marshalling.
|
12
|
+
- Rework old server version detection to avoid a socket read hang.
|
13
|
+
- Refactor the Rails 2.3 :dalli\_store to be closer to :mem\_cache\_store.
|
14
|
+
- Better documentation for session store config (plukevdh)
|
15
|
+
|
4
16
|
0.9.10
|
5
17
|
----
|
6
18
|
|
data/README.md
CHANGED
@@ -61,10 +61,10 @@ A more comprehensive example (note that we are setting a reasonable default for
|
|
61
61
|
config.cache_store = :dalli_store, 'cache-1.example.com', 'cache-2.example.com',
|
62
62
|
:namespace => NAME_OF_RAILS_APP, :expires_in => 1.day, :compress => true, :compress_threshold => 64.kilobytes
|
63
63
|
|
64
|
-
|
64
|
+
To use Dalli for Rails session storage, in `config/initializers/session_store.rb`:
|
65
65
|
|
66
66
|
require 'action_dispatch/middleware/session/dalli_store'
|
67
|
-
Rails.application.config.session_store :dalli_store, :key =>
|
67
|
+
Rails.application.config.session_store :dalli_store, :memcache_server => ['host1', 'host2'], :namespace => 'sessions', :key => '_foundation_session', :expire_after => 30.minutes
|
68
68
|
|
69
69
|
|
70
70
|
Usage with Rails 2.3.x
|
@@ -2,10 +2,7 @@ require 'active_support/cache'
|
|
2
2
|
require 'action_dispatch/middleware/session/abstract_store'
|
3
3
|
require 'dalli'
|
4
4
|
|
5
|
-
# Dalli-based session store for Rails 3.0.
|
6
|
-
#
|
7
|
-
# require 'action_dispatch/middleware/session/dalli_store'
|
8
|
-
# config.session_store ActionDispatch::Session::DalliStore, ['cache-1', 'cache-2'], :expire_after => 2.weeks
|
5
|
+
# Dalli-based session store for Rails 3.0.
|
9
6
|
module ActionDispatch
|
10
7
|
module Session
|
11
8
|
class DalliStore < AbstractStore
|
@@ -40,7 +37,7 @@ module ActionDispatch
|
|
40
37
|
begin
|
41
38
|
session = @pool.get(sid) || {}
|
42
39
|
rescue Dalli::DalliError
|
43
|
-
Rails.logger.warn("Session::DalliStore: #{$!.message}")
|
40
|
+
Rails.logger.warn("Session::DalliStore#get: #{$!.message}")
|
44
41
|
session = {}
|
45
42
|
end
|
46
43
|
[sid, session]
|
@@ -52,7 +49,7 @@ module ActionDispatch
|
|
52
49
|
@pool.set(sid, session_data, expiry)
|
53
50
|
sid
|
54
51
|
rescue Dalli::DalliError
|
55
|
-
Rails.logger.warn("Session::DalliStore: #{$!.message}")
|
52
|
+
Rails.logger.warn("Session::DalliStore#set: #{$!.message}")
|
56
53
|
false
|
57
54
|
end
|
58
55
|
|
@@ -61,7 +58,7 @@ module ActionDispatch
|
|
61
58
|
@pool.delete(sid)
|
62
59
|
end
|
63
60
|
rescue Dalli::DalliError
|
64
|
-
Rails.logger.warn("Session::DalliStore: #{$!.message}")
|
61
|
+
Rails.logger.warn("Session::DalliStore#delete: #{$!.message}")
|
65
62
|
false
|
66
63
|
end
|
67
64
|
|
@@ -17,6 +17,7 @@ module ActiveSupport
|
|
17
17
|
class DalliStore < Store
|
18
18
|
|
19
19
|
ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/
|
20
|
+
RAW = { :raw => true }
|
20
21
|
|
21
22
|
def self.build_mem_cache(*addresses)
|
22
23
|
addresses = addresses.flatten
|
@@ -53,7 +54,7 @@ module ActiveSupport
|
|
53
54
|
options = names.extract_options!
|
54
55
|
options = merged_options(options)
|
55
56
|
keys_to_names = names.inject({}){|map, name| map[escape_key(namespaced_key(name, options))] = name; map}
|
56
|
-
raw_values = @data.get_multi(keys_to_names.keys,
|
57
|
+
raw_values = @data.get_multi(keys_to_names.keys, RAW)
|
57
58
|
values = {}
|
58
59
|
raw_values.each do |key, value|
|
59
60
|
entry = deserialize_entry(value)
|
@@ -75,7 +76,7 @@ module ActiveSupport
|
|
75
76
|
@data.incr(escape_key(namespaced_key(name, options)), amount, expires_in, initial)
|
76
77
|
end
|
77
78
|
rescue Dalli::DalliError => e
|
78
|
-
logger.error("DalliError
|
79
|
+
logger.error("DalliError: #{e.message}") if logger
|
79
80
|
nil
|
80
81
|
end
|
81
82
|
|
@@ -92,7 +93,7 @@ module ActiveSupport
|
|
92
93
|
@data.decr(escape_key(namespaced_key(name, options)), amount, expires_in, initial)
|
93
94
|
end
|
94
95
|
rescue Dalli::DalliError => e
|
95
|
-
logger.error("DalliError
|
96
|
+
logger.error("DalliError: #{e.message}") if logger
|
96
97
|
nil
|
97
98
|
end
|
98
99
|
|
@@ -112,17 +113,22 @@ module ActiveSupport
|
|
112
113
|
end
|
113
114
|
|
114
115
|
protected
|
116
|
+
|
117
|
+
# This CacheStore impl controls value marshalling so we take special
|
118
|
+
# care to always pass :raw => true to the Dalli API so it does not
|
119
|
+
# double marshal.
|
120
|
+
|
115
121
|
# Read an entry from the cache.
|
116
122
|
def read_entry(key, options) # :nodoc:
|
117
|
-
deserialize_entry(@data.get(escape_key(key),
|
123
|
+
deserialize_entry(@data.get(escape_key(key), RAW))
|
118
124
|
rescue Dalli::DalliError => e
|
119
|
-
logger.error("DalliError
|
125
|
+
logger.error("DalliError: #{e.message}") if logger
|
120
126
|
nil
|
121
127
|
end
|
122
128
|
|
123
129
|
# Write an entry to the cache.
|
124
130
|
def write_entry(key, entry, options) # :nodoc:
|
125
|
-
method = options
|
131
|
+
method = options[:unless_exist] ? :add : :set
|
126
132
|
value = options[:raw] ? entry.value.to_s : entry
|
127
133
|
expires_in = options[:expires_in].to_i
|
128
134
|
if expires_in > 0 && !options[:raw]
|
@@ -131,7 +137,7 @@ module ActiveSupport
|
|
131
137
|
end
|
132
138
|
@data.send(method, escape_key(key), value, expires_in, options)
|
133
139
|
rescue Dalli::DalliError => e
|
134
|
-
logger.error("DalliError
|
140
|
+
logger.error("DalliError: #{e.message}") if logger
|
135
141
|
false
|
136
142
|
end
|
137
143
|
|
@@ -139,7 +145,7 @@ module ActiveSupport
|
|
139
145
|
def delete_entry(key, options) # :nodoc:
|
140
146
|
@data.delete(escape_key(key))
|
141
147
|
rescue Dalli::DalliError => e
|
142
|
-
logger.error("DalliError
|
148
|
+
logger.error("DalliError: #{e.message}") if logger
|
143
149
|
false
|
144
150
|
end
|
145
151
|
|
@@ -152,6 +158,8 @@ module ActiveSupport
|
|
152
158
|
|
153
159
|
def deserialize_entry(raw_value)
|
154
160
|
if raw_value
|
161
|
+
# FIXME: This is a terrible implementation for performance reasons:
|
162
|
+
# throwing an exception is much slower than some if logic.
|
155
163
|
entry = Marshal.load(raw_value) rescue raw_value
|
156
164
|
entry.is_a?(Entry) ? entry : Entry.new(entry)
|
157
165
|
else
|
@@ -45,6 +45,8 @@ module ActiveSupport
|
|
45
45
|
# Reads multiple keys from the cache using a single call to the
|
46
46
|
# servers for all keys. Options can be passed in the last argument.
|
47
47
|
def read_multi(*names)
|
48
|
+
options = nil
|
49
|
+
options = names.pop if names.last.is_a?(Hash)
|
48
50
|
keys_to_names = names.inject({}){|map, name| map[escape_key(name)] = name; map}
|
49
51
|
cache_keys = {}
|
50
52
|
# map keys to servers
|
@@ -53,62 +55,24 @@ module ActiveSupport
|
|
53
55
|
cache_keys[cache_key] = key
|
54
56
|
end
|
55
57
|
|
56
|
-
values = @data.get_multi
|
58
|
+
values = @data.get_multi(keys_to_names.keys, options)
|
57
59
|
results = {}
|
58
60
|
values.each do |key, value|
|
59
|
-
results[cache_keys[key]] =
|
61
|
+
results[cache_keys[key]] = value
|
60
62
|
end
|
61
63
|
results
|
62
64
|
end
|
63
65
|
|
64
|
-
# Increment a cached value. This method uses the memcached incr atomic
|
65
|
-
# operator and can only be used on values written with the :raw option.
|
66
|
-
# Calling it on a value not stored with :raw will initialize that value
|
67
|
-
# to zero.
|
68
|
-
def increment(key, amount = 1) # :nodoc:
|
69
|
-
log("incrementing", key, amount)
|
70
|
-
@data.incr(escape_key(key), amount)
|
71
|
-
rescue Dalli::DalliError => e
|
72
|
-
logger.error("DalliError (#{e}): #{e.message}") if logger
|
73
|
-
nil
|
74
|
-
end
|
75
|
-
|
76
|
-
# Decrement a cached value. This method uses the memcached decr atomic
|
77
|
-
# operator and can only be used on values written with the :raw option.
|
78
|
-
# Calling it on a value not stored with :raw will initialize that value
|
79
|
-
# to zero.
|
80
|
-
def decrement(key, amount = 1) # :nodoc:
|
81
|
-
log("decrement", key, amount)
|
82
|
-
@data.decr(escape_key(key), amount)
|
83
|
-
rescue Dalli::DalliError => e
|
84
|
-
logger.error("DalliError (#{e}): #{e.message}") if logger
|
85
|
-
nil
|
86
|
-
end
|
87
|
-
|
88
66
|
def reset
|
89
67
|
@data.reset
|
90
68
|
end
|
91
69
|
|
92
|
-
# Clear the entire cache on all memcached servers. This method should
|
93
|
-
# be used with care when using a shared cache.
|
94
|
-
def clear
|
95
|
-
@data.flush_all
|
96
|
-
end
|
97
|
-
|
98
|
-
# Get the statistics from the memcached servers.
|
99
|
-
def stats
|
100
|
-
@data.stats
|
101
|
-
end
|
102
|
-
|
103
70
|
# Read an entry from the cache.
|
104
71
|
def read(key, options = nil) # :nodoc:
|
105
72
|
super
|
106
|
-
|
107
|
-
return nil if value.nil?
|
108
|
-
value = options && options[:raw] ? value : Marshal.load(value)
|
109
|
-
value
|
73
|
+
@data.get(escape_key(key), options)
|
110
74
|
rescue Dalli::DalliError => e
|
111
|
-
logger.error("DalliError
|
75
|
+
logger.error("DalliError: #{e.message}")
|
112
76
|
nil
|
113
77
|
end
|
114
78
|
|
@@ -121,11 +85,11 @@ module ActiveSupport
|
|
121
85
|
# the cache. See ActiveSupport::Cache::Store#write for an example.
|
122
86
|
def write(key, value, options = nil)
|
123
87
|
super
|
88
|
+
value = value.to_s if options && options[:raw]
|
124
89
|
method = options && options[:unless_exist] ? :add : :set
|
125
|
-
value = options && options[:raw] ? value.to_s : Marshal.dump(value)
|
126
90
|
@data.send(method, escape_key(key), value, expires_in(options), options)
|
127
91
|
rescue Dalli::DalliError => e
|
128
|
-
logger.error("DalliError
|
92
|
+
logger.error("DalliError: #{e.message}")
|
129
93
|
false
|
130
94
|
end
|
131
95
|
|
@@ -133,7 +97,7 @@ module ActiveSupport
|
|
133
97
|
super
|
134
98
|
@data.delete(escape_key(key))
|
135
99
|
rescue Dalli::DalliError => e
|
136
|
-
logger.error("DalliError
|
100
|
+
logger.error("DalliError: #{e.message}")
|
137
101
|
false
|
138
102
|
end
|
139
103
|
|
@@ -144,6 +108,30 @@ module ActiveSupport
|
|
144
108
|
!read(key, options).nil?
|
145
109
|
end
|
146
110
|
|
111
|
+
# Increment a cached value. This method uses the memcached incr atomic
|
112
|
+
# operator and can only be used on values written with the :raw option.
|
113
|
+
# Calling it on a value not stored with :raw will initialize that value
|
114
|
+
# to zero.
|
115
|
+
def increment(key, amount = 1) # :nodoc:
|
116
|
+
log("incrementing", key, amount)
|
117
|
+
@data.incr(escape_key(key), amount)
|
118
|
+
rescue Dalli::DalliError => e
|
119
|
+
logger.error("DalliError: #{e.message}") if logger
|
120
|
+
nil
|
121
|
+
end
|
122
|
+
|
123
|
+
# Decrement a cached value. This method uses the memcached decr atomic
|
124
|
+
# operator and can only be used on values written with the :raw option.
|
125
|
+
# Calling it on a value not stored with :raw will initialize that value
|
126
|
+
# to zero.
|
127
|
+
def decrement(key, amount = 1) # :nodoc:
|
128
|
+
log("decrement", key, amount)
|
129
|
+
@data.decr(escape_key(key), amount)
|
130
|
+
rescue Dalli::DalliError => e
|
131
|
+
logger.error("DalliError: #{e.message}") if logger
|
132
|
+
nil
|
133
|
+
end
|
134
|
+
|
147
135
|
def delete_matched(matcher, options = nil) # :nodoc:
|
148
136
|
# don't do any local caching at present, just pass
|
149
137
|
# through and let the error happen
|
@@ -151,6 +139,17 @@ module ActiveSupport
|
|
151
139
|
raise "Not supported by Memcache"
|
152
140
|
end
|
153
141
|
|
142
|
+
# Clear the entire cache on all memcached servers. This method should
|
143
|
+
# be used with care when using a shared cache.
|
144
|
+
def clear
|
145
|
+
@data.flush_all
|
146
|
+
end
|
147
|
+
|
148
|
+
# Get the statistics from the memcached servers.
|
149
|
+
def stats
|
150
|
+
@data.stats
|
151
|
+
end
|
152
|
+
|
154
153
|
private
|
155
154
|
|
156
155
|
# Exists in 2.3.8 but not in 2.3.2 so roll our own version
|
data/lib/dalli/client.rb
CHANGED
@@ -44,7 +44,7 @@ module Dalli
|
|
44
44
|
def get_multi(*keys)
|
45
45
|
return {} if keys.empty?
|
46
46
|
options = nil
|
47
|
-
options = keys.pop if keys.last.is_a?(Hash)
|
47
|
+
options = keys.pop if keys.last.is_a?(Hash) || keys.last.nil?
|
48
48
|
ring.lock do
|
49
49
|
keys.flatten.each do |key|
|
50
50
|
perform(:getkq, key)
|
data/lib/dalli/server.rb
CHANGED
@@ -14,9 +14,7 @@ module Dalli
|
|
14
14
|
@weight ||= 1
|
15
15
|
@weight = Integer(@weight)
|
16
16
|
@down_at = nil
|
17
|
-
connection
|
18
17
|
@version = detect_memcached_version
|
19
|
-
raise NotImplementedError, "Dalli does not support memcached versions < 1.4.0, found #{@version} at #{@hostname}:#{@port}" if @version < '1.4.0'
|
20
18
|
Dalli.logger.debug { "#{@hostname}:#{@port} running memcached v#{@version}" }
|
21
19
|
end
|
22
20
|
|
@@ -64,15 +62,26 @@ module Dalli
|
|
64
62
|
private
|
65
63
|
|
66
64
|
def detect_memcached_version
|
65
|
+
return "(unknown)" if ENV['SKIP_MEMCACHE_VERSION_CHECK']
|
66
|
+
|
67
67
|
# HACK, the server does not appear to have a way to negotiate the protocol.
|
68
68
|
# If you ask for the version in text, the socket is immediately locked to the text
|
69
|
-
# protocol.
|
70
|
-
#
|
71
|
-
|
69
|
+
# protocol. But if we use binary, an old remote server will not respond. If
|
70
|
+
# the server is using SASL, it will not respond to the text protocol. Sigh.
|
71
|
+
if username
|
72
|
+
# using SASL, assume the binary protocol will work.
|
72
73
|
binary_version
|
73
|
-
|
74
|
-
|
75
|
-
|
74
|
+
else
|
75
|
+
# Use text to determine the remote version, close the socket and open it back up.
|
76
|
+
# Alternative suggestions welcome.
|
77
|
+
version = text_version
|
78
|
+
if version < '1.4.0'
|
79
|
+
Dalli.logger.error "Dalli does not support memcached versions < 1.4.0, found #{version} at #{@hostname}:#{@port}"
|
80
|
+
raise NotImplementedError, "Dalli does not support memcached versions < 1.4.0, found #{version} at #{@hostname}:#{@port}"
|
81
|
+
end
|
82
|
+
close
|
83
|
+
connection
|
84
|
+
version
|
76
85
|
end
|
77
86
|
end
|
78
87
|
|
@@ -188,18 +197,18 @@ module Dalli
|
|
188
197
|
cas_response
|
189
198
|
end
|
190
199
|
|
191
|
-
def binary_version
|
192
|
-
req = [REQUEST, OPCODES[:version], 0, 0, 0, 0, 0, 0, 0].pack(FORMAT[:noop])
|
193
|
-
write(req)
|
194
|
-
generic_response
|
195
|
-
end
|
196
|
-
|
197
200
|
def text_version
|
198
201
|
write("version\r\n")
|
199
202
|
connection.gets =~ /VERSION (.*)\r\n/
|
200
203
|
$1
|
201
204
|
end
|
202
205
|
|
206
|
+
def binary_version
|
207
|
+
req = [REQUEST, OPCODES[:version], 0, 0, 0, 0, 0, 0, 0].pack(FORMAT[:noop])
|
208
|
+
write(req)
|
209
|
+
generic_response
|
210
|
+
end
|
211
|
+
|
203
212
|
def cas_response
|
204
213
|
header = read(24)
|
205
214
|
raise Dalli::NetworkError, 'No response' if !header
|
@@ -450,9 +459,10 @@ module Dalli
|
|
450
459
|
content = read(count, socket)
|
451
460
|
return Dalli.logger.info("Dalli/SASL: #{content}") if status == 0
|
452
461
|
|
453
|
-
raise Dalli::
|
454
|
-
|
455
|
-
|
462
|
+
raise Dalli::DalliError, "Error authenticating: #{status}" unless status == 0x21
|
463
|
+
raise NotImplementedError, "No two-step authentication mechanisms supported"
|
464
|
+
# (step, msg) = sasl.receive('challenge', content)
|
465
|
+
# raise Dalli::NetworkError, "Authentication failed" if sasl.failed? || step != 'response'
|
456
466
|
end
|
457
467
|
end
|
458
468
|
end
|
data/lib/dalli/version.rb
CHANGED
data/test/memcached_mock.rb
CHANGED
data/test/test_active_support.rb
CHANGED
@@ -7,19 +7,20 @@ class TestActiveSupport < Test::Unit::TestCase
|
|
7
7
|
with_activesupport do
|
8
8
|
memcached do
|
9
9
|
connect
|
10
|
-
|
11
|
-
|
10
|
+
mvalue = @mc.fetch('somekeywithoutspaces', :expires_in => 1.second) { 123 }
|
11
|
+
dvalue = @dalli.fetch('someotherkeywithoutspaces', :expires_in => 1.second) { 123 }
|
12
|
+
assert_equal 123, dvalue
|
12
13
|
assert_equal mvalue, dvalue
|
13
14
|
|
14
15
|
o = Object.new
|
15
16
|
o.instance_variable_set :@foo, 'bar'
|
16
|
-
|
17
|
-
|
17
|
+
mvalue = @mc.fetch(rand_key, :raw => true) { o }
|
18
|
+
dvalue = @dalli.fetch(rand_key, :raw => true) { o }
|
18
19
|
assert_equal mvalue, dvalue
|
19
|
-
assert_equal o,
|
20
|
+
assert_equal o, mvalue
|
20
21
|
|
21
|
-
|
22
|
-
|
22
|
+
mvalue = @mc.fetch(rand_key) { o }
|
23
|
+
dvalue = @dalli.fetch(rand_key) { o }
|
23
24
|
assert_equal mvalue, dvalue
|
24
25
|
assert_equal o, dvalue
|
25
26
|
end
|
@@ -65,6 +66,33 @@ class TestActiveSupport < Test::Unit::TestCase
|
|
65
66
|
end
|
66
67
|
end
|
67
68
|
|
69
|
+
should 'support raw read_multi' do
|
70
|
+
with_activesupport do
|
71
|
+
memcached do
|
72
|
+
connect
|
73
|
+
@mc.write("abc", 5, :raw => true)
|
74
|
+
@mc.write("cba", 5, :raw => true)
|
75
|
+
if RAILS_VERSION < '3.0.0'
|
76
|
+
assert_raise ArgumentError do
|
77
|
+
@mc.read_multi("abc", "cba")
|
78
|
+
end
|
79
|
+
else
|
80
|
+
assert_equal({'abc' => '5', 'cba' => '5' }, @mc.read_multi("abc", "cba"))
|
81
|
+
end
|
82
|
+
|
83
|
+
@dalli.write("abc", 5, :raw => true)
|
84
|
+
@dalli.write("cba", 5, :raw => true)
|
85
|
+
if RAILS_VERSION < '3.0.0'
|
86
|
+
assert_raise ArgumentError do
|
87
|
+
@dalli.read_multi("abc", "cba")
|
88
|
+
end
|
89
|
+
else
|
90
|
+
assert_equal({'abc' => '5', 'cba' => '5' }, @dalli.read_multi("abc", "cba"))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
68
96
|
should 'support read, write and delete' do
|
69
97
|
with_activesupport do
|
70
98
|
memcached do
|
data/test/test_dalli.rb
CHANGED
@@ -2,7 +2,7 @@ require 'helper'
|
|
2
2
|
require 'memcached_mock'
|
3
3
|
|
4
4
|
class TestDalli < Test::Unit::TestCase
|
5
|
-
|
5
|
+
|
6
6
|
should "default to localhost:11211" do
|
7
7
|
dc = Dalli::Client.new
|
8
8
|
ring = dc.send(:ring)
|
@@ -323,13 +323,6 @@ class TestDalli < Test::Unit::TestCase
|
|
323
323
|
end
|
324
324
|
end
|
325
325
|
|
326
|
-
should 'gracefully handle authentication failures' do
|
327
|
-
memcached(19124, '-S') do |dc|
|
328
|
-
assert_raise Dalli::DalliError, /32/ do
|
329
|
-
dc.set('abc', 123)
|
330
|
-
end
|
331
|
-
end
|
332
|
-
end
|
333
326
|
|
334
327
|
should "handle namespaced keys" do
|
335
328
|
memcached do |dc|
|
@@ -342,6 +335,26 @@ class TestDalli < Test::Unit::TestCase
|
|
342
335
|
end
|
343
336
|
end
|
344
337
|
|
338
|
+
context 'without authentication credentials' do
|
339
|
+
setup do
|
340
|
+
ENV['MEMCACHE_USERNAME'] = 'testuser'
|
341
|
+
ENV['MEMCACHE_PASSWORD'] = 'wrongpwd'
|
342
|
+
end
|
343
|
+
|
344
|
+
teardown do
|
345
|
+
ENV['MEMCACHE_USERNAME'] = nil
|
346
|
+
ENV['MEMCACHE_PASSWORD'] = nil
|
347
|
+
end
|
348
|
+
|
349
|
+
should 'gracefully handle authentication failures' do
|
350
|
+
memcached(19124, '-S') do |dc|
|
351
|
+
assert_raise Dalli::DalliError, /32/ do
|
352
|
+
dc.set('abc', 123)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
345
358
|
# OSX: Create a SASL user for the memcached application like so:
|
346
359
|
#
|
347
360
|
# saslpasswd2 -a memcached -c testuser
|
@@ -360,7 +373,7 @@ class TestDalli < Test::Unit::TestCase
|
|
360
373
|
|
361
374
|
should 'support SASL authentication' do
|
362
375
|
memcached(19124, '-S') do |dc|
|
363
|
-
# I get "Dalli::
|
376
|
+
# I get "Dalli::DalliError: Error authenticating: 32" in OSX
|
364
377
|
# but SASL works on Heroku servers. YMMV.
|
365
378
|
assert_equal true, dc.set('abc', 123)
|
366
379
|
assert_equal 123, dc.get('abc')
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 9
|
8
7
|
- 10
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.10.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Mike Perham
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-16 00:00:00 -07:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|