dalli 2.7.3 → 3.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +5 -5
  2. data/{History.md → CHANGELOG.md} +211 -0
  3. data/Gemfile +3 -6
  4. data/LICENSE +1 -1
  5. data/README.md +30 -208
  6. data/lib/dalli/cas/client.rb +2 -57
  7. data/lib/dalli/client.rb +254 -253
  8. data/lib/dalli/compressor.rb +13 -2
  9. data/lib/dalli/key_manager.rb +121 -0
  10. data/lib/dalli/options.rb +7 -7
  11. data/lib/dalli/pipelined_getter.rb +177 -0
  12. data/lib/dalli/protocol/base.rb +241 -0
  13. data/lib/dalli/protocol/binary/request_formatter.rb +117 -0
  14. data/lib/dalli/protocol/binary/response_header.rb +36 -0
  15. data/lib/dalli/protocol/binary/response_processor.rb +239 -0
  16. data/lib/dalli/protocol/binary/sasl_authentication.rb +60 -0
  17. data/lib/dalli/protocol/binary.rb +173 -0
  18. data/lib/dalli/protocol/connection_manager.rb +252 -0
  19. data/lib/dalli/protocol/meta/key_regularizer.rb +31 -0
  20. data/lib/dalli/protocol/meta/request_formatter.rb +121 -0
  21. data/lib/dalli/protocol/meta/response_processor.rb +211 -0
  22. data/lib/dalli/protocol/meta.rb +178 -0
  23. data/lib/dalli/protocol/response_buffer.rb +54 -0
  24. data/lib/dalli/protocol/server_config_parser.rb +86 -0
  25. data/lib/dalli/protocol/ttl_sanitizer.rb +45 -0
  26. data/lib/dalli/protocol/value_compressor.rb +85 -0
  27. data/lib/dalli/protocol/value_marshaller.rb +59 -0
  28. data/lib/dalli/protocol/value_serializer.rb +91 -0
  29. data/lib/dalli/protocol.rb +8 -0
  30. data/lib/dalli/ring.rb +97 -86
  31. data/lib/dalli/server.rb +4 -719
  32. data/lib/dalli/servers_arg_normalizer.rb +54 -0
  33. data/lib/dalli/socket.rb +123 -115
  34. data/lib/dalli/version.rb +5 -1
  35. data/lib/dalli.rb +45 -14
  36. data/lib/rack/session/dalli.rb +162 -42
  37. metadata +136 -63
  38. data/Performance.md +0 -42
  39. data/Rakefile +0 -43
  40. data/dalli.gemspec +0 -29
  41. data/lib/action_dispatch/middleware/session/dalli_store.rb +0 -81
  42. data/lib/active_support/cache/dalli_store.rb +0 -372
  43. data/lib/dalli/railtie.rb +0 -7
  44. data/test/benchmark_test.rb +0 -243
  45. data/test/helper.rb +0 -56
  46. data/test/memcached_mock.rb +0 -201
  47. data/test/sasl/memcached.conf +0 -1
  48. data/test/sasl/sasldb +0 -1
  49. data/test/test_active_support.rb +0 -541
  50. data/test/test_cas_client.rb +0 -107
  51. data/test/test_compressor.rb +0 -52
  52. data/test/test_dalli.rb +0 -682
  53. data/test/test_encoding.rb +0 -32
  54. data/test/test_failover.rb +0 -137
  55. data/test/test_network.rb +0 -64
  56. data/test/test_rack_session.rb +0 -341
  57. data/test/test_ring.rb +0 -85
  58. data/test/test_sasl.rb +0 -105
  59. data/test/test_serializer.rb +0 -29
  60. data/test/test_server.rb +0 -110
