dalli 2.7.3 → 3.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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