@@ -1,372 +0,0 @@
1
- # encoding: ascii
2
- require 'dalli'
3
-
4
- module ActiveSupport
5
- module Cache
6
- class DalliStore
7
-
8
- attr_reader :silence, :options
9
- alias_method :silence?, :silence
10
-
11
- # Silence the logger.
12
- def silence!
13
- @silence = true
14
- self
15
- end
16
-
17
- # Silence the logger within a block.
18
- def mute
19
- previous_silence, @silence = defined?(@silence) && @silence, true
20
- yield
21
- ensure
22
- @silence = previous_silence
23
- end
24
-
25
- ESCAPE_KEY_CHARS = /[\x00-\x20%\x7F-\xFF]/
26
-
27
- # Creates a new DalliStore object, with the given memcached server
28
- # addresses. Each address is either a host name, or a host-with-port string
29
- # in the form of "host_name:port". For example:
30
- #
31
- # ActiveSupport::Cache::DalliStore.new("localhost", "server-downstairs.localnetwork:8229")
32
- #
33
- # If no addresses are specified, then DalliStore will connect to
34
- # localhost port 11211 (the default memcached port).
35
- #
36
- # Connection Pool support
37
- #
38
- # If you are using multithreaded Rails, the Rails.cache singleton can become a source
39
- # of contention. You can use a connection pool of Dalli clients with Rails.cache by
40
- # passing :pool_size and/or :pool_timeout:
41
- #
42
- # config.cache_store = :dalli_store, 'localhost:11211', :pool_size => 10
43
- #
44
- # Both pool options default to 5. You must include the `connection_pool` gem if you
45
- # wish to use pool support.
46
- #
47
- def initialize(*addresses)
48
- addresses = addresses.flatten
49
- options = addresses.extract_options!
50
- @options = options.dup
51
-
52
- pool_options = {}
53
- pool_options[:size] = options[:pool_size] if options[:pool_size]
54
- pool_options[:timeout] = options[:pool_timeout] if options[:pool_timeout]
55
-
56
- @options[:compress] ||= @options[:compression]
57
-
58
- addresses.compact!
59
- servers = if addresses.empty?
60
- nil # use the default from Dalli::Client
61
- else
62
- addresses
63
- end
64
- if pool_options.empty?
65
- @data = Dalli::Client.new(servers, @options)
66
- else
67
- @data = ::ConnectionPool.new(pool_options) { Dalli::Client.new(servers, @options.merge(:threadsafe => false)) }
68
- end
69
-
70
- extend Strategy::LocalCache
71
- end
72
-
73
- ##
74
- # Access the underlying Dalli::Client or ConnectionPool instance for
75
- # access to get_multi, etc.
76
- def dalli
77
- @data
78
- end
79
-
80
- def with(&block)
81
- @data.with(&block)
82
- end
83
-
84
- def fetch(name, options=nil)
85
- options ||= {}
86
- namespaced_name = namespaced_key(name, options)
87
-
88
- if block_given?
89
- unless options[:force]
90
- entry = instrument(:read, namespaced_name, options) do |payload|
91
- read_entry(namespaced_name, options).tap do |result|
92
- if payload
93
- payload[:super_operation] = :fetch
94
- payload[:hit] = !result.nil?
95
- end
96
- end
97
- end
98
- end
99
-
100
- if !entry.nil?
101
- instrument(:fetch_hit, name, options) { |payload| }
102
- entry
103
- else
104
- result = instrument(:generate, name, options) do |payload|
105
- yield
106
- end
107
- write(name, result, options)
108
- result
109
- end
110
- else
111
- read(name, options)
112
- end
113
- end
114
-
115
- def read(name, options=nil)
116
- options ||= {}
117
- name = namespaced_key(name, options)
118
-
119
- instrument(:read, name, options) do |payload|
120
- entry = read_entry(name, options)
121
- payload[:hit] = !entry.nil? if payload
122
- entry
123
- end
124
- end
125
-
126
- def write(name, value, options=nil)
127
- options ||= {}
128
- name = namespaced_key(name, options)
129
-
130
- instrument(:write, name, options) do |payload|
131
- with do |connection|
132
- options = options.merge(:connection => connection)
133
- write_entry(name, value, options)
134
- end
135
- end
136
- end
137
-
138
- def exist?(name, options=nil)
139
- options ||= {}
140
- name = namespaced_key(name, options)
141
-
142
- log(:exist, name, options)
143
- !read_entry(name, options).nil?
144
- end
145
-
146
- def delete(name, options=nil)
147
- options ||= {}
148
- name = namespaced_key(name, options)
149
-
150
- instrument(:delete, name, options) do |payload|
151
- delete_entry(name, options)
152
- end
153
- end
154
-
155
- # Reads multiple keys from the cache using a single call to the
156
- # servers for all keys. Keys must be Strings.
157
- def read_multi(*names)
158
- options = names.extract_options!
159
- mapping = names.inject({}) { |memo, name| memo[namespaced_key(name, options)] = name; memo }
160
- instrument(:read_multi, names) do
161
- results = {}
162
- if local_cache
163
- mapping.each_key do |key|
164
- if value = local_cache.read_entry(key, options)
165
- results[key] = value
166
- end
167
- end
168
- end
169
-
170
- data = with { |c| c.get_multi(mapping.keys - results.keys) }
171
- results.merge!(data)
172
- results.inject({}) do |memo, (inner, _)|
173
- entry = results[inner]
174
- # NB Backwards data compatibility, to be removed at some point
175
- value = (entry.is_a?(ActiveSupport::Cache::Entry) ? entry.value : entry)
176
- memo[mapping[inner]] = value
177
- local_cache.write_entry(inner, value, options) if local_cache
178
- memo
179
- end
180
- end
181
- end
182
-
183
- # Fetches data from the cache, using the given keys. If there is data in
184
- # the cache with the given keys, then that data is returned. Otherwise,
185
- # the supplied block is called for each key for which there was no data,
186
- # and the result will be written to the cache and returned.
187
- def fetch_multi(*names)
188
- options = names.extract_options!
189
- mapping = names.inject({}) { |memo, name| memo[namespaced_key(name, options)] = name; memo }
190
-
191
- instrument(:fetch_multi, names) do
192
- with do |connection|
193
- results = connection.get_multi(mapping.keys)
194
-
195
- connection.multi do
196
- mapping.inject({}) do |memo, (expanded, name)|
197
- memo[name] = results[expanded]
198
- if memo[name].nil?
199
- value = yield(name)
200
- memo[name] = value
201
- options = options.merge(:connection => connection)
202
- write_entry(expanded, value, options)
203
- end
204
-
205
- memo
206
- end
207
- end
208
- end
209
- end
210
- end
211
-
212
- # Increment a cached value. This method uses the memcached incr atomic
213
- # operator and can only be used on values written with the :raw option.
214
- # Calling it on a value not stored with :raw will fail.
215
- # :initial defaults to the amount passed in, as if the counter was initially zero.
216
- # memcached counters cannot hold negative values.
217
- def increment(name, amount = 1, options=nil)
218
- options ||= {}
219
- name = namespaced_key(name, options)
220
- initial = options.has_key?(:initial) ? options[:initial] : amount
221
- expires_in = options[:expires_in]
222
- instrument(:increment, name, :amount => amount) do
223
- with { |c| c.incr(name, amount, expires_in, initial) }
224
- end
225
- rescue Dalli::DalliError => e
226
- logger.error("DalliError: #{e.message}") if logger
227
- raise if raise_errors?
228
- nil
229
- end
230
-
231
- # Decrement a cached value. This method uses the memcached decr atomic
232
- # operator and can only be used on values written with the :raw option.
233
- # Calling it on a value not stored with :raw will fail.
234
- # :initial defaults to zero, as if the counter was initially zero.
235
- # memcached counters cannot hold negative values.
236
- def decrement(name, amount = 1, options=nil)
237
- options ||= {}
238
- name = namespaced_key(name, options)
239
- initial = options.has_key?(:initial) ? options[:initial] : 0
240
- expires_in = options[:expires_in]
241
- instrument(:decrement, name, :amount => amount) do
242
- with { |c| c.decr(name, amount, expires_in, initial) }
243
- end
244
- rescue Dalli::DalliError => e
245
- logger.error("DalliError: #{e.message}") if logger
246
- raise if raise_errors?
247
- nil
248
- end
249
-
250
- # Clear the entire cache on all memcached servers. This method should
251
- # be used with care when using a shared cache.
252
- def clear(options=nil)
253
- instrument(:clear, 'flushing all keys') do
254
- with { |c| c.flush_all }
255
- end
256
- rescue Dalli::DalliError => e
257
- logger.error("DalliError: #{e.message}") if logger
258
- raise if raise_errors?
259
- nil
260
- end
261
-
262
- # Clear any local cache
263
- def cleanup(options=nil)
264
- end
265
-
266
- # Get the statistics from the memcached servers.
267
- def stats
268
- with { |c| c.stats }
269
- end
270
-
271
- def reset
272
- with { |c| c.reset }
273
- end
274
-
275
- def logger
276
- Dalli.logger
277
- end
278
-
279
- def logger=(new_logger)
280
- Dalli.logger = new_logger
281
- end
282
-
283
- protected
284
-
285
- # Read an entry from the cache.
286
- def read_entry(key, options) # :nodoc:
287
- entry = with { |c| c.get(key, options) }
288
- # NB Backwards data compatibility, to be removed at some point
289
- entry.is_a?(ActiveSupport::Cache::Entry) ? entry.value : entry
290
- rescue Dalli::DalliError => e
291
- logger.error("DalliError: #{e.message}") if logger
292
- raise if raise_errors?
293
- nil
294
- end
295
-
296
- # Write an entry to the cache.
297
- def write_entry(key, value, options) # :nodoc:
298
- # cleanup LocalCache
299
- cleanup if options[:unless_exist]
300
- method = options[:unless_exist] ? :add : :set
301
- expires_in = options[:expires_in]
302
- connection = options.delete(:connection)
303
- connection.send(method, key, value, expires_in, options)
304
- rescue Dalli::DalliError => e
305
- logger.error("DalliError: #{e.message}") if logger
306
- raise if raise_errors?
307
- false
308
- end
309
-
310
- # Delete an entry from the cache.
311
- def delete_entry(key, options) # :nodoc:
312
- with { |c| c.delete(key) }
313
- rescue Dalli::DalliError => e
314
- logger.error("DalliError: #{e.message}") if logger
315
- raise if raise_errors?
316
- false
317
- end
318
-
319
- private
320
-
321
- def namespaced_key(key, options)
322
- key = expanded_key(key)
323
- namespace = options[:namespace] if options
324
- prefix = namespace.is_a?(Proc) ? namespace.call : namespace
325
- key = "#{prefix}:#{key}" if prefix
326
- key
327
- end
328
-
329
- # Expand key to be a consistent string value. Invoke +cache_key+ if
330
- # object responds to +cache_key+. Otherwise, to_param method will be
331
- # called. If the key is a Hash, then keys will be sorted alphabetically.
332
- def expanded_key(key) # :nodoc:
333
- return key.cache_key.to_s if key.respond_to?(:cache_key)
334
-
335
- case key
336
- when Array
337
- if key.size > 1
338
- key = key.collect{|element| expanded_key(element)}
339
- else
340
- key = key.first
341
- end
342
- when Hash
343
- key = key.sort_by { |k,_| k.to_s }.collect{|k,v| "#{k}=#{v}"}
344
- end
345
-
346
- key = key.to_param
347
- if key.respond_to? :force_encoding
348
- key = key.dup
349
- key.force_encoding('binary')
350
- end
351
- key
352
- end
353
-
354
- def instrument(operation, key, options=nil)
355
- log(operation, key, options)
356
-
357
- payload = { :key => key }
358
- payload.merge!(options) if options.is_a?(Hash)
359
- ActiveSupport::Notifications.instrument("cache_#{operation}.active_support", payload){ yield(payload) }
360
- end
361
-
362
- def log(operation, key, options=nil)
363
- return unless logger && logger.debug? && !silence?
364
- logger.debug("Cache #{operation}: #{key}#{options.blank? ? "" : " (#{options.inspect})"}")
365
- end
366
-
367
- def raise_errors?
368
- !!@options[:raise_errors]
369
- end
370
- end
371
- end
372
- end
data/lib/dalli/railtie.rb DELETED
@@ -1,7 +0,0 @@
1
- module Dalli
2
- class Railtie < ::Rails::Railtie
3
- config.before_configuration do
4
- config.cache_store = :dalli_store
5
- end
6
- end
7
- end
@@ -1,243 +0,0 @@
1
- require 'helper'
2
- require 'benchmark'
3
- require 'active_support/cache/dalli_store'
4
-
5
- describe 'performance' do
6
- before do
7
- puts "Testing #{Dalli::VERSION} with #{RUBY_DESCRIPTION}"
8
- # We'll use a simple @value to try to avoid spending time in Marshal,
9
- # which is a constant penalty that both clients have to pay
10
- @value = []
11
- @marshalled = Marshal.dump(@value)
12
-
13
- @port = 23417
14
- @servers = ["127.0.0.1:#{@port}", "localhost:#{@port}"]
15
- @key1 = "Short"
16
- @key2 = "Sym1-2-3::45"*8
17
- @key3 = "Long"*40
18
- @key4 = "Medium"*8
19
- # 5 and 6 are only used for multiget miss test
20
- @key5 = "Medium2"*8
21
- @key6 = "Long3"*40
22
- @counter = 'counter'
23
- end
24
-
25
- it 'runs benchmarks' do
26
- memcached(@port) do
27
-
28
- Benchmark.bm(37) do |x|
29
-
30
- n = 2500
31
-
32
- @ds = ActiveSupport::Cache::DalliStore.new(@servers)
33
- x.report("mixed:rails:dalli") do
34
- n.times do
35
- @ds.read @key1
36
- @ds.write @key2, @value
37
- @ds.fetch(@key3) { @value }
38
- @ds.fetch(@key2) { @value }
39
- @ds.fetch(@key1) { @value }
40
- @ds.write @key2, @value, :unless_exists => true
41
- @ds.delete @key2
42
- @ds.increment @counter, 1, :initial => 100
43
- @ds.increment @counter, 1, :expires_in => 12
44
- @ds.decrement @counter, 1
45
- end
46
- end
47
-
48
- x.report("mixed:rails-localcache:dalli") do
49
- n.times do
50
- @ds.with_local_cache do
51
- @ds.read @key1
52
- @ds.write @key2, @value
53
- @ds.fetch(@key3) { @value }
54
- @ds.fetch(@key2) { @value }
55
- @ds.fetch(@key1) { @value }
56
- @ds.write @key2, @value, :unless_exists => true
57
- @ds.delete @key2
58
- @ds.increment @counter, 1, :initial => 100
59
- @ds.increment @counter, 1, :expires_in => 12
60
- @ds.decrement @counter, 1
61
- end
62
- end
63
- end
64
-
65
- @ds.clear
66
- sizeable_data = "<marquee>some view partial data</marquee>" * 50
67
- [@key1, @key2, @key3, @key4, @key5, @key6].each do |key|
68
- @ds.write(key, sizeable_data)
69
- end
70
-
71
- x.report("read_multi_big:rails:dalli") do
72
- n.times do
73
- @ds.read_multi @key1, @key2, @key3, @key4
74
- @ds.read @key1
75
- @ds.read @key2
76
- @ds.read @key3
77
- @ds.read @key4
78
- @ds.read @key1
79
- @ds.read @key2
80
- @ds.read @key3
81
- @ds.read_multi @key1, @key2, @key3
82
- end
83
- end
84
-
85
- x.report("read_multi_big:rails-localcache:dalli") do
86
- n.times do
87
- @ds.with_local_cache do
88
- @ds.read_multi @key1, @key2, @key3, @key4
89
- @ds.read @key1
90
- @ds.read @key2
91
- @ds.read @key3
92
- @ds.read @key4
93
- end
94
- @ds.with_local_cache do
95
- @ds.read @key1
96
- @ds.read @key2
97
- @ds.read @key3
98
- @ds.read_multi @key1, @key2, @key3
99
- end
100
- end
101
- end
102
-
103
- @m = Dalli::Client.new(@servers)
104
- x.report("set:plain:dalli") do
105
- n.times do
106
- @m.set @key1, @marshalled, 0, :raw => true
107
- @m.set @key2, @marshalled, 0, :raw => true
108
- @m.set @key3, @marshalled, 0, :raw => true
109
- @m.set @key1, @marshalled, 0, :raw => true
110
- @m.set @key2, @marshalled, 0, :raw => true
111
- @m.set @key3, @marshalled, 0, :raw => true
112
- end
113
- end
114
-
115
- @m = Dalli::Client.new(@servers)
116
- x.report("setq:plain:dalli") do
117
- @m.multi do
118
- n.times do
119
- @m.set @key1, @marshalled, 0, :raw => true
120
- @m.set @key2, @marshalled, 0, :raw => true
121
- @m.set @key3, @marshalled, 0, :raw => true
122
- @m.set @key1, @marshalled, 0, :raw => true
123
- @m.set @key2, @marshalled, 0, :raw => true
124
- @m.set @key3, @marshalled, 0, :raw => true
125
- end
126
- end
127
- end
128
-
129
- @m = Dalli::Client.new(@servers)
130
- x.report("set:ruby:dalli") do
131
- n.times do
132
- @m.set @key1, @value
133
- @m.set @key2, @value
134
- @m.set @key3, @value
135
- @m.set @key1, @value
136
- @m.set @key2, @value
137
- @m.set @key3, @value
138
- end
139
- end
140
-
141
- @m = Dalli::Client.new(@servers)
142
- x.report("get:plain:dalli") do
143
- n.times do
144
- @m.get @key1, :raw => true
145
- @m.get @key2, :raw => true
146
- @m.get @key3, :raw => true
147
- @m.get @key1, :raw => true
148
- @m.get @key2, :raw => true
149
- @m.get @key3, :raw => true
150
- end
151
- end
152
-
153
- @m = Dalli::Client.new(@servers)
154
- x.report("get:ruby:dalli") do
155
- n.times do
156
- @m.get @key1
157
- @m.get @key2
158
- @m.get @key3
159
- @m.get @key1
160
- @m.get @key2
161
- @m.get @key3
162
- end
163
- end
164
-
165
- @m = Dalli::Client.new(@servers)
166
- x.report("multiget:ruby:dalli") do
167
- n.times do
168
- # We don't use the keys array because splat is slow
169
- @m.get_multi @key1, @key2, @key3, @key4, @key5, @key6
170
- end
171
- end
172
-
173
- @m = Dalli::Client.new(@servers)
174
- x.report("missing:ruby:dalli") do
175
- n.times do
176
- begin @m.delete @key1; rescue; end
177
- begin @m.get @key1; rescue; end
178
- begin @m.delete @key2; rescue; end
179
- begin @m.get @key2; rescue; end
180
- begin @m.delete @key3; rescue; end
181
- begin @m.get @key3; rescue; end
182
- end
183
- end
184
-
185
- @m = Dalli::Client.new(@servers)
186
- x.report("mixed:ruby:dalli") do
187
- n.times do
188
- @m.set @key1, @value
189
- @m.set @key2, @value
190
- @m.set @key3, @value
191
- @m.get @key1
192
- @m.get @key2
193
- @m.get @key3
194
- @m.set @key1, @value
195
- @m.get @key1
196
- @m.set @key2, @value
197
- @m.get @key2
198
- @m.set @key3, @value
199
- @m.get @key3
200
- end
201
- end
202
-
203
- @m = Dalli::Client.new(@servers)
204
- x.report("mixedq:ruby:dalli") do
205
- @m.multi do
206
- n.times do
207
- @m.set @key1, @value
208
- @m.set @key2, @value
209
- @m.set @key3, @value
210
- @m.get @key1
211
- @m.get @key2
212
- @m.get @key3
213
- @m.set @key1, @value
214
- @m.get @key1
215
- @m.set @key2, @value
216
- @m.replace @key2, @value
217
- @m.delete @key3
218
- @m.add @key3, @value
219
- @m.get @key2
220
- @m.set @key3, @value
221
- @m.get @key3
222
- end
223
- end
224
- end
225
-
226
- @m = Dalli::Client.new(@servers)
227
- x.report("incr:ruby:dalli") do
228
- counter = 'foocount'
229
- n.times do
230
- @m.incr counter, 1, 0, 1
231
- end
232
- n.times do
233
- @m.decr counter, 1
234
- end
235
-
236
- assert_equal 0, @m.incr(counter, 0)
237
- end
238
-
239
- end
240
- end
241
-
242
- end
243
- end
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